diff --git a/dist/components/api.js b/dist/components/api.js index f19c41794..ee0f6a6be 100644 --- a/dist/components/api.js +++ b/dist/components/api.js @@ -293,7 +293,7 @@ $.api = $.fn.api = function(parameters) { } }, validResponse: function(response) { - if( settings.dataType !== 'json' || !$.isFunction(settings.successTest) ) { + if( (settings.dataType !== 'json' && settings.dataType !== 'jsonp') || !$.isFunction(settings.successTest) ) { module.verbose('Response is not JSON, skipping validation', settings.successTest, response); return true; } @@ -451,13 +451,13 @@ $.api = $.fn.api = function(parameters) { }, xhr: { always: function() { - // calculate if loading time was below minimum threshold + // nothing special }, done: function(response, textStatus, xhr) { var - context = this, - elapsedTime = (new Date().getTime() - requestStartTime), - timeLeft = (settings.loadingDuration - elapsedTime), + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime), translatedResponse = ( $.isFunction(settings.onResponse) ) ? settings.onResponse.call(context, $.extend(true, {}, response)) : false @@ -475,7 +475,7 @@ $.api = $.fn.api = function(parameters) { } setTimeout(function() { if( module.is.validResponse(response) ) { - module.request.resolveWith(context, [response]); + module.request.resolveWith(context, [response, xhr]); } else { module.request.rejectWith(context, [xhr, 'invalid']); @@ -506,10 +506,6 @@ $.api = $.fn.api = function(parameters) { } }, request: { - complete: function(response) { - module.remove.loading(); - settings.onComplete.call(context, response, $module); - }, done: function(response) { module.debug('Successful API Response', response); if(settings.cache === 'local' && url) { @@ -518,17 +514,18 @@ $.api = $.fn.api = function(parameters) { } settings.onSuccess.call(context, response, $module); }, + complete: function(xhr) { + var + response = module.get.responseFromXHR(xhr) + ; + module.remove.loading(); + settings.onComplete.call(context, response, $module, xhr); + }, fail: function(xhr, status, httpMessage) { var // pull response from xhr if available - response = $.isPlainObject(xhr) - ? module.decode.json(xhr.responseText) - : false, - errorMessage = ($.isPlainObject(response) && response.error !== undefined) - ? response.error // use json error message - : (settings.error[status] !== undefined) // use server error message - ? settings.error[status] - : httpMessage + response = module.get.responseFromXHR(xhr), + errorMessage = module.get.errorFromRequest(response, status, httpMessage) ; if(status == 'aborted') { module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); @@ -538,7 +535,6 @@ $.api = $.fn.api = function(parameters) { module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); } else if(status == 'error') { - if(xhr !== undefined) { module.debug('XHR produced a server error', status, httpMessage); // make sure we have an error to display to console @@ -656,6 +652,22 @@ $.api = $.fn.api = function(parameters) { }, get: { + responseFromXHR: function(xhr) { + return $.isPlainObject(xhr) + ? (settings.dataType == 'json' || settings.dataType == 'jsonp') + ? module.decode.json(xhr.responseText) + : xhr.responseText + : false + ; + }, + errorFromRequest: function(response, status, httpMessage) { + return ($.isPlainObject(response) && response.error !== undefined) + ? response.error // use json error message + : (settings.error[status] !== undefined) // use server error message + ? settings.error[status] + : httpMessage + ; + }, request: function() { return module.request || false; }, diff --git a/dist/components/api.min.js b/dist/components/api.min.js index 5a85e780f..051935a74 100644 --- a/dist/components/api.min.js +++ b/dist/components/api.min.js @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(e,t,r,n){"use strict";e.api=e.fn.api=function(r){var o,s=e(e.isFunction(this)?t:this),a=s.selector||"",i=(new Date).getTime(),u=[],c=arguments[0],d="string"==typeof c,l=[].slice.call(arguments,1);return s.each(function(){var s,g,f,m,p,b,v=e.isPlainObject(r)?e.extend(!0,{},e.fn.api.settings,r):e.extend({},e.fn.api.settings),h=v.namespace,y=v.metadata,R=v.selector,q=v.error,x=v.className,k="."+h,A="module-"+h,S=e(this),T=S.closest(R.form),P=v.stateContext?e(v.stateContext):S,j=this,w=P[0],D=S.data(A);b={initialize:function(){d||b.bind.events(),b.instantiate()},instantiate:function(){b.verbose("Storing instance of module",b),D=b,S.data(A,D)},destroy:function(){b.verbose("Destroying previous module for",j),S.removeData(A).off(k)},bind:{events:function(){var e=b.get.event();e?(b.verbose("Attaching API events to element",e),S.on(e+k,b.event.trigger)):"now"==v.on&&(b.debug("Querying API now",e),b.query())}},decode:{json:function(e){if(e!==n&&"string"==typeof e)try{e=JSON.parse(e)}catch(t){}return e}},read:{cachedResponse:function(e){var r;return t.Storage===n?void b.error(q.noStorage):(r=sessionStorage.getItem(e),b.debug("Using cached response",e,r),r=b.decode.json(r),!1)}},write:{cachedResponse:function(r,o){return o&&""===o?void b.debug("Response empty, not caching",o):t.Storage===n?void b.error(q.noStorage):(e.isPlainObject(o)&&(o=JSON.stringify(o)),sessionStorage.setItem(r,o),void b.verbose("Storing cached response for url",r,o))}},query:function(){if(b.is.disabled())return void b.debug("Element is disabled API request aborted");if(b.is.loading()){if(!v.interruptRequests)return void b.debug("Cancelling request, previous request is still pending");b.debug("Interrupting previous request"),b.abort()}return v.defaultData&&e.extend(!0,v.urlData,b.get.defaultData()),v.serializeForm&&(v.data=b.add.formData(v.data)),g=b.get.settings(),g===!1?(b.cancelled=!0,void b.error(q.beforeSend)):(b.cancelled=!1,f=b.get.templatedURL(),f||b.is.mocked()?(f=b.add.urlData(f),f||b.is.mocked()?(s=e.extend(!0,{},v,{type:v.method||v.type,data:m,url:v.base+f,beforeSend:v.beforeXHR,success:function(){},failure:function(){},complete:function(){}}),b.debug("Querying URL",s.url),b.verbose("Using AJAX settings",s),"local"===v.cache&&b.read.cachedResponse(f)?(b.debug("Response returned from local cache"),b.request=b.create.request(),void b.request.resolveWith(w,[b.read.cachedResponse(f)])):void(v.throttle?v.throttleFirstRequest||b.timer?(b.debug("Throttling request",v.throttle),clearTimeout(b.timer),b.timer=setTimeout(function(){b.timer&&delete b.timer,b.debug("Sending throttled request",m,s.method),b.send.request()},v.throttle)):(b.debug("Sending request",m,s.method),b.send.request(),b.timer=setTimeout(function(){},v.throttle)):(b.debug("Sending request",m,s.method),b.send.request()))):void 0):void b.error(q.missingURL))},is:{disabled:function(){return S.filter(R.disabled).length>0},form:function(){return S.is("form")},mocked:function(){return v.mockResponse||v.mockResponseAsync},input:function(){return S.is("input")},loading:function(){return b.request&&"pending"==b.request.state()},abortedRequest:function(e){return e&&e.readyState!==n&&0===e.readyState?(b.verbose("XHR request determined to be aborted"),!0):(b.verbose("XHR request was not aborted"),!1)},validResponse:function(t){return"json"===v.dataType&&e.isFunction(v.successTest)?(b.debug("Checking JSON returned success",v.successTest,t),v.successTest(t)?(b.debug("Response passed success test",t),!0):(b.debug("Response failed success test",t),!1)):(b.verbose("Response is not JSON, skipping validation",v.successTest,t),!0)}},was:{cancelled:function(){return b.cancelled||!1},succesful:function(){return b.request&&"resolved"==b.request.state()},failure:function(){return b.request&&"rejected"==b.request.state()},complete:function(){return b.request&&("resolved"==b.request.state()||"rejected"==b.request.state())}},add:{urlData:function(t,r){var o,s;return t&&(o=t.match(v.regExp.required),s=t.match(v.regExp.optional),r=r||v.urlData,o&&(b.debug("Looking for required URL variables",o),e.each(o,function(o,s){var a=-1!==s.indexOf("$")?s.substr(2,s.length-3):s.substr(1,s.length-2),i=e.isPlainObject(r)&&r[a]!==n?r[a]:S.data(a)!==n?S.data(a):P.data(a)!==n?P.data(a):r[a];return i===n?(b.error(q.requiredParameter,a,t),t=!1,!1):(b.verbose("Found required variable",a,i),void(t=t.replace(s,b.get.urlEncodedValue(i))))})),s&&(b.debug("Looking for optional URL variables",o),e.each(s,function(o,s){var a=-1!==s.indexOf("$")?s.substr(3,s.length-4):s.substr(2,s.length-3),i=e.isPlainObject(r)&&r[a]!==n?r[a]:S.data(a)!==n?S.data(a):P.data(a)!==n?P.data(a):r[a];i!==n?(b.verbose("Optional variable Found",a,i),t=t.replace(s,i)):(b.verbose("Optional variable not found",a),t=-1!==t.indexOf("/"+s)?t.replace("/"+s,""):t.replace(s,""))}))),t},formData:function(t){var r,o=e.fn.serializeObject!==n,s=o?T.serializeObject():T.serialize();return t=t||v.data,r=e.isPlainObject(t),r?o?(b.debug("Extending existing data with form data",t,s),t=e.extend(!0,{},t,s)):(b.error(q.missingSerialize),b.debug("Cant extend data. Replacing data with form data",t,s),t=s):(b.debug("Adding form data",s),t=s),t}},send:{request:function(){b.set.loading(),b.request=b.create.request(),b.is.mocked()?b.mockedXHR=b.create.mockedXHR():b.xhr=b.create.xhr(),v.onRequest.call(w,b.request,b.xhr)}},event:{trigger:function(e){b.query(),("submit"==e.type||"click"==e.type)&&e.preventDefault()},xhr:{always:function(){},done:function(t,r,n){var o=this,s=(new Date).getTime()-p,a=v.loadingDuration-s,i=e.isFunction(v.onResponse)?v.onResponse.call(o,e.extend(!0,{},t)):!1;a=a>0?a:0,i&&(b.debug("Modified API response in onResponse callback",v.onResponse,i,t),t=i),a>0&&b.debug("Response completed early delaying state change by",a),setTimeout(function(){b.is.validResponse(t)?b.request.resolveWith(o,[t]):b.request.rejectWith(o,[n,"invalid"])},a)},fail:function(e,t,r){var n=this,o=(new Date).getTime()-p,s=v.loadingDuration-o;s=s>0?s:0,s>0&&b.debug("Response completed early delaying state change by",s),setTimeout(function(){b.is.abortedRequest(e)?b.request.rejectWith(n,[e,"aborted",r]):b.request.rejectWith(n,[e,"error",t,r])},s)}},request:{complete:function(e){b.remove.loading(),v.onComplete.call(w,e,S)},done:function(e){b.debug("Successful API Response",e),"local"===v.cache&&f&&(b.write.cachedResponse(f,e),b.debug("Saving server response locally",b.cache)),v.onSuccess.call(w,e,S)},fail:function(t,r,o){var a=e.isPlainObject(t)?b.decode.json(t.responseText):!1,i=e.isPlainObject(a)&&a.error!==n?a.error:v.error[r]!==n?v.error[r]:o;"aborted"==r?(b.debug("XHR Aborted (Most likely caused by page navigation or CORS Policy)",r,o),v.onAbort.call(w,r,S)):"invalid"==r?b.debug("JSON did not pass success test. A server-side error has most likely occurred",a):"error"==r&&t!==n&&(b.debug("XHR produced a server error",r,o),200!=t.status&&o!==n&&""!==o&&b.error(q.statusMessage+o,s.url),v.onError.call(w,i,S)),v.errorDuration&&"aborted"!==r&&(b.debug("Adding error state"),b.set.error(),setTimeout(b.remove.error,v.errorDuration)),b.debug("API Request failed",i,t),v.onFailure.call(w,a,S)}}},create:{request:function(){return e.Deferred().always(b.event.request.complete).done(b.event.request.done).fail(b.event.request.fail)},mockedXHR:function(){var t,r,n,o=!1,s=!1,a=!1;return n=e.Deferred().always(b.event.xhr.complete).done(b.event.xhr.done).fail(b.event.xhr.fail),v.mockResponse?(e.isFunction(v.mockResponse)?(b.debug("Using mocked callback returning response",v.mockResponse),r=v.mockResponse.call(w,v)):(b.debug("Using specified response",v.mockResponse),r=v.mockResponse),n.resolveWith(w,[r,o,{responseText:r}])):e.isFunction(v.mockResponseAsync)&&(t=function(e){b.debug("Async callback returned response",e),e?n.resolveWith(w,[e,o,{responseText:e}]):n.rejectWith(w,[{responseText:e},s,a])},b.debug("Using async mocked response",v.mockResponseAsync),v.mockResponseAsync.call(w,v,t)),n},xhr:function(){var t;return t=e.ajax(s).always(b.event.xhr.always).done(b.event.xhr.done).fail(b.event.xhr.fail),b.verbose("Created server request",t),t}},set:{error:function(){b.verbose("Adding error state to element",P),P.addClass(x.error)},loading:function(){b.verbose("Adding loading state to element",P),P.addClass(x.loading),p=(new Date).getTime()}},remove:{error:function(){b.verbose("Removing error state from element",P),P.removeClass(x.error)},loading:function(){b.verbose("Removing loading state from element",P),P.removeClass(x.loading)}},get:{request:function(){return b.request||!1},xhr:function(){return b.xhr||!1},settings:function(){var e;return e=v.beforeSend.call(w,v),e&&(e.success!==n&&(b.debug("Legacy success callback detected",e),b.error(q.legacyParameters,e.success),e.onSuccess=e.success),e.failure!==n&&(b.debug("Legacy failure callback detected",e),b.error(q.legacyParameters,e.failure),e.onFailure=e.failure),e.complete!==n&&(b.debug("Legacy complete callback detected",e),b.error(q.legacyParameters,e.complete),e.onComplete=e.complete)),e===n&&b.error(q.noReturnedValue),e!==n?e:v},urlEncodedValue:function(e){var r=t.decodeURIComponent(e),n=t.encodeURIComponent(e),o=r!==e;return o?(b.debug("URL value is already encoded, avoiding double encoding",e),e):(b.verbose("Encoding value for url",e,n),n)},defaultData:function(){var t={};return e.isWindow(j)||(b.is.input()?t.value=S.val():b.is.form()&&(t.text=S.text())),t},event:function(){return e.isWindow(j)||"now"==v.on?(b.debug("API called without element, no events attached"),!1):"auto"==v.on?S.is("input")?j.oninput!==n?"input":j.onpropertychange!==n?"propertychange":"keyup":S.is("form")?"submit":"click":v.on},templatedURL:function(e){if(e=e||S.data(y.action)||v.action||!1,f=S.data(y.url)||v.url||!1)return b.debug("Using specified url",f),f;if(e){if(b.debug("Looking up url for action",e,v.api),v.api[e]===n&&!b.is.mocked())return void b.error(q.missingAction,v.action,v.api);f=v.api[e]}else b.is.form()&&(f=S.attr("action")||!1,b.debug("No url or action specified, defaulting to form action",f));return f}},abort:function(){var e=b.get.xhr();e&&"resolved"!==e.state()&&(b.debug("Cancelling API request"),e.abort())},reset:function(){b.remove.error(),b.remove.loading()},setting:function(t,r){if(b.debug("Changing setting",t,r),e.isPlainObject(t))e.extend(!0,v,t);else{if(r===n)return v[t];v[t]=r}},internal:function(t,r){if(e.isPlainObject(t))e.extend(!0,b,t);else{if(r===n)return b[t];b[t]=r}},debug:function(){v.debug&&(v.performance?b.performance.log(arguments):(b.debug=Function.prototype.bind.call(console.info,console,v.name+":"),b.debug.apply(console,arguments)))},verbose:function(){v.verbose&&v.debug&&(v.performance?b.performance.log(arguments):(b.verbose=Function.prototype.bind.call(console.info,console,v.name+":"),b.verbose.apply(console,arguments)))},error:function(){b.error=Function.prototype.bind.call(console.error,console,v.name+":"),b.error.apply(console,arguments)},performance:{log:function(e){var t,r,n;v.performance&&(t=(new Date).getTime(),n=i||t,r=t-n,i=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"","Execution Time":r})),clearTimeout(b.performance.timer),b.performance.timer=setTimeout(b.performance.display,500)},display:function(){var t=v.name+":",r=0;i=!1,clearTimeout(b.performance.timer),e.each(u,function(e,t){r+=t["Execution Time"]}),t+=" "+r+"ms",a&&(t+=" '"+a+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,r,s){var a,i,u,c=D;return r=r||l,s=j||s,"string"==typeof t&&c!==n&&(t=t.split(/[\. ]/),a=t.length-1,e.each(t,function(r,o){var s=r!=a?o+t[r+1].charAt(0).toUpperCase()+t[r+1].slice(1):t;if(e.isPlainObject(c[s])&&r!=a)c=c[s];else{if(c[s]!==n)return i=c[s],!1;if(!e.isPlainObject(c[o])||r==a)return c[o]!==n?(i=c[o],!1):(b.error(q.method,t),!1);c=c[o]}})),e.isFunction(i)?u=i.apply(s,r):i!==n&&(u=i),e.isArray(o)?o.push(u):o!==n?o=[o,u]:u!==n&&(o=u),i}},d?(D===n&&b.initialize(),b.invoke(c)):(D!==n&&D.invoke("destroy"),b.initialize())}),o!==n?o:this},e.api.settings={name:"API",namespace:"api",debug:!0,verbose:!1,performance:!0,api:{},cache:!0,interruptRequests:!0,on:"auto",stateContext:!1,loadingDuration:0,errorDuration:2e3,action:!1,url:!1,base:"",urlData:{},defaultData:!0,serializeForm:!1,throttle:0,throttleFirstRequest:!0,method:"get",data:{},dataType:"json",mockResponse:!1,mockResponseAsync:!1,beforeSend:function(e){return e},beforeXHR:function(e){},onRequest:function(e,t){},onResponse:!1,onSuccess:function(e,t){},onComplete:function(e,t){},onFailure:function(e,t){},onError:function(e,t){},onAbort:function(e,t){},successTest:!1,error:{beforeSend:"The before send function has aborted the request",error:"There was an error with your request",exitConditions:"API Request Aborted. Exit conditions met",JSONParse:"JSON could not be parsed during error handling",legacyParameters:"You are using legacy API success callback names",method:"The method you called is not defined",missingAction:"API action used but no url was defined",missingSerialize:"jquery-serialize-object is required to add form data to an existing data object",missingURL:"No URL specified for api event",noReturnedValue:"The beforeSend callback must return a settings object, beforeSend ignored.",noStorage:"Caching respopnses locally requires session storage",parseError:"There was an error parsing your request",requiredParameter:"Missing a required URL parameter: ",statusMessage:"Server gave an error: ",timeout:"Your request timed out"},regExp:{required:/\{\$*[A-z0-9]+\}/g,optional:/\{\/\$*[A-z0-9]+\}/g},className:{loading:"loading",error:"error"},selector:{disabled:".disabled",form:"form"},metadata:{action:"action",url:"url"}}}(jQuery,window,document); \ No newline at end of file +!function(e,t,r,n){"use strict";e.api=e.fn.api=function(r){var o,s=e(e.isFunction(this)?t:this),a=s.selector||"",i=(new Date).getTime(),u=[],c=arguments[0],d="string"==typeof c,l=[].slice.call(arguments,1);return s.each(function(){var s,g,f,p,m,b,v=e.isPlainObject(r)?e.extend(!0,{},e.fn.api.settings,r):e.extend({},e.fn.api.settings),h=v.namespace,y=v.metadata,R=v.selector,q=v.error,x=v.className,k="."+h,T="module-"+h,A=e(this),S=A.closest(R.form),j=v.stateContext?e(v.stateContext):A,P=this,w=j[0],D=A.data(T);b={initialize:function(){d||b.bind.events(),b.instantiate()},instantiate:function(){b.verbose("Storing instance of module",b),D=b,A.data(T,D)},destroy:function(){b.verbose("Destroying previous module for",P),A.removeData(T).off(k)},bind:{events:function(){var e=b.get.event();e?(b.verbose("Attaching API events to element",e),A.on(e+k,b.event.trigger)):"now"==v.on&&(b.debug("Querying API now",e),b.query())}},decode:{json:function(e){if(e!==n&&"string"==typeof e)try{e=JSON.parse(e)}catch(t){}return e}},read:{cachedResponse:function(e){var r;return t.Storage===n?void b.error(q.noStorage):(r=sessionStorage.getItem(e),b.debug("Using cached response",e,r),r=b.decode.json(r),!1)}},write:{cachedResponse:function(r,o){return o&&""===o?void b.debug("Response empty, not caching",o):t.Storage===n?void b.error(q.noStorage):(e.isPlainObject(o)&&(o=JSON.stringify(o)),sessionStorage.setItem(r,o),void b.verbose("Storing cached response for url",r,o))}},query:function(){if(b.is.disabled())return void b.debug("Element is disabled API request aborted");if(b.is.loading()){if(!v.interruptRequests)return void b.debug("Cancelling request, previous request is still pending");b.debug("Interrupting previous request"),b.abort()}return v.defaultData&&e.extend(!0,v.urlData,b.get.defaultData()),v.serializeForm&&(v.data=b.add.formData(v.data)),g=b.get.settings(),g===!1?(b.cancelled=!0,void b.error(q.beforeSend)):(b.cancelled=!1,f=b.get.templatedURL(),f||b.is.mocked()?(f=b.add.urlData(f),f||b.is.mocked()?(s=e.extend(!0,{},v,{type:v.method||v.type,data:p,url:v.base+f,beforeSend:v.beforeXHR,success:function(){},failure:function(){},complete:function(){}}),b.debug("Querying URL",s.url),b.verbose("Using AJAX settings",s),"local"===v.cache&&b.read.cachedResponse(f)?(b.debug("Response returned from local cache"),b.request=b.create.request(),void b.request.resolveWith(w,[b.read.cachedResponse(f)])):void(v.throttle?v.throttleFirstRequest||b.timer?(b.debug("Throttling request",v.throttle),clearTimeout(b.timer),b.timer=setTimeout(function(){b.timer&&delete b.timer,b.debug("Sending throttled request",p,s.method),b.send.request()},v.throttle)):(b.debug("Sending request",p,s.method),b.send.request(),b.timer=setTimeout(function(){},v.throttle)):(b.debug("Sending request",p,s.method),b.send.request()))):void 0):void b.error(q.missingURL))},is:{disabled:function(){return A.filter(R.disabled).length>0},form:function(){return A.is("form")},mocked:function(){return v.mockResponse||v.mockResponseAsync},input:function(){return A.is("input")},loading:function(){return b.request&&"pending"==b.request.state()},abortedRequest:function(e){return e&&e.readyState!==n&&0===e.readyState?(b.verbose("XHR request determined to be aborted"),!0):(b.verbose("XHR request was not aborted"),!1)},validResponse:function(t){return"json"!==v.dataType&&"jsonp"!==v.dataType||!e.isFunction(v.successTest)?(b.verbose("Response is not JSON, skipping validation",v.successTest,t),!0):(b.debug("Checking JSON returned success",v.successTest,t),v.successTest(t)?(b.debug("Response passed success test",t),!0):(b.debug("Response failed success test",t),!1))}},was:{cancelled:function(){return b.cancelled||!1},succesful:function(){return b.request&&"resolved"==b.request.state()},failure:function(){return b.request&&"rejected"==b.request.state()},complete:function(){return b.request&&("resolved"==b.request.state()||"rejected"==b.request.state())}},add:{urlData:function(t,r){var o,s;return t&&(o=t.match(v.regExp.required),s=t.match(v.regExp.optional),r=r||v.urlData,o&&(b.debug("Looking for required URL variables",o),e.each(o,function(o,s){var a=-1!==s.indexOf("$")?s.substr(2,s.length-3):s.substr(1,s.length-2),i=e.isPlainObject(r)&&r[a]!==n?r[a]:A.data(a)!==n?A.data(a):j.data(a)!==n?j.data(a):r[a];return i===n?(b.error(q.requiredParameter,a,t),t=!1,!1):(b.verbose("Found required variable",a,i),void(t=t.replace(s,b.get.urlEncodedValue(i))))})),s&&(b.debug("Looking for optional URL variables",o),e.each(s,function(o,s){var a=-1!==s.indexOf("$")?s.substr(3,s.length-4):s.substr(2,s.length-3),i=e.isPlainObject(r)&&r[a]!==n?r[a]:A.data(a)!==n?A.data(a):j.data(a)!==n?j.data(a):r[a];i!==n?(b.verbose("Optional variable Found",a,i),t=t.replace(s,i)):(b.verbose("Optional variable not found",a),t=-1!==t.indexOf("/"+s)?t.replace("/"+s,""):t.replace(s,""))}))),t},formData:function(t){var r,o=e.fn.serializeObject!==n,s=o?S.serializeObject():S.serialize();return t=t||v.data,r=e.isPlainObject(t),r?o?(b.debug("Extending existing data with form data",t,s),t=e.extend(!0,{},t,s)):(b.error(q.missingSerialize),b.debug("Cant extend data. Replacing data with form data",t,s),t=s):(b.debug("Adding form data",s),t=s),t}},send:{request:function(){b.set.loading(),b.request=b.create.request(),b.is.mocked()?b.mockedXHR=b.create.mockedXHR():b.xhr=b.create.xhr(),v.onRequest.call(w,b.request,b.xhr)}},event:{trigger:function(e){b.query(),("submit"==e.type||"click"==e.type)&&e.preventDefault()},xhr:{always:function(){},done:function(t,r,n){var o=this,s=(new Date).getTime()-m,a=v.loadingDuration-s,i=e.isFunction(v.onResponse)?v.onResponse.call(o,e.extend(!0,{},t)):!1;a=a>0?a:0,i&&(b.debug("Modified API response in onResponse callback",v.onResponse,i,t),t=i),a>0&&b.debug("Response completed early delaying state change by",a),setTimeout(function(){b.is.validResponse(t)?b.request.resolveWith(o,[t,n]):b.request.rejectWith(o,[n,"invalid"])},a)},fail:function(e,t,r){var n=this,o=(new Date).getTime()-m,s=v.loadingDuration-o;s=s>0?s:0,s>0&&b.debug("Response completed early delaying state change by",s),setTimeout(function(){b.is.abortedRequest(e)?b.request.rejectWith(n,[e,"aborted",r]):b.request.rejectWith(n,[e,"error",t,r])},s)}},request:{done:function(e){b.debug("Successful API Response",e),"local"===v.cache&&f&&(b.write.cachedResponse(f,e),b.debug("Saving server response locally",b.cache)),v.onSuccess.call(w,e,A)},complete:function(e){var t=b.get.responseFromXHR(e);b.remove.loading(),v.onComplete.call(w,t,A,e)},fail:function(e,t,r){var o=b.get.responseFromXHR(e),a=b.get.errorFromRequest(o,t,r);"aborted"==t?(b.debug("XHR Aborted (Most likely caused by page navigation or CORS Policy)",t,r),v.onAbort.call(w,t,A)):"invalid"==t?b.debug("JSON did not pass success test. A server-side error has most likely occurred",o):"error"==t&&e!==n&&(b.debug("XHR produced a server error",t,r),200!=e.status&&r!==n&&""!==r&&b.error(q.statusMessage+r,s.url),v.onError.call(w,a,A)),v.errorDuration&&"aborted"!==t&&(b.debug("Adding error state"),b.set.error(),setTimeout(b.remove.error,v.errorDuration)),b.debug("API Request failed",a,e),v.onFailure.call(w,o,A)}}},create:{request:function(){return e.Deferred().always(b.event.request.complete).done(b.event.request.done).fail(b.event.request.fail)},mockedXHR:function(){var t,r,n,o=!1,s=!1,a=!1;return n=e.Deferred().always(b.event.xhr.complete).done(b.event.xhr.done).fail(b.event.xhr.fail),v.mockResponse?(e.isFunction(v.mockResponse)?(b.debug("Using mocked callback returning response",v.mockResponse),r=v.mockResponse.call(w,v)):(b.debug("Using specified response",v.mockResponse),r=v.mockResponse),n.resolveWith(w,[r,o,{responseText:r}])):e.isFunction(v.mockResponseAsync)&&(t=function(e){b.debug("Async callback returned response",e),e?n.resolveWith(w,[e,o,{responseText:e}]):n.rejectWith(w,[{responseText:e},s,a])},b.debug("Using async mocked response",v.mockResponseAsync),v.mockResponseAsync.call(w,v,t)),n},xhr:function(){var t;return t=e.ajax(s).always(b.event.xhr.always).done(b.event.xhr.done).fail(b.event.xhr.fail),b.verbose("Created server request",t),t}},set:{error:function(){b.verbose("Adding error state to element",j),j.addClass(x.error)},loading:function(){b.verbose("Adding loading state to element",j),j.addClass(x.loading),m=(new Date).getTime()}},remove:{error:function(){b.verbose("Removing error state from element",j),j.removeClass(x.error)},loading:function(){b.verbose("Removing loading state from element",j),j.removeClass(x.loading)}},get:{responseFromXHR:function(t){return e.isPlainObject(t)?"json"==v.dataType||"jsonp"==v.dataType?b.decode.json(t.responseText):t.responseText:!1},errorFromRequest:function(t,r,o){return e.isPlainObject(t)&&t.error!==n?t.error:v.error[r]!==n?v.error[r]:o},request:function(){return b.request||!1},xhr:function(){return b.xhr||!1},settings:function(){var e;return e=v.beforeSend.call(w,v),e&&(e.success!==n&&(b.debug("Legacy success callback detected",e),b.error(q.legacyParameters,e.success),e.onSuccess=e.success),e.failure!==n&&(b.debug("Legacy failure callback detected",e),b.error(q.legacyParameters,e.failure),e.onFailure=e.failure),e.complete!==n&&(b.debug("Legacy complete callback detected",e),b.error(q.legacyParameters,e.complete),e.onComplete=e.complete)),e===n&&b.error(q.noReturnedValue),e!==n?e:v},urlEncodedValue:function(e){var r=t.decodeURIComponent(e),n=t.encodeURIComponent(e),o=r!==e;return o?(b.debug("URL value is already encoded, avoiding double encoding",e),e):(b.verbose("Encoding value for url",e,n),n)},defaultData:function(){var t={};return e.isWindow(P)||(b.is.input()?t.value=A.val():b.is.form()&&(t.text=A.text())),t},event:function(){return e.isWindow(P)||"now"==v.on?(b.debug("API called without element, no events attached"),!1):"auto"==v.on?A.is("input")?P.oninput!==n?"input":P.onpropertychange!==n?"propertychange":"keyup":A.is("form")?"submit":"click":v.on},templatedURL:function(e){if(e=e||A.data(y.action)||v.action||!1,f=A.data(y.url)||v.url||!1)return b.debug("Using specified url",f),f;if(e){if(b.debug("Looking up url for action",e,v.api),v.api[e]===n&&!b.is.mocked())return void b.error(q.missingAction,v.action,v.api);f=v.api[e]}else b.is.form()&&(f=A.attr("action")||!1,b.debug("No url or action specified, defaulting to form action",f));return f}},abort:function(){var e=b.get.xhr();e&&"resolved"!==e.state()&&(b.debug("Cancelling API request"),e.abort())},reset:function(){b.remove.error(),b.remove.loading()},setting:function(t,r){if(b.debug("Changing setting",t,r),e.isPlainObject(t))e.extend(!0,v,t);else{if(r===n)return v[t];v[t]=r}},internal:function(t,r){if(e.isPlainObject(t))e.extend(!0,b,t);else{if(r===n)return b[t];b[t]=r}},debug:function(){v.debug&&(v.performance?b.performance.log(arguments):(b.debug=Function.prototype.bind.call(console.info,console,v.name+":"),b.debug.apply(console,arguments)))},verbose:function(){v.verbose&&v.debug&&(v.performance?b.performance.log(arguments):(b.verbose=Function.prototype.bind.call(console.info,console,v.name+":"),b.verbose.apply(console,arguments)))},error:function(){b.error=Function.prototype.bind.call(console.error,console,v.name+":"),b.error.apply(console,arguments)},performance:{log:function(e){var t,r,n;v.performance&&(t=(new Date).getTime(),n=i||t,r=t-n,i=t,u.push({Name:e[0],Arguments:[].slice.call(e,1)||"","Execution Time":r})),clearTimeout(b.performance.timer),b.performance.timer=setTimeout(b.performance.display,500)},display:function(){var t=v.name+":",r=0;i=!1,clearTimeout(b.performance.timer),e.each(u,function(e,t){r+=t["Execution Time"]}),t+=" "+r+"ms",a&&(t+=" '"+a+"'"),(console.group!==n||console.table!==n)&&u.length>0&&(console.groupCollapsed(t),console.table?console.table(u):e.each(u,function(e,t){console.log(t.Name+": "+t["Execution Time"]+"ms")}),console.groupEnd()),u=[]}},invoke:function(t,r,s){var a,i,u,c=D;return r=r||l,s=P||s,"string"==typeof t&&c!==n&&(t=t.split(/[\. ]/),a=t.length-1,e.each(t,function(r,o){var s=r!=a?o+t[r+1].charAt(0).toUpperCase()+t[r+1].slice(1):t;if(e.isPlainObject(c[s])&&r!=a)c=c[s];else{if(c[s]!==n)return i=c[s],!1;if(!e.isPlainObject(c[o])||r==a)return c[o]!==n?(i=c[o],!1):(b.error(q.method,t),!1);c=c[o]}})),e.isFunction(i)?u=i.apply(s,r):i!==n&&(u=i),e.isArray(o)?o.push(u):o!==n?o=[o,u]:u!==n&&(o=u),i}},d?(D===n&&b.initialize(),b.invoke(c)):(D!==n&&D.invoke("destroy"),b.initialize())}),o!==n?o:this},e.api.settings={name:"API",namespace:"api",debug:!0,verbose:!1,performance:!0,api:{},cache:!0,interruptRequests:!0,on:"auto",stateContext:!1,loadingDuration:0,errorDuration:2e3,action:!1,url:!1,base:"",urlData:{},defaultData:!0,serializeForm:!1,throttle:0,throttleFirstRequest:!0,method:"get",data:{},dataType:"json",mockResponse:!1,mockResponseAsync:!1,beforeSend:function(e){return e},beforeXHR:function(e){},onRequest:function(e,t){},onResponse:!1,onSuccess:function(e,t){},onComplete:function(e,t){},onFailure:function(e,t){},onError:function(e,t){},onAbort:function(e,t){},successTest:!1,error:{beforeSend:"The before send function has aborted the request",error:"There was an error with your request",exitConditions:"API Request Aborted. Exit conditions met",JSONParse:"JSON could not be parsed during error handling",legacyParameters:"You are using legacy API success callback names",method:"The method you called is not defined",missingAction:"API action used but no url was defined",missingSerialize:"jquery-serialize-object is required to add form data to an existing data object",missingURL:"No URL specified for api event",noReturnedValue:"The beforeSend callback must return a settings object, beforeSend ignored.",noStorage:"Caching respopnses locally requires session storage",parseError:"There was an error parsing your request",requiredParameter:"Missing a required URL parameter: ",statusMessage:"Server gave an error: ",timeout:"Your request timed out"},regExp:{required:/\{\$*[A-z0-9]+\}/g,optional:/\{\/\$*[A-z0-9]+\}/g},className:{loading:"loading",error:"error"},selector:{disabled:".disabled",form:"form"},metadata:{action:"action",url:"url"}}}(jQuery,window,document); \ No newline at end of file diff --git a/dist/components/popup.js b/dist/components/popup.js index 407ae874b..387bdc6f7 100644 --- a/dist/components/popup.js +++ b/dist/components/popup.js @@ -22,7 +22,7 @@ $.fn.popup = function(parameters) { moduleSelector = $allModules.selector || '', - hasTouch = ('ontouchstart' in document.documentElement), + hasTouch = (true), time = new Date().getTime(), performance = [], @@ -156,7 +156,9 @@ $.fn.popup = function(parameters) { : settings.delay ; clearTimeout(module.hideTimer); - module.showTimer = setTimeout(module.show, delay); + if(!openedWithTouch) { + module.showTimer = setTimeout(module.show, delay); + } }, end: function() { var @@ -169,7 +171,7 @@ $.fn.popup = function(parameters) { }, touchstart: function(event) { openedWithTouch = true; - module.event.start(); + module.show(); }, resize: function() { if( module.is.visible() ) { @@ -279,7 +281,6 @@ $.fn.popup = function(parameters) { show: function(callback) { callback = callback || function(){}; module.debug('Showing pop-up', settings.transition); - if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { if( !module.exists() ) { module.create(); @@ -398,8 +399,8 @@ $.fn.popup = function(parameters) { hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); - if(settings.onShow.call($popup, element) === false) { - module.debug('onShow callback returned false, cancelling popup animation'); + if(settings.onHide.call($popup, element) === false) { + module.debug('onHide callback returned false, cancelling popup animation'); return; } if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { @@ -884,7 +885,7 @@ $.fn.popup = function(parameters) { .on('touchstart' + eventNamespace, module.event.touchstart) ; } - else if( module.get.startEvent() ) { + if( module.get.startEvent() ) { $module .on(module.get.startEvent() + eventNamespace, module.event.start) .on(module.get.endEvent() + eventNamespace, module.event.end) diff --git a/dist/components/popup.min.js b/dist/components/popup.min.js index 622c281a8..eb92e383c 100644 --- a/dist/components/popup.min.js +++ b/dist/components/popup.min.js @@ -8,4 +8,4 @@ * http://opensource.org/licenses/MIT * */ -!function(t,e,o,n){"use strict";t.fn.popup=function(i){var r,a=t(this),s=t(o),p=t(e),l=t("body"),u=a.selector||"",c="ontouchstart"in o.documentElement,d=(new Date).getTime(),f=[],g=arguments[0],h="string"==typeof g,m=[].slice.call(arguments,1);return a.each(function(){var o,a,v,b,w,y=t.isPlainObject(i)?t.extend(!0,{},t.fn.popup.settings,i):t.extend({},t.fn.popup.settings),T=y.selector,P=y.className,C=y.error,k=y.metadata,x=y.namespace,S="."+y.namespace,D="module-"+x,E=t(this),O=t(y.context),j=y.target?t(y.target):E,A=0,F=!1,R=!1,H=this,W=E.data(D);w={initialize:function(){w.debug("Initializing",E),w.createID(),w.bind.events(),!w.exists()&&y.preserve&&w.create(),w.instantiate()},instantiate:function(){w.verbose("Storing instance",w),W=w,E.data(D,W)},refresh:function(){y.popup?o=t(y.popup).eq(0):y.inline&&(o=j.next(T.popup).eq(0),y.popup=o),y.popup?(o.addClass(P.loading),a=w.get.offsetParent(),o.removeClass(P.loading),y.movePopup&&w.has.popup()&&w.get.offsetParent(o)[0]!==a[0]&&(w.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(a))):a=y.inline?w.get.offsetParent(j):w.has.popup()?w.get.offsetParent(o):l,a.is("html")&&a[0]!==l[0]&&(w.debug("Setting page as offset parent"),a=l)},reposition:function(){w.refresh(),w.set.position()},destroy:function(){w.debug("Destroying previous module"),o&&!y.preserve&&w.removePopup(),clearTimeout(w.hideTimer),clearTimeout(w.showTimer),p.off(v),E.off(S).removeData(D)},event:{start:function(e){var o=t.isPlainObject(y.delay)?y.delay.show:y.delay;clearTimeout(w.hideTimer),w.showTimer=setTimeout(w.show,o)},end:function(){var e=t.isPlainObject(y.delay)?y.delay.hide:y.delay;clearTimeout(w.showTimer),w.hideTimer=setTimeout(w.hide,e)},touchstart:function(t){R=!0,w.event.start()},resize:function(){w.is.visible()&&w.set.position()},hideGracefully:function(e){e&&0===t(e.target).closest(T.popup).length?(w.debug("Click occurred outside popup hiding popup"),w.hide()):w.debug("Click was inside popup, keeping popup open")}},create:function(){var e=w.get.html(),n=w.get.variation(),i=w.get.title(),r=w.get.content();e||r||i?(w.debug("Creating pop-up html"),e||(e=y.templates.popup({title:i,content:r})),o=t("
").addClass(P.popup).addClass(n).data(k.activator,E).html(e),n&&o.addClass(n),y.inline?(w.verbose("Inserting popup element inline",o),o.insertAfter(E)):(w.verbose("Appending popup element to body",o),o.appendTo(O)),w.refresh(),y.hoverable&&w.bind.popup(),y.onCreate.call(o,H)):0!==j.next(T.popup).length?(w.verbose("Pre-existing popup found"),y.inline=!0,y.popups=j.next(T.popup).data(k.activator,E),w.refresh(),y.hoverable&&w.bind.popup()):y.popup?(t(y.popup).data(k.activator,E),w.verbose("Used popup specified in settings"),w.refresh(),y.hoverable&&w.bind.popup()):w.debug("No content specified skipping display",H)},createID:function(){b=(Math.random().toString(16)+"000000000").substr(2,8),v="."+b,w.verbose("Creating unique id for element",b)},toggle:function(){w.debug("Toggling pop-up"),w.is.hidden()?(w.debug("Popup is hidden, showing pop-up"),w.unbind.close(),w.show()):(w.debug("Popup is visible, hiding pop-up"),w.hide())},show:function(t){if(t=t||function(){},w.debug("Showing pop-up",y.transition),w.is.hidden()&&(!w.is.active()||!w.is.dropdown())){if(w.exists()||w.create(),y.onShow.call(o,H)===!1)return void w.debug("onShow callback returned false, cancelling popup animation");y.preserve||y.popup||w.refresh(),o&&w.set.position()&&(w.save.conditions(),y.exclusive&&w.hideAll(),w.animate.show(t))}},hide:function(t){if(t=t||function(){},w.is.visible()||w.is.animating()){if(y.onHide.call(o,H)===!1)return void w.debug("onHide callback returned false, cancelling popup animation");w.remove.visible(),w.unbind.close(),w.restore.conditions(),w.animate.hide(t)}},hideAll:function(){t(T.popup).filter("."+P.visible).each(function(){t(this).data(k.activator).popup("hide")})},exists:function(){return o?y.inline||y.popup?w.has.popup():o.closest(O).length>=1?!0:!1:!1},removePopup:function(){w.debug("Removing popup",o),w.has.popup()&&!y.popup&&(o.remove(),o=n),y.onRemove.call(o,H)},save:{conditions:function(){w.cache={title:E.attr("title")},w.cache.title&&E.removeAttr("title"),w.verbose("Saving original attributes",w.cache.title)}},restore:{conditions:function(){return w.cache&&w.cache.title&&(E.attr("title",w.cache.title),w.verbose("Restoring original attributes",w.cache.title)),!0}},animate:{show:function(e){e=t.isFunction(e)?e:function(){},y.transition&&t.fn.transition!==n&&E.transition("is supported")?(w.set.visible(),o.transition({animation:y.transition+" in",queue:!1,debug:y.debug,verbose:y.verbose,duration:y.duration,onComplete:function(){w.bind.close(),e.call(o,H),y.onVisible.call(o,H)}})):w.error(C.noTransition)},hide:function(e){return e=t.isFunction(e)?e:function(){},w.debug("Hiding pop-up"),y.onShow.call(o,H)===!1?void w.debug("onShow callback returned false, cancelling popup animation"):void(y.transition&&t.fn.transition!==n&&E.transition("is supported")?o.transition({animation:y.transition+" out",queue:!1,duration:y.duration,debug:y.debug,verbose:y.verbose,onComplete:function(){w.reset(),e.call(o,H),y.onHidden.call(o,H)}}):w.error(C.noTransition))}},get:{html:function(){return E.removeData(k.html),E.data(k.html)||y.html},title:function(){return E.removeData(k.title),E.data(k.title)||y.title},content:function(){return E.removeData(k.content),E.data(k.content)||E.attr("title")||y.content},variation:function(){return E.removeData(k.variation),E.data(k.variation)||y.variation},popupOffset:function(){return o.offset()},calculations:function(){var t,n=j[0],i=y.inline||y.popup?j.position():j.offset(),r={};return r={target:{element:j[0],width:j.outerWidth(),height:j.outerHeight(),top:i.top,left:i.left,margin:{}},popup:{width:o.outerWidth(),height:o.outerHeight()},parent:{width:a.outerWidth(),height:a.outerHeight()},screen:{scroll:{top:p.scrollTop(),left:p.scrollLeft()},width:p.width(),height:p.height()}},y.setFluidWidth&&w.is.fluid()&&(r.container={width:o.parent().outerWidth()},r.popup.width=r.container.width),r.target.margin.top=y.inline?parseInt(e.getComputedStyle(n).getPropertyValue("margin-top"),10):0,r.target.margin.left=y.inline?w.is.rtl()?parseInt(e.getComputedStyle(n).getPropertyValue("margin-right"),10):parseInt(e.getComputedStyle(n).getPropertyValue("margin-left"),10):0,t=r.screen,r.boundary={top:t.scroll.top,bottom:t.scroll.top+t.height,left:t.scroll.left,right:t.scroll.left+t.width},r},id:function(){return b},startEvent:function(){return"hover"==y.on?"mouseenter":"focus"==y.on?"focus":!1},scrollEvent:function(){return"scroll"},endEvent:function(){return"hover"==y.on?"mouseleave":"focus"==y.on?"blur":!1},distanceFromBoundary:function(t,e){var o,n,i={};return t=t||w.get.offset(),e=e||w.get.calculations(),o=e.popup,n=e.boundary,t&&(i={top:t.top-n.top,left:t.left-n.left,right:n.right-(t.left+o.width),bottom:n.bottom-(t.top+o.height)},w.verbose("Distance from boundaries determined",t,i)),i},offsetParent:function(e){var o=e!==n?e[0]:E[0],i=o.parentNode,r=t(i);if(i)for(var a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");i&&!p&&s&&a;)i=i.parentNode,r=t(i),a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");return r&&r.length>0?r:t()},positions:function(){return{"top left":!1,"top center":!1,"top right":!1,"bottom left":!1,"bottom center":!1,"bottom right":!1,"left center":!1,"right center":!1}},nextPosition:function(t){var e=t.split(" "),o=e[0],n=e[1],i={top:"bottom",bottom:"top",left:"right",right:"left"},r={left:"center",center:"right",right:"left"},a={"top left":"top center","top center":"top right","top right":"right center","right center":"bottom right","bottom right":"bottom center","bottom center":"bottom left","bottom left":"left center","left center":"top left"},s="top"==o||"bottom"==o,p=!1,l=!1,u=!1;return F||(w.verbose("All available positions available"),F=w.get.positions()),w.debug("Recording last position tried",t),F[t]=!0,"opposite"===y.prefer&&(u=[i[o],n],u=u.join(" "),p=F[u]===!0,w.debug("Trying opposite strategy",u)),"adjacent"===y.prefer&&s&&(u=[o,r[n]],u=u.join(" "),l=F[u]===!0,w.debug("Trying adjacent strategy",u)),(l||p)&&(w.debug("Using backup position",u),u=a[t]),u}},set:{position:function(t,e){if(0===j.length||0===o.length)return void w.error(C.notFound);var i,r,a,s,p,l,u,c;if(e=e||w.get.calculations(),t=t||E.data(k.position)||y.position,i=E.data(k.offset)||y.offset,r=y.distanceAway,a=e.target,s=e.popup,p=e.parent,0===a.width&&0===a.height)return w.debug("Popup target is hidden, no action taken"),!1;switch(y.inline&&(w.debug("Adding margin to calculation",a.margin),"left center"==t||"right center"==t?(i+=a.margin.top,r+=-a.margin.left):"top left"==t||"top center"==t||"top right"==t?(i+=a.margin.left,r-=a.margin.top):(i+=a.margin.left,r+=a.margin.top)),w.debug("Determining popup position from calculations",t,e),w.is.rtl()&&(t=t.replace(/left|right/g,function(t){return"left"==t?"right":"left"}),w.debug("RTL: Popup position updated",t)),A==y.maxSearchDepth&&"string"==typeof y.lastResort&&(t=y.lastResort),t){case"top left":l={top:"auto",bottom:p.height-a.top+r,left:a.left+i,right:"auto"};break;case"top center":l={bottom:p.height-a.top+r,left:a.left+a.width/2-s.width/2+i,top:"auto",right:"auto"};break;case"top right":l={bottom:p.height-a.top+r,right:p.width-a.left-a.width-i,top:"auto",left:"auto"};break;case"left center":l={top:a.top+a.height/2-s.height/2+i,right:p.width-a.left+r,left:"auto",bottom:"auto"};break;case"right center":l={top:a.top+a.height/2-s.height/2+i,left:a.left+a.width+r,bottom:"auto",right:"auto"};break;case"bottom left":l={top:a.top+a.height+r,left:a.left+i,bottom:"auto",right:"auto"};break;case"bottom center":l={top:a.top+a.height+r,left:a.left+a.width/2-s.width/2+i,bottom:"auto",right:"auto"};break;case"bottom right":l={top:a.top+a.height+r,right:p.width-a.left-a.width-i,left:"auto",bottom:"auto"}}if(l===n&&w.error(C.invalidPosition,t),w.debug("Calculated popup positioning values",l),o.css(l).removeClass(P.position).addClass(t).addClass(P.loading),u=w.get.popupOffset(),c=w.get.distanceFromBoundary(u,e),w.is.offstage(c,t)){if(w.debug("Position is outside viewport",t),A0}},is:{offstage:function(e,o){var n=[];return t.each(e,function(t,e){e<-y.jitter&&(w.debug("Position exceeds allowable distance from edge",t,e,o),n.push(t))}),n.length>0?!0:!1},active:function(){return E.hasClass(P.active)},animating:function(){return o&&o.hasClass(P.animating)},fluid:function(){return o&&o.hasClass(P.fluid)},visible:function(){return o&&o.hasClass(P.visible)},dropdown:function(){return E.hasClass(P.dropdown)},hidden:function(){return!w.is.visible()},rtl:function(){return"rtl"==E.css("direction")}},reset:function(){w.remove.visible(),y.preserve?t.fn.transition!==n&&o.transition("remove transition"):w.removePopup()},setting:function(e,o){if(t.isPlainObject(e))t.extend(!0,y,e);else{if(o===n)return y[e];y[e]=o}},internal:function(e,o){if(t.isPlainObject(e))t.extend(!0,w,e);else{if(o===n)return w[e];w[e]=o}},debug:function(){y.debug&&(y.performance?w.performance.log(arguments):(w.debug=Function.prototype.bind.call(console.info,console,y.name+":"),w.debug.apply(console,arguments)))},verbose:function(){y.verbose&&y.debug&&(y.performance?w.performance.log(arguments):(w.verbose=Function.prototype.bind.call(console.info,console,y.name+":"),w.verbose.apply(console,arguments)))},error:function(){w.error=Function.prototype.bind.call(console.error,console,y.name+":"),w.error.apply(console,arguments)},performance:{log:function(t){var e,o,n;y.performance&&(e=(new Date).getTime(),n=d||e,o=e-n,d=e,f.push({Name:t[0],Arguments:[].slice.call(t,1)||"",Element:H,"Execution Time":o})),clearTimeout(w.performance.timer),w.performance.timer=setTimeout(w.performance.display,500)},display:function(){var e=y.name+":",o=0;d=!1,clearTimeout(w.performance.timer),t.each(f,function(t,e){o+=e["Execution Time"]}),e+=" "+o+"ms",u&&(e+=" '"+u+"'"),(console.group!==n||console.table!==n)&&f.length>0&&(console.groupCollapsed(e),console.table?console.table(f):t.each(f,function(t,e){console.log(e.Name+": "+e["Execution Time"]+"ms")}),console.groupEnd()),f=[]}},invoke:function(e,o,i){var a,s,p,l=W;return o=o||m,i=H||i,"string"==typeof e&&l!==n&&(e=e.split(/[\. ]/),a=e.length-1,t.each(e,function(o,i){var r=o!=a?i+e[o+1].charAt(0).toUpperCase()+e[o+1].slice(1):e;if(t.isPlainObject(l[r])&&o!=a)l=l[r];else{if(l[r]!==n)return s=l[r],!1;if(!t.isPlainObject(l[i])||o==a)return l[i]!==n?(s=l[i],!1):!1;l=l[i]}})),t.isFunction(s)?p=s.apply(i,o):s!==n&&(p=s),t.isArray(r)?r.push(p):r!==n?r=[r,p]:p!==n&&(r=p),s}},h?(W===n&&w.initialize(),w.invoke(g)):(W!==n&&W.invoke("destroy"),w.initialize())}),r!==n?r:this},t.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!0,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onVisible:function(){},onHide:function(){},onHidden:function(){},on:"hover",addTouchEvents:!0,position:"top left",variation:"",movePopup:!0,target:!1,popup:!1,inline:!1,preserve:!1,hoverable:!1,content:!1,html:!1,title:!1,closable:!0,hideOnScroll:"auto",exclusive:!1,context:"body",prefer:"opposite",lastResort:!1,delay:{show:50,hide:70},setFluidWidth:!0,duration:200,transition:"scale",distanceAway:0,jitter:2,offset:0,maxSearchDepth:15,error:{invalidPosition:"The position you specified is not a valid position",cannotPlace:"Popup does not fit within the boundaries of the viewport",method:"The method you called is not defined.",noTransition:"This module requires ui transitions ",notFound:"The target or popup you specified does not exist on the page"},metadata:{activator:"activator",content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",fluid:"fluid",loading:"loading",popup:"ui popup",position:"top left center bottom right",visible:"visible"},selector:{popup:".ui.popup"},templates:{escape:function(t){var e=/[&<>"'`]/g,o=/[&<>"'`]/,n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},i=function(t){return n[t]};return o.test(t)?t.replace(e,i):t},popup:function(e){var o="",i=t.fn.popup.settings.templates.escape;return typeof e!==n&&(typeof e.title!==n&&e.title&&(e.title=i(e.title),o+='
'+e.title+"
"),typeof e.content!==n&&e.content&&(e.content=i(e.content),o+='
'+e.content+"
")),o}}}}(jQuery,window,document); \ No newline at end of file +!function(t,e,o,n){"use strict";t.fn.popup=function(i){var r,a=t(this),s=t(o),p=t(e),l=t("body"),u=a.selector||"",c=!0,d=(new Date).getTime(),f=[],g=arguments[0],h="string"==typeof g,m=[].slice.call(arguments,1);return a.each(function(){var o,a,v,b,w,y=t.isPlainObject(i)?t.extend(!0,{},t.fn.popup.settings,i):t.extend({},t.fn.popup.settings),T=y.selector,P=y.className,C=y.error,k=y.metadata,x=y.namespace,S="."+y.namespace,D="module-"+x,O=t(this),j=t(y.context),A=y.target?t(y.target):O,E=0,F=!1,R=!1,H=this,W=O.data(D);w={initialize:function(){w.debug("Initializing",O),w.createID(),w.bind.events(),!w.exists()&&y.preserve&&w.create(),w.instantiate()},instantiate:function(){w.verbose("Storing instance",w),W=w,O.data(D,W)},refresh:function(){y.popup?o=t(y.popup).eq(0):y.inline&&(o=A.next(T.popup).eq(0),y.popup=o),y.popup?(o.addClass(P.loading),a=w.get.offsetParent(),o.removeClass(P.loading),y.movePopup&&w.has.popup()&&w.get.offsetParent(o)[0]!==a[0]&&(w.debug("Moving popup to the same offset parent as activating element"),o.detach().appendTo(a))):a=y.inline?w.get.offsetParent(A):w.has.popup()?w.get.offsetParent(o):l,a.is("html")&&a[0]!==l[0]&&(w.debug("Setting page as offset parent"),a=l)},reposition:function(){w.refresh(),w.set.position()},destroy:function(){w.debug("Destroying previous module"),o&&!y.preserve&&w.removePopup(),clearTimeout(w.hideTimer),clearTimeout(w.showTimer),p.off(v),O.off(S).removeData(D)},event:{start:function(e){var o=t.isPlainObject(y.delay)?y.delay.show:y.delay;clearTimeout(w.hideTimer),R||(w.showTimer=setTimeout(w.show,o))},end:function(){var e=t.isPlainObject(y.delay)?y.delay.hide:y.delay;clearTimeout(w.showTimer),w.hideTimer=setTimeout(w.hide,e)},touchstart:function(t){R=!0,w.show()},resize:function(){w.is.visible()&&w.set.position()},hideGracefully:function(e){e&&0===t(e.target).closest(T.popup).length?(w.debug("Click occurred outside popup hiding popup"),w.hide()):w.debug("Click was inside popup, keeping popup open")}},create:function(){var e=w.get.html(),n=w.get.variation(),i=w.get.title(),r=w.get.content();e||r||i?(w.debug("Creating pop-up html"),e||(e=y.templates.popup({title:i,content:r})),o=t("
").addClass(P.popup).addClass(n).data(k.activator,O).html(e),n&&o.addClass(n),y.inline?(w.verbose("Inserting popup element inline",o),o.insertAfter(O)):(w.verbose("Appending popup element to body",o),o.appendTo(j)),w.refresh(),y.hoverable&&w.bind.popup(),y.onCreate.call(o,H)):0!==A.next(T.popup).length?(w.verbose("Pre-existing popup found"),y.inline=!0,y.popups=A.next(T.popup).data(k.activator,O),w.refresh(),y.hoverable&&w.bind.popup()):y.popup?(t(y.popup).data(k.activator,O),w.verbose("Used popup specified in settings"),w.refresh(),y.hoverable&&w.bind.popup()):w.debug("No content specified skipping display",H)},createID:function(){b=(Math.random().toString(16)+"000000000").substr(2,8),v="."+b,w.verbose("Creating unique id for element",b)},toggle:function(){w.debug("Toggling pop-up"),w.is.hidden()?(w.debug("Popup is hidden, showing pop-up"),w.unbind.close(),w.show()):(w.debug("Popup is visible, hiding pop-up"),w.hide())},show:function(t){if(t=t||function(){},w.debug("Showing pop-up",y.transition),w.is.hidden()&&(!w.is.active()||!w.is.dropdown())){if(w.exists()||w.create(),y.onShow.call(o,H)===!1)return void w.debug("onShow callback returned false, cancelling popup animation");y.preserve||y.popup||w.refresh(),o&&w.set.position()&&(w.save.conditions(),y.exclusive&&w.hideAll(),w.animate.show(t))}},hide:function(t){if(t=t||function(){},w.is.visible()||w.is.animating()){if(y.onHide.call(o,H)===!1)return void w.debug("onHide callback returned false, cancelling popup animation");w.remove.visible(),w.unbind.close(),w.restore.conditions(),w.animate.hide(t)}},hideAll:function(){t(T.popup).filter("."+P.visible).each(function(){t(this).data(k.activator).popup("hide")})},exists:function(){return o?y.inline||y.popup?w.has.popup():o.closest(j).length>=1?!0:!1:!1},removePopup:function(){w.debug("Removing popup",o),w.has.popup()&&!y.popup&&(o.remove(),o=n),y.onRemove.call(o,H)},save:{conditions:function(){w.cache={title:O.attr("title")},w.cache.title&&O.removeAttr("title"),w.verbose("Saving original attributes",w.cache.title)}},restore:{conditions:function(){return w.cache&&w.cache.title&&(O.attr("title",w.cache.title),w.verbose("Restoring original attributes",w.cache.title)),!0}},animate:{show:function(e){e=t.isFunction(e)?e:function(){},y.transition&&t.fn.transition!==n&&O.transition("is supported")?(w.set.visible(),o.transition({animation:y.transition+" in",queue:!1,debug:y.debug,verbose:y.verbose,duration:y.duration,onComplete:function(){w.bind.close(),e.call(o,H),y.onVisible.call(o,H)}})):w.error(C.noTransition)},hide:function(e){return e=t.isFunction(e)?e:function(){},w.debug("Hiding pop-up"),y.onHide.call(o,H)===!1?void w.debug("onHide callback returned false, cancelling popup animation"):void(y.transition&&t.fn.transition!==n&&O.transition("is supported")?o.transition({animation:y.transition+" out",queue:!1,duration:y.duration,debug:y.debug,verbose:y.verbose,onComplete:function(){w.reset(),e.call(o,H),y.onHidden.call(o,H)}}):w.error(C.noTransition))}},get:{html:function(){return O.removeData(k.html),O.data(k.html)||y.html},title:function(){return O.removeData(k.title),O.data(k.title)||y.title},content:function(){return O.removeData(k.content),O.data(k.content)||O.attr("title")||y.content},variation:function(){return O.removeData(k.variation),O.data(k.variation)||y.variation},popupOffset:function(){return o.offset()},calculations:function(){var t,n=A[0],i=y.inline||y.popup?A.position():A.offset(),r={};return r={target:{element:A[0],width:A.outerWidth(),height:A.outerHeight(),top:i.top,left:i.left,margin:{}},popup:{width:o.outerWidth(),height:o.outerHeight()},parent:{width:a.outerWidth(),height:a.outerHeight()},screen:{scroll:{top:p.scrollTop(),left:p.scrollLeft()},width:p.width(),height:p.height()}},y.setFluidWidth&&w.is.fluid()&&(r.container={width:o.parent().outerWidth()},r.popup.width=r.container.width),r.target.margin.top=y.inline?parseInt(e.getComputedStyle(n).getPropertyValue("margin-top"),10):0,r.target.margin.left=y.inline?w.is.rtl()?parseInt(e.getComputedStyle(n).getPropertyValue("margin-right"),10):parseInt(e.getComputedStyle(n).getPropertyValue("margin-left"),10):0,t=r.screen,r.boundary={top:t.scroll.top,bottom:t.scroll.top+t.height,left:t.scroll.left,right:t.scroll.left+t.width},r},id:function(){return b},startEvent:function(){return"hover"==y.on?"mouseenter":"focus"==y.on?"focus":!1},scrollEvent:function(){return"scroll"},endEvent:function(){return"hover"==y.on?"mouseleave":"focus"==y.on?"blur":!1},distanceFromBoundary:function(t,e){var o,n,i={};return t=t||w.get.offset(),e=e||w.get.calculations(),o=e.popup,n=e.boundary,t&&(i={top:t.top-n.top,left:t.left-n.left,right:n.right-(t.left+o.width),bottom:n.bottom-(t.top+o.height)},w.verbose("Distance from boundaries determined",t,i)),i},offsetParent:function(e){var o=e!==n?e[0]:O[0],i=o.parentNode,r=t(i);if(i)for(var a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");i&&!p&&s&&a;)i=i.parentNode,r=t(i),a="none"===r.css("transform"),s="static"===r.css("position"),p=r.is("html");return r&&r.length>0?r:t()},positions:function(){return{"top left":!1,"top center":!1,"top right":!1,"bottom left":!1,"bottom center":!1,"bottom right":!1,"left center":!1,"right center":!1}},nextPosition:function(t){var e=t.split(" "),o=e[0],n=e[1],i={top:"bottom",bottom:"top",left:"right",right:"left"},r={left:"center",center:"right",right:"left"},a={"top left":"top center","top center":"top right","top right":"right center","right center":"bottom right","bottom right":"bottom center","bottom center":"bottom left","bottom left":"left center","left center":"top left"},s="top"==o||"bottom"==o,p=!1,l=!1,u=!1;return F||(w.verbose("All available positions available"),F=w.get.positions()),w.debug("Recording last position tried",t),F[t]=!0,"opposite"===y.prefer&&(u=[i[o],n],u=u.join(" "),p=F[u]===!0,w.debug("Trying opposite strategy",u)),"adjacent"===y.prefer&&s&&(u=[o,r[n]],u=u.join(" "),l=F[u]===!0,w.debug("Trying adjacent strategy",u)),(l||p)&&(w.debug("Using backup position",u),u=a[t]),u}},set:{position:function(t,e){if(0===A.length||0===o.length)return void w.error(C.notFound);var i,r,a,s,p,l,u,c;if(e=e||w.get.calculations(),t=t||O.data(k.position)||y.position,i=O.data(k.offset)||y.offset,r=y.distanceAway,a=e.target,s=e.popup,p=e.parent,0===a.width&&0===a.height)return w.debug("Popup target is hidden, no action taken"),!1;switch(y.inline&&(w.debug("Adding margin to calculation",a.margin),"left center"==t||"right center"==t?(i+=a.margin.top,r+=-a.margin.left):"top left"==t||"top center"==t||"top right"==t?(i+=a.margin.left,r-=a.margin.top):(i+=a.margin.left,r+=a.margin.top)),w.debug("Determining popup position from calculations",t,e),w.is.rtl()&&(t=t.replace(/left|right/g,function(t){return"left"==t?"right":"left"}),w.debug("RTL: Popup position updated",t)),E==y.maxSearchDepth&&"string"==typeof y.lastResort&&(t=y.lastResort),t){case"top left":l={top:"auto",bottom:p.height-a.top+r,left:a.left+i,right:"auto"};break;case"top center":l={bottom:p.height-a.top+r,left:a.left+a.width/2-s.width/2+i,top:"auto",right:"auto"};break;case"top right":l={bottom:p.height-a.top+r,right:p.width-a.left-a.width-i,top:"auto",left:"auto"};break;case"left center":l={top:a.top+a.height/2-s.height/2+i,right:p.width-a.left+r,left:"auto",bottom:"auto"};break;case"right center":l={top:a.top+a.height/2-s.height/2+i,left:a.left+a.width+r,bottom:"auto",right:"auto"};break;case"bottom left":l={top:a.top+a.height+r,left:a.left+i,bottom:"auto",right:"auto"};break;case"bottom center":l={top:a.top+a.height+r,left:a.left+a.width/2-s.width/2+i,bottom:"auto",right:"auto"};break;case"bottom right":l={top:a.top+a.height+r,right:p.width-a.left-a.width-i,left:"auto",bottom:"auto"}}if(l===n&&w.error(C.invalidPosition,t),w.debug("Calculated popup positioning values",l),o.css(l).removeClass(P.position).addClass(t).addClass(P.loading),u=w.get.popupOffset(),c=w.get.distanceFromBoundary(u,e),w.is.offstage(c,t)){if(w.debug("Position is outside viewport",t),E0}},is:{offstage:function(e,o){var n=[];return t.each(e,function(t,e){e<-y.jitter&&(w.debug("Position exceeds allowable distance from edge",t,e,o),n.push(t))}),n.length>0?!0:!1},active:function(){return O.hasClass(P.active)},animating:function(){return o&&o.hasClass(P.animating)},fluid:function(){return o&&o.hasClass(P.fluid)},visible:function(){return o&&o.hasClass(P.visible)},dropdown:function(){return O.hasClass(P.dropdown)},hidden:function(){return!w.is.visible()},rtl:function(){return"rtl"==O.css("direction")}},reset:function(){w.remove.visible(),y.preserve?t.fn.transition!==n&&o.transition("remove transition"):w.removePopup()},setting:function(e,o){if(t.isPlainObject(e))t.extend(!0,y,e);else{if(o===n)return y[e];y[e]=o}},internal:function(e,o){if(t.isPlainObject(e))t.extend(!0,w,e);else{if(o===n)return w[e];w[e]=o}},debug:function(){y.debug&&(y.performance?w.performance.log(arguments):(w.debug=Function.prototype.bind.call(console.info,console,y.name+":"),w.debug.apply(console,arguments)))},verbose:function(){y.verbose&&y.debug&&(y.performance?w.performance.log(arguments):(w.verbose=Function.prototype.bind.call(console.info,console,y.name+":"),w.verbose.apply(console,arguments)))},error:function(){w.error=Function.prototype.bind.call(console.error,console,y.name+":"),w.error.apply(console,arguments)},performance:{log:function(t){var e,o,n;y.performance&&(e=(new Date).getTime(),n=d||e,o=e-n,d=e,f.push({Name:t[0],Arguments:[].slice.call(t,1)||"",Element:H,"Execution Time":o})),clearTimeout(w.performance.timer),w.performance.timer=setTimeout(w.performance.display,500)},display:function(){var e=y.name+":",o=0;d=!1,clearTimeout(w.performance.timer),t.each(f,function(t,e){o+=e["Execution Time"]}),e+=" "+o+"ms",u&&(e+=" '"+u+"'"),(console.group!==n||console.table!==n)&&f.length>0&&(console.groupCollapsed(e),console.table?console.table(f):t.each(f,function(t,e){console.log(e.Name+": "+e["Execution Time"]+"ms")}),console.groupEnd()),f=[]}},invoke:function(e,o,i){var a,s,p,l=W;return o=o||m,i=H||i,"string"==typeof e&&l!==n&&(e=e.split(/[\. ]/),a=e.length-1,t.each(e,function(o,i){var r=o!=a?i+e[o+1].charAt(0).toUpperCase()+e[o+1].slice(1):e;if(t.isPlainObject(l[r])&&o!=a)l=l[r];else{if(l[r]!==n)return s=l[r],!1;if(!t.isPlainObject(l[i])||o==a)return l[i]!==n?(s=l[i],!1):!1;l=l[i]}})),t.isFunction(s)?p=s.apply(i,o):s!==n&&(p=s),t.isArray(r)?r.push(p):r!==n?r=[r,p]:p!==n&&(r=p),s}},h?(W===n&&w.initialize(),w.invoke(g)):(W!==n&&W.invoke("destroy"),w.initialize())}),r!==n?r:this},t.fn.popup.settings={name:"Popup",debug:!1,verbose:!1,performance:!0,namespace:"popup",onCreate:function(){},onRemove:function(){},onShow:function(){},onVisible:function(){},onHide:function(){},onHidden:function(){},on:"hover",addTouchEvents:!0,position:"top left",variation:"",movePopup:!0,target:!1,popup:!1,inline:!1,preserve:!1,hoverable:!1,content:!1,html:!1,title:!1,closable:!0,hideOnScroll:"auto",exclusive:!1,context:"body",prefer:"opposite",lastResort:!1,delay:{show:50,hide:70},setFluidWidth:!0,duration:200,transition:"scale",distanceAway:0,jitter:2,offset:0,maxSearchDepth:15,error:{invalidPosition:"The position you specified is not a valid position",cannotPlace:"Popup does not fit within the boundaries of the viewport",method:"The method you called is not defined.",noTransition:"This module requires ui transitions ",notFound:"The target or popup you specified does not exist on the page"},metadata:{activator:"activator",content:"content",html:"html",offset:"offset",position:"position",title:"title",variation:"variation"},className:{active:"active",animating:"animating",dropdown:"dropdown",fluid:"fluid",loading:"loading",popup:"ui popup",position:"top left center bottom right",visible:"visible"},selector:{popup:".ui.popup"},templates:{escape:function(t){var e=/[&<>"'`]/g,o=/[&<>"'`]/,n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},i=function(t){return n[t]};return o.test(t)?t.replace(e,i):t},popup:function(e){var o="",i=t.fn.popup.settings.templates.escape;return typeof e!==n&&(typeof e.title!==n&&e.title&&(e.title=i(e.title),o+='
'+e.title+"
"),typeof e.content!==n&&e.content&&(e.content=i(e.content),o+='
'+e.content+"
")),o}}}}(jQuery,window,document); \ No newline at end of file diff --git a/dist/semantic.js b/dist/semantic.js index 645900d12..88913c2f4 100644 --- a/dist/semantic.js +++ b/dist/semantic.js @@ -9201,7 +9201,7 @@ $.fn.popup = function(parameters) { moduleSelector = $allModules.selector || '', - hasTouch = ('ontouchstart' in document.documentElement), + hasTouch = (true), time = new Date().getTime(), performance = [], @@ -9335,7 +9335,9 @@ $.fn.popup = function(parameters) { : settings.delay ; clearTimeout(module.hideTimer); - module.showTimer = setTimeout(module.show, delay); + if(!openedWithTouch) { + module.showTimer = setTimeout(module.show, delay); + } }, end: function() { var @@ -9348,7 +9350,7 @@ $.fn.popup = function(parameters) { }, touchstart: function(event) { openedWithTouch = true; - module.event.start(); + module.show(); }, resize: function() { if( module.is.visible() ) { @@ -9458,7 +9460,6 @@ $.fn.popup = function(parameters) { show: function(callback) { callback = callback || function(){}; module.debug('Showing pop-up', settings.transition); - if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) { if( !module.exists() ) { module.create(); @@ -9577,8 +9578,8 @@ $.fn.popup = function(parameters) { hide: function(callback) { callback = $.isFunction(callback) ? callback : function(){}; module.debug('Hiding pop-up'); - if(settings.onShow.call($popup, element) === false) { - module.debug('onShow callback returned false, cancelling popup animation'); + if(settings.onHide.call($popup, element) === false) { + module.debug('onHide callback returned false, cancelling popup animation'); return; } if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) { @@ -10063,7 +10064,7 @@ $.fn.popup = function(parameters) { .on('touchstart' + eventNamespace, module.event.touchstart) ; } - else if( module.get.startEvent() ) { + if( module.get.startEvent() ) { $module .on(module.get.startEvent() + eventNamespace, module.event.start) .on(module.get.endEvent() + eventNamespace, module.event.end) @@ -18162,7 +18163,7 @@ $.api = $.fn.api = function(parameters) { } }, validResponse: function(response) { - if( settings.dataType !== 'json' || !$.isFunction(settings.successTest) ) { + if( (settings.dataType !== 'json' && settings.dataType !== 'jsonp') || !$.isFunction(settings.successTest) ) { module.verbose('Response is not JSON, skipping validation', settings.successTest, response); return true; } @@ -18320,13 +18321,13 @@ $.api = $.fn.api = function(parameters) { }, xhr: { always: function() { - // calculate if loading time was below minimum threshold + // nothing special }, done: function(response, textStatus, xhr) { var - context = this, - elapsedTime = (new Date().getTime() - requestStartTime), - timeLeft = (settings.loadingDuration - elapsedTime), + context = this, + elapsedTime = (new Date().getTime() - requestStartTime), + timeLeft = (settings.loadingDuration - elapsedTime), translatedResponse = ( $.isFunction(settings.onResponse) ) ? settings.onResponse.call(context, $.extend(true, {}, response)) : false @@ -18344,7 +18345,7 @@ $.api = $.fn.api = function(parameters) { } setTimeout(function() { if( module.is.validResponse(response) ) { - module.request.resolveWith(context, [response]); + module.request.resolveWith(context, [response, xhr]); } else { module.request.rejectWith(context, [xhr, 'invalid']); @@ -18375,10 +18376,6 @@ $.api = $.fn.api = function(parameters) { } }, request: { - complete: function(response) { - module.remove.loading(); - settings.onComplete.call(context, response, $module); - }, done: function(response) { module.debug('Successful API Response', response); if(settings.cache === 'local' && url) { @@ -18387,17 +18384,18 @@ $.api = $.fn.api = function(parameters) { } settings.onSuccess.call(context, response, $module); }, + complete: function(xhr) { + var + response = module.get.responseFromXHR(xhr) + ; + module.remove.loading(); + settings.onComplete.call(context, response, $module, xhr); + }, fail: function(xhr, status, httpMessage) { var // pull response from xhr if available - response = $.isPlainObject(xhr) - ? module.decode.json(xhr.responseText) - : false, - errorMessage = ($.isPlainObject(response) && response.error !== undefined) - ? response.error // use json error message - : (settings.error[status] !== undefined) // use server error message - ? settings.error[status] - : httpMessage + response = module.get.responseFromXHR(xhr), + errorMessage = module.get.errorFromRequest(response, status, httpMessage) ; if(status == 'aborted') { module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage); @@ -18407,7 +18405,6 @@ $.api = $.fn.api = function(parameters) { module.debug('JSON did not pass success test. A server-side error has most likely occurred', response); } else if(status == 'error') { - if(xhr !== undefined) { module.debug('XHR produced a server error', status, httpMessage); // make sure we have an error to display to console @@ -18525,6 +18522,22 @@ $.api = $.fn.api = function(parameters) { }, get: { + responseFromXHR: function(xhr) { + return $.isPlainObject(xhr) + ? (settings.dataType == 'json' || settings.dataType == 'jsonp') + ? module.decode.json(xhr.responseText) + : xhr.responseText + : false + ; + }, + errorFromRequest: function(response, status, httpMessage) { + return ($.isPlainObject(response) && response.error !== undefined) + ? response.error // use json error message + : (settings.error[status] !== undefined) // use server error message + ? settings.error[status] + : httpMessage + ; + }, request: function() { return module.request || false; }, diff --git a/dist/semantic.min.js b/dist/semantic.min.js index 555d04f57..c419cc9cd 100644 --- a/dist/semantic.min.js +++ b/dist/semantic.min.js @@ -12,8 +12,8 @@ },disabled:function(){return w.prop("disabled")!==i&&w.prop("disabled")},enabled:function(){return!m.is.disabled()},determinate:function(){return!m.is.indeterminate()},unchecked:function(){return!m.is.checked()}},can:{change:function(){return!(x.hasClass(g.disabled)||x.hasClass(g.readOnly)||w.prop("disabled")||w.prop("readonly"))},uncheck:function(){return"boolean"==typeof f.uncheckable?f.uncheckable:!m.is.radio()}},set:{checked:function(){return m.verbose("Setting class to checked"),x.removeClass(g.indeterminate).addClass(g.checked),m.is.radio()&&m.uncheckOthers(),!m.is.indeterminate()&&m.is.checked()?void m.debug("Input is already checked, skipping input property change"):(m.verbose("Setting state to checked",w[0]),w.prop("indeterminate",!1).prop("checked",!0),void m.trigger.change())},unchecked:function(){return m.verbose("Removing checked class"),x.removeClass(g.indeterminate).removeClass(g.checked),!m.is.indeterminate()&&m.is.unchecked()?void m.debug("Input is already unchecked"):(m.debug("Setting state to unchecked"),w.prop("indeterminate",!1).prop("checked",!1),void m.trigger.change())},indeterminate:function(){return m.verbose("Setting class to indeterminate"),x.addClass(g.indeterminate),m.is.indeterminate()?void m.debug("Input is already indeterminate, skipping input property change"):(m.debug("Setting state to indeterminate"),w.prop("indeterminate",!0),void m.trigger.change())},determinate:function(){return m.verbose("Removing indeterminate class"),x.removeClass(g.indeterminate),m.is.determinate()?void m.debug("Input is already determinate, skipping input property change"):(m.debug("Setting state to determinate"),void w.prop("indeterminate",!1))},disabled:function(){return m.verbose("Setting class to disabled"),x.addClass(g.disabled),m.is.disabled()?void m.debug("Input is already disabled, skipping input property change"):(m.debug("Setting state to disabled"),w.prop("disabled","disabled"),void m.trigger.change())},enabled:function(){return m.verbose("Removing disabled class"),x.removeClass(g.disabled),m.is.enabled()?void m.debug("Input is already enabled, skipping input property change"):(m.debug("Setting state to enabled"),w.prop("disabled",!1),void m.trigger.change())},tabbable:function(){m.verbose("Adding tabindex to checkbox"),w.attr("tabindex")===i&&w.attr("tabindex",0)}},trigger:{change:function(){m.verbose("Triggering change event from programmatic change"),w.trigger("change")}},create:{label:function(){w.prevAll(v.label).length>0?(w.prev(v.label).detach().insertAfter(w),m.debug("Moving existing label",C)):m.has.label()||(C=e("