renalware-core 2.0.0.pre.beta5 → 2.0.0.pre.beta6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/renalware/session_timeout_redirect.js.erb +8 -4
- data/app/assets/stylesheets/renalware/partials/_navigation.scss +2 -2
- data/app/controllers/renalware/admin/users_controller.rb +3 -3
- data/app/helpers/renalware/application_helper.rb +2 -1
- data/app/helpers/renalware/layout_helper.rb +2 -2
- data/app/views/renalware/clinical/body_compositions/_form.html.slim +6 -2
- data/app/views/renalware/clinical/body_compositions/new.html.slim +4 -3
- data/app/views/renalware/clinics/clinic_visits/edit.html.slim +5 -2
- data/app/views/renalware/events/swabs/edit.html.slim +4 -2
- data/app/views/renalware/hd/historical_profiles/show.html.slim +6 -3
- data/app/views/renalware/patients/alerts/_form.html.slim +1 -1
- data/app/views/renalware/renal/profiles/edit.html.slim +5 -3
- data/app/views/renalware/transplants/donor_operations/edit.html.slim +7 -3
- data/lib/breadcrumb.rb +8 -0
- data/lib/renalware/version.rb +1 -1
- data/vendor/assets/fonts/foundation-icons.eot +0 -0
- data/vendor/assets/fonts/foundation-icons.scss +594 -0
- data/vendor/assets/fonts/foundation-icons.svg +970 -0
- data/vendor/assets/fonts/foundation-icons.ttf +0 -0
- data/vendor/assets/fonts/foundation-icons.woff +0 -0
- data/vendor/assets/javascripts/renalware/iframeResizer.contentWindow.js +1108 -0
- data/vendor/assets/javascripts/renalware/iframeResizer.js +1002 -0
- data/vendor/assets/javascripts/renalware/jquery-readyselector.js +17 -0
- data/vendor/assets/javascripts/renalware/masonry.min.js +9 -0
- data/vendor/assets/javascripts/renalware/modernizr.js +3 -0
- data/vendor/assets/javascripts/renalware/mousetrap.js +1044 -0
- data/vendor/assets/javascripts/renalware/print.min.js +1 -0
- data/vendor/assets/javascripts/renalware/rails.validations.js +660 -0
- data/vendor/assets/javascripts/renalware/rails.validations.simple_form.js +46 -0
- data/vendor/assets/stylesheets/renalware/print.min.css +1 -0
- data/vendor/assets/stylesheets/renalware/select2/css/select2.css +431 -0
- data/vendor/assets/stylesheets/renalware/select2/css/select2.min.css +1 -0
- data/vendor/xsd/ukrdc/README.md +9 -0
- data/vendor/xsd/ukrdc/Schema/Allergies/Allergy.xsd +69 -0
- data/vendor/xsd/ukrdc/Schema/ClinicalRelationships/ClinicalRelationship.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Diagnoses/CauseOfDeath.xsd +32 -0
- data/vendor/xsd/ukrdc/Schema/Diagnoses/Diagnosis.xsd +41 -0
- data/vendor/xsd/ukrdc/Schema/Diagnoses/RenalDiagnosis.xsd +41 -0
- data/vendor/xsd/ukrdc/Schema/Documents/Document.xsd +72 -0
- data/vendor/xsd/ukrdc/Schema/Encounters/Encounter.xsd +121 -0
- data/vendor/xsd/ukrdc/Schema/Encounters/TransplantList.xsd +108 -0
- data/vendor/xsd/ukrdc/Schema/Encounters/Treatment.xsd +207 -0
- data/vendor/xsd/ukrdc/Schema/FamilyHistories/FamilyHistory.xsd +42 -0
- data/vendor/xsd/ukrdc/Schema/LabOrders/LabOrder.xsd +181 -0
- data/vendor/xsd/ukrdc/Schema/Medications/Medication.xsd +88 -0
- data/vendor/xsd/ukrdc/Schema/Observations/Observation.xsd +65 -0
- data/vendor/xsd/ukrdc/Schema/Patient.xsd +87 -0
- data/vendor/xsd/ukrdc/Schema/Procedures/DialysisSession.xsd +61 -0
- data/vendor/xsd/ukrdc/Schema/Procedures/Procedure.xsd +38 -0
- data/vendor/xsd/ukrdc/Schema/Procedures/Transplant.xsd +160 -0
- data/vendor/xsd/ukrdc/Schema/Procedures/VascularAccess.xsd +49 -0
- data/vendor/xsd/ukrdc/Schema/ProgramMemberships/ProgramMembership.xsd +46 -0
- data/vendor/xsd/ukrdc/Schema/README.md +1 -0
- data/vendor/xsd/ukrdc/Schema/SocialHistories/SocialHistory.xsd +15 -0
- data/vendor/xsd/ukrdc/Schema/Surveys/Survey.xsd +143 -0
- data/vendor/xsd/ukrdc/Schema/Types/ActionCode.xsd +37 -0
- data/vendor/xsd/ukrdc/Schema/Types/Address.xsd +67 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_DMD.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_EDTA_COD.xsd +343 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_EDTA_PRD.xsd +356 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_0004.xsd +76 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_00204.xsd +46 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_HL7_00206.xsd +41 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_RR1.xsd +567 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_RR23.xsd +82 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_RR7_Discharge.xsd +80 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_RR7_Treatment.xsd +241 -0
- data/vendor/xsd/ukrdc/Schema/Types/CF_SNOMED.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/Clinician.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/CodeTableDetail.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/CodedField.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/CommonMetadata.xsd +23 -0
- data/vendor/xsd/ukrdc/Schema/Types/ContactDetail.xsd +55 -0
- data/vendor/xsd/ukrdc/Schema/Types/DrugProduct.xsd +41 -0
- data/vendor/xsd/ukrdc/Schema/Types/EthnicGroup.xsd +114 -0
- data/vendor/xsd/ukrdc/Schema/Types/FamilyDoctor.xsd +21 -0
- data/vendor/xsd/ukrdc/Schema/Types/LabResultItem.xsd +160 -0
- data/vendor/xsd/ukrdc/Schema/Types/LabTestItem.xsd +24 -0
- data/vendor/xsd/ukrdc/Schema/Types/Language.xsd +981 -0
- data/vendor/xsd/ukrdc/Schema/Types/Location.xsd +27 -0
- data/vendor/xsd/ukrdc/Schema/Types/NV_RR14.xsd +39 -0
- data/vendor/xsd/ukrdc/Schema/Types/Name.xsd +51 -0
- data/vendor/xsd/ukrdc/Schema/Types/Occupation.xsd +75 -0
- data/vendor/xsd/ukrdc/Schema/Types/Order.xsd +48 -0
- data/vendor/xsd/ukrdc/Schema/Types/PatientNumber.xsd +90 -0
- data/vendor/xsd/ukrdc/Schema/Types/PersonalContactType.xsd +11 -0
- data/vendor/xsd/ukrdc/Schema/Types/Result.xsd +178 -0
- data/vendor/xsd/ukrdc/Schema/UKRDC.xsd +148 -0
- metadata +78 -5
- data/lib/renalware/breadcrumb.rb +0 -10
@@ -0,0 +1,17 @@
|
|
1
|
+
(function ($) {
|
2
|
+
var ready = $.fn.ready;
|
3
|
+
$.fn.ready = function (fn) {
|
4
|
+
if (this.context === undefined) {
|
5
|
+
// The $().ready(fn) case.
|
6
|
+
ready(fn);
|
7
|
+
} else if (this.selector) {
|
8
|
+
ready($.proxy(function(){
|
9
|
+
$(this.selector, this.context).each(fn);
|
10
|
+
}, this));
|
11
|
+
} else {
|
12
|
+
ready($.proxy(function(){
|
13
|
+
$(this).each(fn);
|
14
|
+
}, this));
|
15
|
+
}
|
16
|
+
}
|
17
|
+
})(jQuery);
|
@@ -0,0 +1,9 @@
|
|
1
|
+
/*!
|
2
|
+
* Masonry PACKAGED v4.1.1
|
3
|
+
* Cascading grid layout library
|
4
|
+
* http://masonry.desandro.com
|
5
|
+
* MIT License
|
6
|
+
* by David DeSandro
|
7
|
+
*/
|
8
|
+
|
9
|
+
!function(t,e){"function"==typeof define&&define.amd?define("jquery-bridget/jquery-bridget",["jquery"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("jquery")):t.jQueryBridget=e(t,t.jQuery)}(window,function(t,e){"use strict";function i(i,r,a){function h(t,e,n){var o,r="$()."+i+'("'+e+'")';return t.each(function(t,h){var u=a.data(h,i);if(!u)return void s(i+" not initialized. Cannot call methods, i.e. "+r);var d=u[e];if(!d||"_"==e.charAt(0))return void s(r+" is not a valid method");var l=d.apply(u,n);o=void 0===o?l:o}),void 0!==o?o:t}function u(t,e){t.each(function(t,n){var o=a.data(n,i);o?(o.option(e),o._init()):(o=new r(n,e),a.data(n,i,o))})}a=a||e||t.jQuery,a&&(r.prototype.option||(r.prototype.option=function(t){a.isPlainObject(t)&&(this.options=a.extend(!0,this.options,t))}),a.fn[i]=function(t){if("string"==typeof t){var e=o.call(arguments,1);return h(this,t,e)}return u(this,t),this},n(a))}function n(t){!t||t&&t.bridget||(t.bridget=i)}var o=Array.prototype.slice,r=t.console,s="undefined"==typeof r?function(){}:function(t){r.error(t)};return n(e||t.jQuery),i}),function(t,e){"function"==typeof define&&define.amd?define("ev-emitter/ev-emitter",e):"object"==typeof module&&module.exports?module.exports=e():t.EvEmitter=e()}("undefined"!=typeof window?window:this,function(){function t(){}var e=t.prototype;return e.on=function(t,e){if(t&&e){var i=this._events=this._events||{},n=i[t]=i[t]||[];return-1==n.indexOf(e)&&n.push(e),this}},e.once=function(t,e){if(t&&e){this.on(t,e);var i=this._onceEvents=this._onceEvents||{},n=i[t]=i[t]||{};return n[e]=!0,this}},e.off=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=i.indexOf(e);return-1!=n&&i.splice(n,1),this}},e.emitEvent=function(t,e){var i=this._events&&this._events[t];if(i&&i.length){var n=0,o=i[n];e=e||[];for(var r=this._onceEvents&&this._onceEvents[t];o;){var s=r&&r[o];s&&(this.off(t,o),delete r[o]),o.apply(this,e),n+=s?0:1,o=i[n]}return this}},t}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("get-size/get-size",[],function(){return e()}):"object"==typeof module&&module.exports?module.exports=e():t.getSize=e()}(window,function(){"use strict";function t(t){var e=parseFloat(t),i=-1==t.indexOf("%")&&!isNaN(e);return i&&e}function e(){}function i(){for(var t={width:0,height:0,innerWidth:0,innerHeight:0,outerWidth:0,outerHeight:0},e=0;u>e;e++){var i=h[e];t[i]=0}return t}function n(t){var e=getComputedStyle(t);return e||a("Style returned "+e+". Are you running this code in a hidden iframe on Firefox? See http://bit.ly/getsizebug1"),e}function o(){if(!d){d=!0;var e=document.createElement("div");e.style.width="200px",e.style.padding="1px 2px 3px 4px",e.style.borderStyle="solid",e.style.borderWidth="1px 2px 3px 4px",e.style.boxSizing="border-box";var i=document.body||document.documentElement;i.appendChild(e);var o=n(e);r.isBoxSizeOuter=s=200==t(o.width),i.removeChild(e)}}function r(e){if(o(),"string"==typeof e&&(e=document.querySelector(e)),e&&"object"==typeof e&&e.nodeType){var r=n(e);if("none"==r.display)return i();var a={};a.width=e.offsetWidth,a.height=e.offsetHeight;for(var d=a.isBorderBox="border-box"==r.boxSizing,l=0;u>l;l++){var c=h[l],f=r[c],m=parseFloat(f);a[c]=isNaN(m)?0:m}var p=a.paddingLeft+a.paddingRight,g=a.paddingTop+a.paddingBottom,y=a.marginLeft+a.marginRight,v=a.marginTop+a.marginBottom,_=a.borderLeftWidth+a.borderRightWidth,E=a.borderTopWidth+a.borderBottomWidth,z=d&&s,b=t(r.width);b!==!1&&(a.width=b+(z?0:p+_));var x=t(r.height);return x!==!1&&(a.height=x+(z?0:g+E)),a.innerWidth=a.width-(p+_),a.innerHeight=a.height-(g+E),a.outerWidth=a.width+y,a.outerHeight=a.height+v,a}}var s,a="undefined"==typeof console?e:function(t){console.error(t)},h=["paddingLeft","paddingRight","paddingTop","paddingBottom","marginLeft","marginRight","marginTop","marginBottom","borderLeftWidth","borderRightWidth","borderTopWidth","borderBottomWidth"],u=h.length,d=!1;return r}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("desandro-matches-selector/matches-selector",e):"object"==typeof module&&module.exports?module.exports=e():t.matchesSelector=e()}(window,function(){"use strict";var t=function(){var t=Element.prototype;if(t.matches)return"matches";if(t.matchesSelector)return"matchesSelector";for(var e=["webkit","moz","ms","o"],i=0;i<e.length;i++){var n=e[i],o=n+"MatchesSelector";if(t[o])return o}}();return function(e,i){return e[t](i)}}),function(t,e){"function"==typeof define&&define.amd?define("fizzy-ui-utils/utils",["desandro-matches-selector/matches-selector"],function(i){return e(t,i)}):"object"==typeof module&&module.exports?module.exports=e(t,require("desandro-matches-selector")):t.fizzyUIUtils=e(t,t.matchesSelector)}(window,function(t,e){var i={};i.extend=function(t,e){for(var i in e)t[i]=e[i];return t},i.modulo=function(t,e){return(t%e+e)%e},i.makeArray=function(t){var e=[];if(Array.isArray(t))e=t;else if(t&&"number"==typeof t.length)for(var i=0;i<t.length;i++)e.push(t[i]);else e.push(t);return e},i.removeFrom=function(t,e){var i=t.indexOf(e);-1!=i&&t.splice(i,1)},i.getParent=function(t,i){for(;t!=document.body;)if(t=t.parentNode,e(t,i))return t},i.getQueryElement=function(t){return"string"==typeof t?document.querySelector(t):t},i.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},i.filterFindElements=function(t,n){t=i.makeArray(t);var o=[];return t.forEach(function(t){if(t instanceof HTMLElement){if(!n)return void o.push(t);e(t,n)&&o.push(t);for(var i=t.querySelectorAll(n),r=0;r<i.length;r++)o.push(i[r])}}),o},i.debounceMethod=function(t,e,i){var n=t.prototype[e],o=e+"Timeout";t.prototype[e]=function(){var t=this[o];t&&clearTimeout(t);var e=arguments,r=this;this[o]=setTimeout(function(){n.apply(r,e),delete r[o]},i||100)}},i.docReady=function(t){var e=document.readyState;"complete"==e||"interactive"==e?t():document.addEventListener("DOMContentLoaded",t)},i.toDashed=function(t){return t.replace(/(.)([A-Z])/g,function(t,e,i){return e+"-"+i}).toLowerCase()};var n=t.console;return i.htmlInit=function(e,o){i.docReady(function(){var r=i.toDashed(o),s="data-"+r,a=document.querySelectorAll("["+s+"]"),h=document.querySelectorAll(".js-"+r),u=i.makeArray(a).concat(i.makeArray(h)),d=s+"-options",l=t.jQuery;u.forEach(function(t){var i,r=t.getAttribute(s)||t.getAttribute(d);try{i=r&&JSON.parse(r)}catch(a){return void(n&&n.error("Error parsing "+s+" on "+t.className+": "+a))}var h=new e(t,i);l&&l.data(t,o,h)})})},i}),function(t,e){"function"==typeof define&&define.amd?define("outlayer/item",["ev-emitter/ev-emitter","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("ev-emitter"),require("get-size")):(t.Outlayer={},t.Outlayer.Item=e(t.EvEmitter,t.getSize))}(window,function(t,e){"use strict";function i(t){for(var e in t)return!1;return e=null,!0}function n(t,e){t&&(this.element=t,this.layout=e,this.position={x:0,y:0},this._create())}function o(t){return t.replace(/([A-Z])/g,function(t){return"-"+t.toLowerCase()})}var r=document.documentElement.style,s="string"==typeof r.transition?"transition":"WebkitTransition",a="string"==typeof r.transform?"transform":"WebkitTransform",h={WebkitTransition:"webkitTransitionEnd",transition:"transitionend"}[s],u={transform:a,transition:s,transitionDuration:s+"Duration",transitionProperty:s+"Property",transitionDelay:s+"Delay"},d=n.prototype=Object.create(t.prototype);d.constructor=n,d._create=function(){this._transn={ingProperties:{},clean:{},onEnd:{}},this.css({position:"absolute"})},d.handleEvent=function(t){var e="on"+t.type;this[e]&&this[e](t)},d.getSize=function(){this.size=e(this.element)},d.css=function(t){var e=this.element.style;for(var i in t){var n=u[i]||i;e[n]=t[i]}},d.getPosition=function(){var t=getComputedStyle(this.element),e=this.layout._getOption("originLeft"),i=this.layout._getOption("originTop"),n=t[e?"left":"right"],o=t[i?"top":"bottom"],r=this.layout.size,s=-1!=n.indexOf("%")?parseFloat(n)/100*r.width:parseInt(n,10),a=-1!=o.indexOf("%")?parseFloat(o)/100*r.height:parseInt(o,10);s=isNaN(s)?0:s,a=isNaN(a)?0:a,s-=e?r.paddingLeft:r.paddingRight,a-=i?r.paddingTop:r.paddingBottom,this.position.x=s,this.position.y=a},d.layoutPosition=function(){var t=this.layout.size,e={},i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop"),o=i?"paddingLeft":"paddingRight",r=i?"left":"right",s=i?"right":"left",a=this.position.x+t[o];e[r]=this.getXValue(a),e[s]="";var h=n?"paddingTop":"paddingBottom",u=n?"top":"bottom",d=n?"bottom":"top",l=this.position.y+t[h];e[u]=this.getYValue(l),e[d]="",this.css(e),this.emitEvent("layout",[this])},d.getXValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&!e?t/this.layout.size.width*100+"%":t+"px"},d.getYValue=function(t){var e=this.layout._getOption("horizontal");return this.layout.options.percentPosition&&e?t/this.layout.size.height*100+"%":t+"px"},d._transitionTo=function(t,e){this.getPosition();var i=this.position.x,n=this.position.y,o=parseInt(t,10),r=parseInt(e,10),s=o===this.position.x&&r===this.position.y;if(this.setPosition(t,e),s&&!this.isTransitioning)return void this.layoutPosition();var a=t-i,h=e-n,u={};u.transform=this.getTranslate(a,h),this.transition({to:u,onTransitionEnd:{transform:this.layoutPosition},isCleaning:!0})},d.getTranslate=function(t,e){var i=this.layout._getOption("originLeft"),n=this.layout._getOption("originTop");return t=i?t:-t,e=n?e:-e,"translate3d("+t+"px, "+e+"px, 0)"},d.goTo=function(t,e){this.setPosition(t,e),this.layoutPosition()},d.moveTo=d._transitionTo,d.setPosition=function(t,e){this.position.x=parseInt(t,10),this.position.y=parseInt(e,10)},d._nonTransition=function(t){this.css(t.to),t.isCleaning&&this._removeStyles(t.to);for(var e in t.onTransitionEnd)t.onTransitionEnd[e].call(this)},d.transition=function(t){if(!parseFloat(this.layout.options.transitionDuration))return void this._nonTransition(t);var e=this._transn;for(var i in t.onTransitionEnd)e.onEnd[i]=t.onTransitionEnd[i];for(i in t.to)e.ingProperties[i]=!0,t.isCleaning&&(e.clean[i]=!0);if(t.from){this.css(t.from);var n=this.element.offsetHeight;n=null}this.enableTransition(t.to),this.css(t.to),this.isTransitioning=!0};var l="opacity,"+o(a);d.enableTransition=function(){if(!this.isTransitioning){var t=this.layout.options.transitionDuration;t="number"==typeof t?t+"ms":t,this.css({transitionProperty:l,transitionDuration:t,transitionDelay:this.staggerDelay||0}),this.element.addEventListener(h,this,!1)}},d.onwebkitTransitionEnd=function(t){this.ontransitionend(t)},d.onotransitionend=function(t){this.ontransitionend(t)};var c={"-webkit-transform":"transform"};d.ontransitionend=function(t){if(t.target===this.element){var e=this._transn,n=c[t.propertyName]||t.propertyName;if(delete e.ingProperties[n],i(e.ingProperties)&&this.disableTransition(),n in e.clean&&(this.element.style[t.propertyName]="",delete e.clean[n]),n in e.onEnd){var o=e.onEnd[n];o.call(this),delete e.onEnd[n]}this.emitEvent("transitionEnd",[this])}},d.disableTransition=function(){this.removeTransitionStyles(),this.element.removeEventListener(h,this,!1),this.isTransitioning=!1},d._removeStyles=function(t){var e={};for(var i in t)e[i]="";this.css(e)};var f={transitionProperty:"",transitionDuration:"",transitionDelay:""};return d.removeTransitionStyles=function(){this.css(f)},d.stagger=function(t){t=isNaN(t)?0:t,this.staggerDelay=t+"ms"},d.removeElem=function(){this.element.parentNode.removeChild(this.element),this.css({display:""}),this.emitEvent("remove",[this])},d.remove=function(){return s&&parseFloat(this.layout.options.transitionDuration)?(this.once("transitionEnd",function(){this.removeElem()}),void this.hide()):void this.removeElem()},d.reveal=function(){delete this.isHidden,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("visibleStyle");e[i]=this.onRevealTransitionEnd,this.transition({from:t.hiddenStyle,to:t.visibleStyle,isCleaning:!0,onTransitionEnd:e})},d.onRevealTransitionEnd=function(){this.isHidden||this.emitEvent("reveal")},d.getHideRevealTransitionEndProperty=function(t){var e=this.layout.options[t];if(e.opacity)return"opacity";for(var i in e)return i},d.hide=function(){this.isHidden=!0,this.css({display:""});var t=this.layout.options,e={},i=this.getHideRevealTransitionEndProperty("hiddenStyle");e[i]=this.onHideTransitionEnd,this.transition({from:t.visibleStyle,to:t.hiddenStyle,isCleaning:!0,onTransitionEnd:e})},d.onHideTransitionEnd=function(){this.isHidden&&(this.css({display:"none"}),this.emitEvent("hide"))},d.destroy=function(){this.css({position:"",left:"",right:"",top:"",bottom:"",transition:"",transform:""})},n}),function(t,e){"use strict";"function"==typeof define&&define.amd?define("outlayer/outlayer",["ev-emitter/ev-emitter","get-size/get-size","fizzy-ui-utils/utils","./item"],function(i,n,o,r){return e(t,i,n,o,r)}):"object"==typeof module&&module.exports?module.exports=e(t,require("ev-emitter"),require("get-size"),require("fizzy-ui-utils"),require("./item")):t.Outlayer=e(t,t.EvEmitter,t.getSize,t.fizzyUIUtils,t.Outlayer.Item)}(window,function(t,e,i,n,o){"use strict";function r(t,e){var i=n.getQueryElement(t);if(!i)return void(h&&h.error("Bad element for "+this.constructor.namespace+": "+(i||t)));this.element=i,u&&(this.$element=u(this.element)),this.options=n.extend({},this.constructor.defaults),this.option(e);var o=++l;this.element.outlayerGUID=o,c[o]=this,this._create();var r=this._getOption("initLayout");r&&this.layout()}function s(t){function e(){t.apply(this,arguments)}return e.prototype=Object.create(t.prototype),e.prototype.constructor=e,e}function a(t){if("number"==typeof t)return t;var e=t.match(/(^\d*\.?\d*)(\w*)/),i=e&&e[1],n=e&&e[2];if(!i.length)return 0;i=parseFloat(i);var o=m[n]||1;return i*o}var h=t.console,u=t.jQuery,d=function(){},l=0,c={};r.namespace="outlayer",r.Item=o,r.defaults={containerStyle:{position:"relative"},initLayout:!0,originLeft:!0,originTop:!0,resize:!0,resizeContainer:!0,transitionDuration:"0.4s",hiddenStyle:{opacity:0,transform:"scale(0.001)"},visibleStyle:{opacity:1,transform:"scale(1)"}};var f=r.prototype;n.extend(f,e.prototype),f.option=function(t){n.extend(this.options,t)},f._getOption=function(t){var e=this.constructor.compatOptions[t];return e&&void 0!==this.options[e]?this.options[e]:this.options[t]},r.compatOptions={initLayout:"isInitLayout",horizontal:"isHorizontal",layoutInstant:"isLayoutInstant",originLeft:"isOriginLeft",originTop:"isOriginTop",resize:"isResizeBound",resizeContainer:"isResizingContainer"},f._create=function(){this.reloadItems(),this.stamps=[],this.stamp(this.options.stamp),n.extend(this.element.style,this.options.containerStyle);var t=this._getOption("resize");t&&this.bindResize()},f.reloadItems=function(){this.items=this._itemize(this.element.children)},f._itemize=function(t){for(var e=this._filterFindItemElements(t),i=this.constructor.Item,n=[],o=0;o<e.length;o++){var r=e[o],s=new i(r,this);n.push(s)}return n},f._filterFindItemElements=function(t){return n.filterFindElements(t,this.options.itemSelector)},f.getItemElements=function(){return this.items.map(function(t){return t.element})},f.layout=function(){this._resetLayout(),this._manageStamps();var t=this._getOption("layoutInstant"),e=void 0!==t?t:!this._isLayoutInited;this.layoutItems(this.items,e),this._isLayoutInited=!0},f._init=f.layout,f._resetLayout=function(){this.getSize()},f.getSize=function(){this.size=i(this.element)},f._getMeasurement=function(t,e){var n,o=this.options[t];o?("string"==typeof o?n=this.element.querySelector(o):o instanceof HTMLElement&&(n=o),this[t]=n?i(n)[e]:o):this[t]=0},f.layoutItems=function(t,e){t=this._getItemsForLayout(t),this._layoutItems(t,e),this._postLayout()},f._getItemsForLayout=function(t){return t.filter(function(t){return!t.isIgnored})},f._layoutItems=function(t,e){if(this._emitCompleteOnItems("layout",t),t&&t.length){var i=[];t.forEach(function(t){var n=this._getItemLayoutPosition(t);n.item=t,n.isInstant=e||t.isLayoutInstant,i.push(n)},this),this._processLayoutQueue(i)}},f._getItemLayoutPosition=function(){return{x:0,y:0}},f._processLayoutQueue=function(t){this.updateStagger(),t.forEach(function(t,e){this._positionItem(t.item,t.x,t.y,t.isInstant,e)},this)},f.updateStagger=function(){var t=this.options.stagger;return null===t||void 0===t?void(this.stagger=0):(this.stagger=a(t),this.stagger)},f._positionItem=function(t,e,i,n,o){n?t.goTo(e,i):(t.stagger(o*this.stagger),t.moveTo(e,i))},f._postLayout=function(){this.resizeContainer()},f.resizeContainer=function(){var t=this._getOption("resizeContainer");if(t){var e=this._getContainerSize();e&&(this._setContainerMeasure(e.width,!0),this._setContainerMeasure(e.height,!1))}},f._getContainerSize=d,f._setContainerMeasure=function(t,e){if(void 0!==t){var i=this.size;i.isBorderBox&&(t+=e?i.paddingLeft+i.paddingRight+i.borderLeftWidth+i.borderRightWidth:i.paddingBottom+i.paddingTop+i.borderTopWidth+i.borderBottomWidth),t=Math.max(t,0),this.element.style[e?"width":"height"]=t+"px"}},f._emitCompleteOnItems=function(t,e){function i(){o.dispatchEvent(t+"Complete",null,[e])}function n(){s++,s==r&&i()}var o=this,r=e.length;if(!e||!r)return void i();var s=0;e.forEach(function(e){e.once(t,n)})},f.dispatchEvent=function(t,e,i){var n=e?[e].concat(i):i;if(this.emitEvent(t,n),u)if(this.$element=this.$element||u(this.element),e){var o=u.Event(e);o.type=t,this.$element.trigger(o,i)}else this.$element.trigger(t,i)},f.ignore=function(t){var e=this.getItem(t);e&&(e.isIgnored=!0)},f.unignore=function(t){var e=this.getItem(t);e&&delete e.isIgnored},f.stamp=function(t){t=this._find(t),t&&(this.stamps=this.stamps.concat(t),t.forEach(this.ignore,this))},f.unstamp=function(t){t=this._find(t),t&&t.forEach(function(t){n.removeFrom(this.stamps,t),this.unignore(t)},this)},f._find=function(t){return t?("string"==typeof t&&(t=this.element.querySelectorAll(t)),t=n.makeArray(t)):void 0},f._manageStamps=function(){this.stamps&&this.stamps.length&&(this._getBoundingRect(),this.stamps.forEach(this._manageStamp,this))},f._getBoundingRect=function(){var t=this.element.getBoundingClientRect(),e=this.size;this._boundingRect={left:t.left+e.paddingLeft+e.borderLeftWidth,top:t.top+e.paddingTop+e.borderTopWidth,right:t.right-(e.paddingRight+e.borderRightWidth),bottom:t.bottom-(e.paddingBottom+e.borderBottomWidth)}},f._manageStamp=d,f._getElementOffset=function(t){var e=t.getBoundingClientRect(),n=this._boundingRect,o=i(t),r={left:e.left-n.left-o.marginLeft,top:e.top-n.top-o.marginTop,right:n.right-e.right-o.marginRight,bottom:n.bottom-e.bottom-o.marginBottom};return r},f.handleEvent=n.handleEvent,f.bindResize=function(){t.addEventListener("resize",this),this.isResizeBound=!0},f.unbindResize=function(){t.removeEventListener("resize",this),this.isResizeBound=!1},f.onresize=function(){this.resize()},n.debounceMethod(r,"onresize",100),f.resize=function(){this.isResizeBound&&this.needsResizeLayout()&&this.layout()},f.needsResizeLayout=function(){var t=i(this.element),e=this.size&&t;return e&&t.innerWidth!==this.size.innerWidth},f.addItems=function(t){var e=this._itemize(t);return e.length&&(this.items=this.items.concat(e)),e},f.appended=function(t){var e=this.addItems(t);e.length&&(this.layoutItems(e,!0),this.reveal(e))},f.prepended=function(t){var e=this._itemize(t);if(e.length){var i=this.items.slice(0);this.items=e.concat(i),this._resetLayout(),this._manageStamps(),this.layoutItems(e,!0),this.reveal(e),this.layoutItems(i)}},f.reveal=function(t){if(this._emitCompleteOnItems("reveal",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.reveal()})}},f.hide=function(t){if(this._emitCompleteOnItems("hide",t),t&&t.length){var e=this.updateStagger();t.forEach(function(t,i){t.stagger(i*e),t.hide()})}},f.revealItemElements=function(t){var e=this.getItems(t);this.reveal(e)},f.hideItemElements=function(t){var e=this.getItems(t);this.hide(e)},f.getItem=function(t){for(var e=0;e<this.items.length;e++){var i=this.items[e];if(i.element==t)return i}},f.getItems=function(t){t=n.makeArray(t);var e=[];return t.forEach(function(t){var i=this.getItem(t);i&&e.push(i)},this),e},f.remove=function(t){var e=this.getItems(t);this._emitCompleteOnItems("remove",e),e&&e.length&&e.forEach(function(t){t.remove(),n.removeFrom(this.items,t)},this)},f.destroy=function(){var t=this.element.style;t.height="",t.position="",t.width="",this.items.forEach(function(t){t.destroy()}),this.unbindResize();var e=this.element.outlayerGUID;delete c[e],delete this.element.outlayerGUID,u&&u.removeData(this.element,this.constructor.namespace)},r.data=function(t){t=n.getQueryElement(t);var e=t&&t.outlayerGUID;return e&&c[e]},r.create=function(t,e){var i=s(r);return i.defaults=n.extend({},r.defaults),n.extend(i.defaults,e),i.compatOptions=n.extend({},r.compatOptions),i.namespace=t,i.data=r.data,i.Item=s(o),n.htmlInit(i,t),u&&u.bridget&&u.bridget(t,i),i};var m={ms:1,s:1e3};return r.Item=o,r}),function(t,e){"function"==typeof define&&define.amd?define(["outlayer/outlayer","get-size/get-size"],e):"object"==typeof module&&module.exports?module.exports=e(require("outlayer"),require("get-size")):t.Masonry=e(t.Outlayer,t.getSize)}(window,function(t,e){var i=t.create("masonry");return i.compatOptions.fitWidth="isFitWidth",i.prototype._resetLayout=function(){this.getSize(),this._getMeasurement("columnWidth","outerWidth"),this._getMeasurement("gutter","outerWidth"),this.measureColumns(),this.colYs=[];for(var t=0;t<this.cols;t++)this.colYs.push(0);this.maxY=0},i.prototype.measureColumns=function(){if(this.getContainerWidth(),!this.columnWidth){var t=this.items[0],i=t&&t.element;this.columnWidth=i&&e(i).outerWidth||this.containerWidth}var n=this.columnWidth+=this.gutter,o=this.containerWidth+this.gutter,r=o/n,s=n-o%n,a=s&&1>s?"round":"floor";r=Math[a](r),this.cols=Math.max(r,1)},i.prototype.getContainerWidth=function(){var t=this._getOption("fitWidth"),i=t?this.element.parentNode:this.element,n=e(i);this.containerWidth=n&&n.innerWidth},i.prototype._getItemLayoutPosition=function(t){t.getSize();var e=t.size.outerWidth%this.columnWidth,i=e&&1>e?"round":"ceil",n=Math[i](t.size.outerWidth/this.columnWidth);n=Math.min(n,this.cols);for(var o=this._getColGroup(n),r=Math.min.apply(Math,o),s=o.indexOf(r),a={x:this.columnWidth*s,y:r},h=r+t.size.outerHeight,u=this.cols+1-o.length,d=0;u>d;d++)this.colYs[s+d]=h;return a},i.prototype._getColGroup=function(t){if(2>t)return this.colYs;for(var e=[],i=this.cols+1-t,n=0;i>n;n++){var o=this.colYs.slice(n,n+t);e[n]=Math.max.apply(Math,o)}return e},i.prototype._manageStamp=function(t){var i=e(t),n=this._getElementOffset(t),o=this._getOption("originLeft"),r=o?n.left:n.right,s=r+i.outerWidth,a=Math.floor(r/this.columnWidth);a=Math.max(0,a);var h=Math.floor(s/this.columnWidth);h-=s%this.columnWidth?0:1,h=Math.min(this.cols-1,h);for(var u=this._getOption("originTop"),d=(u?n.top:n.bottom)+i.outerHeight,l=a;h>=l;l++)this.colYs[l]=Math.max(d,this.colYs[l])},i.prototype._getContainerSize=function(){this.maxY=Math.max.apply(Math,this.colYs);var t={height:this.maxY};return this._getOption("fitWidth")&&(t.width=this._getContainerFitWidth()),t},i.prototype._getContainerFitWidth=function(){for(var t=0,e=this.cols;--e&&0===this.colYs[e];)t++;return(this.cols-t)*this.columnWidth-this.gutter},i.prototype.needsResizeLayout=function(){var t=this.containerWidth;return this.getContainerWidth(),t!=this.containerWidth},i});
|
@@ -0,0 +1,3 @@
|
|
1
|
+
/*! modernizr 3.5.0 (Custom Build) | MIT *
|
2
|
+
* https://modernizr.com/download/?-setclasses !*/
|
3
|
+
!function(n,e,s){function o(n,e){return typeof n===e}function a(){var n,e,s,a,i,l,r;for(var c in f)if(f.hasOwnProperty(c)){if(n=[],e=f[c],e.name&&(n.push(e.name.toLowerCase()),e.options&&e.options.aliases&&e.options.aliases.length))for(s=0;s<e.options.aliases.length;s++)n.push(e.options.aliases[s].toLowerCase());for(a=o(e.fn,"function")?e.fn():e.fn,i=0;i<n.length;i++)l=n[i],r=l.split("."),1===r.length?Modernizr[r[0]]=a:(!Modernizr[r[0]]||Modernizr[r[0]]instanceof Boolean||(Modernizr[r[0]]=new Boolean(Modernizr[r[0]])),Modernizr[r[0]][r[1]]=a),t.push((a?"":"no-")+r.join("-"))}}function i(n){var e=r.className,s=Modernizr._config.classPrefix||"";if(c&&(e=e.baseVal),Modernizr._config.enableJSClass){var o=new RegExp("(^|\\s)"+s+"no-js(\\s|$)");e=e.replace(o,"$1"+s+"js$2")}Modernizr._config.enableClasses&&(e+=" "+s+n.join(" "+s),c?r.className.baseVal=e:r.className=e)}var t=[],f=[],l={_version:"3.5.0",_config:{classPrefix:"",enableClasses:!0,enableJSClass:!0,usePrefixes:!0},_q:[],on:function(n,e){var s=this;setTimeout(function(){e(s[n])},0)},addTest:function(n,e,s){f.push({name:n,fn:e,options:s})},addAsyncTest:function(n){f.push({name:null,fn:n})}},Modernizr=function(){};Modernizr.prototype=l,Modernizr=new Modernizr;var r=e.documentElement,c="svg"===r.nodeName.toLowerCase();a(),i(t),delete l.addTest,delete l.addAsyncTest;for(var u=0;u<Modernizr._q.length;u++)Modernizr._q[u]();n.Modernizr=Modernizr}(window,document);
|
@@ -0,0 +1,1044 @@
|
|
1
|
+
/*global define:false */
|
2
|
+
/**
|
3
|
+
* Copyright 2016 Craig Campbell
|
4
|
+
*
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
6
|
+
* you may not use this file except in compliance with the License.
|
7
|
+
* You may obtain a copy of the License at
|
8
|
+
*
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
10
|
+
*
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
14
|
+
* See the License for the specific language governing permissions and
|
15
|
+
* limitations under the License.
|
16
|
+
*
|
17
|
+
* Mousetrap is a simple keyboard shortcut library for Javascript with
|
18
|
+
* no external dependencies
|
19
|
+
*
|
20
|
+
* @version 1.6.0
|
21
|
+
* @url craig.is/killing/mice
|
22
|
+
*/
|
23
|
+
(function(window, document, undefined) {
|
24
|
+
|
25
|
+
// Check if mousetrap is used inside browser, if not, return
|
26
|
+
if (!window) {
|
27
|
+
return;
|
28
|
+
}
|
29
|
+
|
30
|
+
/**
|
31
|
+
* mapping of special keycodes to their corresponding keys
|
32
|
+
*
|
33
|
+
* everything in this dictionary cannot use keypress events
|
34
|
+
* so it has to be here to map to the correct keycodes for
|
35
|
+
* keyup/keydown events
|
36
|
+
*
|
37
|
+
* @type {Object}
|
38
|
+
*/
|
39
|
+
var _MAP = {
|
40
|
+
8: 'backspace',
|
41
|
+
9: 'tab',
|
42
|
+
13: 'enter',
|
43
|
+
16: 'shift',
|
44
|
+
17: 'ctrl',
|
45
|
+
18: 'alt',
|
46
|
+
20: 'capslock',
|
47
|
+
27: 'esc',
|
48
|
+
32: 'space',
|
49
|
+
33: 'pageup',
|
50
|
+
34: 'pagedown',
|
51
|
+
35: 'end',
|
52
|
+
36: 'home',
|
53
|
+
37: 'left',
|
54
|
+
38: 'up',
|
55
|
+
39: 'right',
|
56
|
+
40: 'down',
|
57
|
+
45: 'ins',
|
58
|
+
46: 'del',
|
59
|
+
91: 'meta',
|
60
|
+
93: 'meta',
|
61
|
+
224: 'meta'
|
62
|
+
};
|
63
|
+
|
64
|
+
/**
|
65
|
+
* mapping for special characters so they can support
|
66
|
+
*
|
67
|
+
* this dictionary is only used incase you want to bind a
|
68
|
+
* keyup or keydown event to one of these keys
|
69
|
+
*
|
70
|
+
* @type {Object}
|
71
|
+
*/
|
72
|
+
var _KEYCODE_MAP = {
|
73
|
+
106: '*',
|
74
|
+
107: '+',
|
75
|
+
109: '-',
|
76
|
+
110: '.',
|
77
|
+
111 : '/',
|
78
|
+
186: ';',
|
79
|
+
187: '=',
|
80
|
+
188: ',',
|
81
|
+
189: '-',
|
82
|
+
190: '.',
|
83
|
+
191: '/',
|
84
|
+
192: '`',
|
85
|
+
219: '[',
|
86
|
+
220: '\\',
|
87
|
+
221: ']',
|
88
|
+
222: '\''
|
89
|
+
};
|
90
|
+
|
91
|
+
/**
|
92
|
+
* this is a mapping of keys that require shift on a US keypad
|
93
|
+
* back to the non shift equivelents
|
94
|
+
*
|
95
|
+
* this is so you can use keyup events with these keys
|
96
|
+
*
|
97
|
+
* note that this will only work reliably on US keyboards
|
98
|
+
*
|
99
|
+
* @type {Object}
|
100
|
+
*/
|
101
|
+
var _SHIFT_MAP = {
|
102
|
+
'~': '`',
|
103
|
+
'!': '1',
|
104
|
+
'@': '2',
|
105
|
+
'#': '3',
|
106
|
+
'$': '4',
|
107
|
+
'%': '5',
|
108
|
+
'^': '6',
|
109
|
+
'&': '7',
|
110
|
+
'*': '8',
|
111
|
+
'(': '9',
|
112
|
+
')': '0',
|
113
|
+
'_': '-',
|
114
|
+
'+': '=',
|
115
|
+
':': ';',
|
116
|
+
'\"': '\'',
|
117
|
+
'<': ',',
|
118
|
+
'>': '.',
|
119
|
+
'?': '/',
|
120
|
+
'|': '\\'
|
121
|
+
};
|
122
|
+
|
123
|
+
/**
|
124
|
+
* this is a list of special strings you can use to map
|
125
|
+
* to modifier keys when you specify your keyboard shortcuts
|
126
|
+
*
|
127
|
+
* @type {Object}
|
128
|
+
*/
|
129
|
+
var _SPECIAL_ALIASES = {
|
130
|
+
'option': 'alt',
|
131
|
+
'command': 'meta',
|
132
|
+
'return': 'enter',
|
133
|
+
'escape': 'esc',
|
134
|
+
'plus': '+',
|
135
|
+
'mod': /Mac|iPod|iPhone|iPad/.test(navigator.platform) ? 'meta' : 'ctrl'
|
136
|
+
};
|
137
|
+
|
138
|
+
/**
|
139
|
+
* variable to store the flipped version of _MAP from above
|
140
|
+
* needed to check if we should use keypress or not when no action
|
141
|
+
* is specified
|
142
|
+
*
|
143
|
+
* @type {Object|undefined}
|
144
|
+
*/
|
145
|
+
var _REVERSE_MAP;
|
146
|
+
|
147
|
+
/**
|
148
|
+
* loop through the f keys, f1 to f19 and add them to the map
|
149
|
+
* programatically
|
150
|
+
*/
|
151
|
+
for (var i = 1; i < 20; ++i) {
|
152
|
+
_MAP[111 + i] = 'f' + i;
|
153
|
+
}
|
154
|
+
|
155
|
+
/**
|
156
|
+
* loop through to map numbers on the numeric keypad
|
157
|
+
*/
|
158
|
+
for (i = 0; i <= 9; ++i) {
|
159
|
+
|
160
|
+
// This needs to use a string cause otherwise since 0 is falsey
|
161
|
+
// mousetrap will never fire for numpad 0 pressed as part of a keydown
|
162
|
+
// event.
|
163
|
+
//
|
164
|
+
// @see https://github.com/ccampbell/mousetrap/pull/258
|
165
|
+
_MAP[i + 96] = i.toString();
|
166
|
+
}
|
167
|
+
|
168
|
+
/**
|
169
|
+
* cross browser add event method
|
170
|
+
*
|
171
|
+
* @param {Element|HTMLDocument} object
|
172
|
+
* @param {string} type
|
173
|
+
* @param {Function} callback
|
174
|
+
* @returns void
|
175
|
+
*/
|
176
|
+
function _addEvent(object, type, callback) {
|
177
|
+
if (object.addEventListener) {
|
178
|
+
object.addEventListener(type, callback, false);
|
179
|
+
return;
|
180
|
+
}
|
181
|
+
|
182
|
+
object.attachEvent('on' + type, callback);
|
183
|
+
}
|
184
|
+
|
185
|
+
/**
|
186
|
+
* takes the event and returns the key character
|
187
|
+
*
|
188
|
+
* @param {Event} e
|
189
|
+
* @return {string}
|
190
|
+
*/
|
191
|
+
function _characterFromEvent(e) {
|
192
|
+
|
193
|
+
// for keypress events we should return the character as is
|
194
|
+
if (e.type == 'keypress') {
|
195
|
+
var character = String.fromCharCode(e.which);
|
196
|
+
|
197
|
+
// if the shift key is not pressed then it is safe to assume
|
198
|
+
// that we want the character to be lowercase. this means if
|
199
|
+
// you accidentally have caps lock on then your key bindings
|
200
|
+
// will continue to work
|
201
|
+
//
|
202
|
+
// the only side effect that might not be desired is if you
|
203
|
+
// bind something like 'A' cause you want to trigger an
|
204
|
+
// event when capital A is pressed caps lock will no longer
|
205
|
+
// trigger the event. shift+a will though.
|
206
|
+
if (!e.shiftKey) {
|
207
|
+
character = character.toLowerCase();
|
208
|
+
}
|
209
|
+
|
210
|
+
return character;
|
211
|
+
}
|
212
|
+
|
213
|
+
// for non keypress events the special maps are needed
|
214
|
+
if (_MAP[e.which]) {
|
215
|
+
return _MAP[e.which];
|
216
|
+
}
|
217
|
+
|
218
|
+
if (_KEYCODE_MAP[e.which]) {
|
219
|
+
return _KEYCODE_MAP[e.which];
|
220
|
+
}
|
221
|
+
|
222
|
+
// if it is not in the special map
|
223
|
+
|
224
|
+
// with keydown and keyup events the character seems to always
|
225
|
+
// come in as an uppercase character whether you are pressing shift
|
226
|
+
// or not. we should make sure it is always lowercase for comparisons
|
227
|
+
return String.fromCharCode(e.which).toLowerCase();
|
228
|
+
}
|
229
|
+
|
230
|
+
/**
|
231
|
+
* checks if two arrays are equal
|
232
|
+
*
|
233
|
+
* @param {Array} modifiers1
|
234
|
+
* @param {Array} modifiers2
|
235
|
+
* @returns {boolean}
|
236
|
+
*/
|
237
|
+
function _modifiersMatch(modifiers1, modifiers2) {
|
238
|
+
return modifiers1.sort().join(',') === modifiers2.sort().join(',');
|
239
|
+
}
|
240
|
+
|
241
|
+
/**
|
242
|
+
* takes a key event and figures out what the modifiers are
|
243
|
+
*
|
244
|
+
* @param {Event} e
|
245
|
+
* @returns {Array}
|
246
|
+
*/
|
247
|
+
function _eventModifiers(e) {
|
248
|
+
var modifiers = [];
|
249
|
+
|
250
|
+
if (e.shiftKey) {
|
251
|
+
modifiers.push('shift');
|
252
|
+
}
|
253
|
+
|
254
|
+
if (e.altKey) {
|
255
|
+
modifiers.push('alt');
|
256
|
+
}
|
257
|
+
|
258
|
+
if (e.ctrlKey) {
|
259
|
+
modifiers.push('ctrl');
|
260
|
+
}
|
261
|
+
|
262
|
+
if (e.metaKey) {
|
263
|
+
modifiers.push('meta');
|
264
|
+
}
|
265
|
+
|
266
|
+
return modifiers;
|
267
|
+
}
|
268
|
+
|
269
|
+
/**
|
270
|
+
* prevents default for this event
|
271
|
+
*
|
272
|
+
* @param {Event} e
|
273
|
+
* @returns void
|
274
|
+
*/
|
275
|
+
function _preventDefault(e) {
|
276
|
+
if (e.preventDefault) {
|
277
|
+
e.preventDefault();
|
278
|
+
return;
|
279
|
+
}
|
280
|
+
|
281
|
+
e.returnValue = false;
|
282
|
+
}
|
283
|
+
|
284
|
+
/**
|
285
|
+
* stops propogation for this event
|
286
|
+
*
|
287
|
+
* @param {Event} e
|
288
|
+
* @returns void
|
289
|
+
*/
|
290
|
+
function _stopPropagation(e) {
|
291
|
+
if (e.stopPropagation) {
|
292
|
+
e.stopPropagation();
|
293
|
+
return;
|
294
|
+
}
|
295
|
+
|
296
|
+
e.cancelBubble = true;
|
297
|
+
}
|
298
|
+
|
299
|
+
/**
|
300
|
+
* determines if the keycode specified is a modifier key or not
|
301
|
+
*
|
302
|
+
* @param {string} key
|
303
|
+
* @returns {boolean}
|
304
|
+
*/
|
305
|
+
function _isModifier(key) {
|
306
|
+
return key == 'shift' || key == 'ctrl' || key == 'alt' || key == 'meta';
|
307
|
+
}
|
308
|
+
|
309
|
+
/**
|
310
|
+
* reverses the map lookup so that we can look for specific keys
|
311
|
+
* to see what can and can't use keypress
|
312
|
+
*
|
313
|
+
* @return {Object}
|
314
|
+
*/
|
315
|
+
function _getReverseMap() {
|
316
|
+
if (!_REVERSE_MAP) {
|
317
|
+
_REVERSE_MAP = {};
|
318
|
+
for (var key in _MAP) {
|
319
|
+
|
320
|
+
// pull out the numeric keypad from here cause keypress should
|
321
|
+
// be able to detect the keys from the character
|
322
|
+
if (key > 95 && key < 112) {
|
323
|
+
continue;
|
324
|
+
}
|
325
|
+
|
326
|
+
if (_MAP.hasOwnProperty(key)) {
|
327
|
+
_REVERSE_MAP[_MAP[key]] = key;
|
328
|
+
}
|
329
|
+
}
|
330
|
+
}
|
331
|
+
return _REVERSE_MAP;
|
332
|
+
}
|
333
|
+
|
334
|
+
/**
|
335
|
+
* picks the best action based on the key combination
|
336
|
+
*
|
337
|
+
* @param {string} key - character for key
|
338
|
+
* @param {Array} modifiers
|
339
|
+
* @param {string=} action passed in
|
340
|
+
*/
|
341
|
+
function _pickBestAction(key, modifiers, action) {
|
342
|
+
|
343
|
+
// if no action was picked in we should try to pick the one
|
344
|
+
// that we think would work best for this key
|
345
|
+
if (!action) {
|
346
|
+
action = _getReverseMap()[key] ? 'keydown' : 'keypress';
|
347
|
+
}
|
348
|
+
|
349
|
+
// modifier keys don't work as expected with keypress,
|
350
|
+
// switch to keydown
|
351
|
+
if (action == 'keypress' && modifiers.length) {
|
352
|
+
action = 'keydown';
|
353
|
+
}
|
354
|
+
|
355
|
+
return action;
|
356
|
+
}
|
357
|
+
|
358
|
+
/**
|
359
|
+
* Converts from a string key combination to an array
|
360
|
+
*
|
361
|
+
* @param {string} combination like "command+shift+l"
|
362
|
+
* @return {Array}
|
363
|
+
*/
|
364
|
+
function _keysFromString(combination) {
|
365
|
+
if (combination === '+') {
|
366
|
+
return ['+'];
|
367
|
+
}
|
368
|
+
|
369
|
+
combination = combination.replace(/\+{2}/g, '+plus');
|
370
|
+
return combination.split('+');
|
371
|
+
}
|
372
|
+
|
373
|
+
/**
|
374
|
+
* Gets info for a specific key combination
|
375
|
+
*
|
376
|
+
* @param {string} combination key combination ("command+s" or "a" or "*")
|
377
|
+
* @param {string=} action
|
378
|
+
* @returns {Object}
|
379
|
+
*/
|
380
|
+
function _getKeyInfo(combination, action) {
|
381
|
+
var keys;
|
382
|
+
var key;
|
383
|
+
var i;
|
384
|
+
var modifiers = [];
|
385
|
+
|
386
|
+
// take the keys from this pattern and figure out what the actual
|
387
|
+
// pattern is all about
|
388
|
+
keys = _keysFromString(combination);
|
389
|
+
|
390
|
+
for (i = 0; i < keys.length; ++i) {
|
391
|
+
key = keys[i];
|
392
|
+
|
393
|
+
// normalize key names
|
394
|
+
if (_SPECIAL_ALIASES[key]) {
|
395
|
+
key = _SPECIAL_ALIASES[key];
|
396
|
+
}
|
397
|
+
|
398
|
+
// if this is not a keypress event then we should
|
399
|
+
// be smart about using shift keys
|
400
|
+
// this will only work for US keyboards however
|
401
|
+
if (action && action != 'keypress' && _SHIFT_MAP[key]) {
|
402
|
+
key = _SHIFT_MAP[key];
|
403
|
+
modifiers.push('shift');
|
404
|
+
}
|
405
|
+
|
406
|
+
// if this key is a modifier then add it to the list of modifiers
|
407
|
+
if (_isModifier(key)) {
|
408
|
+
modifiers.push(key);
|
409
|
+
}
|
410
|
+
}
|
411
|
+
|
412
|
+
// depending on what the key combination is
|
413
|
+
// we will try to pick the best event for it
|
414
|
+
action = _pickBestAction(key, modifiers, action);
|
415
|
+
|
416
|
+
return {
|
417
|
+
key: key,
|
418
|
+
modifiers: modifiers,
|
419
|
+
action: action
|
420
|
+
};
|
421
|
+
}
|
422
|
+
|
423
|
+
function _belongsTo(element, ancestor) {
|
424
|
+
if (element === null || element === document) {
|
425
|
+
return false;
|
426
|
+
}
|
427
|
+
|
428
|
+
if (element === ancestor) {
|
429
|
+
return true;
|
430
|
+
}
|
431
|
+
|
432
|
+
return _belongsTo(element.parentNode, ancestor);
|
433
|
+
}
|
434
|
+
|
435
|
+
function Mousetrap(targetElement) {
|
436
|
+
var self = this;
|
437
|
+
|
438
|
+
targetElement = targetElement || document;
|
439
|
+
|
440
|
+
if (!(self instanceof Mousetrap)) {
|
441
|
+
return new Mousetrap(targetElement);
|
442
|
+
}
|
443
|
+
|
444
|
+
/**
|
445
|
+
* element to attach key events to
|
446
|
+
*
|
447
|
+
* @type {Element}
|
448
|
+
*/
|
449
|
+
self.target = targetElement;
|
450
|
+
|
451
|
+
/**
|
452
|
+
* a list of all the callbacks setup via Mousetrap.bind()
|
453
|
+
*
|
454
|
+
* @type {Object}
|
455
|
+
*/
|
456
|
+
self._callbacks = {};
|
457
|
+
|
458
|
+
/**
|
459
|
+
* direct map of string combinations to callbacks used for trigger()
|
460
|
+
*
|
461
|
+
* @type {Object}
|
462
|
+
*/
|
463
|
+
self._directMap = {};
|
464
|
+
|
465
|
+
/**
|
466
|
+
* keeps track of what level each sequence is at since multiple
|
467
|
+
* sequences can start out with the same sequence
|
468
|
+
*
|
469
|
+
* @type {Object}
|
470
|
+
*/
|
471
|
+
var _sequenceLevels = {};
|
472
|
+
|
473
|
+
/**
|
474
|
+
* variable to store the setTimeout call
|
475
|
+
*
|
476
|
+
* @type {null|number}
|
477
|
+
*/
|
478
|
+
var _resetTimer;
|
479
|
+
|
480
|
+
/**
|
481
|
+
* temporary state where we will ignore the next keyup
|
482
|
+
*
|
483
|
+
* @type {boolean|string}
|
484
|
+
*/
|
485
|
+
var _ignoreNextKeyup = false;
|
486
|
+
|
487
|
+
/**
|
488
|
+
* temporary state where we will ignore the next keypress
|
489
|
+
*
|
490
|
+
* @type {boolean}
|
491
|
+
*/
|
492
|
+
var _ignoreNextKeypress = false;
|
493
|
+
|
494
|
+
/**
|
495
|
+
* are we currently inside of a sequence?
|
496
|
+
* type of action ("keyup" or "keydown" or "keypress") or false
|
497
|
+
*
|
498
|
+
* @type {boolean|string}
|
499
|
+
*/
|
500
|
+
var _nextExpectedAction = false;
|
501
|
+
|
502
|
+
/**
|
503
|
+
* resets all sequence counters except for the ones passed in
|
504
|
+
*
|
505
|
+
* @param {Object} doNotReset
|
506
|
+
* @returns void
|
507
|
+
*/
|
508
|
+
function _resetSequences(doNotReset) {
|
509
|
+
doNotReset = doNotReset || {};
|
510
|
+
|
511
|
+
var activeSequences = false,
|
512
|
+
key;
|
513
|
+
|
514
|
+
for (key in _sequenceLevels) {
|
515
|
+
if (doNotReset[key]) {
|
516
|
+
activeSequences = true;
|
517
|
+
continue;
|
518
|
+
}
|
519
|
+
_sequenceLevels[key] = 0;
|
520
|
+
}
|
521
|
+
|
522
|
+
if (!activeSequences) {
|
523
|
+
_nextExpectedAction = false;
|
524
|
+
}
|
525
|
+
}
|
526
|
+
|
527
|
+
/**
|
528
|
+
* finds all callbacks that match based on the keycode, modifiers,
|
529
|
+
* and action
|
530
|
+
*
|
531
|
+
* @param {string} character
|
532
|
+
* @param {Array} modifiers
|
533
|
+
* @param {Event|Object} e
|
534
|
+
* @param {string=} sequenceName - name of the sequence we are looking for
|
535
|
+
* @param {string=} combination
|
536
|
+
* @param {number=} level
|
537
|
+
* @returns {Array}
|
538
|
+
*/
|
539
|
+
function _getMatches(character, modifiers, e, sequenceName, combination, level) {
|
540
|
+
var i;
|
541
|
+
var callback;
|
542
|
+
var matches = [];
|
543
|
+
var action = e.type;
|
544
|
+
|
545
|
+
// if there are no events related to this keycode
|
546
|
+
if (!self._callbacks[character]) {
|
547
|
+
return [];
|
548
|
+
}
|
549
|
+
|
550
|
+
// if a modifier key is coming up on its own we should allow it
|
551
|
+
if (action == 'keyup' && _isModifier(character)) {
|
552
|
+
modifiers = [character];
|
553
|
+
}
|
554
|
+
|
555
|
+
// loop through all callbacks for the key that was pressed
|
556
|
+
// and see if any of them match
|
557
|
+
for (i = 0; i < self._callbacks[character].length; ++i) {
|
558
|
+
callback = self._callbacks[character][i];
|
559
|
+
|
560
|
+
// if a sequence name is not specified, but this is a sequence at
|
561
|
+
// the wrong level then move onto the next match
|
562
|
+
if (!sequenceName && callback.seq && _sequenceLevels[callback.seq] != callback.level) {
|
563
|
+
continue;
|
564
|
+
}
|
565
|
+
|
566
|
+
// if the action we are looking for doesn't match the action we got
|
567
|
+
// then we should keep going
|
568
|
+
if (action != callback.action) {
|
569
|
+
continue;
|
570
|
+
}
|
571
|
+
|
572
|
+
// if this is a keypress event and the meta key and control key
|
573
|
+
// are not pressed that means that we need to only look at the
|
574
|
+
// character, otherwise check the modifiers as well
|
575
|
+
//
|
576
|
+
// chrome will not fire a keypress if meta or control is down
|
577
|
+
// safari will fire a keypress if meta or meta+shift is down
|
578
|
+
// firefox will fire a keypress if meta or control is down
|
579
|
+
if ((action == 'keypress' && !e.metaKey && !e.ctrlKey) || _modifiersMatch(modifiers, callback.modifiers)) {
|
580
|
+
|
581
|
+
// when you bind a combination or sequence a second time it
|
582
|
+
// should overwrite the first one. if a sequenceName or
|
583
|
+
// combination is specified in this call it does just that
|
584
|
+
//
|
585
|
+
// @todo make deleting its own method?
|
586
|
+
var deleteCombo = !sequenceName && callback.combo == combination;
|
587
|
+
var deleteSequence = sequenceName && callback.seq == sequenceName && callback.level == level;
|
588
|
+
if (deleteCombo || deleteSequence) {
|
589
|
+
self._callbacks[character].splice(i, 1);
|
590
|
+
}
|
591
|
+
|
592
|
+
matches.push(callback);
|
593
|
+
}
|
594
|
+
}
|
595
|
+
|
596
|
+
return matches;
|
597
|
+
}
|
598
|
+
|
599
|
+
/**
|
600
|
+
* actually calls the callback function
|
601
|
+
*
|
602
|
+
* if your callback function returns false this will use the jquery
|
603
|
+
* convention - prevent default and stop propogation on the event
|
604
|
+
*
|
605
|
+
* @param {Function} callback
|
606
|
+
* @param {Event} e
|
607
|
+
* @returns void
|
608
|
+
*/
|
609
|
+
function _fireCallback(callback, e, combo, sequence) {
|
610
|
+
|
611
|
+
// if this event should not happen stop here
|
612
|
+
if (self.stopCallback(e, e.target || e.srcElement, combo, sequence)) {
|
613
|
+
return;
|
614
|
+
}
|
615
|
+
|
616
|
+
if (callback(e, combo) === false) {
|
617
|
+
_preventDefault(e);
|
618
|
+
_stopPropagation(e);
|
619
|
+
}
|
620
|
+
}
|
621
|
+
|
622
|
+
/**
|
623
|
+
* handles a character key event
|
624
|
+
*
|
625
|
+
* @param {string} character
|
626
|
+
* @param {Array} modifiers
|
627
|
+
* @param {Event} e
|
628
|
+
* @returns void
|
629
|
+
*/
|
630
|
+
self._handleKey = function(character, modifiers, e) {
|
631
|
+
var callbacks = _getMatches(character, modifiers, e);
|
632
|
+
var i;
|
633
|
+
var doNotReset = {};
|
634
|
+
var maxLevel = 0;
|
635
|
+
var processedSequenceCallback = false;
|
636
|
+
|
637
|
+
// Calculate the maxLevel for sequences so we can only execute the longest callback sequence
|
638
|
+
for (i = 0; i < callbacks.length; ++i) {
|
639
|
+
if (callbacks[i].seq) {
|
640
|
+
maxLevel = Math.max(maxLevel, callbacks[i].level);
|
641
|
+
}
|
642
|
+
}
|
643
|
+
|
644
|
+
// loop through matching callbacks for this key event
|
645
|
+
for (i = 0; i < callbacks.length; ++i) {
|
646
|
+
|
647
|
+
// fire for all sequence callbacks
|
648
|
+
// this is because if for example you have multiple sequences
|
649
|
+
// bound such as "g i" and "g t" they both need to fire the
|
650
|
+
// callback for matching g cause otherwise you can only ever
|
651
|
+
// match the first one
|
652
|
+
if (callbacks[i].seq) {
|
653
|
+
|
654
|
+
// only fire callbacks for the maxLevel to prevent
|
655
|
+
// subsequences from also firing
|
656
|
+
//
|
657
|
+
// for example 'a option b' should not cause 'option b' to fire
|
658
|
+
// even though 'option b' is part of the other sequence
|
659
|
+
//
|
660
|
+
// any sequences that do not match here will be discarded
|
661
|
+
// below by the _resetSequences call
|
662
|
+
if (callbacks[i].level != maxLevel) {
|
663
|
+
continue;
|
664
|
+
}
|
665
|
+
|
666
|
+
processedSequenceCallback = true;
|
667
|
+
|
668
|
+
// keep a list of which sequences were matches for later
|
669
|
+
doNotReset[callbacks[i].seq] = 1;
|
670
|
+
_fireCallback(callbacks[i].callback, e, callbacks[i].combo, callbacks[i].seq);
|
671
|
+
continue;
|
672
|
+
}
|
673
|
+
|
674
|
+
// if there were no sequence matches but we are still here
|
675
|
+
// that means this is a regular match so we should fire that
|
676
|
+
if (!processedSequenceCallback) {
|
677
|
+
_fireCallback(callbacks[i].callback, e, callbacks[i].combo);
|
678
|
+
}
|
679
|
+
}
|
680
|
+
|
681
|
+
// if the key you pressed matches the type of sequence without
|
682
|
+
// being a modifier (ie "keyup" or "keypress") then we should
|
683
|
+
// reset all sequences that were not matched by this event
|
684
|
+
//
|
685
|
+
// this is so, for example, if you have the sequence "h a t" and you
|
686
|
+
// type "h e a r t" it does not match. in this case the "e" will
|
687
|
+
// cause the sequence to reset
|
688
|
+
//
|
689
|
+
// modifier keys are ignored because you can have a sequence
|
690
|
+
// that contains modifiers such as "enter ctrl+space" and in most
|
691
|
+
// cases the modifier key will be pressed before the next key
|
692
|
+
//
|
693
|
+
// also if you have a sequence such as "ctrl+b a" then pressing the
|
694
|
+
// "b" key will trigger a "keypress" and a "keydown"
|
695
|
+
//
|
696
|
+
// the "keydown" is expected when there is a modifier, but the
|
697
|
+
// "keypress" ends up matching the _nextExpectedAction since it occurs
|
698
|
+
// after and that causes the sequence to reset
|
699
|
+
//
|
700
|
+
// we ignore keypresses in a sequence that directly follow a keydown
|
701
|
+
// for the same character
|
702
|
+
var ignoreThisKeypress = e.type == 'keypress' && _ignoreNextKeypress;
|
703
|
+
if (e.type == _nextExpectedAction && !_isModifier(character) && !ignoreThisKeypress) {
|
704
|
+
_resetSequences(doNotReset);
|
705
|
+
}
|
706
|
+
|
707
|
+
_ignoreNextKeypress = processedSequenceCallback && e.type == 'keydown';
|
708
|
+
};
|
709
|
+
|
710
|
+
/**
|
711
|
+
* handles a keydown event
|
712
|
+
*
|
713
|
+
* @param {Event} e
|
714
|
+
* @returns void
|
715
|
+
*/
|
716
|
+
function _handleKeyEvent(e) {
|
717
|
+
|
718
|
+
// normalize e.which for key events
|
719
|
+
// @see http://stackoverflow.com/questions/4285627/javascript-keycode-vs-charcode-utter-confusion
|
720
|
+
if (typeof e.which !== 'number') {
|
721
|
+
e.which = e.keyCode;
|
722
|
+
}
|
723
|
+
|
724
|
+
var character = _characterFromEvent(e);
|
725
|
+
|
726
|
+
// no character found then stop
|
727
|
+
if (!character) {
|
728
|
+
return;
|
729
|
+
}
|
730
|
+
|
731
|
+
// need to use === for the character check because the character can be 0
|
732
|
+
if (e.type == 'keyup' && _ignoreNextKeyup === character) {
|
733
|
+
_ignoreNextKeyup = false;
|
734
|
+
return;
|
735
|
+
}
|
736
|
+
|
737
|
+
self.handleKey(character, _eventModifiers(e), e);
|
738
|
+
}
|
739
|
+
|
740
|
+
/**
|
741
|
+
* called to set a 1 second timeout on the specified sequence
|
742
|
+
*
|
743
|
+
* this is so after each key press in the sequence you have 1 second
|
744
|
+
* to press the next key before you have to start over
|
745
|
+
*
|
746
|
+
* @returns void
|
747
|
+
*/
|
748
|
+
function _resetSequenceTimer() {
|
749
|
+
clearTimeout(_resetTimer);
|
750
|
+
_resetTimer = setTimeout(_resetSequences, 1000);
|
751
|
+
}
|
752
|
+
|
753
|
+
/**
|
754
|
+
* binds a key sequence to an event
|
755
|
+
*
|
756
|
+
* @param {string} combo - combo specified in bind call
|
757
|
+
* @param {Array} keys
|
758
|
+
* @param {Function} callback
|
759
|
+
* @param {string=} action
|
760
|
+
* @returns void
|
761
|
+
*/
|
762
|
+
function _bindSequence(combo, keys, callback, action) {
|
763
|
+
|
764
|
+
// start off by adding a sequence level record for this combination
|
765
|
+
// and setting the level to 0
|
766
|
+
_sequenceLevels[combo] = 0;
|
767
|
+
|
768
|
+
/**
|
769
|
+
* callback to increase the sequence level for this sequence and reset
|
770
|
+
* all other sequences that were active
|
771
|
+
*
|
772
|
+
* @param {string} nextAction
|
773
|
+
* @returns {Function}
|
774
|
+
*/
|
775
|
+
function _increaseSequence(nextAction) {
|
776
|
+
return function() {
|
777
|
+
_nextExpectedAction = nextAction;
|
778
|
+
++_sequenceLevels[combo];
|
779
|
+
_resetSequenceTimer();
|
780
|
+
};
|
781
|
+
}
|
782
|
+
|
783
|
+
/**
|
784
|
+
* wraps the specified callback inside of another function in order
|
785
|
+
* to reset all sequence counters as soon as this sequence is done
|
786
|
+
*
|
787
|
+
* @param {Event} e
|
788
|
+
* @returns void
|
789
|
+
*/
|
790
|
+
function _callbackAndReset(e) {
|
791
|
+
_fireCallback(callback, e, combo);
|
792
|
+
|
793
|
+
// we should ignore the next key up if the action is key down
|
794
|
+
// or keypress. this is so if you finish a sequence and
|
795
|
+
// release the key the final key will not trigger a keyup
|
796
|
+
if (action !== 'keyup') {
|
797
|
+
_ignoreNextKeyup = _characterFromEvent(e);
|
798
|
+
}
|
799
|
+
|
800
|
+
// weird race condition if a sequence ends with the key
|
801
|
+
// another sequence begins with
|
802
|
+
setTimeout(_resetSequences, 10);
|
803
|
+
}
|
804
|
+
|
805
|
+
// loop through keys one at a time and bind the appropriate callback
|
806
|
+
// function. for any key leading up to the final one it should
|
807
|
+
// increase the sequence. after the final, it should reset all sequences
|
808
|
+
//
|
809
|
+
// if an action is specified in the original bind call then that will
|
810
|
+
// be used throughout. otherwise we will pass the action that the
|
811
|
+
// next key in the sequence should match. this allows a sequence
|
812
|
+
// to mix and match keypress and keydown events depending on which
|
813
|
+
// ones are better suited to the key provided
|
814
|
+
for (var i = 0; i < keys.length; ++i) {
|
815
|
+
var isFinal = i + 1 === keys.length;
|
816
|
+
var wrappedCallback = isFinal ? _callbackAndReset : _increaseSequence(action || _getKeyInfo(keys[i + 1]).action);
|
817
|
+
_bindSingle(keys[i], wrappedCallback, action, combo, i);
|
818
|
+
}
|
819
|
+
}
|
820
|
+
|
821
|
+
/**
|
822
|
+
* binds a single keyboard combination
|
823
|
+
*
|
824
|
+
* @param {string} combination
|
825
|
+
* @param {Function} callback
|
826
|
+
* @param {string=} action
|
827
|
+
* @param {string=} sequenceName - name of sequence if part of sequence
|
828
|
+
* @param {number=} level - what part of the sequence the command is
|
829
|
+
* @returns void
|
830
|
+
*/
|
831
|
+
function _bindSingle(combination, callback, action, sequenceName, level) {
|
832
|
+
|
833
|
+
// store a direct mapped reference for use with Mousetrap.trigger
|
834
|
+
self._directMap[combination + ':' + action] = callback;
|
835
|
+
|
836
|
+
// make sure multiple spaces in a row become a single space
|
837
|
+
combination = combination.replace(/\s+/g, ' ');
|
838
|
+
|
839
|
+
var sequence = combination.split(' ');
|
840
|
+
var info;
|
841
|
+
|
842
|
+
// if this pattern is a sequence of keys then run through this method
|
843
|
+
// to reprocess each pattern one key at a time
|
844
|
+
if (sequence.length > 1) {
|
845
|
+
_bindSequence(combination, sequence, callback, action);
|
846
|
+
return;
|
847
|
+
}
|
848
|
+
|
849
|
+
info = _getKeyInfo(combination, action);
|
850
|
+
|
851
|
+
// make sure to initialize array if this is the first time
|
852
|
+
// a callback is added for this key
|
853
|
+
self._callbacks[info.key] = self._callbacks[info.key] || [];
|
854
|
+
|
855
|
+
// remove an existing match if there is one
|
856
|
+
_getMatches(info.key, info.modifiers, {type: info.action}, sequenceName, combination, level);
|
857
|
+
|
858
|
+
// add this call back to the array
|
859
|
+
// if it is a sequence put it at the beginning
|
860
|
+
// if not put it at the end
|
861
|
+
//
|
862
|
+
// this is important because the way these are processed expects
|
863
|
+
// the sequence ones to come first
|
864
|
+
self._callbacks[info.key][sequenceName ? 'unshift' : 'push']({
|
865
|
+
callback: callback,
|
866
|
+
modifiers: info.modifiers,
|
867
|
+
action: info.action,
|
868
|
+
seq: sequenceName,
|
869
|
+
level: level,
|
870
|
+
combo: combination
|
871
|
+
});
|
872
|
+
}
|
873
|
+
|
874
|
+
/**
|
875
|
+
* binds multiple combinations to the same callback
|
876
|
+
*
|
877
|
+
* @param {Array} combinations
|
878
|
+
* @param {Function} callback
|
879
|
+
* @param {string|undefined} action
|
880
|
+
* @returns void
|
881
|
+
*/
|
882
|
+
self._bindMultiple = function(combinations, callback, action) {
|
883
|
+
for (var i = 0; i < combinations.length; ++i) {
|
884
|
+
_bindSingle(combinations[i], callback, action);
|
885
|
+
}
|
886
|
+
};
|
887
|
+
|
888
|
+
// start!
|
889
|
+
_addEvent(targetElement, 'keypress', _handleKeyEvent);
|
890
|
+
_addEvent(targetElement, 'keydown', _handleKeyEvent);
|
891
|
+
_addEvent(targetElement, 'keyup', _handleKeyEvent);
|
892
|
+
}
|
893
|
+
|
894
|
+
/**
|
895
|
+
* binds an event to mousetrap
|
896
|
+
*
|
897
|
+
* can be a single key, a combination of keys separated with +,
|
898
|
+
* an array of keys, or a sequence of keys separated by spaces
|
899
|
+
*
|
900
|
+
* be sure to list the modifier keys first to make sure that the
|
901
|
+
* correct key ends up getting bound (the last key in the pattern)
|
902
|
+
*
|
903
|
+
* @param {string|Array} keys
|
904
|
+
* @param {Function} callback
|
905
|
+
* @param {string=} action - 'keypress', 'keydown', or 'keyup'
|
906
|
+
* @returns void
|
907
|
+
*/
|
908
|
+
Mousetrap.prototype.bind = function(keys, callback, action) {
|
909
|
+
var self = this;
|
910
|
+
keys = keys instanceof Array ? keys : [keys];
|
911
|
+
self._bindMultiple.call(self, keys, callback, action);
|
912
|
+
return self;
|
913
|
+
};
|
914
|
+
|
915
|
+
/**
|
916
|
+
* unbinds an event to mousetrap
|
917
|
+
*
|
918
|
+
* the unbinding sets the callback function of the specified key combo
|
919
|
+
* to an empty function and deletes the corresponding key in the
|
920
|
+
* _directMap dict.
|
921
|
+
*
|
922
|
+
* TODO: actually remove this from the _callbacks dictionary instead
|
923
|
+
* of binding an empty function
|
924
|
+
*
|
925
|
+
* the keycombo+action has to be exactly the same as
|
926
|
+
* it was defined in the bind method
|
927
|
+
*
|
928
|
+
* @param {string|Array} keys
|
929
|
+
* @param {string} action
|
930
|
+
* @returns void
|
931
|
+
*/
|
932
|
+
Mousetrap.prototype.unbind = function(keys, action) {
|
933
|
+
var self = this;
|
934
|
+
return self.bind.call(self, keys, function() {}, action);
|
935
|
+
};
|
936
|
+
|
937
|
+
/**
|
938
|
+
* triggers an event that has already been bound
|
939
|
+
*
|
940
|
+
* @param {string} keys
|
941
|
+
* @param {string=} action
|
942
|
+
* @returns void
|
943
|
+
*/
|
944
|
+
Mousetrap.prototype.trigger = function(keys, action) {
|
945
|
+
var self = this;
|
946
|
+
if (self._directMap[keys + ':' + action]) {
|
947
|
+
self._directMap[keys + ':' + action]({}, keys);
|
948
|
+
}
|
949
|
+
return self;
|
950
|
+
};
|
951
|
+
|
952
|
+
/**
|
953
|
+
* resets the library back to its initial state. this is useful
|
954
|
+
* if you want to clear out the current keyboard shortcuts and bind
|
955
|
+
* new ones - for example if you switch to another page
|
956
|
+
*
|
957
|
+
* @returns void
|
958
|
+
*/
|
959
|
+
Mousetrap.prototype.reset = function() {
|
960
|
+
var self = this;
|
961
|
+
self._callbacks = {};
|
962
|
+
self._directMap = {};
|
963
|
+
return self;
|
964
|
+
};
|
965
|
+
|
966
|
+
/**
|
967
|
+
* should we stop this event before firing off callbacks
|
968
|
+
*
|
969
|
+
* @param {Event} e
|
970
|
+
* @param {Element} element
|
971
|
+
* @return {boolean}
|
972
|
+
*/
|
973
|
+
Mousetrap.prototype.stopCallback = function(e, element) {
|
974
|
+
var self = this;
|
975
|
+
|
976
|
+
// if the element has the class "mousetrap" then no need to stop
|
977
|
+
if ((' ' + element.className + ' ').indexOf(' mousetrap ') > -1) {
|
978
|
+
return false;
|
979
|
+
}
|
980
|
+
|
981
|
+
if (_belongsTo(element, self.target)) {
|
982
|
+
return false;
|
983
|
+
}
|
984
|
+
|
985
|
+
// stop for input, select, and textarea
|
986
|
+
return element.tagName == 'INPUT' || element.tagName == 'SELECT' || element.tagName == 'TEXTAREA' || element.isContentEditable;
|
987
|
+
};
|
988
|
+
|
989
|
+
/**
|
990
|
+
* exposes _handleKey publicly so it can be overwritten by extensions
|
991
|
+
*/
|
992
|
+
Mousetrap.prototype.handleKey = function() {
|
993
|
+
var self = this;
|
994
|
+
return self._handleKey.apply(self, arguments);
|
995
|
+
};
|
996
|
+
|
997
|
+
/**
|
998
|
+
* allow custom key mappings
|
999
|
+
*/
|
1000
|
+
Mousetrap.addKeycodes = function(object) {
|
1001
|
+
for (var key in object) {
|
1002
|
+
if (object.hasOwnProperty(key)) {
|
1003
|
+
_MAP[key] = object[key];
|
1004
|
+
}
|
1005
|
+
}
|
1006
|
+
_REVERSE_MAP = null;
|
1007
|
+
};
|
1008
|
+
|
1009
|
+
/**
|
1010
|
+
* Init the global mousetrap functions
|
1011
|
+
*
|
1012
|
+
* This method is needed to allow the global mousetrap functions to work
|
1013
|
+
* now that mousetrap is a constructor function.
|
1014
|
+
*/
|
1015
|
+
Mousetrap.init = function() {
|
1016
|
+
var documentMousetrap = Mousetrap(document);
|
1017
|
+
for (var method in documentMousetrap) {
|
1018
|
+
if (method.charAt(0) !== '_') {
|
1019
|
+
Mousetrap[method] = (function(method) {
|
1020
|
+
return function() {
|
1021
|
+
return documentMousetrap[method].apply(documentMousetrap, arguments);
|
1022
|
+
};
|
1023
|
+
} (method));
|
1024
|
+
}
|
1025
|
+
}
|
1026
|
+
};
|
1027
|
+
|
1028
|
+
Mousetrap.init();
|
1029
|
+
|
1030
|
+
// expose mousetrap to the global object
|
1031
|
+
window.Mousetrap = Mousetrap;
|
1032
|
+
|
1033
|
+
// expose as a common js module
|
1034
|
+
if (typeof module !== 'undefined' && module.exports) {
|
1035
|
+
module.exports = Mousetrap;
|
1036
|
+
}
|
1037
|
+
|
1038
|
+
// expose mousetrap as an AMD module
|
1039
|
+
if (typeof define === 'function' && define.amd) {
|
1040
|
+
define(function() {
|
1041
|
+
return Mousetrap;
|
1042
|
+
});
|
1043
|
+
}
|
1044
|
+
}) (typeof window !== 'undefined' ? window : null, typeof window !== 'undefined' ? document : null);
|