From ed4d5669d5089854b87e4a2ce482ef84083440dc Mon Sep 17 00:00:00 2001 From: Kyle Paulsen Date: Thu, 15 Jan 2015 17:44:09 -0800 Subject: [PATCH] Adding event to object that gets passed to event handlers for modal buttons. --- README.md | 2 +- nanomodal.js | 16 ++++++++++++++-- nanomodal.min.js | 2 +- package.json | 2 +- src/Modal.js | 16 ++++++++++++++-- test/basic.html | 5 +++-- 6 files changed, 34 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 654f072..62d79b8 100644 --- a/README.md +++ b/README.md @@ -124,7 +124,7 @@ var modalObj = nanoModal("sup", {buttons: [ /* button definition objects here */ When defining custom button objects, here are the properties you can set and what they do: - **text**: The string of text that goes inside the button. -- **handler**: This can be the string "hide" *OR* a function. If it is the string "hide", the button will simply close the modal when it is clicked. Otherwise the passed function will be called when the button is clicked. The function will also be passed the modal API. +- **handler**: This can be the string "hide" *OR* a function. If it is the string "hide", the button will simply close the modal when it is clicked. Otherwise the passed function will be called when the button is clicked. The function will also be passed the modal API with the click event added on under the key 'event'. - **primary**: A boolean (true or false). If this is true, it just adds the "nanoModalBtnPrimary" class to the button (which makes it look blue by default). - **classes**: A string of space separated classes you want on the button: "myClassA myClassB" diff --git a/nanomodal.js b/nanomodal.js index 8f95ca3..bb25fa5 100644 --- a/nanomodal.js +++ b/nanomodal.js @@ -191,6 +191,16 @@ function Modal(content, options, overlay, customShow, customHide) { } }; + var quickClone = function(obj) { + var newObj = {}; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + newObj[key] = obj[key]; + } + } + return newObj; + }; + pub = { modal: modal, overlay: overlay, @@ -234,8 +244,10 @@ function Modal(content, options, overlay, customShow, customHide) { var btnEl; var classes; var giveButtonCustomClickListener = function(btnEl, btnObj) { - btnEl.addClickListener(function() { - btnObj.handler(pub); + var pubCopy = quickClone(pub); + btnEl.addClickListener(function(e) { + pubCopy.event = e || window.event; + btnObj.handler(pubCopy); }); }; diff --git a/nanomodal.min.js b/nanomodal.min.js index 1788b15..2e04e03 100644 --- a/nanomodal.min.js +++ b/nanomodal.min.js @@ -1 +1 @@ -var nanoModal;!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0;)if(c=f[d],c.event===a&&c.handler===b){f.splice(d,1);break}},k=function(a){"ontouchend"in document.documentElement?i("touchstart",a):i("click",a)},l=function(a){e&&(e.style.display="block",g.fire(a))},m=function(a){e&&(e.style.display="none",h.fire(a))},n=function(){return e.style&&"block"===e.style.display},o=function(a){e&&(e.innerHTML=a)},p=function(a){e&&(o(""),e.appendChild(c.createTextNode(a)))},q=function(){if(e.parentNode){for(var a,b=f.length;b-->0;)a=f[b],j(a.event,a.handler);e.parentNode.removeChild(e),g.removeAllListeners(),h.removeAllListeners()}},r=function(a){var b=a.el||a;e.appendChild(b)};return{el:e,addListener:i,addClickListener:k,onShowEvent:g,onHideEvent:h,show:l,hide:m,isShowing:n,html:o,text:p,remove:q,add:r}}var d=a("./ModalEvent");b.exports=c},{"./ModalEvent":3}],2:[function(a,b){function c(a,b,e,f,g){if(void 0!==a){b=b||{};var h,i=d("div","nanoModal nanoModalOverride "+(b.classes||"")),j=d("div","nanoModalContent"),k=d("div","nanoModalButtons");i.add(j),i.add(k),i.el.style.display="none";var l,m=[];b.buttons=b.buttons||[{text:"Close",handler:"hide",primary:!0}];var n=function(){for(var a=m.length;a-->0;){var b=m[a];b.remove()}m=[]},o=function(){i.el.style.marginLeft=-i.el.clientWidth/2+"px"},p=function(){for(var a=document.querySelectorAll(".nanoModal"),b=a.length;b-->0;)if("none"!==a[b].style.display)return!0;return!1},q=function(){i.isShowing()||(c.resizeOverlay(),e.show(e),i.show(l),o())},r=function(){i.isShowing()&&(i.hide(l),p()||e.hide(e),b.autoRemove&&l.remove())};return l={modal:i,overlay:e,show:function(){return f?f(q,l):q(),l},hide:function(){return g?g(r,l):r(),l},onShow:function(a){return i.onShowEvent.addListener(function(){a(l)}),l},onHide:function(a){return i.onHideEvent.addListener(function(){a(l)}),l},remove:function(){e.onRequestHide.removeListener(h),h=null,n(),i.remove()},setButtons:function(a){var b,c,e,f=a.length,g=function(a,b){a.addClickListener(function(){b.handler(l)})};if(n(),0===f)k.hide();else for(k.show();f-->0;)b=a[f],e="nanoModalBtn",b.primary&&(e+=" nanoModalBtnPrimary"),e+=b.classes?" "+b.classes:"",c=d("button",e),"hide"===b.handler?c.addClickListener(l.hide):b.handler&&g(c,b),c.text(b.text),k.add(c),m.push(c);return o(),l},setContent:function(b){return b.nodeType?(j.html(""),j.add(b)):j.html(b),o(),a=b,l},getContent:function(){return a}},h=e.onRequestHide.addListener(function(){b.overlayClose!==!1&&i.isShowing()&&l.hide()}),l.setContent(a).setButtons(b.buttons),document.body.appendChild(i.el),l}}var d=a("./El"),e=document,f=function(a){var b=e.documentElement,c="scroll"+a,d="offset"+a;return Math.max(e.body[c],b[c],e.body[d],b[d],b["client"+a])};c.resizeOverlay=function(){var a=e.getElementById("nanoModalOverlay");a.style.width=f("Width")+"px",a.style.height=f("Height")+"px"},b.exports=c},{"./El":1}],3:[function(a,b){function c(){var a={},b=0,c=function(c){return a[b]=c,b++},d=function(b){b&&delete a[b]},e=function(){a={}},f=function(){for(var c=0,d=b;d>c;++c)a[c]&&a[c].apply(null,arguments)};return{addListener:c,removeListener:d,removeAllListeners:e,fire:f}}b.exports=c},{}],4:[function(a){var b=a("./ModalEvent"),c=function(){function c(){if(!g.querySelector("#nanoModalOverlay")){var a=e("style"),c=a.el,h=g.querySelectorAll("head")[0].childNodes[0];h.parentNode.insertBefore(c,h);var i=".nanoModal{position:absolute;top:100px;left:50%;display:none;z-index:9999;min-width:300px;padding:15px 20px 10px;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;background:#fff;background:-moz-linear-gradient(top,#fff 0,#ddd 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#ddd));background:-webkit-linear-gradient(top,#fff 0,#ddd 100%);background:-o-linear-gradient(top,#fff 0,#ddd 100%);background:-ms-linear-gradient(top,#fff 0,#ddd 100%);background:linear-gradient(to bottom,#fff 0,#ddd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dddddd', GradientType=0)}.nanoModalOverlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:9998;background:#000;display:none;-ms-filter:\"alpha(Opacity=50)\";-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}.nanoModalButtons{border-top:1px solid #ddd;margin-top:15px;text-align:right}.nanoModalBtn{color:#333;background-color:#fff;display:inline-block;padding:6px 12px;margin:8px 4px 0;font-size:14px;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nanoModalBtn:active,.nanoModalBtn:focus,.nanoModalBtn:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.nanoModalBtn.nanoModalBtnPrimary{color:#fff;background-color:#428bca;border-color:#357ebd}.nanoModalBtn.nanoModalBtnPrimary:active,.nanoModalBtn.nanoModalBtnPrimary:focus,.nanoModalBtn.nanoModalBtnPrimary:hover{color:#fff;background-color:#3071a9;border-color:#285e8e}";c.styleSheet?c.styleSheet.cssText=i:a.text(i),d=e("div","nanoModalOverlay nanoModalOverride"),d.el.id="nanoModalOverlay",g.body.appendChild(d.el),d.onRequestHide=b();var j=function(){d.onRequestHide.fire()};d.addClickListener(j),e(g).addListener("keydown",function(a){var b=a.which||a.keyCode;27===b&&j()});var k,l=e(window);l.addListener("resize",function(){k&&clearTimeout(k),k=setTimeout(f.resizeOverlay,100)}),l.addListener("orientationchange",function(){for(var a=0;3>a;++a)setTimeout(f.resizeOverlay,1e3*a+200)})}}var d,e=a("./El"),f=a("./Modal"),g=document;document.body&&c();var h=function(a,b){return c(),f(a,b,d,h.customShow,h.customHide)};return h.resizeOverlay=f.resizeOverlay,h}();nanoModal=c},{"./El":1,"./Modal":2,"./ModalEvent":3}]},{},[1,2,3,4]),"undefined"!=typeof window&&("function"==typeof window.define&&window.define.amd&&window.define(function(){return nanoModal}),window.nanoModal=nanoModal),"undefined"!=typeof module&&(module.exports=nanoModal); \ No newline at end of file +var nanoModal;!function a(b,c,d){function e(g,h){if(!c[g]){if(!b[g]){var i="function"==typeof require&&require;if(!h&&i)return i(g,!0);if(f)return f(g,!0);throw new Error("Cannot find module '"+g+"'")}var j=c[g]={exports:{}};b[g][0].call(j.exports,function(a){var c=b[g][1][a];return e(c?c:a)},j,j.exports,a,b,c,d)}return c[g].exports}for(var f="function"==typeof require&&require,g=0;g0;)if(c=f[d],c.event===a&&c.handler===b){f.splice(d,1);break}},k=function(a){"ontouchend"in document.documentElement?i("touchstart",a):i("click",a)},l=function(a){e&&(e.style.display="block",g.fire(a))},m=function(a){e&&(e.style.display="none",h.fire(a))},n=function(){return e.style&&"block"===e.style.display},o=function(a){e&&(e.innerHTML=a)},p=function(a){e&&(o(""),e.appendChild(c.createTextNode(a)))},q=function(){if(e.parentNode){for(var a,b=f.length;b-->0;)a=f[b],j(a.event,a.handler);e.parentNode.removeChild(e),g.removeAllListeners(),h.removeAllListeners()}},r=function(a){var b=a.el||a;e.appendChild(b)};return{el:e,addListener:i,addClickListener:k,onShowEvent:g,onHideEvent:h,show:l,hide:m,isShowing:n,html:o,text:p,remove:q,add:r}}var d=a("./ModalEvent");b.exports=c},{"./ModalEvent":3}],2:[function(a,b){function c(a,b,e,f,g){if(void 0!==a){b=b||{};var h,i=d("div","nanoModal nanoModalOverride "+(b.classes||"")),j=d("div","nanoModalContent"),k=d("div","nanoModalButtons");i.add(j),i.add(k),i.el.style.display="none";var l,m=[];b.buttons=b.buttons||[{text:"Close",handler:"hide",primary:!0}];var n=function(){for(var a=m.length;a-->0;){var b=m[a];b.remove()}m=[]},o=function(){i.el.style.marginLeft=-i.el.clientWidth/2+"px"},p=function(){for(var a=document.querySelectorAll(".nanoModal"),b=a.length;b-->0;)if("none"!==a[b].style.display)return!0;return!1},q=function(){i.isShowing()||(c.resizeOverlay(),e.show(e),i.show(l),o())},r=function(){i.isShowing()&&(i.hide(l),p()||e.hide(e),b.autoRemove&&l.remove())},s=function(a){var b={};for(var c in a)a.hasOwnProperty(c)&&(b[c]=a[c]);return b};return l={modal:i,overlay:e,show:function(){return f?f(q,l):q(),l},hide:function(){return g?g(r,l):r(),l},onShow:function(a){return i.onShowEvent.addListener(function(){a(l)}),l},onHide:function(a){return i.onHideEvent.addListener(function(){a(l)}),l},remove:function(){e.onRequestHide.removeListener(h),h=null,n(),i.remove()},setButtons:function(a){var b,c,e,f=a.length,g=function(a,b){var c=s(l);a.addClickListener(function(a){c.event=a||window.event,b.handler(c)})};if(n(),0===f)k.hide();else for(k.show();f-->0;)b=a[f],e="nanoModalBtn",b.primary&&(e+=" nanoModalBtnPrimary"),e+=b.classes?" "+b.classes:"",c=d("button",e),"hide"===b.handler?c.addClickListener(l.hide):b.handler&&g(c,b),c.text(b.text),k.add(c),m.push(c);return o(),l},setContent:function(b){return b.nodeType?(j.html(""),j.add(b)):j.html(b),o(),a=b,l},getContent:function(){return a}},h=e.onRequestHide.addListener(function(){b.overlayClose!==!1&&i.isShowing()&&l.hide()}),l.setContent(a).setButtons(b.buttons),document.body.appendChild(i.el),l}}var d=a("./El"),e=document,f=function(a){var b=e.documentElement,c="scroll"+a,d="offset"+a;return Math.max(e.body[c],b[c],e.body[d],b[d],b["client"+a])};c.resizeOverlay=function(){var a=e.getElementById("nanoModalOverlay");a.style.width=f("Width")+"px",a.style.height=f("Height")+"px"},b.exports=c},{"./El":1}],3:[function(a,b){function c(){var a={},b=0,c=function(c){return a[b]=c,b++},d=function(b){b&&delete a[b]},e=function(){a={}},f=function(){for(var c=0,d=b;d>c;++c)a[c]&&a[c].apply(null,arguments)};return{addListener:c,removeListener:d,removeAllListeners:e,fire:f}}b.exports=c},{}],4:[function(a){var b=a("./ModalEvent"),c=function(){function c(){if(!g.querySelector("#nanoModalOverlay")){var a=e("style"),c=a.el,h=g.querySelectorAll("head")[0].childNodes[0];h.parentNode.insertBefore(c,h);var i=".nanoModal{position:absolute;top:100px;left:50%;display:none;z-index:9999;min-width:300px;padding:15px 20px 10px;-webkit-border-radius:10px;-moz-border-radius:10px;border-radius:10px;background:#fff;background:-moz-linear-gradient(top,#fff 0,#ddd 100%);background:-webkit-gradient(linear,left top,left bottom,color-stop(0%,#fff),color-stop(100%,#ddd));background:-webkit-linear-gradient(top,#fff 0,#ddd 100%);background:-o-linear-gradient(top,#fff 0,#ddd 100%);background:-ms-linear-gradient(top,#fff 0,#ddd 100%);background:linear-gradient(to bottom,#fff 0,#ddd 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffff', endColorstr='#dddddd', GradientType=0)}.nanoModalOverlay{position:absolute;top:0;left:0;width:100%;height:100%;z-index:9998;background:#000;display:none;-ms-filter:\"alpha(Opacity=50)\";-moz-opacity:.5;-khtml-opacity:.5;opacity:.5}.nanoModalButtons{border-top:1px solid #ddd;margin-top:15px;text-align:right}.nanoModalBtn{color:#333;background-color:#fff;display:inline-block;padding:6px 12px;margin:8px 4px 0;font-size:14px;text-align:center;white-space:nowrap;vertical-align:middle;cursor:pointer;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:1px solid transparent;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px}.nanoModalBtn:active,.nanoModalBtn:focus,.nanoModalBtn:hover{color:#333;background-color:#e6e6e6;border-color:#adadad}.nanoModalBtn.nanoModalBtnPrimary{color:#fff;background-color:#428bca;border-color:#357ebd}.nanoModalBtn.nanoModalBtnPrimary:active,.nanoModalBtn.nanoModalBtnPrimary:focus,.nanoModalBtn.nanoModalBtnPrimary:hover{color:#fff;background-color:#3071a9;border-color:#285e8e}";c.styleSheet?c.styleSheet.cssText=i:a.text(i),d=e("div","nanoModalOverlay nanoModalOverride"),d.el.id="nanoModalOverlay",g.body.appendChild(d.el),d.onRequestHide=b();var j=function(){d.onRequestHide.fire()};d.addClickListener(j),e(g).addListener("keydown",function(a){var b=a.which||a.keyCode;27===b&&j()});var k,l=e(window);l.addListener("resize",function(){k&&clearTimeout(k),k=setTimeout(f.resizeOverlay,100)}),l.addListener("orientationchange",function(){for(var a=0;3>a;++a)setTimeout(f.resizeOverlay,1e3*a+200)})}}var d,e=a("./El"),f=a("./Modal"),g=document;document.body&&c();var h=function(a,b){return c(),f(a,b,d,h.customShow,h.customHide)};return h.resizeOverlay=f.resizeOverlay,h}();nanoModal=c},{"./El":1,"./Modal":2,"./ModalEvent":3}]},{},[1,2,3,4]),"undefined"!=typeof window&&("function"==typeof window.define&&window.define.amd&&window.define(function(){return nanoModal}),window.nanoModal=nanoModal),"undefined"!=typeof module&&(module.exports=nanoModal); \ No newline at end of file diff --git a/package.json b/package.json index fabb7ea..fa829eb 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nanomodal", - "version": "5.0.3", + "version": "5.1.0", "description": "A small, self-contained JavaScript modal library with some extra features", "homepage": "https://github.com/kylepaulsen/NanoModal", "author": { diff --git a/src/Modal.js b/src/Modal.js index 9607806..d068487 100644 --- a/src/Modal.js +++ b/src/Modal.js @@ -70,6 +70,16 @@ function Modal(content, options, overlay, customShow, customHide) { } }; + var quickClone = function(obj) { + var newObj = {}; + for (var key in obj) { + if (obj.hasOwnProperty(key)) { + newObj[key] = obj[key]; + } + } + return newObj; + }; + pub = { modal: modal, overlay: overlay, @@ -113,8 +123,10 @@ function Modal(content, options, overlay, customShow, customHide) { var btnEl; var classes; var giveButtonCustomClickListener = function(btnEl, btnObj) { - btnEl.addClickListener(function() { - btnObj.handler(pub); + var pubCopy = quickClone(pub); + btnEl.addClickListener(function(e) { + pubCopy.event = e || window.event; + btnObj.handler(pubCopy); }); }; diff --git a/test/basic.html b/test/basic.html index 42c72af..ce101f0 100644 --- a/test/basic.html +++ b/test/basic.html @@ -166,8 +166,9 @@ touchClick(nanoModalButtons[0]); assert.ok(wasHandlerCalled, "After clicking the second button, the handler should be called."); - assert.strictEqual(handlerArg, modal, - "After clicking the second button, the handler should be passed the modal as an argument."); + assert.deepEqual(Object.keys(handlerArg), ["modal", "overlay", "show", "hide", "onShow", + "onHide", "remove", "setButtons", "setContent", "getContent", "event"], + "After clicking the second button, the handler should be passed an object with these keys."); modal.remove(); });