UNPKG

@patternslib/patternslib

Version:

Patternslib is a JavaScript library that enables designers to build rich interactive prototypes without the need for writing any Javascript. All events are triggered by classes and other attributes in the HTML, without abusing the HTML as a programming la

301 lines (263 loc) 9.8 kB
/** * @license * Patterns @VERSION@ jquery-ext - various jQuery extensions * * Copyright 2011 Humberto Sermeño */ import $ from "jquery"; var methods = { init: function (options) { var settings = { time: 3 /* time it will wait before moving to "timeout" after a move event */, initialTime: 8 /* time it will wait before first adding the "timeout" class */, exceptionAreas: [] /* IDs of elements that, if the mouse is over them, will reset the timer */, }; return this.each(function () { var $this = $(this), data = $this.data("timeout"); if (!data) { if (options) { $.extend(settings, options); } $this.data("timeout", { lastEvent: new Date(), trueTime: settings.time, time: settings.initialTime, untouched: true, inExceptionArea: false, }); $this.on("mouseover.timeout", methods.mouseMoved); $this.on("mouseenter.timeout", methods.mouseMoved); $(settings.exceptionAreas).each(function () { $this .find(this) .live( "mouseover.timeout", { parent: $this }, methods.enteredException ) .live( "mouseleave.timeout", { parent: $this }, methods.leftException ); }); if (settings.initialTime > 0) $this.timeout("startTimer"); else $this.addClass("timeout"); } }); }, enteredException: function (event) { var data = event.data.parent.data("timeout"); data.inExceptionArea = true; event.data.parent.data("timeout", data); event.data.parent.trigger("mouseover"); }, leftException: function (event) { var data = event.data.parent.data("timeout"); data.inExceptionArea = false; event.data.parent.data("timeout", data); }, destroy: function () { return this.each(function () { var $this = $(this), data = $this.data("timeout"); $(window).off(".timeout"); data.timeout.remove(); $this.removeData("timeout"); }); }, mouseMoved: function () { var $this = $(this), data = $this.data("timeout"); if ($this.hasClass("timeout")) { $this.removeClass("timeout"); $this.timeout("startTimer"); } else if (data.untouched) { data.untouched = false; data.time = data.trueTime; } data.lastEvent = new Date(); $this.data("timeout", data); }, startTimer: function () { var $this = $(this), data = $this.data("timeout"); var fn = function () { var data = $this.data("timeout"); if (data && data.lastEvent) { if (data.inExceptionArea) { setTimeout(fn, Math.floor(data.time * 1000)); } else { var now = new Date(); var diff = Math.floor(data.time * 1000) - (now - data.lastEvent); if (diff > 0) { // the timeout has not ocurred, so set the timeout again setTimeout(fn, diff + 100); } else { // timeout ocurred, so set the class $this.addClass("timeout"); } } } }; setTimeout(fn, Math.floor(data.time * 1000)); }, }; $.fn.timeout = function (method) { if (methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } else if (typeof method === "object" || !method) { return methods.init.apply(this, arguments); } else { $.error("Method " + method + " does not exist on jQuery.timeout"); } }; // Custom jQuery selector to find elements with scrollbars $.extend($.expr[":"], { scrollable: function (element) { var vertically_scrollable, horizontally_scrollable; if ( $(element).css("overflow") === "scroll" || $(element).css("overflowX") === "scroll" || $(element).css("overflowY") === "scroll" ) return true; vertically_scrollable = element.clientHeight < element.scrollHeight && ($.inArray($(element).css("overflowY"), ["scroll", "auto"]) !== -1 || $.inArray($(element).css("overflow"), ["scroll", "auto"]) !== -1); if (vertically_scrollable) return true; horizontally_scrollable = element.clientWidth < element.scrollWidth && ($.inArray($(element).css("overflowX"), ["scroll", "auto"]) !== -1 || $.inArray($(element).css("overflow"), ["scroll", "auto"]) !== -1); return horizontally_scrollable; }, }); // Make Visible in scroll $.fn.makeVisibleInScroll = function (parent_id) { var absoluteParent = null; if (typeof parent_id === "string") { absoluteParent = $("#" + parent_id); } else if (parent_id) { absoluteParent = $(parent_id); } return this.each(function () { var $this = $(this), parent; if (!absoluteParent) { parent = $this.parents(":scrollable"); if (parent.length > 0) { parent = $(parent[0]); } else { parent = $(window); } } else { parent = absoluteParent; } var elemTop = $this.position().top; var elemBottom = $this.height() + elemTop; var viewTop = parent.scrollTop(); var viewBottom = parent.height() + viewTop; if (elemTop < viewTop) { parent.scrollTop(elemTop); } else if (elemBottom > viewBottom - parent.height() / 2) { parent.scrollTop(elemTop - (parent.height() - $this.height()) / 2); } }); }; //Work around warning for jQuery 3.x: //JQMIGRATE: jQuery.fn.offset() requires an element connected to a document $.fn.safeOffset = function () { var docElem, elem = this[0], origin = { top: 0, left: 0 }; if (!elem || !elem.nodeType) { return origin; } docElem = (elem.ownerDocument || document).documentElement; if (!$.contains(docElem, elem)) { return origin; } return $.fn.offset.apply(this, arguments); }; //Make absolute location $.fn.setPositionAbsolute = function (element, offsettop, offsetleft) { return this.each(function () { // set absolute location for based on the element passed // dynamically since every browser has different settings var $this = $(this); var thiswidth = $(this).width(); var pos = element.safeOffset(); var width = element.width(); var height = element.height(); var setleft = pos.left + width - thiswidth + offsetleft; var settop = pos.top + height + offsettop; $this.css({ "z-index": 1, "position": "absolute", "marginLeft": 0, "marginTop": 0, "left": setleft + "px", "top": settop + "px", "width": thiswidth, }); $this.remove().appendTo("body").show(); }); }; $.fn.positionAncestor = function (selector) { var left = 0; var top = 0; this.each(function () { // check if current element has an ancestor matching a selector // and that ancestor is positioned var $ancestor = $(this).closest(selector); if ($ancestor.length && $ancestor.css("position") !== "static") { var $child = $(this); var childMarginEdgeLeft = $child.safeOffset().left - parseInt($child.css("marginLeft"), 10); var childMarginEdgeTop = $child.safeOffset().top - parseInt($child.css("marginTop"), 10); var ancestorPaddingEdgeLeft = $ancestor.safeOffset().left + parseInt($ancestor.css("borderLeftWidth"), 10); var ancestorPaddingEdgeTop = $ancestor.safeOffset().top + parseInt($ancestor.css("borderTopWidth"), 10); left = childMarginEdgeLeft - ancestorPaddingEdgeLeft; top = childMarginEdgeTop - ancestorPaddingEdgeTop; // we have found the ancestor and computed the position // stop iterating return false; } }); return { left: left, top: top, }; }; $.fn.findInclusive = function (selector) { return this.find("*").addBack().filter(selector); }; $.fn.slideIn = function (speed, easing, callback) { return this.animate({ width: "show" }, speed, easing, callback); }; $.fn.slideOut = function (speed, easing, callback) { return this.animate({ width: "hide" }, speed, easing, callback); }; // case-insensitive :contains $.expr[":"].Contains = function (a, i, m) { return $(a).text().toUpperCase().indexOf(m[3].toUpperCase()) >= 0; }; $.fn.scopedFind = function (selector) { /* If the selector starts with an object id do a global search, * otherwise do a local search. */ if (selector.indexOf("#") === 0) { return $(selector); } else { return this.find(selector); } }; export default undefined;