diff --git a/src/jqueryextensions.js b/src/jqueryextensions.js index 1166a84..78f532f 100644 --- a/src/jqueryextensions.js +++ b/src/jqueryextensions.js @@ -64,3 +64,119 @@ setupPassiveListeners(); } })(jQuery); + +/* + When autoresize is enabled, we obtain the width of the wrapper element and resize to that, however when we're hidden because of + one of our ancenstors, jQuery width function returns 0. Ideally, we could use ResizeObserver/MutationObserver to detect + when we hide/show and resize on that event instead of resizing while we are not visible but until official support of older + browsers is dropped, we need to go this route. The plugin below will provide the actual width even when we're not visible. + + Source: https://raw.githubusercontent.com/dreamerslab/jquery.actual/master/jquery.actual.js +*/ +/*! Copyright 2012, Ben Lin (http://dreamerslab.com/) + * Licensed under the MIT License (LICENSE.txt). + * + * Version: 1.0.19 + * + * Requires: jQuery >= 1.2.3 + */ +/* eslint-disable one-var */ +(function ($) { + 'use strict'; + + $.fn.addBack = $.fn.addBack || $.fn.andSelf; + + $.fn.extend({ + actual: function (method, options) { + // check if the jQuery method exist + if (!this[method]) { + throw ( + '$.actual => The jQuery method "' + + method + + '" you called does not exist' + ); + } + + var defaults = { + absolute: false, + clone: false, + includeMargin: false, + display: 'block' + }; + + var configs = $.extend(defaults, options); + + var $target = this.eq(0); + var fix, restore; + + if (configs.clone === true) { + fix = function () { + var style = 'position: absolute !important; top: -1000 !important; '; + + // this is useful with css3pie + $target = $target.clone().attr('style', style).appendTo('body'); + }; + + restore = function () { + // remove DOM element after getting the width + $target.remove(); + }; + } else { + var tmp = []; + var style = ''; + var $hidden; + + fix = function () { + // get all hidden parents + $hidden = $target.parents().addBack().filter(':hidden'); + style += + 'visibility: hidden !important; display: ' + + configs.display + + ' !important; '; + + if (configs.absolute === true) + style += 'position: absolute !important; '; + + // save the origin style props + // set the hidden el css to be got the actual value later + $hidden.each(function () { + // Save original style. If no style was set, attr() returns undefined + var $this = $(this); + var thisStyle = $this.attr('style'); + + tmp.push(thisStyle); + // Retain as much of the original style as possible, if there is one + $this.attr('style', thisStyle ? thisStyle + ';' + style : style); + }); + }; + + restore = function () { + // restore origin style values + $hidden.each(function (i) { + var $this = $(this); + var _tmp = tmp[i]; + + if (_tmp === undefined) { + $this.removeAttr('style'); + } else { + $this.attr('style', _tmp); + } + }); + }; + } + + fix(); + // get the actual value with user specific methed + // it can be 'width', 'height', 'outerWidth', 'innerWidth'... etc + // configs.includeMargin only works for 'outerWidth' and 'outerHeight' + var actual = /(outer)/.test(method) + ? $target[method](configs.includeMargin) + : $target[method](); + + restore(); + // IMPORTANT, this plugin only return the value of the first element + return actual; + } + }); +})(jQuery); +/* eslint-enable one-var */ diff --git a/src/scale.js b/src/scale.js index 022a509..c66bb43 100644 --- a/src/scale.js +++ b/src/scale.js @@ -191,7 +191,19 @@ m.MapData.prototype.autoResize = function (duration, callback) { var me = this; - me.resize($(me.wrapper).width(), null, duration, callback); + + /* + When autoresize is enabled, we obtain the width of the wrapper element and resize to that, however when we're hidden because of + one of our ancenstors, jQuery width function returns 0. Ideally, we could use ResizeObserver/MutationObserver to detect + when we hide/show and resize on that event instead of resizing while we are not visible but until official support of older + browsers is dropped, we need to go this route. + */ + me.resize( + $(me.wrapper).width() || $(me.wrapper).actual('width'), + null, + duration, + callback + ); }; m.MapData.prototype.configureAutoResize = function () { diff --git a/src/zepto.js b/src/zepto.js index 6cccc97..bf7de78 100644 --- a/src/zepto.js +++ b/src/zepto.js @@ -1,4 +1,4 @@ -/* +/* zepto.js Monkey patch for Zepto to add some methods ImageMapster needs */ @@ -22,4 +22,45 @@ }; } }); + + var origFnExtend = $.fn.extend; + if (!origFnExtend) { + $.fn.extend = function (obj) { + $.extend($.fn, obj); + }; + } + + var origAddSelf = $.fn.addSelf; + if (!origAddSelf) { + /* + Including Zepto Stack module manually since it is small and avoids updating docs, rebuilding zepto dist, etc. + This is needed to support autoresize functionality which needs to resize when the map and/or one (or more) of + its parents is not visible. Ideally, we could use ResizeObserver/MutationObserver to detect when we hide/show + and resize on that event instead of resizing while we are not visible but until official support of older browsers + is dropped, we need to go this route. + + Source: https://github.com/madrobby/zepto/blob/main/src/stack.js + */ + // Zepto.js + // (c) 2010-2016 Thomas Fuchs + // Zepto.js may be freely distributed under the MIT license. + $.fn.end = function () { + return this.prevObject || $(); + }; + + $.fn.andSelf = function () { + return this.add(this.prevObject || $()); + }; + + 'filter,add,not,eq,first,last,find,closest,parents,parent,children,siblings' + .split(',') + .forEach(function (property) { + var fn = $.fn[property]; + $.fn[property] = function () { + var ret = fn.apply(this, arguments); + ret.prevObject = this; + return ret; + }; + }); + } })(jQuery); diff --git a/tests/imagemapster-test-runner.html b/tests/imagemapster-test-runner.html index d8ab41a..ac9b846 100644 --- a/tests/imagemapster-test-runner.html +++ b/tests/imagemapster-test-runner.html @@ -116,12 +116,24 @@