").addClass("strp-close-icon")))
+ ))
+ );
- var orientation = this.getOrientation();
+ Pages.initialize(this._pages);
- var elements = this.element;
- if (this.spinnerMove) elements = elements.add(this.spinnerMove);
+ // support classes
+ if (Support.mobileTouch) this.element.addClass("strp-mobile-touch");
+ if (!Support.svg) this.element.addClass("strp-no-svg");
- elements
- .removeClass("strp-horizontal strp-vertical")
- .addClass("strp-" + orientation);
+ // events
+ this._close.on(
+ "click",
+ function (event) {
+ event.preventDefault();
+ this.hide();
+ }.bind(this)
+ );
+
+ this._previous.on(
+ "click",
+ function (event) {
+ this.previous();
+ this._onMouseMove(event); // update cursor
+ }.bind(this)
+ );
+
+ this._next.on(
+ "click",
+ function (event) {
+ this.next();
+ this._onMouseMove(event); // update cursor
+ }.bind(this)
+ );
+
+ this.hideUI(null, 0); // start with hidden <>
+ },
+
+ setSkin: function (skin) {
+ if (this._skin) {
+ this.element.removeClass("strp-window-skin-" + this._skin);
+ }
+ this.element.addClass("strp-window-skin-" + skin);
- var ss = "strp-side-";
- elements
- .removeClass(ss + "top " + ss + "right " + ss + "bottom " + ss + "left")
- .addClass(ss + side);
+ this._skin = skin;
+ },
- if (callback) callback();
- },
+ setSpinnerSkin: function (skin) {
+ if (!this.spinnerMove) return;
- getOrientation: function(side) {
- return this.side === "left" || this.side === "right"
- ? "horizontal"
- : "vertical";
- },
+ if (this._spinnerSkin) {
+ this.spinnerMove.removeClass(
+ "strp-spinner-move-skin-" + this._spinnerSkin
+ );
+ }
- // loading indicator
- startLoading: function() {
- if (!this._spinner) return;
+ this.spinnerMove.addClass("strp-spinner-move-skin-" + skin);
+ // refresh in case of styling updates
+ this._spinner.refresh();
- this.spinnerMove.show();
- this._spinner.show();
- },
+ this._spinnerSkin = skin;
+ },
- stopLoading: function() {
- if (!this._spinner) return;
+ // Resize
+ startObservingResize: function () {
+ if (this._isObservingResize) return;
- // we only stop loading if there are no loading pages anymore
- var loadingCount = Pages.getLoadingCount();
+ this._onWindowResizeHandler = this._onWindowResize.bind(this);
+ $(window).on("resize orientationchange", this._onWindowResizeHandler);
- if (loadingCount < 1) {
- this._spinner.hide(
- $.proxy(function() {
- this.spinnerMove.hide();
- }, this)
- );
- }
- },
+ this._isObservingResize = true;
+ },
- setPosition: function(position, callback) {
- this._position = position;
+ stopObservingResize: function () {
+ if (this._onWindowResizeHandler) {
+ $(window).off("resize orientationchange", this._onWindowResizeHandler);
+ this._onWindowResizeHandler = null;
+ }
- // store the current view
- this.view = this.views[position - 1];
-
- // we need to make sure that a possible hide effect doesn't
- // trigger its callbacks, as that would cancel the showing/loading
- // of the page started below
- this.stopHideQueue();
-
- // store the page and show it
- this.page = Pages.show(
- position,
- $.proxy(function() {
- var afterPosition = this.view.options.afterPosition;
- if ($.type(afterPosition) === "function") {
- afterPosition.call(Strip, position);
- }
- if (callback) callback();
- }, this)
- );
- },
+ this._isObservingResize = false;
+ },
+
+ _onWindowResize: function () {
+ var page;
+ if (!(page = Pages.page)) return;
+
+ if (page.animated || page.animatingWindow) {
+ // we're animating, don't stop the animation,
+ // instead update dimensions and restart/continue showing
+ page.fitToWindow();
+ page.show();
+ } else {
+ // we're not in an animation, resize instantly
+ page.fitToWindow();
+ this.resize(page.z, null, 0);
+ this.adjustPrevNext(null, true);
+ }
+ },
- hide: function(callback) {
- if (!this.view) return;
+ resize: function (wh, callback, alternateDuration) {
+ var orientation = this.getOrientation(),
+ Z = orientation === "vertical" ? "Height" : "Width",
+ z = Z.toLowerCase();
- var hideQueue = this.queues.hide;
- hideQueue.queue([]); // clear queue
+ if (wh > 0) {
+ this.visible = true;
+ this.startObservingResize();
+ }
- hideQueue.queue(
- $.proxy(function(next_stop) {
- Pages.stop();
- next_stop();
- }, this)
- );
+ var fromZ = Window.element["outer" + Z](),
+ duration;
+
+ // if we're opening use the show duration
+ if (fromZ === 0) {
+ duration = this.view.options.effects.window.show;
+
+ // add opening class
+ this.element.addClass("strp-opening");
+ this.opening = true;
+ } else if (typeof alternateDuration === "number") {
+ // alternate when set
+ duration = alternateDuration;
+ } else {
+ // otherwise decide on a duration for the transition
+ // based on distance
+ var transition = this.view.options.effects.transition,
+ min = transition.min,
+ max = transition.max,
+ tdiff = max - min,
+ viewport = Bounds.viewport(),
+ distance = Math.abs(fromZ - wh),
+ percentage = Math.min(1, distance / viewport[z]);
+
+ duration = Math.round(min + percentage * tdiff);
+ }
- hideQueue.queue(
- $.proxy(function(next_unbinds) {
- // ui
- var duration = this.view ? this.view.options.effects.window.hide : 0;
- this.unbindUI();
- this.hideUI(null, duration);
+ if (wh === 0) {
+ this.closing = true;
+ // we only add the closing class if we're not currently animating the window
+ if (!this.element.is(":animated")) {
+ this.element.addClass("strp-closing");
+ }
+ }
- // close on click outside
- this.unbindHideOnClickOutside();
+ // the animations
+ var css = { overflow: "visible" };
+ css[z] = wh;
- // keyboard
- Keyboard.disable();
+ var fx = 1;
- next_unbinds();
- }, this)
- );
+ // _getEventSide checks this.element.outerWidth() on mousemove only when
+ // this._outerWidth isn't set, we need that during animation,
+ // afterResize will set it back along with the cached offsetLeft
+ this._outerWidth = null;
+ this._offsetLeft = null;
- hideQueue.queue(
- $.proxy(function(next_zero) {
- // active classes should removed right as the closing effect starts
- // because clicking an element as it closes will re-open it,
- // that needs to be reflected in the class
- Pages.removeActiveClasses();
+ var onResize = this.view.options.onResize,
+ hasOnResize = typeof onResize === "function";
- this.resize(0, next_zero, this.view.options.effects.window.hide);
+ this.element.stop(true).animate(
+ css,
+ $.extend(
+ {
+ duration: duration,
+ complete: function () {
+ if (--fx < 1) this._afterResize(callback);
+ }.bind(this),
+ },
+ !hasOnResize
+ ? {}
+ : {
+ // we only add step if there's an onResize callback
+ step: function (now, fx) {
+ if (fx.prop === z) {
+ onResize.call(Strip, fx.prop, now, this.side);
+ }
+ }.bind(this),
+ }
+ )
+ );
- // after we initiate the hide resize, the next resize should bring up the UI again
- this._showUIOnResize = true;
- }, this)
+ if (this.spinnerMove) {
+ fx++; // sync this effect
+ this.spinnerMove.stop(true).animate(
+ css,
+ duration,
+ function () {
+ if (--fx < 1) this._afterResize(callback);
+ }.bind(this)
);
+ }
- // callbacks after resize in a separate queue
- // so we can stop the hideQueue without stopping the resize
- hideQueue.queue(
- $.proxy(function(next_after_resize) {
- this._safeResetsAfterSwitchSide();
+ // return the duration for later use in synced animations
+ return duration;
+ },
- this.stopObservingResize();
+ _afterResize: function (callback) {
+ this.opening = false;
+ this.closing = false;
+ this.element.removeClass("strp-opening strp-closing");
- Pages.removeAll();
+ // cache outerWidth and offsetLeft for _getEventSide on mousemove
+ this._outerWidth = this.element.outerWidth();
+ this._offsetLeft = this.element.offset().left;
- this.timers.clear();
+ if (callback) callback();
+ },
- this._position = -1;
+ adjustPrevNext: function (callback, alternateDuration) {
+ if (!this.view || !Pages.page) return;
+ var page = Pages.page;
- // afterHide callback
- var afterHide = this.view && this.view.options.afterHide;
- if ($.type(afterHide) === "function") {
- afterHide.call(Strip);
- }
+ // offset <>
+ var windowVisible = this.element.is(":visible");
+ if (!windowVisible) this.element.show();
- this.view = null;
+ var pRestoreStyle = this._previous.attr("style");
+ //this._previous.attr({ style: '' });
+ this._previous.removeAttr("style");
+ var pnMarginTop = parseInt(this._previous.css("margin-top")); // the original margin top
+ this._previous.attr({ style: pRestoreStyle });
- next_after_resize();
- }, this)
- );
+ if (!windowVisible) this.element.hide();
- if ($.type(callback) === "function") {
- hideQueue.queue(
- $.proxy(function(next_callback) {
- callback();
- next_callback();
- }, this)
- );
- }
- },
+ var iH = page.info ? page.info.outerHeight() : 0;
- // stop all callbacks possibly queued up into a hide animation
- // this allows the hide animation to finish as we start showing/loading
- // a new page, a callback could otherwise interrupt this
- stopHideQueue: function() {
- this.queues.hide.queue([]);
- },
+ var buttons = this._previous.add(this._next),
+ css = { "margin-top": pnMarginTop - iH * 0.5 };
- // these are things we can safely call when switching side as well
- _safeResetsAfterSwitchSide: function() {
- // remove styling from window, so no width: 100%; height: 0 issues
- this.element.removeAttr("style");
- if (this.spinnerMove) this.spinnerMove.removeAttr("style");
+ var duration = this.view.options.effects.transition.min;
+ if (typeof alternateDuration === "number") duration = alternateDuration;
- //Pages.removeExpired();
- this.visible = false;
- this.hideUI(null, 0);
- this.timers.clear("ui");
- this.resetPrevNext();
+ // adjust <> instantly when opening
+ if (this.opening) duration = 0;
- // clear cached mousemove
- this._x = -1;
- this._y = -1;
- },
+ buttons.stop(true).animate(css, duration, callback);
- // Previous / Next
- mayPrevious: function() {
- return (
- (this.view &&
- this.view.options.loop &&
- this.views &&
- this.views.length > 1) ||
- this._position !== 1
- );
- },
+ this._previous[this.mayPrevious() ? "show" : "hide"]();
+ this._next[this.mayNext() ? "show" : "hide"]();
+ },
- previous: function(force) {
- var mayPrevious = this.mayPrevious();
+ resetPrevNext: function () {
+ var buttons = this._previous.add(this._next);
+ buttons.stop(true).removeAttr("style");
+ },
- if (force || mayPrevious) {
- this.setPosition(this.getSurroundingIndexes().previous);
- }
- },
+ // Load
+ load: function (views, position) {
+ this.views = views;
- mayNext: function() {
- var hasViews = this.views && this.views.length > 1;
+ Pages.add(views);
- return (
- (this.view && this.view.options.loop && hasViews) ||
- (hasViews && this.getSurroundingIndexes().next !== 1)
- );
- },
+ if (position) {
+ this.setPosition(position);
+ }
+ },
- next: function(force) {
- var mayNext = this.mayNext();
+ // adjust the size based on the current view
+ // this might require closing the window first
+ setSide: function (side, callback) {
+ if (this.side === side) {
+ if (callback) callback();
+ return;
+ }
- if (force || mayNext) {
- this.setPosition(this.getSurroundingIndexes().next);
- }
- },
+ // side has change, first close the window if it isn't already closed
+ if (this.visible) {
+ // NOTE: side should be set here since the window was visible
+ // so using resize should be safe
- // surrounding
- getSurroundingIndexes: function() {
- if (!this.views) return {};
+ // hide the UI
+ var duration = this.view ? this.view.options.effects.window.hide : 0;
+ this.hideUI(null, duration);
- var pos = this._position,
- length = this.views.length;
+ // avoid tracking mouse movement while the window is closing
+ this.unbindUI();
- var previous = pos <= 1 ? length : pos - 1,
- next = pos >= length ? 1 : pos + 1;
+ // hide
+ this.resize(
+ 0,
+ function () {
+ // some of the things we'd normally do in hide
+ this._safeResetsAfterSwitchSide();
- return {
- previous: previous,
- next: next
- };
- },
+ // we instantly hide the other views here
+ Pages.hideVisibleInactive(0);
- // close when clicking outside of strip or an element opening strip
- bindHideOnClickOutside: function() {
- this.unbindHideOnClickOutside();
- $(document.documentElement).on(
- "click",
- (this._delegateHideOutsideHandler = $.proxy(
- this._delegateHideOutside,
- this
- ))
+ this._setSide(side, callback);
+ }.bind(this)
);
- },
- unbindHideOnClickOutside: function() {
- if (this._delegateHideOutsideHandler) {
- $(document.documentElement).off(
- "click",
- this._delegateHideOutsideHandler
- );
- this._delegateHideOutsideHandler = null;
- }
- },
+ // show the UI on the next resize
+ this._showUIOnResize = true;
+ } else {
+ this._setSide(side, callback);
+ }
+ },
- _delegateHideOutside: function(event) {
- var page = Pages.page;
- if (!this.visible || !(page && page.view.options.hideOnClickOutside))
- return;
+ _setSide: function (side, callback) {
+ this.side = side;
- var element = event.target;
+ var orientation = this.getOrientation();
- if (!$(element).closest(".strip, .strp-window")[0]) {
- this.hide();
- }
- },
+ var elements = this.element;
+ if (this.spinnerMove) elements = elements.add(this.spinnerMove);
- // UI
- bindUI: function() {
- this.unbindUI();
+ elements
+ .removeClass("strp-horizontal strp-vertical")
+ .addClass("strp-" + orientation);
- if (!Support.mobileTouch) {
- this.element
- .on("mouseenter", (this._showUIHandler = $.proxy(this.showUI, this)))
- .on("mouseleave", (this._hideUIHandler = $.proxy(this.hideUI, this)));
+ var ss = "strp-side-";
+ elements
+ .removeClass(ss + "top " + ss + "right " + ss + "bottom " + ss + "left")
+ .addClass(ss + side);
- this.element.on(
- "mousemove",
- (this._mousemoveUIHandler = $.proxy(function(event) {
- // Chrome has a bug that triggers mousemove events incorrectly
- // we have to work around this by comparing cursor positions
- // so only true mousemove events pass through:
- // https://code.google.com/p/chromium/issues/detail?id=420032
- var x = event.pageX,
- y = event.pageY;
-
- if (this._hoveringNav || (y === this._y && x === this._x)) {
- return;
- }
+ if (callback) callback();
+ },
- // cache x/y
- this._x = x;
- this._y = y;
+ getOrientation: function (side) {
+ return this.side === "left" || this.side === "right"
+ ? "horizontal"
+ : "vertical";
+ },
- this.showUI();
- this.startUITimer();
- }, this))
- );
+ // loading indicator
+ startLoading: function () {
+ if (!this._spinner) return;
- // delegate <> mousemove/click states
- this._pages
- .on(
- "mousemove",
- ".strp-container",
- (this._onMouseMoveHandler = $.proxy(this._onMouseMove, this))
- )
- .on(
- "mouseleave",
- ".strp-container",
- (this._onMouseLeaveHandler = $.proxy(this._onMouseLeave, this))
- )
- .on(
- "mouseenter",
- ".strp-container",
- (this._onMouseEnterHandler = $.proxy(this._onMouseEnter, this))
- );
+ this.spinnerMove.show();
+ this._spinner.show();
+ },
- // delegate moving onto the <> buttons
- // keeping the mouse on them should keep the buttons visible
- this.element
- .on(
- "mouseenter",
- ".strp-nav",
- (this._onNavMouseEnterHandler = $.proxy(
- this._onNavMouseEnter,
- this
- ))
- )
- .on(
- "mouseleave",
- ".strp-nav",
- (this._onNavMouseLeaveHandler = $.proxy(
- this._onNavMouseLeave,
- this
- ))
- );
+ stopLoading: function () {
+ if (!this._spinner) return;
- $(window).on(
- "scroll",
- (this._onScrollHandler = $.proxy(this._onScroll, this))
- );
- }
+ // we only stop loading if there are no loading pages anymore
+ var loadingCount = Pages.getLoadingCount();
- this._pages.on(
- "click",
- ".strp-container",
- (this._onClickHandler = $.proxy(this._onClick, this))
+ if (loadingCount < 1) {
+ this._spinner.hide(
+ function () {
+ this.spinnerMove.hide();
+ }.bind(this)
);
- },
-
- // TODO: switch to jQuery.on/off
- unbindUI: function() {
- if (this._showUIHandler) {
- this.element
- .off("mouseenter", this._showUIHandler)
- .off("mouseleave", this._hideUIHandler)
- .off("mousemove", this._mousemoveUIHandler);
-
- this._pages
- .off("mousemove", ".strp-container", this._onMouseMoveHandler)
- .off("mouseleave", ".strp-container", this._onMouseLeaveHandler)
- .off("mouseenter", ".strp-container", this._onMouseEnterHandler);
-
- this.element
- .off("mouseenter", ".strp-nav", this._onNavMouseEnterHandler)
- .off("mouseleave", ".strp-nav", this._onNavMouseLeaveHandler);
+ }
+ },
+
+ setPosition: function (position, callback) {
+ this._position = position;
+
+ // store the current view
+ this.view = this.views[position - 1];
+
+ // we need to make sure that a possible hide effect doesn't
+ // trigger its callbacks, as that would cancel the showing/loading
+ // of the page started below
+ this.stopHideQueue();
+
+ // store the page and show it
+ this.page = Pages.show(
+ position,
+ function () {
+ var afterPosition = this.view.options.afterPosition;
+ if (typeof afterPosition === "function") {
+ afterPosition.call(Strip, position);
+ }
+ if (callback) callback();
+ }.bind(this)
+ );
+ },
- $(window).off("scroll", this._onScrollHandler);
+ hide: function (callback) {
+ if (!this.view) return;
- this._showUIHandler = null;
- }
+ var hideQueue = this.queues.hide;
+ hideQueue.queue([]); // clear queue
- if (this._onClickHandler) {
- this._pages.off("click", ".strp-container", this._onClickHandler);
- this._onClickHandler = null;
- }
- },
+ hideQueue.queue(
+ function (next_stop) {
+ Pages.stop();
+ next_stop();
+ }.bind(this)
+ );
- // reset cached offsetLeft and outerWidth so they are recalculated after scrolling,
- // the cached values might be incorrect after scrolling left/right
- _onScroll: function() {
- this._offsetLeft = this._outerWidth = null;
- },
+ hideQueue.queue(
+ function (next_unbinds) {
+ // ui
+ var duration = this.view ? this.view.options.effects.window.hide : 0;
+ this.unbindUI();
+ this.hideUI(null, duration);
- // events bounds by bindUI
- _onMouseMove: function(event) {
- var Side = this._getEventSide(event),
- side = Side.toLowerCase();
+ // close on click outside
+ this.unbindHideOnClickOutside();
- this.element[(this["may" + Side]() ? "add" : "remove") + "Class"](
- "strp-hovering-clickable"
- );
- this._previous[(side !== "next" ? "add" : "remove") + "Class"](
- "strp-nav-previous-hover strp-nav-hover"
- );
- this._next[(side === "next" ? "add" : "remove") + "Class"](
- "strp-nav-next-hover strp-nav-hover"
- );
- },
+ // keyboard
+ Keyboard.disable();
- _onMouseLeave: function(event) {
- this.element.removeClass("strp-hovering-clickable");
- this._previous
- .removeClass("strp-nav-previous-hover")
- .add(this._next.removeClass("strp-nav-next-hover"))
- .removeClass("strp-nav-hover");
- },
+ next_unbinds();
+ }.bind(this)
+ );
- _onClick: function(event) {
- var Side = this._getEventSide(event),
- side = Side.toLowerCase();
+ hideQueue.queue(
+ function (next_zero) {
+ // active classes should removed right as the closing effect starts
+ // because clicking an element as it closes will re-open it,
+ // that needs to be reflected in the class
+ Pages.removeActiveClasses();
- this[side]();
+ this.resize(0, next_zero, this.view.options.effects.window.hide);
- // adjust cursor, doesn't work with effects
- // but _onMouseEnter is used to fix that
- this._onMouseMove(event);
- },
+ // after we initiate the hide resize, the next resize should bring up the UI again
+ this._showUIOnResize = true;
+ }.bind(this)
+ );
- _onMouseEnter: function(event) {
- // this solves clicking an area and not having an updating cursor
- // when not moving cursor after click. When an overlapping page comes into view
- // it'll trigger a mouseenter after the mouseout on the disappearing page
- // that would normally remove the clickable class
- this._onMouseMove(event);
- },
+ // callbacks after resize in a separate queue
+ // so we can stop the hideQueue without stopping the resize
+ hideQueue.queue(
+ function (next_after_resize) {
+ this._safeResetsAfterSwitchSide();
- _getEventSide: function(event) {
- var offsetLeft = this._offsetLeft || this.element.offset().left,
- left = event.pageX - offsetLeft,
- width = this._outerWidth || this.element.outerWidth();
+ this.stopObservingResize();
- return left < 0.5 * width ? "Previous" : "Next";
- },
+ Pages.removeAll();
- _onNavMouseEnter: function(event) {
- this._hoveringNav = true;
- this.clearUITimer();
- },
+ this.timers.clear();
- _onNavMouseLeave: function(event) {
- this._hoveringNav = false;
- this.startUITimer();
- },
+ this._position = -1;
- // Actual UI actions
- showUI: function(callback, alternateDuration) {
- // clear the timer everytime so we can keep clicking elements and fading
- // in the ui while not having the timer interupt that with a hide
- this.clearUITimer();
+ // afterHide callback
+ var afterHide = this.view && this.view.options.afterHide;
+ if (typeof afterHide === "function") {
+ afterHide.call(Strip);
+ }
- // we're only fading the inner button icons since the margin on their wrapper divs might change
- var elements = this.element.find(".strp-nav-button");
+ this.view = null;
- var duration = this.view ? this.view.options.effects.ui.show : 0;
- if ($.type(alternateDuration) === "number") duration = alternateDuration;
+ next_after_resize();
+ }.bind(this)
+ );
- elements.stop(true).fadeTo(
- duration,
- 1,
- "stripEaseInSine",
- $.proxy(function() {
- this.startUITimer();
- if ($.type(callback) === "function") callback();
- }, this)
+ if (typeof callback === "function") {
+ hideQueue.queue(
+ function (next_callback) {
+ callback();
+ next_callback();
+ }.bind(this)
);
- },
+ }
+ },
+
+ // stop all callbacks possibly queued up into a hide animation
+ // this allows the hide animation to finish as we start showing/loading
+ // a new page, a callback could otherwise interrupt this
+ stopHideQueue: function () {
+ this.queues.hide.queue([]);
+ },
+
+ // these are things we can safely call when switching side as well
+ _safeResetsAfterSwitchSide: function () {
+ // remove styling from window, so no width: 100%; height: 0 issues
+ this.element.removeAttr("style");
+ if (this.spinnerMove) this.spinnerMove.removeAttr("style");
+
+ //Pages.removeExpired();
+ this.visible = false;
+ this.hideUI(null, 0);
+ this.timers.clear("ui");
+ this.resetPrevNext();
+
+ // clear cached mousemove
+ this._x = -1;
+ this._y = -1;
+ },
+
+ // Previous / Next
+ mayPrevious: function () {
+ return (
+ (this.view &&
+ this.view.options.loop &&
+ this.views &&
+ this.views.length > 1) ||
+ this._position !== 1
+ );
+ },
+
+ previous: function (force) {
+ var mayPrevious = this.mayPrevious();
+
+ if (force || mayPrevious) {
+ this.setPosition(this.getSurroundingIndexes().previous);
+ }
+ },
- hideUI: function(callback, alternateDuration) {
- var elements = this.element.find(".strp-nav-button");
+ mayNext: function () {
+ var hasViews = this.views && this.views.length > 1;
- var duration = this.view ? this.view.options.effects.ui.hide : 0;
- if ($.type(alternateDuration) === "number") duration = alternateDuration;
+ return (
+ (this.view && this.view.options.loop && hasViews) ||
+ (hasViews && this.getSurroundingIndexes().next !== 1)
+ );
+ },
- elements.stop(true).fadeOut(duration, "stripEaseOutSine", function() {
- if ($.type(callback) === "function") callback();
- });
- },
+ next: function (force) {
+ var mayNext = this.mayNext();
- // UI Timer
- // not used on mobile-touch based devices
- clearUITimer: function() {
- if (Support.mobileTouch) return;
+ if (force || mayNext) {
+ this.setPosition(this.getSurroundingIndexes().next);
+ }
+ },
- this.timers.clear("ui");
- },
+ // surrounding
+ getSurroundingIndexes: function () {
+ if (!this.views) return {};
- startUITimer: function() {
- if (Support.mobileTouch) return;
+ var pos = this._position,
+ length = this.views.length;
- this.clearUITimer();
- this.timers.set(
- "ui",
- $.proxy(function() {
- this.hideUI();
- }, this),
- this.view ? this.view.options.uiDelay : 0
+ var previous = pos <= 1 ? length : pos - 1,
+ next = pos >= length ? 1 : pos + 1;
+
+ return {
+ previous: previous,
+ next: next,
+ };
+ },
+
+ // close when clicking outside of strip or an element opening strip
+ bindHideOnClickOutside: function () {
+ this.unbindHideOnClickOutside();
+ $(document.documentElement).on(
+ "click",
+ (this._delegateHideOutsideHandler = this._delegateHideOutside.bind(this))
+ );
+ },
+
+ unbindHideOnClickOutside: function () {
+ if (this._delegateHideOutsideHandler) {
+ $(document.documentElement).off(
+ "click",
+ this._delegateHideOutsideHandler
);
+ this._delegateHideOutsideHandler = null;
}
- };
+ },
- // Keyboard
- // keeps track of keyboard events when enabled
- var Keyboard = {
- enabled: false,
+ _delegateHideOutside: function (event) {
+ var page = Pages.page;
+ if (!this.visible || !(page && page.view.options.hideOnClickOutside))
+ return;
- keyCode: {
- left: 37,
- right: 39,
- esc: 27
- },
+ var element = event.target;
- // enable is passed the keyboard option of a page, which can be false
- // or contains multiple buttons to toggle
- enable: function(enabled) {
- this.disable();
+ if (!$(element).closest(".strip, .strp-window")[0]) {
+ this.hide();
+ }
+ },
+
+ // UI
+ bindUI: function () {
+ this.unbindUI();
+
+ if (!Support.mobileTouch) {
+ this.element
+ .on("mouseenter", (this._showUIHandler = this.showUI.bind(this)))
+ .on("mouseleave", (this._hideUIHandler = this.hideUI.bind(this)));
+
+ this.element.on(
+ "mousemove",
+ (this._mousemoveUIHandler = function (event) {
+ // Chrome has a bug that triggers mousemove events incorrectly
+ // we have to work around this by comparing cursor positions
+ // so only true mousemove events pass through:
+ // https://code.google.com/p/chromium/issues/detail?id=420032
+ var x = event.pageX,
+ y = event.pageY;
+
+ if (this._hoveringNav || (y === this._y && x === this._x)) {
+ return;
+ }
- if (!enabled) return;
+ // cache x/y
+ this._x = x;
+ this._y = y;
- $(document)
- .on("keydown", (this._onKeyDownHandler = $.proxy(this.onKeyDown, this)))
- .on("keyup", (this._onKeyUpHandler = $.proxy(this.onKeyUp, this)));
+ this.showUI();
+ this.startUITimer();
+ }.bind(this))
+ );
- this.enabled = enabled;
- },
+ // delegate <> mousemove/click states
+ this._pages
+ .on(
+ "mousemove",
+ ".strp-container",
+ (this._onMouseMoveHandler = this._onMouseMove.bind(this))
+ )
+ .on(
+ "mouseleave",
+ ".strp-container",
+ (this._onMouseLeaveHandler = this._onMouseLeave.bind(this))
+ )
+ .on(
+ "mouseenter",
+ ".strp-container",
+ (this._onMouseEnterHandler = this._onMouseEnter.bind(this))
+ );
- disable: function() {
- this.enabled = false;
+ // delegate moving onto the <> buttons
+ // keeping the mouse on them should keep the buttons visible
+ this.element
+ .on(
+ "mouseenter",
+ ".strp-nav",
+ (this._onNavMouseEnterHandler = this._onNavMouseEnter.bind(this))
+ )
+ .on(
+ "mouseleave",
+ ".strp-nav",
+ (this._onNavMouseLeaveHandler = this._onNavMouseLeave.bind(this))
+ );
- if (this._onKeyUpHandler) {
- $(document)
- .off("keyup", this._onKeyUpHandler)
- .off("keydown", this._onKeyDownHandler);
- this._onKeyUpHandler = this._onKeyDownHandler = null;
- }
- },
+ $(window).on(
+ "scroll",
+ (this._onScrollHandler = this._onScroll.bind(this))
+ );
+ }
- onKeyDown: function(event) {
- if (!this.enabled || !Window.visible) return;
+ this._pages.on(
+ "click",
+ ".strp-container",
+ (this._onClickHandler = this._onClick.bind(this))
+ );
+ },
- var key = this.getKeyByKeyCode(event.keyCode);
+ unbindUI: function () {
+ if (this._showUIHandler) {
+ this.element
+ .off("mouseenter", this._showUIHandler)
+ .off("mouseleave", this._hideUIHandler)
+ .off("mousemove", this._mousemoveUIHandler);
- if (!key || (key && this.enabled && !this.enabled[key])) return;
+ this._pages
+ .off("mousemove", ".strp-container", this._onMouseMoveHandler)
+ .off("mouseleave", ".strp-container", this._onMouseLeaveHandler)
+ .off("mouseenter", ".strp-container", this._onMouseEnterHandler);
- event.preventDefault();
- event.stopPropagation();
+ this.element
+ .off("mouseenter", ".strp-nav", this._onNavMouseEnterHandler)
+ .off("mouseleave", ".strp-nav", this._onNavMouseLeaveHandler);
- switch (key) {
- case "left":
- Window.previous();
- break;
- case "right":
- Window.next();
- break;
- }
- },
+ $(window).off("scroll", this._onScrollHandler);
+
+ this._showUIHandler = null;
+ }
- onKeyUp: function(event) {
- if (!this.enabled || !Window.visible) return;
+ if (this._onClickHandler) {
+ this._pages.off("click", ".strp-container", this._onClickHandler);
+ this._onClickHandler = null;
+ }
+ },
+
+ // reset cached offsetLeft and outerWidth so they are recalculated after scrolling,
+ // the cached values might be incorrect after scrolling left/right
+ _onScroll: function () {
+ this._offsetLeft = this._outerWidth = null;
+ },
+
+ // events bounds by bindUI
+ _onMouseMove: function (event) {
+ var Side = this._getEventSide(event),
+ side = Side.toLowerCase();
+
+ this.element[(this["may" + Side]() ? "add" : "remove") + "Class"](
+ "strp-hovering-clickable"
+ );
+ this._previous[(side !== "next" ? "add" : "remove") + "Class"](
+ "strp-nav-previous-hover strp-nav-hover"
+ );
+ this._next[(side === "next" ? "add" : "remove") + "Class"](
+ "strp-nav-next-hover strp-nav-hover"
+ );
+ },
+
+ _onMouseLeave: function () {
+ this.element.removeClass("strp-hovering-clickable");
+ this._previous
+ .removeClass("strp-nav-previous-hover")
+ .add(this._next.removeClass("strp-nav-next-hover"))
+ .removeClass("strp-nav-hover");
+ },
+
+ _onClick: function (event) {
+ var Side = this._getEventSide(event),
+ side = Side.toLowerCase();
+
+ this[side]();
+
+ // adjust cursor, doesn't work with effects
+ // but _onMouseEnter is used to fix that
+ this._onMouseMove(event);
+ },
+
+ _onMouseEnter: function (event) {
+ // this solves clicking an area and not having an updating cursor
+ // when not moving cursor after click. When an overlapping page comes into view
+ // it'll trigger a mouseenter after the mouseout on the disappearing page
+ // that would normally remove the clickable class
+ this._onMouseMove(event);
+ },
+
+ _getEventSide: function (event) {
+ var offsetLeft = this._offsetLeft || this.element.offset().left,
+ left = event.pageX - offsetLeft,
+ width = this._outerWidth || this.element.outerWidth();
+
+ return left < 0.5 * width ? "Previous" : "Next";
+ },
+
+ _onNavMouseEnter: function (event) {
+ this._hoveringNav = true;
+ this.clearUITimer();
+ },
+
+ _onNavMouseLeave: function (event) {
+ this._hoveringNav = false;
+ this.startUITimer();
+ },
+
+ // Actual UI actions
+ showUI: function (callback, alternateDuration) {
+ // clear the timer everytime so we can keep clicking elements and fading
+ // in the ui while not having the timer interupt that with a hide
+ this.clearUITimer();
+
+ // we're only fading the inner button icons since the margin on their wrapper divs might change
+ var elements = this.element.find(".strp-nav-button");
+
+ var duration = this.view ? this.view.options.effects.ui.show : 0;
+ if (typeof alternateDuration === "number") duration = alternateDuration;
+
+ elements.stop(true).fadeTo(
+ duration,
+ 1,
+ "stripEaseInSine",
+ function () {
+ this.startUITimer();
+ if (typeof callback === "function") callback();
+ }.bind(this)
+ );
+ },
+
+ hideUI: function (callback, alternateDuration) {
+ var elements = this.element.find(".strp-nav-button");
+
+ var duration = this.view ? this.view.options.effects.ui.hide : 0;
+ if (typeof alternateDuration === "number") duration = alternateDuration;
+
+ elements.stop(true).fadeOut(duration, "stripEaseOutSine", function () {
+ if (typeof callback === "function") callback();
+ });
+ },
+
+ // UI Timer
+ // not used on mobile-touch based devices
+ clearUITimer: function () {
+ if (Support.mobileTouch) return;
+
+ this.timers.clear("ui");
+ },
+
+ startUITimer: function () {
+ if (Support.mobileTouch) return;
+
+ this.clearUITimer();
+ this.timers.set(
+ "ui",
+ function () {
+ this.hideUI();
+ }.bind(this),
+ this.view ? this.view.options.uiDelay : 0
+ );
+ },
+};
+
+// Keyboard
+// keeps track of keyboard events when enabled
+var Keyboard = {
+ enabled: false,
+
+ keyCode: {
+ left: 37,
+ right: 39,
+ esc: 27,
+ },
+
+ // enable is passed the keyboard option of a page, which can be false
+ // or contains multiple buttons to toggle
+ enable: function (enabled) {
+ this.disable();
+
+ if (!enabled) return;
+
+ $(document)
+ .on("keydown", (this._onKeyDownHandler = this.onKeyDown.bind(this)))
+ .on("keyup", (this._onKeyUpHandler = this.onKeyUp.bind(this)));
+
+ this.enabled = enabled;
+ },
+
+ disable: function () {
+ this.enabled = false;
+
+ if (this._onKeyUpHandler) {
+ $(document)
+ .off("keyup", this._onKeyUpHandler)
+ .off("keydown", this._onKeyDownHandler);
+ this._onKeyUpHandler = this._onKeyDownHandler = null;
+ }
+ },
- var key = this.getKeyByKeyCode(event.keyCode);
+ onKeyDown: function (event) {
+ if (!this.enabled || !Window.visible) return;
- if (!key || (key && this.enabled && !this.enabled[key])) return;
+ var key = this.getKeyByKeyCode(event.keyCode);
- switch (key) {
- case "esc":
- Window.hide();
- break;
- }
- },
+ if (!key || (key && this.enabled && !this.enabled[key])) return;
- getKeyByKeyCode: function(keyCode) {
- for (var key in this.keyCode) {
- if (this.keyCode[key] === keyCode) return key;
- }
- return null;
+ event.preventDefault();
+ event.stopPropagation();
+
+ switch (key) {
+ case "left":
+ Window.previous();
+ break;
+ case "right":
+ Window.next();
+ break;
}
- };
+ },
- // API
+ onKeyUp: function (event) {
+ if (!this.enabled || !Window.visible) return;
- // an unexposed object for internal use
- var _Strip = {
- _disabled: false,
- _fallback: true,
+ var key = this.getKeyByKeyCode(event.keyCode);
- initialize: function() {
- Window.initialize();
- if (!this._disabled) this.startDelegating();
- },
+ if (!key || (key && this.enabled && !this.enabled[key])) return;
+
+ switch (key) {
+ case "esc":
+ Window.hide();
+ break;
+ }
+ },
- // click delegation
- startDelegating: function() {
- this.stopDelegating();
- $(document.documentElement).on(
+ getKeyByKeyCode: function (keyCode) {
+ for (var key in this.keyCode) {
+ if (this.keyCode[key] === keyCode) return key;
+ }
+ return null;
+ },
+};
+
+// API
+
+// an unexposed object for internal use
+var _Strip = {
+ _disabled: false,
+ _fallback: true,
+
+ initialize: function () {
+ Window.initialize();
+ if (!this._disabled) this.startDelegating();
+ },
+
+ // click delegation
+ startDelegating: function () {
+ this.stopDelegating();
+ $(document.documentElement).on(
+ "click",
+ ".strip[href]",
+ (this._delegateHandler = this.delegate.bind(this))
+ );
+ },
+
+ stopDelegating: function () {
+ if (this._delegateHandler) {
+ $(document.documentElement).off(
"click",
".strip[href]",
- (this._delegateHandler = $.proxy(this.delegate, this))
+ this._delegateHandler
);
- },
-
- stopDelegating: function() {
- if (this._delegateHandler) {
- $(document.documentElement).off(
- "click",
- ".strip[href]",
- this._delegateHandler
- );
- this._delegateHandler = null;
- }
- },
+ this._delegateHandler = null;
+ }
+ },
- delegate: function(event) {
- if (this._disabled) return;
+ delegate: function (event) {
+ if (this._disabled) return;
- event.stopPropagation();
- event.preventDefault();
+ event.stopPropagation();
+ event.preventDefault();
- var element = event.currentTarget;
+ var element = event.currentTarget;
- _Strip.show(element);
- },
+ _Strip.show(element);
+ },
- show: function(object) {
- if (this._disabled) {
- this.showFallback.apply(_Strip, _slice.call(arguments));
- return;
- }
+ show: function (object) {
+ if (this._disabled) {
+ this.showFallback.apply(_Strip, _slice.call(arguments));
+ return;
+ }
- var options = arguments[1] || {},
- position = arguments[2];
+ var options = arguments[1] || {},
+ position = arguments[2];
- if (arguments[1] && $.type(arguments[1]) === "number") {
- position = arguments[1];
- options = {};
- }
+ if (arguments[1] && typeof arguments[1] === "number") {
+ position = arguments[1];
+ options = {};
+ }
- var views = [],
- object_type,
- isElement = object && object.nodeType === 1;
-
- switch ((object_type = $.type(object))) {
- case "string":
- case "object":
- var view = new View(object, options),
- _dgo = "data-strip-group-options";
-
- if (view.group) {
- // extend the entire group
-
- // if we have an element, look for other elements
- if (isElement) {
- var elements = $(
- '.strip[data-strip-group="' +
- $(object).attr("data-strip-group") +
- '"]'
- );
+ var views = [],
+ object_type,
+ isElement = object && object.nodeType === 1;
+
+ switch ((object_type = typeof object)) {
+ case "string":
+ case "object":
+ var view = new View(object, options),
+ _dgo = "data-strip-group-options";
+
+ if (view.group) {
+ // extend the entire group
+
+ // if we have an element, look for other elements
+ if (isElement) {
+ var elements = $(
+ '.strip[data-strip-group="' +
+ $(object).attr("data-strip-group") +
+ '"]'
+ );
- // find possible group options
- var groupOptions = {};
-
- elements.filter("[" + _dgo + "]").each(function(i, element) {
- $.extend(
- groupOptions,
- eval("({" + ($(element).attr(_dgo) || "") + "})")
- );
- });
-
- elements.each(function(i, element) {
- // adjust the position if we find the given object position
- if (!position && element === object) position = i + 1;
- views.push(
- new View(element, $.extend({}, groupOptions, options))
- );
- });
- }
- } else {
+ // find possible group options
var groupOptions = {};
- if (isElement && $(object).is("[" + _dgo + "]")) {
+
+ elements.filter("[" + _dgo + "]").each(function (i, element) {
$.extend(
groupOptions,
- eval("({" + ($(object).attr(_dgo) || "") + "})")
+ eval("({" + ($(element).attr(_dgo) || "") + "})")
);
- // reset the view with group options applied
- view = new View(object, $.extend({}, groupOptions, options));
- }
+ });
- views.push(view);
+ elements.each(function (i, element) {
+ // adjust the position if we find the given object position
+ if (!position && element === object) position = i + 1;
+ views.push(
+ new View(element, $.extend({}, groupOptions, options))
+ );
+ });
+ }
+ } else {
+ var groupOptions = {};
+ if (isElement && $(object).is("[" + _dgo + "]")) {
+ $.extend(
+ groupOptions,
+ eval("({" + ($(object).attr(_dgo) || "") + "})")
+ );
+ // reset the view with group options applied
+ view = new View(object, $.extend({}, groupOptions, options));
}
- break;
-
- case "array":
- $.each(object, function(i, item) {
- var view = new View(item, options);
- views.push(view);
- });
- break;
- }
- // if we haven't found a position by now, load the first view
- if (!position || position < 1) {
- position = 1;
- }
- if (position > views.length) position = views.length;
-
- // Allow API events to pass through by disabling hideOnClickOutside.
- // It is re-enabled when bringing a page into view using a slight delay
- // allowing a possible click event that triggers this show() function to
- // fully bubble up. This is needed when Strip is visible and Strip.show()
- // is called, the click would otherwise bubble down and instantly hide,
- // cancelling the show()
- Window.unbindHideOnClickOutside();
-
- // if we've clicked an element, search for it in the currently open pagegroup
- var positionInAPG;
- if (
- isElement &&
- (positionInAPG = Pages.getPositionInActivePageGroup(object))
- ) {
- // if we've clicked the exact same element it'll never re-enable
- // hideOnClickOutside delegation because Pages.show() won't let it
- // through, we re-enable it here in that case
- if (positionInAPG === Window._position) {
- Window.bindHideOnClickOutside();
+ views.push(view);
}
+ break;
- Window.setPosition(positionInAPG);
- } else {
- // otherwise start loading and open
- Window.load(views, position);
- }
- },
-
- showFallback: (function() {
- function getUrl(object) {
- var url,
- type = $.type(object);
-
- if (type === "string") {
- url = object;
- } else if (type === "array" && object[0]) {
- url = getUrl(object[0]);
- } else if (_.isElement(object) && $(object).attr("href")) {
- url = $(object).attr("href");
- } else if (object.url) {
- url = object.url;
- } else {
- url = false;
- }
+ case "array":
+ $.each(object, function (i, item) {
+ var view = new View(item, options);
+ views.push(view);
+ });
+ break;
+ }
- return url;
+ // if we haven't found a position by now, load the first view
+ if (!position || position < 1) {
+ position = 1;
+ }
+ if (position > views.length) position = views.length;
+
+ // Allow API events to pass through by disabling hideOnClickOutside.
+ // It is re-enabled when bringing a page into view using a slight delay
+ // allowing a possible click event that triggers this show() function to
+ // fully bubble up. This is needed when Strip is visible and Strip.show()
+ // is called, the click would otherwise bubble down and instantly hide,
+ // cancelling the show()
+ Window.unbindHideOnClickOutside();
+
+ // if we've clicked an element, search for it in the currently open pagegroup
+ var positionInAPG;
+ if (
+ isElement &&
+ (positionInAPG = Pages.getPositionInActivePageGroup(object))
+ ) {
+ // if we've clicked the exact same element it'll never re-enable
+ // hideOnClickOutside delegation because Pages.show() won't let it
+ // through, we re-enable it here in that case
+ if (positionInAPG === Window._position) {
+ Window.bindHideOnClickOutside();
}
- return function(object) {
- if (!_Strip._fallback) return;
- var url = getUrl(object);
- if (url) window.location.href = url;
- };
- })()
- };
-
- $.extend(Strip, {
- show: function(object) {
- _Strip.show.apply(_Strip, _slice.call(arguments));
- return this;
- },
-
- hide: function() {
- Window.hide();
- return this;
- },
-
- disable: function() {
- _Strip.stopDelegating();
- _Strip._disabled = true;
- return this;
- },
+ Window.setPosition(positionInAPG);
+ } else {
+ // otherwise start loading and open
+ Window.load(views, position);
+ }
+ },
+
+ showFallback: (function () {
+ function getUrl(object) {
+ var url,
+ type = typeof object;
+
+ if (type === "string") {
+ url = object;
+ } else if (type === "array" && object[0]) {
+ url = getUrl(object[0]);
+ } else if (_.isElement(object) && $(object).attr("href")) {
+ url = $(object).attr("href");
+ } else if (object.url) {
+ url = object.url;
+ } else {
+ url = false;
+ }
- enable: function() {
- _Strip._disabled = false;
- _Strip.startDelegating();
- return this;
- },
+ return url;
+ }
- fallback: function(fallback) {
- _Strip._fallback = fallback;
- return this;
- },
+ return function (object) {
+ if (!_Strip._fallback) return;
+ var url = getUrl(object);
+ if (url) window.location.href = url;
+ };
+ })(),
+};
+
+$.extend(Strip, {
+ show: function (object) {
+ _Strip.show.apply(_Strip, _slice.call(arguments));
+ return this;
+ },
+
+ hide: function () {
+ Window.hide();
+ return this;
+ },
+
+ disable: function () {
+ _Strip.stopDelegating();
+ _Strip._disabled = true;
+ return this;
+ },
+
+ enable: function () {
+ _Strip._disabled = false;
+ _Strip.startDelegating();
+ return this;
+ },
+
+ fallback: function (fallback) {
+ _Strip._fallback = fallback;
+ return this;
+ },
+
+ setDefaultSkin: function (skin) {
+ Options.defaults.skin = skin;
+ return this;
+ },
+});
- setDefaultSkin: function(skin) {
- Options.defaults.skin = skin;
- return this;
+// fallback for old browsers without full position:fixed support
+if (
+ // IE6
+ (Browser.IE && Browser.IE < 7) ||
+ // old Android
+ // added a version check because Firefox on Android doesn't have a
+ // version number above 4.2 anymore
+ (typeof Browser.Android === "number" && Browser.Android < 3) ||
+ // old WebKit
+ (Browser.MobileSafari &&
+ typeof Browser.WebKit === "number" &&
+ Browser.WebKit < 533.18)
+) {
+ // we'll reset the show function
+ _Strip.show = _Strip.showFallback;
+
+ // disable some functions we don't want to run
+ $.each(
+ "startDelegating stopDelegating initialize".split(" "),
+ function (i, fn) {
+ _Strip[fn] = function () {};
}
- });
+ );
- // fallback for old browsers without full position:fixed support
- if (
- // IE6
- (Browser.IE && Browser.IE < 7) ||
- // old Android
- // added a version check because Firefox on Android doesn't have a
- // version number above 4.2 anymore
- ($.type(Browser.Android) === "number" && Browser.Android < 3) ||
- // old WebKit
- (Browser.MobileSafari &&
- ($.type(Browser.WebKit) === "number" && Browser.WebKit < 533.18))
- ) {
- // we'll reset the show function
- _Strip.show = _Strip.showFallback;
-
- // disable some functions we don't want to run
- $.each("startDelegating stopDelegating initialize".split(" "), function(
- i,
- fn
- ) {
- _Strip[fn] = function() {};
- });
+ Strip.hide = function () {
+ return this;
+ };
+}
- Strip.hide = function() {
- return this;
- };
- }
+// start
+$(document).ready(function(event) {
+ _Strip.initialize();
+});
- // start
- $(document).ready(function(event) {
- _Strip.initialize();
- });
+return Strip;
- return Strip;
-});
+}));
diff --git a/dist/js/strip.pkgd.min.js b/dist/js/strip.pkgd.min.js
index e340f45..9ac31dd 100644
--- a/dist/js/strip.pkgd.min.js
+++ b/dist/js/strip.pkgd.min.js
@@ -1,2071 +1,9 @@
/*!
- * Strip - An Unobtrusive Responsive Lightbox - v1.7.0
- * (c) 2014-2019 Nick Stakenburg
+ * Strip - An Unobtrusive Responsive Lightbox - v1.8.0
+ * (c) 2014-2021 Nick Stakenburg
*
- * http://www.stripjs.com
+ * https://github.com/staaky/strip
*
* @license: https://creativecommons.org/licenses/by/4.0
*/
-!(function(t, i) {
- "function" == typeof define && define.amd
- ? define(["jquery"], i)
- : "object" == typeof module && module.exports
- ? (module.exports = i(require("jquery")))
- : (t.Strip = i(jQuery));
-})(this, function($) {
- var Strip = { version: "1.7.0", Skins: { strip: {} } },
- Browser =
- ((c = navigator.userAgent),
- {
- IE: !(!window.attachEvent || -1 !== c.indexOf("Opera")) && d("MSIE "),
- Opera:
- -1 < c.indexOf("Opera") &&
- ((!!window.opera && opera.version && parseFloat(opera.version())) ||
- 7.55),
- WebKit: -1 < c.indexOf("AppleWebKit/") && d("AppleWebKit/"),
- Gecko: -1 < c.indexOf("Gecko") && -1 === c.indexOf("KHTML") && d("rv:"),
- MobileSafari: !!c.match(/Apple.*Mobile.*Safari/),
- Chrome: -1 < c.indexOf("Chrome") && d("Chrome/"),
- ChromeMobile: -1 < c.indexOf("CrMo") && d("CrMo/"),
- Android: -1 < c.indexOf("Android") && d("Android "),
- IEMobile: -1 < c.indexOf("IEMobile") && d("IEMobile/")
- }),
- c;
- function d(t) {
- var i = new RegExp(t + "([\\d.]+)").exec(c);
- return !i || parseFloat(i[1]);
- }
- var _slice = Array.prototype.slice,
- Fit = {
- within: function(t, i) {
- for (
- var e = $.extend({ height: !0, width: !0 }, arguments[2] || {}),
- s = $.extend({}, i),
- n = 1,
- o = 5,
- r = e.width,
- a = e.height;
- 0 < o && ((r && s.width > t.width) || (a && s.height > t.height));
-
- ) {
- var h = 1,
- d = 1;
- r && s.width > t.width && (h = t.width / s.width),
- a && s.height > t.height && (d = t.height / s.height);
- n = Math.min(h, d);
- (s = {
- width: Math.round(i.width * n),
- height: Math.round(i.height * n)
- }),
- o--;
- }
- return (
- (s.width = Math.max(s.width, 0)),
- (s.height = Math.max(s.height, 0)),
- s
- );
- }
- };
- $.extend($.easing, {
- stripEaseInCubic: function(t, i, e, s, n) {
- return s * (i /= n) * i * i + e;
- },
- stripEaseInSine: function(t, i, e, s, n) {
- return -s * Math.cos((i / n) * (Math.PI / 2)) + s + e;
- },
- stripEaseOutSine: function(t, i, e, s, n) {
- return s * Math.sin((i / n) * (Math.PI / 2)) + e;
- }
- });
- var Support =
- ((F = document.createElement("div")),
- (G = "Webkit Moz O ms Khtml".split(" ")),
- {
- css: {
- animation: J("animation"),
- transform: J("transform"),
- prefixed: function(t) {
- return J(t, "prefix");
- }
- },
- svg:
- !!document.createElementNS &&
- !!document.createElementNS("http://www.w3.org/2000/svg", "svg")
- .createSVGRect,
- touch: (function() {
- try {
- return !!(
- "ontouchstart" in window ||
- (window.DocumentTouch && document instanceof DocumentTouch)
- );
- } catch (t) {
- return !1;
- }
- })()
- }),
- F,
- G;
- function J(t, i) {
- var e = t.charAt(0).toUpperCase() + t.substr(1);
- return (function(t, i) {
- for (var e in t)
- if (void 0 !== F.style[t[e]]) return "prefix" != i || t[e];
- return !1;
- })((t + " " + G.join(e + " ") + e).split(" "), i);
- }
- Support.mobileTouch =
- Support.touch &&
- (Browser.MobileSafari ||
- Browser.Android ||
- Browser.IEMobile ||
- Browser.ChromeMobile ||
- !/^(Win|Mac|Linux)/.test(navigator.platform));
- var Bounds = {
- viewport: function() {
- var t = { width: $(window).width() };
- if (Browser.MobileSafari || (Browser.Android && Browser.Gecko)) {
- var i = document.documentElement.clientWidth / window.innerWidth;
- t.height = window.innerHeight * i;
- } else t.height = $(window).height();
- return t;
- }
- },
- ImageReady = (function(o) {
- function t() {
- return this.initialize.apply(
- this,
- Array.prototype.slice.call(arguments)
- );
- }
- o.extend(t.prototype, {
- initialize: function() {
- (this.options = o.extend(
- {
- test: function() {},
- success: function() {},
- timeout: function() {},
- callAt: !1,
- intervals: [[0, 0], [1e3, 10], [2e3, 50], [4e3, 100], [2e4, 500]]
- },
- arguments[0] || {}
- )),
- (this._test = this.options.test),
- (this._success = this.options.success),
- (this._timeout = this.options.timeout),
- (this._ipos = 0),
- (this._time = 0),
- (this._delay = this.options.intervals[this._ipos][1]),
- (this._callTimeouts = []),
- this.poll(),
- this._createCallsAt();
- },
- poll: function() {
- this._polling = setTimeout(
- o.proxy(function() {
- if (this._test()) this.success();
- else {
- if (
- ((this._time += this._delay),
- this._time >= this.options.intervals[this._ipos][0])
- ) {
- if (!this.options.intervals[this._ipos + 1])
- return void (
- "function" == o.type(this._timeout) && this._timeout()
- );
- this._ipos++,
- (this._delay = this.options.intervals[this._ipos][1]);
- }
- this.poll();
- }
- }, this),
- this._delay
- );
- },
- success: function() {
- this.abort(), this._success();
- },
- _createCallsAt: function() {
- this.options.callAt &&
- o.each(
- this.options.callAt,
- o.proxy(function(t, i) {
- var e = i[0],
- s = i[1],
- n = setTimeout(
- o.proxy(function() {
- s();
- }, this),
- e
- );
- this._callTimeouts.push(n);
- }, this)
- );
- },
- _stopCallTimeouts: function() {
- o.each(this._callTimeouts, function(t, i) {
- clearTimeout(i);
- }),
- (this._callTimeouts = []);
- },
- abort: function() {
- this._stopCallTimeouts(),
- this._polling &&
- (clearTimeout(this._polling), (this._polling = null));
- }
- });
- function i() {
- return this.initialize.apply(
- this,
- Array.prototype.slice.call(arguments)
- );
- }
- return (
- o.extend(i.prototype, {
- supports: { naturalWidth: "naturalWidth" in new Image() },
- initialize: function(t, i, e) {
- (this.img = o(t)[0]),
- (this.successCallback = i),
- (this.errorCallback = e),
- (this.isLoaded = !1),
- (this.options = o.extend(
- { method: "onload", pollFallbackAfter: 1e3 },
- arguments[3] || {}
- )),
- "onload" != this.options.method && this.supports.naturalWidth
- ? this.poll()
- : this.load();
- },
- poll: function() {
- this._poll = new t({
- test: o.proxy(function() {
- return 0 < this.img.naturalWidth;
- }, this),
- success: o.proxy(function() {
- this.success();
- }, this),
- timeout: o.proxy(function() {
- this.error();
- }, this),
- callAt: [
- [
- this.options.pollFallbackAfter,
- o.proxy(function() {
- this.load();
- }, this)
- ]
- ]
- });
- },
- load: function() {
- this._loading = setTimeout(
- o.proxy(function() {
- var t = new Image();
- ((this._onloadImage = t).onload = o.proxy(function() {
- (t.onload = function() {}),
- this.supports.naturalWidth ||
- ((this.img.naturalWidth = t.width),
- (this.img.naturalHeight = t.height),
- (t.naturalWidth = t.width),
- (t.naturalHeight = t.height)),
- this.success();
- }, this)),
- (t.onerror = o.proxy(this.error, this)),
- (t.src = this.img.src);
- }, this)
- );
- },
- success: function() {
- this._calledSuccess ||
- ((this._calledSuccess = !0),
- this.abort(),
- this.waitForRender(
- o.proxy(function() {
- (this.isLoaded = !0), this.successCallback(this);
- }, this)
- ));
- },
- error: function() {
- this._calledError ||
- ((this._calledError = !0),
- this.abort(),
- (this._errorRenderTimeout = setTimeout(
- o.proxy(function() {
- this.errorCallback && this.errorCallback(this);
- }, this)
- )));
- },
- abort: function() {
- this.stopLoading(), this.stopPolling(), this.stopWaitingForRender();
- },
- stopPolling: function() {
- this._poll && (this._poll.abort(), (this._poll = null));
- },
- stopLoading: function() {
- this._loading &&
- (clearTimeout(this._loading), (this._loading = null)),
- this._onloadImage &&
- ((this._onloadImage.onload = function() {}),
- (this._onloadImage.onerror = function() {}));
- },
- waitForRender: function(t) {
- this._renderTimeout = setTimeout(t);
- },
- stopWaitingForRender: function() {
- this._renderTimeout &&
- (clearTimeout(this._renderTimeout), (this._renderTimeout = null)),
- this._errorRenderTimeout &&
- (clearTimeout(this._errorRenderTimeout),
- (this._errorRenderTimeout = null));
- }
- }),
- i
- );
- })(jQuery);
- function Spinner() {
- return this.initialize.apply(this, _slice.call(arguments));
- }
- function Timers() {
- return this.initialize.apply(this, _slice.call(arguments));
- }
- function getURIData(s) {
- var n = { type: "image" };
- return (
- $.each(Types, function(t, i) {
- var e = i.data(s);
- e && (((n = e).type = t), (n.url = s));
- }),
- n
- );
- }
- function detectExtension(t) {
- var i = (t || "").replace(/\?.*/g, "").match(/\.([^.]{3,4})$/);
- return i ? i[1].toLowerCase() : null;
- }
- (Spinner.supported = Support.css.transform && Support.css.animation),
- $.extend(Spinner.prototype, {
- initialize: function(t) {
- (this.element = $(t)),
- this.element[0] &&
- ((this.classPrefix = "strp-"),
- this.setOptions(arguments[1] || {}),
- this.element.addClass(this.classPrefix + "spinner"),
- this.element.append(
- (this._rotate = $("
").addClass(
- this.classPrefix + "spinner-rotate"
- ))
- ),
- this.build(),
- this.start());
- },
- setOptions: function(t) {
- this.options = $.extend({ show: 200, hide: 200 }, t || {});
- },
- build: function() {
- if (!this._build) {
- this._rotate.html("");
- this.options.length, this.options.radius;
- var t = this.element.is(":visible");
- t || this.element.show(),
- this._rotate.append(
- (n = $("
")
- .addClass(this.classPrefix + "spinner-frame")
- .append(
- (o = $("
").addClass(this.classPrefix + "spinner-line"))
- ))
- );
- var i,
- e = parseInt($(o).css("z-index"));
- (this.lines = e),
- o.css({ "z-index": "inherit" }),
- n.remove(),
- t || this.element.hide();
- for (var s = 0; s < e; s++) {
- var n, o;
- this._rotate.append(
- (n = $("
")
- .addClass(this.classPrefix + "spinner-frame")
- .append(
- (o = $("
").addClass(this.classPrefix + "spinner-line"))
- ))
- ),
- (i = i || o.css("color")),
- o.css({ background: i }),
- n.css({ opacity: ((1 / e) * (s + 1)).toFixed(2) });
- var r = {};
- (r[Support.css.prefixed("transform")] =
- "rotate(" + (360 / e) * (s + 1) + "deg)"),
- n.css(r);
- }
- this._build = !0;
- }
- },
- start: function() {
- var t = {};
- (t[Support.css.prefixed("animation")] =
- this.classPrefix +
- "spinner-spin 1s infinite steps(" +
- this.lines +
- ")"),
- this._rotate.css(t);
- },
- stop: function() {
- var t = {};
- (t[Support.css.prefixed("animation")] = "none"), this._rotate.css(t);
- },
- show: function(t) {
- this.build(),
- this.start(),
- this.element.stop(!0).fadeTo(this.options.show, 1, t);
- },
- hide: function(t) {
- this.element.stop(!0).fadeOut(
- this.options.hide,
- $.proxy(function() {
- this.stop(), t && t();
- }, this)
- );
- },
- refresh: function() {
- (this._build = !1), this.build();
- }
- }),
- $.extend(Timers.prototype, {
- initialize: function() {
- this._timers = {};
- },
- set: function(t, i, e) {
- this._timers[t] = setTimeout(i, e);
- },
- get: function(t) {
- return this._timers[t];
- },
- clear: function(t) {
- t
- ? this._timers[t] &&
- (clearTimeout(this._timers[t]), delete this._timers[t])
- : this.clearAll();
- },
- clearAll: function() {
- $.each(this._timers, function(t, i) {
- clearTimeout(i);
- }),
- (this._timers = {});
- }
- });
- var Types = {
- image: {
- extensions: "bmp gif jpeg jpg png webp",
- detect: function(t) {
- return -1 < $.inArray(detectExtension(t), this.extensions.split(" "));
- },
- data: function(t) {
- return !!this.detect() && { extension: detectExtension(t) };
- }
- },
- youtube: {
- detect: function(t) {
- var i = /(youtube\.com|youtu\.be)\/watch\?(?=.*vi?=([a-zA-Z0-9-_]+))(?:\S+)?$/.exec(
- t
- );
- return i && i[2]
- ? i[2]
- : !(
- !(i = /(youtube\.com|youtu\.be)\/(vi?\/|u\/|embed\/)?([a-zA-Z0-9-_]+)(?:\S+)?$/i.exec(
- t
- )) || !i[3]
- ) && i[3];
- },
- data: function(t) {
- var i = this.detect(t);
- return !!i && { id: i };
- }
- },
- vimeo: {
- detect: function(t) {
- var i = /(vimeo\.com)\/([a-zA-Z0-9-_]+)(?:\S+)?$/i.exec(t);
- return !(!i || !i[2]) && i[2];
- },
- data: function(t) {
- var i = this.detect(t);
- return !!i && { id: i };
- }
- }
- },
- VimeoReady = (function() {
- function t() {
- return this.initialize.apply(this, _slice.call(arguments));
- }
- $.extend(t.prototype, {
- initialize: function(t, i) {
- (this.url = t), (this.callback = i), this.load();
- },
- load: function() {
- var t = s.get(this.url);
- if (t) return this.callback(t.data);
- var i =
- "http" +
- (window.location && "https:" == window.location.protocol
- ? "s"
- : "") +
- ":",
- e = getURIData(this.url).id;
- this._xhr = $.getJSON(
- i +
- "//vimeo.com/api/oembed.json?url=" +
- i +
- "//vimeo.com/" +
- e +
- "&maxwidth=9999999&maxheight=9999999&callback=?",
- $.proxy(function(t) {
- var i = { dimensions: { width: t.width, height: t.height } };
- s.set(this.url, i), this.callback && this.callback(i);
- }, this)
- );
- },
- abort: function() {
- this._xhr && (this._xhr.abort(), (this._xhr = null));
- }
- });
- var s = {
- cache: [],
- get: function(t) {
- for (var i = null, e = 0; e < this.cache.length; e++)
- this.cache[e] && this.cache[e].url == t && (i = this.cache[e]);
- return i;
- },
- set: function(t, i) {
- this.remove(t), this.cache.push({ url: t, data: i });
- },
- remove: function(t) {
- for (var i = 0; i < this.cache.length; i++)
- this.cache[i] && this.cache[i].url == t && delete this.cache[i];
- }
- };
- return t;
- })(),
- Options = {
- defaults: {
- effects: {
- spinner: { show: 200, hide: 200 },
- transition: { min: 175, max: 250 },
- ui: { show: 0, hide: 200 },
- window: { show: 300, hide: 300 }
- },
- hideOnClickOutside: !0,
- keyboard: { left: !0, right: !0, esc: !0 },
- loop: !0,
- overlap: !0,
- preload: [1, 2],
- position: !0,
- skin: "strip",
- side: "right",
- spinner: !0,
- toggle: !0,
- uiDelay: 3e3,
- vimeo: {
- autoplay: 1,
- api: 1,
- title: 1,
- byline: 1,
- portrait: 0,
- loop: 0
- },
- youtube: {
- autoplay: 1,
- controls: 1,
- enablejsapi: 1,
- hd: 1,
- iv_load_policy: 3,
- loop: 0,
- modestbranding: 1,
- rel: 0,
- vq: "hd1080"
- },
- initialTypeOptions: {
- image: {},
- vimeo: { width: 1280 },
- youtube: { width: 1280, height: 720 }
- }
- },
- create: function(t, i, e) {
- (t = t || {}).skin = t.skin || this.defaults.skin;
- var s = t.skin
- ? $.extend(
- {},
- Strip.Skins[t.skin] || Strip.Skins[this.defaults.skin]
- )
- : {},
- n = $.extend(!0, {}, this.defaults, s);
- n.initialTypeOptions &&
- (i &&
- n.initialTypeOptions[i] &&
- (n = $.extend(!0, {}, n.initialTypeOptions[i], n)),
- delete n.initialTypeOptions);
- var o = $.extend(!0, {}, n, t);
- return (
- (!o.effects || (Browser.IE && Browser.IE < 9)) &&
- ((o.effects = {}),
- $.each(this.defaults.effects, function(i, t) {
- $.each((o.effects[i] = $.extend({}, t)), function(t) {
- o.effects[i][t] = 0;
- });
- }),
- (o.spinner = !1)),
- o.keyboard &&
- ("boolean" === $.type(o.keyboard) &&
- ((o.keyboard = {}),
- $.each(this.defaults.keyboard, function(t, i) {
- o.keyboard[t] = !0;
- })),
- ("vimeo" !== i && "youtube" !== i) ||
- $.extend(o.keyboard, { left: !1, right: !1 })),
- ("vimeo" !== i && "youtube" !== i) || (o.overlap = !1),
- o
- );
- }
- };
- function View() {
- this.initialize.apply(this, _slice.call(arguments));
- }
- $.extend(View.prototype, {
- initialize: function(object) {
- var options = arguments[1] || {},
- data = {};
- if ("string" === $.type(object)) object = { url: object };
- else if (object && 1 === object.nodeType) {
- var element = $(object);
- object = {
- element: element[0],
- url: element.attr("href"),
- caption: element.attr("data-strip-caption"),
- group: element.attr("data-strip-group"),
- extension: element.attr("data-strip-extension"),
- type: element.attr("data-strip-type"),
- options:
- (element.attr("data-strip-options") &&
- eval("({" + element.attr("data-strip-options") + "})")) ||
- {}
- };
- }
- if (
- object &&
- (object.extension || (object.extension = detectExtension(object.url)),
- !object.type)
- ) {
- var data = getURIData(object.url);
- (object._data = data), (object.type = data.type);
- }
- return (
- object._data || (object._data = getURIData(object.url)),
- object && object.options
- ? (object.options = $.extend(
- !0,
- $.extend({}, options),
- $.extend({}, object.options)
- ))
- : (object.options = $.extend({}, options)),
- (object.options = Options.create(
- object.options,
- object.type,
- object._data
- )),
- $.extend(this, object),
- this
- );
- }
- });
- var Pages = {
- initialize: function(t) {
- (this.element = t), (this.pages = {}), (this.uid = 1);
- },
- add: function(t) {
- this.uid++,
- (this.views = t),
- (this.pages[this.uid] = []),
- (Window._showUIOnResize = !0),
- $.each(
- t,
- $.proxy(function(t, i) {
- this.pages[this.uid].push(new Page(i, t + 1, this.views.length));
- }, this)
- );
- },
- show: function(t, i) {
- var e = this.pages[this.uid][t - 1];
- this.page && this.page.uid == e.uid
- ? e.view.options.toggle && (Window.hide(), (this.page = null))
- : (Pages.setActiveClass(e),
- (this.page = e),
- this.removeHiddenAndLoadingInactive(),
- e.show(
- $.proxy(function() {
- (this._switched = !1), i && i();
- }, this)
- ));
- },
- getLoadingCount: function() {
- var e = 0;
- return (
- $.each(this.pages, function(t, i) {
- $.each(i, function(t, i) {
- i.loading && e++;
- });
- }),
- e
- );
- },
- getPositionInActivePageGroup: function(e) {
- var s = 0,
- t = this.pages[this.uid];
- return (
- t &&
- $.each(t, function(t, i) {
- i.view.element && i.view.element == e && (s = t + 1);
- }),
- s
- );
- },
- removeExpired: function(e) {
- $.each(this.pages, function(t, i) {
- t != this._id &&
- $.each(i, function(t, i) {
- i.remove(e);
- });
- });
- },
- removeAll: function() {
- $.each(this.pages, function(t, i) {
- $.each(i, function(t, i) {
- i.remove();
- });
- }),
- (this.pages = {});
- },
- hideVisibleInactive: function(e) {
- $.each(
- this.pages,
- $.proxy(function(t, i) {
- $.each(
- i,
- $.proxy(function(t, i) {
- i.uid != this.page.uid && i.hide(null, e);
- }, this)
- );
- }, this)
- );
- },
- stopInactive: function() {
- $.each(
- this.pages,
- $.proxy(function(t, i) {
- $.each(
- i,
- $.proxy(function(t, i) {
- i.uid == this.page.uid || i.preloading || i.stop();
- }, this)
- );
- }, this)
- );
- },
- removeHiddenAndLoadingInactive: function() {
- var s = [];
- $.each(
- this.pages,
- $.proxy(function(t, i) {
- if (t != this.uid) {
- var e = 0;
- $.each(
- i,
- $.proxy(function(t, i) {
- (i.visible && !i.loading) || i.animatingWindow || i.remove(),
- i.removed && e++;
- }, this)
- ),
- e == i.length && s.push(t);
- }
- }, this)
- ),
- $.each(
- s,
- $.proxy(function(t, i) {
- delete this.pages[i];
- }, this)
- );
- },
- stop: function() {
- $.each(this.pages, function(t, i) {
- $.each(i, function(t, i) {
- i.stop();
- });
- });
- },
- setActiveClass: function(t) {
- this.removeActiveClasses();
- var i = t.view.element;
- if (i) {
- $(i).addClass("strip-active-element strip-active-group");
- var e = $(i).attr("data-strip-group");
- e &&
- $('.strip[data-strip-group="' + e + '"]').addClass(
- "strip-active-group"
- );
- }
- },
- removeActiveClasses: function() {
- $(".strip-active-group").removeClass(
- "strip-active-group strip-active-element"
- );
- }
- },
- Page =
- ((sc = 0),
- (tc = {}),
- $.extend(uc.prototype, {
- initialize: function(t, i, e) {
- (this.view = t),
- (this.dimensions = { width: 0, height: 0 }),
- (this.uid = sc++),
- (this._position = i),
- (this._total = e),
- (this.animated = !1),
- (this.visible = !1),
- (this.queues = {}),
- (this.queues.showhide = $({}));
- },
- create: function() {
- if (!this._created) {
- Pages.element.append(
- (this.element = $("
")
- .addClass("strp-page")
- .append(
- (this.container = $("
").addClass("strp-container"))
- )
- .css({ opacity: 0 })
- .hide())
- );
- var t = this.view.options.position && 1 < this._total;
- switch (
- ((this.view.caption || t) &&
- (this.element.append(
- (this.info = $("
")
- .addClass("strp-info")
- .append(
- (this.info_padder = $("
").addClass(
- "strp-info-padder"
- ))
- ))
- ),
- t &&
- (this.element.addClass("strp-has-position"),
- this.info_padder.append(
- $("
")
- .addClass("strp-position")
- .html(this._position + " / " + this._total)
- )),
- this.view.caption &&
- this.info_padder.append(
- (this.caption = $("
")
- .addClass("strp-caption")
- .html(this.view.caption))
- )),
- this.view.type)
- ) {
- case "image":
- this.container.append(
- (this.content = $("
").attr({ src: this.view.url }))
- );
- break;
- case "vimeo":
- case "youtube":
- this.container.append((this.content = $("
")));
- }
- this.element.addClass(
- "strp" + (this.view.options.overlap ? "" : "-no") + "-overlap"
- ),
- this._total < 2 && this.element.addClass("strp-no-sides"),
- this.content.addClass("strp-content-element"),
- (this._created = !0);
- }
- },
- _getSurroundingPages: function() {
- var t;
- if (!(t = this.view.options.preload)) return [];
- for (
- var i = [],
- e = Math.max(1, this._position - t[0]),
- s = Math.min(this._position + t[1], this._total),
- n = this._position,
- o = n;
- o <= s;
- o++
- )
- (r = Pages.pages[Pages.uid][o - 1])._position != n && i.push(r);
- for (o = n; e <= o; o--) {
- var r;
- (r = Pages.pages[Pages.uid][o - 1])._position != n && i.push(r);
- }
- return i;
- },
- preloadSurroundingImages: function() {
- var t = this._getSurroundingPages();
- $.each(
- t,
- $.proxy(function(t, i) {
- i.preload();
- }, this)
- );
- },
- preload: function() {
- this.preloading ||
- this.preloaded ||
- "image" !== this.view.type ||
- !this.view.options.preload ||
- this.loaded ||
- (this.create(),
- (this.preloading = !0),
- new ImageReady(
- this.content[0],
- $.proxy(function(t) {
- (this.loaded = !0),
- (this.preloading = !1),
- (this.preloaded = !0),
- (this.dimensions = {
- width: t.img.naturalWidth,
- height: t.img.naturalHeight
- });
- }, this),
- null,
- { method: "naturalWidth" }
- ));
- },
- load: function(i, t) {
- if ((this.create(), this.loaded)) i && i();
- else
- switch (
- (this.abort(),
- (this.loading = !0),
- this.view.options.spinner &&
- !tc[this.view.url] &&
- Window.startLoading(),
- this.view.type)
- ) {
- case "image":
- if (this.error) return void (i && i());
- this.imageReady = new ImageReady(
- this.content[0],
- $.proxy(function(t) {
- this._markAsLoaded(),
- (this.dimensions = {
- width: t.img.naturalWidth,
- height: t.img.naturalHeight
- }),
- i && i();
- }, this),
- $.proxy(function() {
- this._markAsLoaded(),
- this.content.hide(),
- this.container.append(
- (this.error = $("
").addClass("strp-error"))
- ),
- this.element.addClass("strp-has-error"),
- (this.dimensions = {
- width: this.error.outerWidth(),
- height: this.error.outerHeight()
- }),
- i && i();
- }, this),
- { method: "naturalWidth" }
- );
- break;
- case "vimeo":
- this.vimeoReady = new VimeoReady(
- this.view.url,
- $.proxy(function(t) {
- this._markAsLoaded(),
- (this.dimensions = {
- width: t.dimensions.width,
- height: t.dimensions.height
- }),
- i && i();
- }, this)
- );
- break;
- case "youtube":
- this._markAsLoaded(),
- (this.dimensions = {
- width: this.view.options.width,
- height: this.view.options.height
- }),
- i && i();
- }
- },
- _markAsLoaded: function() {
- (this.loading = !1),
- (this.loaded = !0),
- (tc[this.view.url] = !0),
- Window.stopLoading();
- },
- isVideo: function() {
- return /^(youtube|vimeo)$/.test(this.view.type);
- },
- insertVideo: function(t) {
- if (!this.playerIframe && this.isVideo()) {
- var i =
- "http" +
- (window.location && "https:" === window.location.protocol
- ? "s"
- : "") +
- ":",
- e = $.extend({}, this.view.options[this.view.type] || {}),
- s = $.param(e),
- n = {
- vimeo: i + "//player.vimeo.com/video/{id}?{queryString}",
- youtube: i + "//www.youtube.com/embed/{id}?{queryString}"
- }[this.view.type]
- .replace("{id}", this.view._data.id)
- .replace("{queryString}", s);
- this.content.append(
- (this.playerIframe = $(
- "