diff --git a/Gemfile b/Gemfile index c38e36e..e8edcfb 100644 --- a/Gemfile +++ b/Gemfile @@ -7,6 +7,7 @@ group :assets do gem 'coffee-rails', '~> 3.2.1' gem 'uglifier', '>= 1.0.3', :require => 'uglifier' gem 'compass-rails' + gem 'zurb-foundation', ">= 3.2" end # Bundle edge Rails instead: diff --git a/Gemfile.lock b/Gemfile.lock index b44a518..c6771e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -28,83 +28,87 @@ GEM activesupport (3.2.0) i18n (~> 0.6) multi_json (~> 1.0) - acts_as_commentable (3.0.1) - acts_as_tree (0.1.1) - ansi (1.4.2) + acts_as_commentable (4.0.0) + acts_as_tree (1.2.0) + activerecord (>= 3.0.0) + ansi (1.4.3) arel (3.0.2) bcrypt-ruby (3.0.1) - builder (3.0.0) - capistrano (2.11.2) + builder (3.0.4) + capistrano (2.14.2) highline net-scp (>= 1.0.0) net-sftp (>= 2.0.0) net-ssh (>= 2.0.14) net-ssh-gateway (>= 1.1.0) - carrierwave (0.6.1) + carrierwave (0.8.0) activemodel (>= 3.2.0) activesupport (>= 3.2.0) - chunky_png (1.2.5) + chunky_png (1.2.7) coffee-rails (3.2.2) coffee-script (>= 2.2.0) railties (~> 3.2.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.2.0) - compass (0.12.1) + coffee-script-source (1.4.0) + compass (0.12.2) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.1) - compass-rails (1.0.1) - compass (~> 0.12.0) - devise (2.0.4) + compass-rails (1.0.3) + compass (>= 0.12.2, < 0.14) + devise (2.2.3) bcrypt-ruby (~> 3.0) - orm_adapter (~> 0.0.3) + orm_adapter (~> 0.1) railties (~> 3.1) - warden (~> 1.1.1) + warden (~> 1.2.1) erubis (2.7.0) - execjs (1.3.0) + execjs (1.4.0) multi_json (~> 1.0) - formtastic (2.1.1) - actionpack (~> 3.0) - fssm (0.2.8.1) - geocoder (1.1.1) - gravatar_image_tag (1.1.2) - haml (3.1.4) - highline (1.6.11) + formtastic (2.2.1) + actionpack (>= 3.0) + fssm (0.2.10) + geocoder (1.1.6) + gravatar_image_tag (1.1.3) + haml (3.1.7) + highline (1.6.15) hike (1.2.1) - i18n (0.6.0) - journey (1.0.3) - jquery-rails (2.0.2) - railties (>= 3.2.0, < 5.0) - thor (~> 0.14) - json (1.6.6) - kaminari (0.13.0) + i18n (0.6.1) + journey (1.0.4) + jquery-rails (2.2.1) + railties (>= 3.0, < 5.0) + thor (>= 0.14, < 2.0) + json (1.7.7) + kaminari (0.14.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) - railties (>= 3.0.0) mail (2.4.4) i18n (>= 0.4.0) mime-types (~> 1.16) treetop (~> 1.4.8) - mime-types (1.18) - multi_json (1.2.0) + mime-types (1.21) + modular-scale (1.0.6) + compass (>= 0.12.1) + sass (>= 3.2.0) + sassy-math (>= 1.5) + multi_json (1.5.1) mysql2 (0.3.11) - net-scp (1.0.4) - net-ssh (>= 1.99.1) - net-sftp (2.0.5) - net-ssh (>= 2.0.9) - net-ssh (2.3.0) - net-ssh-gateway (1.1.0) - net-ssh (>= 1.99.1) - orm_adapter (0.0.7) + net-scp (1.1.0) + net-ssh (>= 2.6.5) + net-sftp (2.1.1) + net-ssh (>= 2.6.5) + net-ssh (2.6.5) + net-ssh-gateway (1.2.0) + net-ssh (>= 2.6.5) + orm_adapter (0.4.0) polyglot (0.3.3) - rack (1.4.1) + rack (1.4.5) rack-cache (1.2) rack (>= 0.4) - rack-ssl (1.3.2) + rack-ssl (1.3.3) rack - rack-test (0.6.1) + rack-test (0.6.2) rack (>= 1.0) rails (3.2.0) actionmailer (= 3.2.0) @@ -121,34 +125,41 @@ GEM rake (>= 0.8.7) rdoc (~> 3.4) thor (~> 0.14.6) - rake (0.9.2.2) - rdoc (3.12) + rake (10.0.3) + rdoc (3.12.1) json (~> 1.4) - rmagick (2.13.1) - rvm-capistrano (1.1.0) + rmagick (2.13.2) + rvm-capistrano (1.2.7) capistrano (>= 2.0.0) - sass (3.1.15) - sass-rails (3.2.5) + sass (3.2.5) + sass-rails (3.2.6) railties (~> 3.2.0) sass (>= 3.1.10) tilt (~> 1.3) - sprockets (2.1.2) + sassy-math (1.5) + compass (~> 0.11) + sprockets (2.1.3) hike (~> 1.2) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) thor (0.14.6) tilt (1.3.3) - treetop (1.4.10) + treetop (1.4.12) polyglot polyglot (>= 0.3.1) turn (0.8.2) ansi (>= 1.2.2) - tzinfo (0.3.32) - uglifier (1.2.4) + tzinfo (0.3.35) + uglifier (1.3.0) execjs (>= 0.3.0) - multi_json (>= 1.0.2) - warden (1.1.1) + multi_json (~> 1.0, >= 1.0.2) + warden (1.2.1) rack (>= 1.0) + zurb-foundation (3.2.5) + compass (>= 0.12.2) + modular-scale (= 1.0.6) + rake + sass (>= 3.2.0) PLATFORMS ruby @@ -174,3 +185,4 @@ DEPENDENCIES sass-rails (~> 3.2.3) turn (= 0.8.2) uglifier (>= 1.0.3) + zurb-foundation (>= 3.2) diff --git a/app/assets/images/admin/backgrounds/bg-green.jpg b/app/assets/images/admin/backgrounds/bg-green.jpg deleted file mode 100644 index 885dabf..0000000 Binary files a/app/assets/images/admin/backgrounds/bg-green.jpg and /dev/null differ diff --git a/app/assets/images/front/background.png b/app/assets/images/front/background.png new file mode 100644 index 0000000..f24bf21 Binary files /dev/null and b/app/assets/images/front/background.png differ diff --git a/app/assets/images/front/cc-licenses-terms.png b/app/assets/images/front/cc-licenses-terms.png deleted file mode 100644 index 072f8cd..0000000 Binary files a/app/assets/images/front/cc-licenses-terms.png and /dev/null differ diff --git a/app/assets/images/front/default_avatar.jpg b/app/assets/images/front/default_avatar.jpg deleted file mode 100644 index c177b99..0000000 Binary files a/app/assets/images/front/default_avatar.jpg and /dev/null differ diff --git a/app/assets/images/front/facebook.png b/app/assets/images/front/facebook.png deleted file mode 100755 index 05279fd..0000000 Binary files a/app/assets/images/front/facebook.png and /dev/null differ diff --git a/app/assets/images/front/facebook_active.png b/app/assets/images/front/facebook_active.png deleted file mode 100644 index 1e38d9c..0000000 Binary files a/app/assets/images/front/facebook_active.png and /dev/null differ diff --git a/app/assets/images/front/facebook_bw.png b/app/assets/images/front/facebook_bw.png deleted file mode 100755 index 11df6cb..0000000 Binary files a/app/assets/images/front/facebook_bw.png and /dev/null differ diff --git a/app/assets/images/front/facebook_dark.png b/app/assets/images/front/facebook_dark.png deleted file mode 100644 index 800136d..0000000 Binary files a/app/assets/images/front/facebook_dark.png and /dev/null differ diff --git a/app/assets/images/front/fleche.png b/app/assets/images/front/fleche.png new file mode 100644 index 0000000..db4bd80 Binary files /dev/null and b/app/assets/images/front/fleche.png differ diff --git a/app/assets/images/front/fond.jpg b/app/assets/images/front/fond.jpg deleted file mode 100644 index 23856bc..0000000 Binary files a/app/assets/images/front/fond.jpg and /dev/null differ diff --git a/app/assets/images/front/go_top.png b/app/assets/images/front/go_top.png new file mode 100644 index 0000000..0707e04 Binary files /dev/null and b/app/assets/images/front/go_top.png differ diff --git a/app/assets/images/front/in_active.png b/app/assets/images/front/in_active.png deleted file mode 100644 index 657aa62..0000000 Binary files a/app/assets/images/front/in_active.png and /dev/null differ diff --git a/app/assets/images/front/in_dark.png b/app/assets/images/front/in_dark.png deleted file mode 100644 index 2ad4f5b..0000000 Binary files a/app/assets/images/front/in_dark.png and /dev/null differ diff --git a/app/assets/images/front/linkedin.png b/app/assets/images/front/linkedin.png deleted file mode 100755 index f5b369c..0000000 Binary files a/app/assets/images/front/linkedin.png and /dev/null differ diff --git a/app/assets/images/front/linkedin_bw.png b/app/assets/images/front/linkedin_bw.png deleted file mode 100755 index fb9bd2c..0000000 Binary files a/app/assets/images/front/linkedin_bw.png and /dev/null differ diff --git a/app/assets/images/front/logo copie.png b/app/assets/images/front/logo copie.png deleted file mode 100644 index cf0b428..0000000 Binary files a/app/assets/images/front/logo copie.png and /dev/null differ diff --git a/app/assets/images/front/logo.png b/app/assets/images/front/logo.png index 9d8b017..d36bcef 100644 Binary files a/app/assets/images/front/logo.png and b/app/assets/images/front/logo.png differ diff --git a/app/assets/images/front/logo_fade.png b/app/assets/images/front/logo_fade.png new file mode 100644 index 0000000..d7beece Binary files /dev/null and b/app/assets/images/front/logo_fade.png differ diff --git a/app/assets/images/front/nicolasbally.jpg b/app/assets/images/front/nicolasbally.jpg deleted file mode 100644 index 8ce541e..0000000 Binary files a/app/assets/images/front/nicolasbally.jpg and /dev/null differ diff --git a/app/assets/images/front/pagination.png b/app/assets/images/front/pagination.png new file mode 100755 index 0000000..ee77798 Binary files /dev/null and b/app/assets/images/front/pagination.png differ diff --git a/app/assets/images/front/slider_shadow.png b/app/assets/images/front/slider_shadow.png new file mode 100644 index 0000000..769187c Binary files /dev/null and b/app/assets/images/front/slider_shadow.png differ diff --git a/app/assets/images/front/stumbleupon_active.png b/app/assets/images/front/stumbleupon_active.png deleted file mode 100644 index 4003d21..0000000 Binary files a/app/assets/images/front/stumbleupon_active.png and /dev/null differ diff --git a/app/assets/images/front/stumbleupon_dark.png b/app/assets/images/front/stumbleupon_dark.png deleted file mode 100644 index a6b3021..0000000 Binary files a/app/assets/images/front/stumbleupon_dark.png and /dev/null differ diff --git a/app/assets/images/front/top.png b/app/assets/images/front/top.png deleted file mode 100644 index 4299088..0000000 Binary files a/app/assets/images/front/top.png and /dev/null differ diff --git a/app/assets/images/front/tumblr_active.png b/app/assets/images/front/tumblr_active.png deleted file mode 100644 index 33d9caa..0000000 Binary files a/app/assets/images/front/tumblr_active.png and /dev/null differ diff --git a/app/assets/images/front/tumblr_dark.png b/app/assets/images/front/tumblr_dark.png deleted file mode 100644 index 1380063..0000000 Binary files a/app/assets/images/front/tumblr_dark.png and /dev/null differ diff --git a/app/assets/images/front/twitter_active.png b/app/assets/images/front/twitter_active.png deleted file mode 100644 index a04904e..0000000 Binary files a/app/assets/images/front/twitter_active.png and /dev/null differ diff --git a/app/assets/images/front/twitter_bw.png b/app/assets/images/front/twitter_bw.png deleted file mode 100755 index 9b7bf62..0000000 Binary files a/app/assets/images/front/twitter_bw.png and /dev/null differ diff --git a/app/assets/images/front/twitter_dark.png b/app/assets/images/front/twitter_dark.png deleted file mode 100644 index 4a25b32..0000000 Binary files a/app/assets/images/front/twitter_dark.png and /dev/null differ diff --git a/app/assets/images/front/viadeo.png b/app/assets/images/front/viadeo.png deleted file mode 100755 index d1e84b6..0000000 Binary files a/app/assets/images/front/viadeo.png and /dev/null differ diff --git a/app/assets/images/front/viadeo_active.png b/app/assets/images/front/viadeo_active.png deleted file mode 100644 index 6e84e90..0000000 Binary files a/app/assets/images/front/viadeo_active.png and /dev/null differ diff --git a/app/assets/images/front/viadeo_dark.png b/app/assets/images/front/viadeo_dark.png deleted file mode 100644 index e22c1e3..0000000 Binary files a/app/assets/images/front/viadeo_dark.png and /dev/null differ diff --git a/app/assets/images/front/web.jpg b/app/assets/images/front/web.jpg deleted file mode 100644 index 5d46b05..0000000 Binary files a/app/assets/images/front/web.jpg and /dev/null differ diff --git a/app/assets/javascripts/admin.js b/app/assets/javascripts/admin.js index 0e44948..58302d7 100644 --- a/app/assets/javascripts/admin.js +++ b/app/assets/javascripts/admin.js @@ -1,6 +1,9 @@ /* *= require ./shared/jquery.js *= require ./shared/jquery-ui.js + + + *= require ./shared/jquery.strings.js *= require ./shared/jquery.utils.js *= require ./shared/ui.timepickr.js diff --git a/app/assets/javascripts/admin/block.js b/app/assets/javascripts/admin/block.js index 09ed343..146bac1 100644 --- a/app/assets/javascripts/admin/block.js +++ b/app/assets/javascripts/admin/block.js @@ -32,7 +32,7 @@ function block_js_initialize(){ $(this).addClass('portlet_hover'); $(this).parents('.portlet').children(".actions").css({'display':'none'}); - $(this).parents('.portlet').css({ "border" : "1px solid #FBFBFB"}); + }); diff --git a/app/assets/javascripts/admin/cible.js b/app/assets/javascripts/admin/cible.js index 8e0e208..5bfcdbe 100644 --- a/app/assets/javascripts/admin/cible.js +++ b/app/assets/javascripts/admin/cible.js @@ -1,5 +1,5 @@ function select_cible_from_manager(input_id){ - set_busy(); + manager_prompt("/admin/cibles/?manager=true",function(m_return){ diff --git a/app/assets/javascripts/admin/manager.js b/app/assets/javascripts/admin/manager.js index eea43e9..92064ba 100644 --- a/app/assets/javascripts/admin/manager.js +++ b/app/assets/javascripts/admin/manager.js @@ -87,7 +87,7 @@ function manager_send_response(send_value){ } function select_image_from_manager(input_id){ - set_busy(); + manager_prompt("/admin/image_files/?manager=true",function(m_return){ $('#input_'+input_id).val(m_return.image_file_id); diff --git a/app/assets/javascripts/admin/menu_items.js b/app/assets/javascripts/admin/menu_items.js index 899a6b9..db0f6cd 100644 --- a/app/assets/javascripts/admin/menu_items.js +++ b/app/assets/javascripts/admin/menu_items.js @@ -27,7 +27,7 @@ function initialize_menu_items(){ tolerance : "pointer", drop: function( event, ui ) { ui.draggable.fadeOut(); - set_busy(); + $.ajax({ url:"/admin/menu_items/"+ui.draggable.attr("data-menu_item_id")+".js", type: "PUT", @@ -51,8 +51,7 @@ function initialize_menu_items(){ tolerance : "pointer", drop: function( event, ui ) { ui.draggable.fadeOut(); - set_busy(); - + $.ajax({ url:"/admin/menu_items/"+ui.draggable.attr("data-menu_item_id")+".js", type: "PUT", @@ -77,5 +76,34 @@ function initialize_menu_items(){ $(document).ready(function(){ initialize_menu_items(); + + + $(".switch").live('click',function(){ + + + $(this).toggleClass("on"); + + }); + + $(".menu_item_enabled_switch").live('click',function(){ + + + $.ajax({ + url:"/admin/menu_items/"+$(this).data("menu_item_id")+".js", + type: "PUT", + data: { + menu_item : { + enabled : $(this).hasClass("on") + } + }, + success : function (){ + + } + }); + + + + }); + }); \ No newline at end of file diff --git a/app/assets/javascripts/admin/pages_actions.js.coffee b/app/assets/javascripts/admin/pages_actions.js.coffee index 233278c..4ab0179 100644 --- a/app/assets/javascripts/admin/pages_actions.js.coffee +++ b/app/assets/javascripts/admin/pages_actions.js.coffee @@ -8,6 +8,7 @@ $('.menu_item_row .show_details').live "click", -> $("#menu_item_detail").show().delay(1).css "-webkit-transition-duration": "0.8s" + "-webkit-transform": "scale(1)" "-moz-transition-duration": "0.8s" "margin-right": "0px" @@ -31,6 +32,7 @@ $('#menu_item_detail .hide').live "click", -> $("#menu_item_detail").css( "-webkit-transition-duration": "0.8s" + "-webkit-transform": "scale(0.2)" "-moz-transition-duration": "0.8s" "margin-right": "-110%").delay(800).queue -> $("#menu_item_detail").html("").clearQueue() diff --git a/app/assets/javascripts/admin/qi_core.js b/app/assets/javascripts/admin/qi_core.js index 47e24e7..20d98f3 100644 --- a/app/assets/javascripts/admin/qi_core.js +++ b/app/assets/javascripts/admin/qi_core.js @@ -19,13 +19,15 @@ function auto_load_div(div_to_load) { url = div_to_load.attr("data-url"); - load_block = div_to_load.children(".loading") ; + div_to_load.children(".ajax_load_content").hide(); - load_block.activity({segments: 8, steps: 5, opacity: 0.5, width: 5, space: 0, length: 5, color: '#212222', speed: 1.5}); - load_block.show(); - div_to_load.children(".ajax_load_content").load(url, function() {div_to_load.children(".loading").hide();$(this).show();block_js_initialize();}) + + div_to_load.children(".ajax_load_content").load(url, function() { + + $(this).show();block_js_initialize();} + ) } diff --git a/app/assets/javascripts/public.js.coffee b/app/assets/javascripts/public.js.coffee index b7f3b61..ac084d2 100644 --- a/app/assets/javascripts/public.js.coffee +++ b/app/assets/javascripts/public.js.coffee @@ -1,35 +1,11 @@ -#= require ./shared/jquery.js +#= require jquery #= require jquery_ujs -#= require ./shared/jquery.easing.1.3 -#= require ./shared/jquery.fancybox-1.3.4.pack - $ -> - - - $("a[rel^='prettyPhoto']").fancybox() - - $("#legals").click -> - - $('#legals_large').toggle() - $('#legals_large .content').css("margin-top",( ($(window).height()-$("#legals_large .content").height())/2)+"px") - return false - - $("#legals_large").click -> - - $('#legals_large').toggle(); - return false - - - $("#legals_large a").click -> - - $('#legals_large').toggle(); - return false - - \ No newline at end of file + #dfdf \ No newline at end of file diff --git a/app/assets/javascripts/shared/jquery.mobile-1.1.1.js b/app/assets/javascripts/shared/jquery.mobile-1.1.1.js new file mode 100644 index 0000000..058936c --- /dev/null +++ b/app/assets/javascripts/shared/jquery.mobile-1.1.1.js @@ -0,0 +1,7690 @@ +/* +* jQuery Mobile Framework 1.1.1 1981b3f5ec22675ae47df8f0bdf9622e7780e90e +* http://jquerymobile.com +* +* Copyright 2012 jQuery Foundation and other contributors +* Dual licensed under the MIT or GPL Version 2 licenses. +* http://jquery.org/license +* +*/ +(function ( root, doc, factory ) { + if ( typeof define === "function" && define.amd ) { + // AMD. Register as an anonymous module. + define( [ "jquery" ], function ( $ ) { + factory( $, root, doc ); + return $.mobile; + }); + } else { + // Browser globals + factory( root.jQuery, root, doc ); + } +}( this, document, function ( jQuery, window, document, undefined ) { + + +// This plugin is an experiment for abstracting away the touch and mouse +// events so that developers don't have to worry about which method of input +// the device their document is loaded on supports. +// +// The idea here is to allow the developer to register listeners for the +// basic mouse events, such as mousedown, mousemove, mouseup, and click, +// and the plugin will take care of registering the correct listeners +// behind the scenes to invoke the listener at the fastest possible time +// for that device, while still retaining the order of event firing in +// the traditional mouse environment, should multiple handlers be registered +// on the same element for different events. +// +// The current version exposes the following virtual events to jQuery bind methods: +// "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel" + +(function( $, window, document, undefined ) { + +var dataPropertyName = "virtualMouseBindings", + touchTargetPropertyName = "virtualTouchID", + virtualEventNames = "vmouseover vmousedown vmousemove vmouseup vclick vmouseout vmousecancel".split( " " ), + touchEventProps = "clientX clientY pageX pageY screenX screenY".split( " " ), + mouseHookProps = $.event.mouseHooks ? $.event.mouseHooks.props : [], + mouseEventProps = $.event.props.concat( mouseHookProps ), + activeDocHandlers = {}, + resetTimerID = 0, + startX = 0, + startY = 0, + didScroll = false, + clickBlockList = [], + blockMouseTriggers = false, + blockTouchTriggers = false, + eventCaptureSupported = "addEventListener" in document, + $document = $( document ), + nextTouchID = 1, + lastTouchID = 0; + +$.vmouse = { + moveDistanceThreshold: 10, + clickDistanceThreshold: 10, + resetTimerDuration: 1500 +}; + +function getNativeEvent( event ) { + + while ( event && typeof event.originalEvent !== "undefined" ) { + event = event.originalEvent; + } + return event; +} + +function createVirtualEvent( event, eventType ) { + + var t = event.type, + oe, props, ne, prop, ct, touch, i, j; + + event = $.Event(event); + event.type = eventType; + + oe = event.originalEvent; + props = $.event.props; + + // addresses separation of $.event.props in to $.event.mouseHook.props and Issue 3280 + // https://github.com/jquery/jquery-mobile/issues/3280 + if ( t.search( /^(mouse|click)/ ) > -1 ) { + props = mouseEventProps; + } + + // copy original event properties over to the new event + // this would happen if we could call $.event.fix instead of $.Event + // but we don't have a way to force an event to be fixed multiple times + if ( oe ) { + for ( i = props.length, prop; i; ) { + prop = props[ --i ]; + event[ prop ] = oe[ prop ]; + } + } + + // make sure that if the mouse and click virtual events are generated + // without a .which one is defined + if ( t.search(/mouse(down|up)|click/) > -1 && !event.which ){ + event.which = 1; + } + + if ( t.search(/^touch/) !== -1 ) { + ne = getNativeEvent( oe ); + t = ne.touches; + ct = ne.changedTouches; + touch = ( t && t.length ) ? t[0] : ( (ct && ct.length) ? ct[ 0 ] : undefined ); + + if ( touch ) { + for ( j = 0, len = touchEventProps.length; j < len; j++){ + prop = touchEventProps[ j ]; + event[ prop ] = touch[ prop ]; + } + } + } + + return event; +} + +function getVirtualBindingFlags( element ) { + + var flags = {}, + b, k; + + while ( element ) { + + b = $.data( element, dataPropertyName ); + + for ( k in b ) { + if ( b[ k ] ) { + flags[ k ] = flags.hasVirtualBinding = true; + } + } + element = element.parentNode; + } + return flags; +} + +function getClosestElementWithVirtualBinding( element, eventType ) { + var b; + while ( element ) { + + b = $.data( element, dataPropertyName ); + + if ( b && ( !eventType || b[ eventType ] ) ) { + return element; + } + element = element.parentNode; + } + return null; +} + +function enableTouchBindings() { + blockTouchTriggers = false; +} + +function disableTouchBindings() { + blockTouchTriggers = true; +} + +function enableMouseBindings() { + lastTouchID = 0; + clickBlockList.length = 0; + blockMouseTriggers = false; + + // When mouse bindings are enabled, our + // touch bindings are disabled. + disableTouchBindings(); +} + +function disableMouseBindings() { + // When mouse bindings are disabled, our + // touch bindings are enabled. + enableTouchBindings(); +} + +function startResetTimer() { + clearResetTimer(); + resetTimerID = setTimeout(function(){ + resetTimerID = 0; + enableMouseBindings(); + }, $.vmouse.resetTimerDuration ); +} + +function clearResetTimer() { + if ( resetTimerID ){ + clearTimeout( resetTimerID ); + resetTimerID = 0; + } +} + +function triggerVirtualEvent( eventType, event, flags ) { + var ve; + + if ( ( flags && flags[ eventType ] ) || + ( !flags && getClosestElementWithVirtualBinding( event.target, eventType ) ) ) { + + ve = createVirtualEvent( event, eventType ); + + $( event.target).trigger( ve ); + } + + return ve; +} + +function mouseEventCallback( event ) { + var touchID = $.data(event.target, touchTargetPropertyName); + + if ( !blockMouseTriggers && ( !lastTouchID || lastTouchID !== touchID ) ){ + var ve = triggerVirtualEvent( "v" + event.type, event ); + if ( ve ) { + if ( ve.isDefaultPrevented() ) { + event.preventDefault(); + } + if ( ve.isPropagationStopped() ) { + event.stopPropagation(); + } + if ( ve.isImmediatePropagationStopped() ) { + event.stopImmediatePropagation(); + } + } + } +} + +function handleTouchStart( event ) { + + var touches = getNativeEvent( event ).touches, + target, flags; + + if ( touches && touches.length === 1 ) { + + target = event.target; + flags = getVirtualBindingFlags( target ); + + if ( flags.hasVirtualBinding ) { + + lastTouchID = nextTouchID++; + $.data( target, touchTargetPropertyName, lastTouchID ); + + clearResetTimer(); + + disableMouseBindings(); + didScroll = false; + + var t = getNativeEvent( event ).touches[ 0 ]; + startX = t.pageX; + startY = t.pageY; + + triggerVirtualEvent( "vmouseover", event, flags ); + triggerVirtualEvent( "vmousedown", event, flags ); + } + } +} + +function handleScroll( event ) { + if ( blockTouchTriggers ) { + return; + } + + if ( !didScroll ) { + triggerVirtualEvent( "vmousecancel", event, getVirtualBindingFlags( event.target ) ); + } + + didScroll = true; + startResetTimer(); +} + +function handleTouchMove( event ) { + if ( blockTouchTriggers ) { + return; + } + + var t = getNativeEvent( event ).touches[ 0 ], + didCancel = didScroll, + moveThreshold = $.vmouse.moveDistanceThreshold; + didScroll = didScroll || + ( Math.abs(t.pageX - startX) > moveThreshold || + Math.abs(t.pageY - startY) > moveThreshold ), + flags = getVirtualBindingFlags( event.target ); + + if ( didScroll && !didCancel ) { + triggerVirtualEvent( "vmousecancel", event, flags ); + } + + triggerVirtualEvent( "vmousemove", event, flags ); + startResetTimer(); +} + +function handleTouchEnd( event ) { + if ( blockTouchTriggers ) { + return; + } + + disableTouchBindings(); + + var flags = getVirtualBindingFlags( event.target ), + t; + triggerVirtualEvent( "vmouseup", event, flags ); + + if ( !didScroll ) { + var ve = triggerVirtualEvent( "vclick", event, flags ); + if ( ve && ve.isDefaultPrevented() ) { + // The target of the mouse events that follow the touchend + // event don't necessarily match the target used during the + // touch. This means we need to rely on coordinates for blocking + // any click that is generated. + t = getNativeEvent( event ).changedTouches[ 0 ]; + clickBlockList.push({ + touchID: lastTouchID, + x: t.clientX, + y: t.clientY + }); + + // Prevent any mouse events that follow from triggering + // virtual event notifications. + blockMouseTriggers = true; + } + } + triggerVirtualEvent( "vmouseout", event, flags); + didScroll = false; + + startResetTimer(); +} + +function hasVirtualBindings( ele ) { + var bindings = $.data( ele, dataPropertyName ), + k; + + if ( bindings ) { + for ( k in bindings ) { + if ( bindings[ k ] ) { + return true; + } + } + } + return false; +} + +function dummyMouseHandler(){} + +function getSpecialEventObject( eventType ) { + var realType = eventType.substr( 1 ); + + return { + setup: function( data, namespace ) { + // If this is the first virtual mouse binding for this element, + // add a bindings object to its data. + + if ( !hasVirtualBindings( this ) ) { + $.data( this, dataPropertyName, {}); + } + + // If setup is called, we know it is the first binding for this + // eventType, so initialize the count for the eventType to zero. + var bindings = $.data( this, dataPropertyName ); + bindings[ eventType ] = true; + + // If this is the first virtual mouse event for this type, + // register a global handler on the document. + + activeDocHandlers[ eventType ] = ( activeDocHandlers[ eventType ] || 0 ) + 1; + + if ( activeDocHandlers[ eventType ] === 1 ) { + $document.bind( realType, mouseEventCallback ); + } + + // Some browsers, like Opera Mini, won't dispatch mouse/click events + // for elements unless they actually have handlers registered on them. + // To get around this, we register dummy handlers on the elements. + + $( this ).bind( realType, dummyMouseHandler ); + + // For now, if event capture is not supported, we rely on mouse handlers. + if ( eventCaptureSupported ) { + // If this is the first virtual mouse binding for the document, + // register our touchstart handler on the document. + + activeDocHandlers[ "touchstart" ] = ( activeDocHandlers[ "touchstart" ] || 0) + 1; + + if (activeDocHandlers[ "touchstart" ] === 1) { + $document.bind( "touchstart", handleTouchStart ) + .bind( "touchend", handleTouchEnd ) + + // On touch platforms, touching the screen and then dragging your finger + // causes the window content to scroll after some distance threshold is + // exceeded. On these platforms, a scroll prevents a click event from being + // dispatched, and on some platforms, even the touchend is suppressed. To + // mimic the suppression of the click event, we need to watch for a scroll + // event. Unfortunately, some platforms like iOS don't dispatch scroll + // events until *AFTER* the user lifts their finger (touchend). This means + // we need to watch both scroll and touchmove events to figure out whether + // or not a scroll happenens before the touchend event is fired. + + .bind( "touchmove", handleTouchMove ) + .bind( "scroll", handleScroll ); + } + } + }, + + teardown: function( data, namespace ) { + // If this is the last virtual binding for this eventType, + // remove its global handler from the document. + + --activeDocHandlers[ eventType ]; + + if ( !activeDocHandlers[ eventType ] ) { + $document.unbind( realType, mouseEventCallback ); + } + + if ( eventCaptureSupported ) { + // If this is the last virtual mouse binding in existence, + // remove our document touchstart listener. + + --activeDocHandlers[ "touchstart" ]; + + if ( !activeDocHandlers[ "touchstart" ] ) { + $document.unbind( "touchstart", handleTouchStart ) + .unbind( "touchmove", handleTouchMove ) + .unbind( "touchend", handleTouchEnd ) + .unbind( "scroll", handleScroll ); + } + } + + var $this = $( this ), + bindings = $.data( this, dataPropertyName ); + + // teardown may be called when an element was + // removed from the DOM. If this is the case, + // jQuery core may have already stripped the element + // of any data bindings so we need to check it before + // using it. + if ( bindings ) { + bindings[ eventType ] = false; + } + + // Unregister the dummy event handler. + + $this.unbind( realType, dummyMouseHandler ); + + // If this is the last virtual mouse binding on the + // element, remove the binding data from the element. + + if ( !hasVirtualBindings( this ) ) { + $this.removeData( dataPropertyName ); + } + } + }; +} + +// Expose our custom events to the jQuery bind/unbind mechanism. + +for ( var i = 0; i < virtualEventNames.length; i++ ){ + $.event.special[ virtualEventNames[ i ] ] = getSpecialEventObject( virtualEventNames[ i ] ); +} + +// Add a capture click handler to block clicks. +// Note that we require event capture support for this so if the device +// doesn't support it, we punt for now and rely solely on mouse events. +if ( eventCaptureSupported ) { + document.addEventListener( "click", function( e ){ + var cnt = clickBlockList.length, + target = e.target, + x, y, ele, i, o, touchID; + + if ( cnt ) { + x = e.clientX; + y = e.clientY; + threshold = $.vmouse.clickDistanceThreshold; + + // The idea here is to run through the clickBlockList to see if + // the current click event is in the proximity of one of our + // vclick events that had preventDefault() called on it. If we find + // one, then we block the click. + // + // Why do we have to rely on proximity? + // + // Because the target of the touch event that triggered the vclick + // can be different from the target of the click event synthesized + // by the browser. The target of a mouse/click event that is syntehsized + // from a touch event seems to be implementation specific. For example, + // some browsers will fire mouse/click events for a link that is near + // a touch event, even though the target of the touchstart/touchend event + // says the user touched outside the link. Also, it seems that with most + // browsers, the target of the mouse/click event is not calculated until the + // time it is dispatched, so if you replace an element that you touched + // with another element, the target of the mouse/click will be the new + // element underneath that point. + // + // Aside from proximity, we also check to see if the target and any + // of its ancestors were the ones that blocked a click. This is necessary + // because of the strange mouse/click target calculation done in the + // Android 2.1 browser, where if you click on an element, and there is a + // mouse/click handler on one of its ancestors, the target will be the + // innermost child of the touched element, even if that child is no where + // near the point of touch. + + ele = target; + + while ( ele ) { + for ( i = 0; i < cnt; i++ ) { + o = clickBlockList[ i ]; + touchID = 0; + + if ( ( ele === target && Math.abs( o.x - x ) < threshold && Math.abs( o.y - y ) < threshold ) || + $.data( ele, touchTargetPropertyName ) === o.touchID ) { + // XXX: We may want to consider removing matches from the block list + // instead of waiting for the reset timer to fire. + e.preventDefault(); + e.stopPropagation(); + return; + } + } + ele = ele.parentNode; + } + } + }, true); +} +})( jQuery, window, document ); + + + +// Script: jQuery hashchange event +// +// *Version: 1.3, Last updated: 7/21/2010* +// +// Project Home - http://benalman.com/projects/jquery-hashchange-plugin/ +// GitHub - http://github.com/cowboy/jquery-hashchange/ +// Source - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.js +// (Minified) - http://github.com/cowboy/jquery-hashchange/raw/master/jquery.ba-hashchange.min.js (0.8kb gzipped) +// +// About: License +// +// Copyright (c) 2010 "Cowboy" Ben Alman, +// Dual licensed under the MIT and GPL licenses. +// http://benalman.com/about/license/ +// +// About: Examples +// +// These working examples, complete with fully commented code, illustrate a few +// ways in which this plugin can be used. +// +// hashchange event - http://benalman.com/code/projects/jquery-hashchange/examples/hashchange/ +// document.domain - http://benalman.com/code/projects/jquery-hashchange/examples/document_domain/ +// +// About: Support and Testing +// +// Information about what version or versions of jQuery this plugin has been +// tested with, what browsers it has been tested in, and where the unit tests +// reside (so you can test it yourself). +// +// jQuery Versions - 1.2.6, 1.3.2, 1.4.1, 1.4.2 +// Browsers Tested - Internet Explorer 6-8, Firefox 2-4, Chrome 5-6, Safari 3.2-5, +// Opera 9.6-10.60, iPhone 3.1, Android 1.6-2.2, BlackBerry 4.6-5. +// Unit Tests - http://benalman.com/code/projects/jquery-hashchange/unit/ +// +// About: Known issues +// +// While this jQuery hashchange event implementation is quite stable and +// robust, there are a few unfortunate browser bugs surrounding expected +// hashchange event-based behaviors, independent of any JavaScript +// window.onhashchange abstraction. See the following examples for more +// information: +// +// Chrome: Back Button - http://benalman.com/code/projects/jquery-hashchange/examples/bug-chrome-back-button/ +// Firefox: Remote XMLHttpRequest - http://benalman.com/code/projects/jquery-hashchange/examples/bug-firefox-remote-xhr/ +// WebKit: Back Button in an Iframe - http://benalman.com/code/projects/jquery-hashchange/examples/bug-webkit-hash-iframe/ +// Safari: Back Button from a different domain - http://benalman.com/code/projects/jquery-hashchange/examples/bug-safari-back-from-diff-domain/ +// +// Also note that should a browser natively support the window.onhashchange +// event, but not report that it does, the fallback polling loop will be used. +// +// About: Release History +// +// 1.3 - (7/21/2010) Reorganized IE6/7 Iframe code to make it more +// "removable" for mobile-only development. Added IE6/7 document.title +// support. Attempted to make Iframe as hidden as possible by using +// techniques from http://www.paciellogroup.com/blog/?p=604. Added +// support for the "shortcut" format $(window).hashchange( fn ) and +// $(window).hashchange() like jQuery provides for built-in events. +// Renamed jQuery.hashchangeDelay to and +// lowered its default value to 50. Added +// and properties plus document-domain.html +// file to address access denied issues when setting document.domain in +// IE6/7. +// 1.2 - (2/11/2010) Fixed a bug where coming back to a page using this plugin +// from a page on another domain would cause an error in Safari 4. Also, +// IE6/7 Iframe is now inserted after the body (this actually works), +// which prevents the page from scrolling when the event is first bound. +// Event can also now be bound before DOM ready, but it won't be usable +// before then in IE6/7. +// 1.1 - (1/21/2010) Incorporated document.documentMode test to fix IE8 bug +// where browser version is incorrectly reported as 8.0, despite +// inclusion of the X-UA-Compatible IE=EmulateIE7 meta tag. +// 1.0 - (1/9/2010) Initial Release. Broke out the jQuery BBQ event.special +// window.onhashchange functionality into a separate plugin for users +// who want just the basic event & back button support, without all the +// extra awesomeness that BBQ provides. This plugin will be included as +// part of jQuery BBQ, but also be available separately. + +(function($,window,undefined){ + // Reused string. + var str_hashchange = 'hashchange', + + // Method / object references. + doc = document, + fake_onhashchange, + special = $.event.special, + + // Does the browser support window.onhashchange? Note that IE8 running in + // IE7 compatibility mode reports true for 'onhashchange' in window, even + // though the event isn't supported, so also test document.documentMode. + doc_mode = doc.documentMode, + supports_onhashchange = 'on' + str_hashchange in window && ( doc_mode === undefined || doc_mode > 7 ); + + // Get location.hash (or what you'd expect location.hash to be) sans any + // leading #. Thanks for making this necessary, Firefox! + function get_fragment( url ) { + url = url || location.href; + return '#' + url.replace( /^[^#]*#?(.*)$/, '$1' ); + }; + + // Method: jQuery.fn.hashchange + // + // Bind a handler to the window.onhashchange event or trigger all bound + // window.onhashchange event handlers. This behavior is consistent with + // jQuery's built-in event handlers. + // + // Usage: + // + // > jQuery(window).hashchange( [ handler ] ); + // + // Arguments: + // + // handler - (Function) Optional handler to be bound to the hashchange + // event. This is a "shortcut" for the more verbose form: + // jQuery(window).bind( 'hashchange', handler ). If handler is omitted, + // all bound window.onhashchange event handlers will be triggered. This + // is a shortcut for the more verbose + // jQuery(window).trigger( 'hashchange' ). These forms are described in + // the section. + // + // Returns: + // + // (jQuery) The initial jQuery collection of elements. + + // Allow the "shortcut" format $(elem).hashchange( fn ) for binding and + // $(elem).hashchange() for triggering, like jQuery does for built-in events. + $.fn[ str_hashchange ] = function( fn ) { + return fn ? this.bind( str_hashchange, fn ) : this.trigger( str_hashchange ); + }; + + // Property: jQuery.fn.hashchange.delay + // + // The numeric interval (in milliseconds) at which the + // polling loop executes. Defaults to 50. + + // Property: jQuery.fn.hashchange.domain + // + // If you're setting document.domain in your JavaScript, and you want hash + // history to work in IE6/7, not only must this property be set, but you must + // also set document.domain BEFORE jQuery is loaded into the page. This + // property is only applicable if you are supporting IE6/7 (or IE8 operating + // in "IE7 compatibility" mode). + // + // In addition, the property must be set to the + // path of the included "document-domain.html" file, which can be renamed or + // modified if necessary (note that the document.domain specified must be the + // same in both your main JavaScript as well as in this file). + // + // Usage: + // + // jQuery.fn.hashchange.domain = document.domain; + + // Property: jQuery.fn.hashchange.src + // + // If, for some reason, you need to specify an Iframe src file (for example, + // when setting document.domain as in ), you can + // do so using this property. Note that when using this property, history + // won't be recorded in IE6/7 until the Iframe src file loads. This property + // is only applicable if you are supporting IE6/7 (or IE8 operating in "IE7 + // compatibility" mode). + // + // Usage: + // + // jQuery.fn.hashchange.src = 'path/to/file.html'; + + $.fn[ str_hashchange ].delay = 50; + /* + $.fn[ str_hashchange ].domain = null; + $.fn[ str_hashchange ].src = null; + */ + + // Event: hashchange event + // + // Fired when location.hash changes. In browsers that support it, the native + // HTML5 window.onhashchange event is used, otherwise a polling loop is + // initialized, running every milliseconds to + // see if the hash has changed. In IE6/7 (and IE8 operating in "IE7 + // compatibility" mode), a hidden Iframe is created to allow the back button + // and hash-based history to work. + // + // Usage as described in : + // + // > // Bind an event handler. + // > jQuery(window).hashchange( function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).hashchange(); + // + // A more verbose usage that allows for event namespacing: + // + // > // Bind an event handler. + // > jQuery(window).bind( 'hashchange', function(e) { + // > var hash = location.hash; + // > ... + // > }); + // > + // > // Manually trigger the event handler. + // > jQuery(window).trigger( 'hashchange' ); + // + // Additional Notes: + // + // * The polling loop and Iframe are not created until at least one handler + // is actually bound to the 'hashchange' event. + // * If you need the bound handler(s) to execute immediately, in cases where + // a location.hash exists on page load, via bookmark or page refresh for + // example, use jQuery(window).hashchange() or the more verbose + // jQuery(window).trigger( 'hashchange' ). + // * The event can be bound before DOM ready, but since it won't be usable + // before then in IE6/7 (due to the necessary Iframe), recommended usage is + // to bind it inside a DOM ready handler. + + // Override existing $.event.special.hashchange methods (allowing this plugin + // to be defined after jQuery BBQ in BBQ's source code). + special[ str_hashchange ] = $.extend( special[ str_hashchange ], { + + // Called only when the first 'hashchange' event is bound to window. + setup: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to create our own. And we don't want to call this + // until the user binds to the event, just in case they never do, since it + // will create a polling loop and possibly even a hidden Iframe. + $( fake_onhashchange.start ); + }, + + // Called only when the last 'hashchange' event is unbound from window. + teardown: function() { + // If window.onhashchange is supported natively, there's nothing to do.. + if ( supports_onhashchange ) { return false; } + + // Otherwise, we need to stop ours (if possible). + $( fake_onhashchange.stop ); + } + + }); + + // fake_onhashchange does all the work of triggering the window.onhashchange + // event for browsers that don't natively support it, including creating a + // polling loop to watch for hash changes and in IE 6/7 creating a hidden + // Iframe to enable back and forward. + fake_onhashchange = (function(){ + var self = {}, + timeout_id, + + // Remember the initial hash so it doesn't get triggered immediately. + last_hash = get_fragment(), + + fn_retval = function(val){ return val; }, + history_set = fn_retval, + history_get = fn_retval; + + // Start the polling loop. + self.start = function() { + timeout_id || poll(); + }; + + // Stop the polling loop. + self.stop = function() { + timeout_id && clearTimeout( timeout_id ); + timeout_id = undefined; + }; + + // This polling loop checks every $.fn.hashchange.delay milliseconds to see + // if location.hash has changed, and triggers the 'hashchange' event on + // window when necessary. + function poll() { + var hash = get_fragment(), + history_hash = history_get( last_hash ); + + if ( hash !== last_hash ) { + history_set( last_hash = hash, history_hash ); + + $(window).trigger( str_hashchange ); + + } else if ( history_hash !== last_hash ) { + location.href = location.href.replace( /#.*/, '' ) + history_hash; + } + + timeout_id = setTimeout( poll, $.fn[ str_hashchange ].delay ); + }; + + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvv REMOVE IF NOT SUPPORTING IE6/7/8 vvvvvvvvvvvvvvvvvvv + // vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv + $.browser.msie && !supports_onhashchange && (function(){ + // Not only do IE6/7 need the "magical" Iframe treatment, but so does IE8 + // when running in "IE7 compatibility" mode. + + var iframe, + iframe_src; + + // When the event is bound and polling starts in IE 6/7, create a hidden + // Iframe for history handling. + self.start = function(){ + if ( !iframe ) { + iframe_src = $.fn[ str_hashchange ].src; + iframe_src = iframe_src && iframe_src + get_fragment(); + + // Create hidden Iframe. Attempt to make Iframe as hidden as possible + // by using techniques from http://www.paciellogroup.com/blog/?p=604. + iframe = $('