Created
April 13, 2012 17:44
-
-
Save pamelafox/2378697 to your computer and use it in GitHub Desktop.
Revisions
-
pamelafox revised this gist
Apr 13, 2012 . No changes.There are no files selected for viewing
-
pamelafox created this gist
Apr 13, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,639 @@ var ED = ED || {}; // Utility functions ED.util = (function() { // Data structure functions function each(object, callback) { if (object === null) return; if (object instanceof Array) { for (var i = 0, item; i < object.length; i++) { callback(object[i], i); } } else { for (var key in object) { if (object.hasOwnProperty(key)) { callback(object[key], key); } } } } function keys(object) { var objectKeys = []; for (var key in object) { if (object.hasOwnProperty(key)) { objectKeys.push(key); } } return objectKeys; } function values(object) { var objectValues = []; for (var key in object) { if (object.hasOwnProperty(key)) { objectValues.push(object[key]); } } return objectValues; } function inArray(arr, val) { if (!arr) return false; for (var i = 0; i < arr.length; i++) { if (arr[i] === val) { return true; } } return false; } function impl(parent, generator) { var par = new parent(); var pub; pub = generator.call(par); for (var name in pub) { if (pub.hasOwnProperty(name)) { par[name] = pub[name]; } } return par; } // String functions function toCamelCase(string) { return string.replace(new RegExp('_(\\w)', 'g'), function(text, letter) { return letter.toUpperCase(); }); } function toUnderscore(string) { return string.replace(new RegExp('([A-Z])', 'g'), function(text, letter) { return '_' + letter.toLowerCase(); }); } function linkifyText(string){ if (string) { string = string.replace( /((https?\:\/\/)|(www\.))(\S+)(\w{2,4})(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/gi, function(url){ var full_url = url; if (!full_url.match('^https?:\/\/')) { full_url = 'http://' + full_url; } return '<a target="_blank" href="' + full_url + '">' + url.substring(0, Math.min(full_url.length, 20)) + '...</a>'; }); } return string; } function trimText(string) { return $.trim(string); } function truncateText(string, nMaxChars) { if (string.length <= nMaxChars) return string; var xMaxFit = nMaxChars - 3; var xTruncateAt = string.lastIndexOf(' ', xMaxFit); if (xTruncateAt == -1 || xTruncateAt < nMaxChars / 2) xTruncateAt = xMaxFit; return string.substr(0, xTruncateAt) + "..."; } function stripHtml(html) { return html.replace(/<.*?>/g, ''); } // Browser/feature detection functions function isIOS() { return ((navigator.userAgent.match(/iPhone/i)) || (navigator.userAgent.match(/iPod/i))); } function isAndroid() { var ua = navigator.userAgent.toLowerCase(); return ua.indexOf("android") > -1; } function isSafari() { return ($.browser.webkit && !(/chrome/.test(navigator.userAgent.toLowerCase()))); } function isTouchDevice() { return ('ontouchstart' in window); } function isSmallScreen() { if (!window.orientation) return false; if (window.orientation === 0) { // portrait return screen.width < 400; } else { // landscape return screen.height < 400; } } // Window & DOM functions function changePage(url) { window.location.href = url; } function getUrlParam(name) { name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); var regexS = "[\\?&]"+name+"=([^&#]*)"; var regex = new RegExp( regexS ); var results = regex.exec(unescape(window.location.href)); if( results === null ) return null; else return results[1]; } function getHashParam(name) { var regexS = name + "=([^&#]*)"; var regex = new RegExp(regexS); var splitUrl = unescape(window.location.href).split('#'); var hash = ((splitUrl.length > 1) && splitUrl[1]) || ''; var results = regex.exec(hash); if( results === null ) return null; else return results[1]; } function changeHashParam(name, value) { var regexS = name + "=([^&#]*)"; var regex = new RegExp(regexS); var hash = window.location.hash; var results = regex.exec(hash); if (getHashParam(name)) { window.location.hash = window.location.hash.replace(regex, name + '=' + value); } else { if (window.location.hash.indexOf('=') > -1) { window.location.hash += '&'; } window.location.hash += name + '=' + value; } } function getBrowserInfo() { if (window.device) { return device.name + ' | ' + device.phonegap + ' | ' + device.platform + ' | ' + device.uuid + ' | ' + device.version; } else { return navigator.userAgent; } } // Abstract on top of Zepto/jQuery differences function isVisible(elem) { if ($(elem).isVisible) { return $(elem).isVisible(); } else { return $(elem).is(':visible'); } } function inView(elem, nearThreshold) { var viewportHeight = getViewportHeight(); var scrollTop = (document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop); var elemTop = elem.offset().top; var elemHeight = elem.height(); nearThreshold = nearThreshold || 0; if ((scrollTop + viewportHeight + nearThreshold) > (elemTop + elemHeight)) { return true; } return false; } function getViewportHeight() { var height = window.innerHeight; // Safari, Opera var mode = document.compatMode; if ( (mode || !$.support.boxModel) ) { // IE, Gecko height = (mode == 'CSS1Compat') ? document.documentElement.clientHeight : // Standards document.body.clientHeight; // Quirks } return height; } function resetScroll(top) { top = top || 0; $(document).scrollTop(top); window.setTimeout(function() { $(document).scrollTop(top); }, 10); } function detectHash() { function maybeScrollToHash() { if (window.location.hash && $(window.location.hash).length) { var newTop = $(window.location.hash).offset().top - 40; $(window).scrollTop(newTop); } } $(window).bind('hashchange', function() { maybeScrollToHash(); }); maybeScrollToHash(); } function putCursorAtEnd(textarea) { $(textarea).focus(); if (textarea.setSelectionRange) { // ... then use it // (Doesn't work in IE) // Double the length because Opera is inconsistent about whether a carriage return is one character or two. Sigh. var len = $(textarea).val().length * 2; textarea.setSelectionRange(len, len); } else { // ... otherwise replace the contents with itself // (Doesn't work in Google Chrome) $(textarea).val($(textarea).val()); } // Scroll to the bottom, in case we're in a tall textarea // (Necessary for Firefox and Google Chrome) textarea.scrollTop = 999999; } // Time and date functionality function toDateObject(shortDate) { var splitDate = shortDate.split('/'); if (splitDate.length != 3) return; var month = parseInt(splitDate[0], 10) - 1; var day = parseInt(splitDate[1], 10); var year = parseInt(splitDate[2], 10); var date = new Date(year, month, day); return date; } function toShortWeekday(date) { var days = ['S', 'M', 'T', 'W', 'T', 'F', 'S']; return days[date.getDay()]; } function toShortDate(date) { if (typeof date == 'string') date = new Date(date); if (!date) date = new Date(); return date.format('mm/dd/yyyy'); // or 'shortDate' } function toLongDate(date) { if (date && typeof date == 'string') date = new Date(date); if (!date) date = new Date(); return date.format('dddd, mmm. d, yyyy'); // or 'fullDate' } function toISODate(date) { function pad(n) { return n < 10 ? '0' + n : n; } return date.getUTCFullYear() + '-' + pad(date.getUTCMonth()+1) + '-' + pad(date.getUTCDate()) + 'T' + pad(date.getUTCHours()) + ':' + pad(date.getUTCMinutes()) + ':' + pad(date.getUTCSeconds()) + 'Z'; } // Inclusive function getDatesBetween(oldestDate, newestDate) { var allDates = []; var currentDate = new Date(oldestDate.getTime()); var num = 0; while (currentDate <= newestDate) { allDates.push(toShortDate(currentDate)); currentDate.setDate(currentDate.getDate()+1); num++; } return allDates; } function getDatesSince(oldestDate) { var allDates = []; var today = new Date(); var currentDate = new Date(oldestDate.getTime()); var num = 0; while (currentDate < today) { allDates.push(toShortDate(currentDate)); currentDate.setTime(currentDate.getTime()+(1*24*60*60*1000)); num++; } return allDates; } function getCurrentTime() { var nowTime = new Date(); var timeHours = nowTime.getHours(); var timeMinutes = ':00'; if (nowTime.getMinutes() > 15) { if (nowTime.getMinutes() < 45) { timeMinutes = ':30'; } else { timeHours += 1; } } var timeSuffix = 'am'; if (timeHours >= 12) { timeSuffix = 'pm'; } if (timeHours > 12) { timeHours = timeHours - 12; } if (timeHours === 0) timeHours = 12; return {time: (timeHours + timeMinutes), suffix: timeSuffix}; } function renderTemplate(templateId, data) { var template; var html; templateId = templateId && templateId.replace('#', ''); if (!document.getElementById(templateId)) { log('Could not find template ' + templateId); return ''; } if (window.JsViews) { template = window.JsViews.template(templateId, document.getElementById(templateId).innerHTML); html = window.JsViews.render(data || {}, templateId); } else { template = $.template(templateId, document.getElementById(templateId).innerHTML); html = $.render(data || {}, templateId); } loadVisibleImages(); return html; } function useTouchEvents() { if (isTouchDevice()) { if (isAndroid()) return true; if (isIOS()) return false; } return false; } function triggerClick(dom) { if (useTouchEvents()) { dom.trigger('tap'); } else { dom.trigger('click'); } } ISTOUCHING = false; function addTouchOrClickHandler(dom, callback, logThis) { function logAction(message, dom) { log(message + ' on ' + $(dom).text().replace('\n', '')); } if (useTouchEvents()) { dom.each(function() { $(this).unbind('tap', callback); $(this).bind('tap', callback); $(this).bind('touchstart', function(e) { e.preventDefault(); //e.stopPropagation(); var item = e.currentTarget; if (ISTOUCHING) return; item.moved = false; ISTOUCHING = true; item.startX = e.touches[0].pageX; item.startY = e.touches[0].pageY; $(item).addClass('active'); }); $(this).bind('touchmove', function(e) { var item = e.currentTarget; if (Math.abs(e.touches[0].pageX - item.startX) > 10 || Math.abs(e.touches[0].pageY - item.startY) > 10) { item.moved = true; $(item).removeClass('active'); } }); $(this).bind('touchend', function(e) { var item = e.currentTarget; ISTOUCHING = false; if(!item.moved) { //e.stopPropagation(); //e.preventDefault(); $(item).trigger('tap'); } setTimeout(function() { $(item).removeClass('active'); }, 1000); delete item.moved; }); }); } else { dom.unbind('click', callback).bind('click', callback); } } function addClickHandler(dom, callback) { dom.unbind('click', callback).bind('click', callback); } function addWindowScrollHandler(callback) { $(window).off('scroll', callback).on('scroll', $.throttle(500, callback)); } function enableElement(dom) { $(dom).attr('disabled', false).removeAttr('disabled'); } function disableElement(dom) { $(dom).attr('disabled', 'disabled'); } function showModal(dom) { if ($(dom).modal) { $(dom).modal('show'); } } function hideModal(dom) { if ($(dom).modal) { $(dom).modal('hide'); } } function addModalShowHandler(dom, callback) { $(dom).unbind('shown', callback).bind('shown', callback); } function addModalHideHandler(dom, callback) { $(dom).unbind('hidden', callback).bind('hidden', callback); } function loadVisibleImages() { $('img').each(function() { if (this.src === '' && $(this).attr('data-src') && ED.util.isVisible($(this))) { if (ED.util.inView($(this), 500)) { this.src = $(this).attr('data-src'); } } }); } // Logging var allLogs = []; function log(something) { // Store var storedSomething = something; if (window.JSON) { storedSomething = JSON.stringify(something); } storedSomething = 'LOG @ ' + new Date().toString() + ': ' + truncateText(storedSomething, 200); allLogs.push(storedSomething); $('#mobile-feedback-logs').html(allLogs.reverse().join('<br>')); // Output if (window.console) { if (something instanceof Date) { something = something.toDateString(); } if (isIOS() || isAndroid()) { if (typeof something == 'object') { something = JSON.stringify(something); } something = truncateText(something, 2000); something = '\nLOG: ' + something; var stacktrace = ''; if (window.printStackTrace) { try { stacktrace = '\n -' + printStackTrace().slice(4).join('\n -'); something += '\nSTACKTRACE:' + stacktrace; } catch(e) {} } if (isIOS()) { //alert(something); console.log(something); } else { console.log(something); } if ($('#logs-viewer').length) { $('#logs-viewer').prepend(something.replace(/\n/g, '<br>') + '<br>'); } } else { console.log(something); } } } function getLogs() { return allLogs; } var timedEvents = []; function timeEvent(name) { timedEvents.push({'name': name || 'unnamed', time: Date.now()}); } function showTimedEvents() { var timeText = ''; var lastTime = null; for (var i = 0; i < timedEvents.length; i++) { var timedEvent = timedEvents[i]; timeText += 'Event ' + timedEvent.name + ': ' + timedEvent.time; if (lastTime) timeText += timedEvent.time - lastTime.time + ' after'; timeText += '\\n'; } log(timeText); } return { // Data structures each: each, keys: keys, values: values, inArray: inArray, impl: impl, // Strings toCamelCase: toCamelCase, toUnderscore: toUnderscore, truncateText: truncateText, linkifyText: linkifyText, stripHtml: stripHtml, trimText: trimText, // Dates toLongDate: toLongDate, toShortDate: toShortDate, toISODate: toISODate, toShortWeekday: toShortWeekday, toDateObject: toDateObject, getDatesSince: getDatesSince, getDatesBetween: getDatesBetween, getCurrentTime: getCurrentTime, // Window isAndroid: isAndroid, isSafari: isSafari, isIOS: isIOS, isSmallScreen: isSmallScreen, isTouchDevice: isTouchDevice, changePage: changePage, getUrlParam: getUrlParam, getHashParam: getHashParam, changeHashParam: changeHashParam, getBrowserInfo: getBrowserInfo, // DOM inView: inView, isVisible: isVisible, detectHash: detectHash, resetScroll: resetScroll, putCursorAtEnd: putCursorAtEnd, renderTemplate: renderTemplate, addClickHandler: addClickHandler, addTouchOrClickHandler: addTouchOrClickHandler, addWindowScrollHandler: addWindowScrollHandler, enableElement: enableElement, disableElement: disableElement, triggerClick: triggerClick, showModal: showModal, hideModal: hideModal, addModalShowHandler: addModalShowHandler, addModalHideHandler: addModalHideHandler, loadVisibleImages: loadVisibleImages, // Logging log: log, getLogs: getLogs, timeEvent: timeEvent, showTimedEvents: showTimedEvents }; })();