muck-commerce 0.2.6 → 0.2.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (31) hide show
  1. data/VERSION +1 -1
  2. data/lib/active_record/acts/muck_order_transaction.rb +1 -0
  3. data/muck-commerce.gemspec +26 -4
  4. data/test/rails_root/Gemfile +47 -0
  5. data/test/rails_root/config/boot.rb +14 -0
  6. data/test/rails_root/config/environment.rb +0 -21
  7. data/test/rails_root/config/preinitializer.rb +20 -0
  8. data/test/rails_root/public/javascripts/jquery/fg.menu.js +517 -0
  9. data/test/rails_root/public/javascripts/jquery/jquery.easing.js +45 -71
  10. data/test/rails_root/public/javascripts/jquery/jquery.form.js +45 -30
  11. data/test/rails_root/public/javascripts/jquery/jquery.timers.js +138 -0
  12. data/test/rails_root/public/javascripts/muck-src.js +147 -0
  13. data/test/rails_root/public/javascripts/muck.js +7 -89
  14. data/test/rails_root/public/javascripts/muck_admin.js +13 -0
  15. data/test/rails_root/public/stylesheets/admin.css +12 -0
  16. data/test/rails_root/public/stylesheets/fgmenu/fg.menu.css +114 -0
  17. data/test/rails_root/public/stylesheets/flick/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  18. data/test/rails_root/public/stylesheets/flick/images/ui-bg_flat_0_eeeeee_40x100.png +0 -0
  19. data/test/rails_root/public/stylesheets/flick/images/ui-bg_flat_55_ffffff_40x100.png +0 -0
  20. data/test/rails_root/public/stylesheets/flick/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  21. data/test/rails_root/public/stylesheets/flick/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  22. data/test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png +0 -0
  23. data/test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png +0 -0
  24. data/test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png +0 -0
  25. data/test/rails_root/public/stylesheets/flick/images/ui-icons_0073ea_256x240.png +0 -0
  26. data/test/rails_root/public/stylesheets/flick/images/ui-icons_454545_256x240.png +0 -0
  27. data/test/rails_root/public/stylesheets/flick/images/ui-icons_666666_256x240.png +0 -0
  28. data/test/rails_root/public/stylesheets/flick/images/ui-icons_ff0084_256x240.png +0 -0
  29. data/test/rails_root/public/stylesheets/flick/images/ui-icons_ffffff_256x240.png +0 -0
  30. data/test/rails_root/public/stylesheets/flick/jquery-ui-1.8.1.custom.css +486 -0
  31. metadata +41 -4
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.2.6
1
+ 0.2.7
@@ -244,6 +244,7 @@ module ActiveRecord
244
244
 
245
245
  def direct_message
246
246
  return '' if self.params.blank?
247
+ return '' if self.params['direct_response'].blank?
247
248
  self.params['direct_response']['message']
248
249
  end
249
250
 
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{muck-commerce}
8
- s.version = "0.2.6"
8
+ s.version = "0.2.7"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Justin Ball", "Joel Duffin"]
12
- s.date = %q{2010-05-14}
12
+ s.date = %q{2010-06-03}
13
13
  s.description = %q{Add ecommerce functionality to your muck project. This includes integration with Paypal and Authorize.net. This gem uses active merchant and so adding other gateways should be simple.}
14
14
  s.email = %q{justin@tatemae.com}
15
15
  s.extra_rdoc_files = [
@@ -159,6 +159,7 @@ Gem::Specification.new do |s|
159
159
  "rails/init.rb",
160
160
  "test/rails_root/.gitignore",
161
161
  "test/rails_root/.rake_tasks",
162
+ "test/rails_root/Gemfile",
162
163
  "test/rails_root/Rakefile",
163
164
  "test/rails_root/app/controllers/application_controller.rb",
164
165
  "test/rails_root/app/controllers/default_controller.rb",
@@ -191,6 +192,7 @@ Gem::Specification.new do |s|
191
192
  "test/rails_root/config/initializers/mime_types.rb",
192
193
  "test/rails_root/config/initializers/requires.rb",
193
194
  "test/rails_root/config/initializers/session_store.rb",
195
+ "test/rails_root/config/preinitializer.rb",
194
196
  "test/rails_root/config/routes.rb",
195
197
  "test/rails_root/db/migrate/20090320174818_create_muck_permissions_and_roles.rb",
196
198
  "test/rails_root/db/migrate/20090327231918_create_users.rb",
@@ -639,6 +641,7 @@ Gem::Specification.new do |s|
639
641
  "test/rails_root/public/javascripts/effects.js",
640
642
  "test/rails_root/public/javascripts/fancyzoom.min.js",
641
643
  "test/rails_root/public/javascripts/jquery/colorpicker.js",
644
+ "test/rails_root/public/javascripts/jquery/fg.menu.js",
642
645
  "test/rails_root/public/javascripts/jquery/jquery-ui.js",
643
646
  "test/rails_root/public/javascripts/jquery/jquery.autocomplete.js.readme",
644
647
  "test/rails_root/public/javascripts/jquery/jquery.autocomplete.min.js",
@@ -653,12 +656,15 @@ Gem::Specification.new do |s|
653
656
  "test/rails_root/public/javascripts/jquery/jquery.queryString.js",
654
657
  "test/rails_root/public/javascripts/jquery/jquery.swapimage.js",
655
658
  "test/rails_root/public/javascripts/jquery/jquery.swapimage.min.js",
659
+ "test/rails_root/public/javascripts/jquery/jquery.timers.js",
656
660
  "test/rails_root/public/javascripts/jquery/jquery.tips.js",
657
661
  "test/rails_root/public/javascripts/jquery/jrails.js",
658
662
  "test/rails_root/public/javascripts/muck-countries.js",
663
+ "test/rails_root/public/javascripts/muck-src.js",
659
664
  "test/rails_root/public/javascripts/muck-users.js",
660
665
  "test/rails_root/public/javascripts/muck.js",
661
666
  "test/rails_root/public/javascripts/muck_activities.js",
667
+ "test/rails_root/public/javascripts/muck_admin.js",
662
668
  "test/rails_root/public/javascripts/muck_time/en.js",
663
669
  "test/rails_root/public/javascripts/prototype.js",
664
670
  "test/rails_root/public/javascripts/scriptaculous.js",
@@ -700,6 +706,21 @@ Gem::Specification.new do |s|
700
706
  "test/rails_root/public/stylesheets/blueprint/src/print.css",
701
707
  "test/rails_root/public/stylesheets/blueprint/src/reset.css",
702
708
  "test/rails_root/public/stylesheets/blueprint/src/typography.css",
709
+ "test/rails_root/public/stylesheets/fgmenu/fg.menu.css",
710
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_flat_0_aaaaaa_40x100.png",
711
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_flat_0_eeeeee_40x100.png",
712
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_flat_55_ffffff_40x100.png",
713
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_flat_75_ffffff_40x100.png",
714
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_glass_65_ffffff_1x400.png",
715
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_100_f6f6f6_1x100.png",
716
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_25_0073ea_1x100.png",
717
+ "test/rails_root/public/stylesheets/flick/images/ui-bg_highlight-soft_50_dddddd_1x100.png",
718
+ "test/rails_root/public/stylesheets/flick/images/ui-icons_0073ea_256x240.png",
719
+ "test/rails_root/public/stylesheets/flick/images/ui-icons_454545_256x240.png",
720
+ "test/rails_root/public/stylesheets/flick/images/ui-icons_666666_256x240.png",
721
+ "test/rails_root/public/stylesheets/flick/images/ui-icons_ff0084_256x240.png",
722
+ "test/rails_root/public/stylesheets/flick/images/ui-icons_ffffff_256x240.png",
723
+ "test/rails_root/public/stylesheets/flick/jquery-ui-1.8.1.custom.css",
703
724
  "test/rails_root/public/stylesheets/jquery/cupertino/images/ui-bg_diagonals-small_0_aaaaaa_40x40.png",
704
725
  "test/rails_root/public/stylesheets/jquery/cupertino/images/ui-bg_diagonals-thick_15_444444_40x40.png",
705
726
  "test/rails_root/public/stylesheets/jquery/cupertino/images/ui-bg_glass_100_f0f0f0_1x400.png",
@@ -859,7 +880,7 @@ Gem::Specification.new do |s|
859
880
  s.homepage = %q{http://github.com/tatemae/muck-commerce}
860
881
  s.rdoc_options = ["--charset=UTF-8"]
861
882
  s.require_paths = ["lib"]
862
- s.rubygems_version = %q{1.3.6}
883
+ s.rubygems_version = %q{1.3.7}
863
884
  s.summary = %q{Add ecommerce capabilities to your muck project}
864
885
  s.test_files = [
865
886
  "test/rails_root/app/controllers/application_controller.rb",
@@ -890,6 +911,7 @@ Gem::Specification.new do |s|
890
911
  "test/rails_root/config/initializers/mime_types.rb",
891
912
  "test/rails_root/config/initializers/requires.rb",
892
913
  "test/rails_root/config/initializers/session_store.rb",
914
+ "test/rails_root/config/preinitializer.rb",
893
915
  "test/rails_root/config/routes.rb",
894
916
  "test/rails_root/db/migrate/20090320174818_create_muck_permissions_and_roles.rb",
895
917
  "test/rails_root/db/migrate/20090327231918_create_users.rb",
@@ -968,7 +990,7 @@ Gem::Specification.new do |s|
968
990
  current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
969
991
  s.specification_version = 3
970
992
 
971
- if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
993
+ if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
972
994
  s.add_runtime_dependency(%q<activemerchant>, [">= 0"])
973
995
  s.add_runtime_dependency(%q<aasm>, [">= 0"])
974
996
  s.add_runtime_dependency(%q<muck-engine>, [">= 0"])
@@ -0,0 +1,47 @@
1
+ source :gemcutter
2
+
3
+ gem "rails", "2.3.5"
4
+ gem 'mysql'
5
+ gem "authlogic", '2.1.3'
6
+ gem "searchlogic", '2.4.19'
7
+ gem 'will_paginate', '2.3.14'
8
+ gem 'bcrypt-ruby', '2.1.2', :require => 'bcrypt'
9
+ gem 'paperclip', '2.3.1.1'
10
+ gem 'activemerchant', '1.4.2', :require => 'active_merchant'
11
+ gem 'aasm', '2.1.5'
12
+ gem 'geokit', '1.5.0'
13
+ gem 'sanitize', '1.2.1'
14
+ gem 'overlord', '0.1.22'
15
+ gem 'muck-engine', '0.4.27', :require => 'muck_engine'
16
+ gem 'muck-users', '0.3.13', :require => 'muck_users'
17
+ gem 'muck-profiles', '0.2.1', :require => 'muck_profiles'
18
+ gem 'muck-commerce', :require => 'muck_commerce', :path => File.join(File.dirname(__FILE__), *%w(.. .. ..))
19
+
20
+ group :development do
21
+ gem 'ruby-debug'
22
+ # gem 'muck-engine', :require => 'muck_engine', :path => "~/projects/muck-engine"
23
+ # gem 'muck-users', :require => 'muck_users', :path => "~/projects/muck-users"
24
+ # gem 'muck-profiles', :require => 'muck_profiles', :path => "~/projects/muck-profiles"
25
+ end
26
+
27
+ group :test do
28
+ # bundler requires these gems while running tests
29
+ gem 'ruby-debug'
30
+ gem 'mocha', '>= 0.9.8'
31
+ gem 'redgreen'
32
+ gem 'factory_girl'
33
+ gem 'shoulda'
34
+ gem 'treetop', '>=1.2.4'
35
+ gem 'term-ansicolor', '>=1.0.3', :require => 'term/ansicolor'
36
+ gem 'cucumber', '>=0.1.13', :require => 'cucumber'
37
+ gem 'polyglot', '>=0.2.4'
38
+ gem "rcov", '>=0.8.1.2.0'
39
+ gem "webrat", '>=0.4.4'
40
+ gem 'redgreen'
41
+ # gem 'rspec', '>=1.1.12', :require_as => 'spec'
42
+ # gem 'rspec-rails', '>=1.1.12', :require_as => 'spec/rails'
43
+ # only required if you want to use selenium for testing
44
+ #gem 'selenium-client', :require_as => 'selenium/client'
45
+ #gem 'database_cleaner'
46
+ end
47
+
@@ -105,5 +105,19 @@ module Rails
105
105
  end
106
106
  end
107
107
 
108
+ class Rails::Boot
109
+ def run
110
+ load_initializer
111
+
112
+ Rails::Initializer.class_eval do
113
+ def load_gems
114
+ @bundler_loaded ||= Bundler.require :default, Rails.env
115
+ end
116
+ end
117
+
118
+ Rails::Initializer.run(:set_load_path)
119
+ end
120
+ end
121
+
108
122
  # All that for this:
109
123
  Rails.boot!
@@ -7,29 +7,8 @@ require 'ostruct'
7
7
  require 'yaml'
8
8
  ::GlobalConfig = OpenStruct.new(YAML.load_file("#{RAILS_ROOT}/config/global_config.yml")[RAILS_ENV])
9
9
 
10
- class TestGemLocator < Rails::Plugin::Locator
11
- def plugins
12
- Rails::Plugin.new(File.join(File.dirname(__FILE__), *%w(.. .. ..)))
13
- end
14
- end
15
-
16
10
  Rails::Initializer.run do |config|
17
11
  config.time_zone = 'UTC'
18
- config.gem 'authlogic'
19
- config.gem 'searchlogic'
20
- config.gem 'will_paginate'
21
- config.gem 'bcrypt-ruby', :lib => 'bcrypt'
22
- config.gem 'paperclip'
23
- config.gem 'activemerchant', :lib => 'active_merchant'
24
- config.gem 'aasm'
25
- config.gem 'geokit'
26
- config.gem 'sanitize'
27
- config.gem 'overlord'
28
- config.gem 'muck-engine', :lib => 'muck_engine'
29
- config.gem 'muck-users', :lib => 'muck_users'
30
- config.gem 'muck-profiles', :lib => 'muck_profiles'
31
- config.plugin_locators << TestGemLocator
32
-
33
12
  config.after_initialize do
34
13
  MuckCommerce::Configure.gateway
35
14
  end
@@ -0,0 +1,20 @@
1
+ begin
2
+ require "rubygems"
3
+ require "bundler"
4
+ rescue LoadError
5
+ raise "Could not load the bundler gem. Install it with `gem install bundler`."
6
+ end
7
+
8
+ if Gem::Version.new(Bundler::VERSION) <= Gem::Version.new("0.9.24")
9
+ raise RuntimeError, "Your bundler version is too old." +
10
+ "Run `gem install bundler` to upgrade."
11
+ end
12
+
13
+ begin
14
+ # Set up load paths for all bundled gems
15
+ ENV["BUNDLE_GEMFILE"] = File.expand_path("../../Gemfile", __FILE__)
16
+ Bundler.setup
17
+ rescue Bundler::GemNotFound
18
+ raise RuntimeError, "Bundler couldn't find some gems." +
19
+ "Did you run `bundle install`?"
20
+ end
@@ -0,0 +1,517 @@
1
+ /*--------------------------------------------------------------------
2
+ Scripts for creating and manipulating custom menus based on standard <ul> markup
3
+ Version: 3.0, 03.31.2009
4
+
5
+ By: Maggie Costello Wachs (maggie@filamentgroup.com) and Scott Jehl (scott@filamentgroup.com)
6
+ http://www.filamentgroup.com
7
+ * reference articles: http://www.filamentgroup.com/lab/jquery_ipod_style_drilldown_menu/
8
+
9
+ Copyright (c) 2009 Filament Group
10
+ Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
11
+ --------------------------------------------------------------------*/
12
+
13
+
14
+ var allUIMenus = [];
15
+
16
+ $.fn.menu = function(options){
17
+ var caller = this;
18
+ var options = options;
19
+ var m = new Menu(caller, options);
20
+ allUIMenus.push(m);
21
+
22
+ $(this)
23
+ .mousedown(function(){
24
+ if (!m.menuOpen) { m.showLoading(); };
25
+ })
26
+ .click(function(){
27
+ if (m.menuOpen == false) { m.showMenu(); }
28
+ else { m.kill(); };
29
+ return false;
30
+ });
31
+ };
32
+
33
+ function Menu(caller, options){
34
+ var menu = this;
35
+ var caller = $(caller);
36
+ var container = $('<div class="fg-menu-container ui-widget ui-widget-content ui-corner-all">'+options.content+'</div>');
37
+
38
+ this.menuOpen = false;
39
+ this.menuExists = false;
40
+
41
+ var options = jQuery.extend({
42
+ content: null,
43
+ width: 180, // width of menu container, must be set or passed in to calculate widths of child menus
44
+ maxHeight: 180, // max height of menu (if a drilldown: height does not include breadcrumb)
45
+ positionOpts: {
46
+ posX: 'left',
47
+ posY: 'bottom',
48
+ offsetX: 0,
49
+ offsetY: 0,
50
+ directionH: 'right',
51
+ directionV: 'down',
52
+ detectH: true, // do horizontal collision detection
53
+ detectV: true, // do vertical collision detection
54
+ linkToFront: false
55
+ },
56
+ showSpeed: 200, // show/hide speed in milliseconds
57
+ callerOnState: 'ui-state-active', // class to change the appearance of the link/button when the menu is showing
58
+ loadingState: 'ui-state-loading', // class added to the link/button while the menu is created
59
+ linkHover: 'ui-state-hover', // class for menu option hover state
60
+ linkHoverSecondary: 'li-hover', // alternate class, may be used for multi-level menus
61
+ // ----- multi-level menu defaults -----
62
+ crossSpeed: 200, // cross-fade speed for multi-level menus
63
+ crumbDefaultText: 'Choose an option:',
64
+ backLink: true, // in the ipod-style menu: instead of breadcrumbs, show only a 'back' link
65
+ backLinkText: 'Back',
66
+ flyOut: false, // multi-level menus are ipod-style by default; this parameter overrides to make a flyout instead
67
+ flyOutOnState: 'ui-state-default',
68
+ nextMenuLink: 'ui-icon-triangle-1-e', // class to style the link (specifically, a span within the link) used in the multi-level menu to show the next level
69
+ topLinkText: 'All',
70
+ nextCrumbLink: 'ui-icon-carat-1-e'
71
+ }, options);
72
+
73
+ var killAllMenus = function(){
74
+ $.each(allUIMenus, function(i){
75
+ if (allUIMenus[i].menuOpen) { allUIMenus[i].kill(); };
76
+ });
77
+ };
78
+
79
+ this.kill = function(){
80
+ caller
81
+ .removeClass(options.loadingState)
82
+ .removeClass('fg-menu-open')
83
+ .removeClass(options.callerOnState);
84
+ container.find('li').removeClass(options.linkHoverSecondary).find('a').removeClass(options.linkHover);
85
+ if (options.flyOutOnState) { container.find('li a').removeClass(options.flyOutOnState); };
86
+ if (options.callerOnState) { caller.removeClass(options.callerOnState); };
87
+ if (container.is('.fg-menu-ipod')) { menu.resetDrilldownMenu(); };
88
+ if (container.is('.fg-menu-flyout')) { menu.resetFlyoutMenu(); };
89
+ container.parent().hide();
90
+ menu.menuOpen = false;
91
+ $(document).unbind('click', killAllMenus);
92
+ $(document).unbind('keydown');
93
+ };
94
+
95
+ this.showLoading = function(){
96
+ caller.addClass(options.loadingState);
97
+ };
98
+
99
+ this.showMenu = function(){
100
+ killAllMenus();
101
+ if (!menu.menuExists) { menu.create() };
102
+ caller
103
+ .addClass('fg-menu-open')
104
+ .addClass(options.callerOnState);
105
+ container.parent().show().click(function(){ menu.kill(); return false; });
106
+ container.hide().slideDown(options.showSpeed).find('.fg-menu:eq(0)');
107
+ menu.menuOpen = true;
108
+ caller.removeClass(options.loadingState);
109
+ $(document).click(killAllMenus);
110
+
111
+ // assign key events
112
+ $(document).keydown(function(event){
113
+ var e;
114
+ if (event.which !="") { e = event.which; }
115
+ else if (event.charCode != "") { e = event.charCode; }
116
+ else if (event.keyCode != "") { e = event.keyCode; }
117
+
118
+ var menuType = ($(event.target).parents('div').is('.fg-menu-flyout')) ? 'flyout' : 'ipod' ;
119
+
120
+ switch(e) {
121
+ case 37: // left arrow
122
+ if (menuType == 'flyout') {
123
+ $(event.target).trigger('mouseout');
124
+ if ($('.'+options.flyOutOnState).size() > 0) { $('.'+options.flyOutOnState).trigger('mouseover'); };
125
+ };
126
+
127
+ if (menuType == 'ipod') {
128
+ $(event.target).trigger('mouseout');
129
+ if ($('.fg-menu-footer').find('a').size() > 0) { $('.fg-menu-footer').find('a').trigger('click'); };
130
+ if ($('.fg-menu-header').find('a').size() > 0) { $('.fg-menu-current-crumb').prev().find('a').trigger('click'); };
131
+ if ($('.fg-menu-current').prev().is('.fg-menu-indicator')) {
132
+ $('.fg-menu-current').prev().trigger('mouseover');
133
+ };
134
+ };
135
+ return false;
136
+ break;
137
+
138
+ case 38: // up arrow
139
+ if ($(event.target).is('.' + options.linkHover)) {
140
+ var prevLink = $(event.target).parent().prev().find('a:eq(0)');
141
+ if (prevLink.size() > 0) {
142
+ $(event.target).trigger('mouseout');
143
+ prevLink.trigger('mouseover');
144
+ };
145
+ }
146
+ else { container.find('a:eq(0)').trigger('mouseover'); }
147
+ return false;
148
+ break;
149
+
150
+ case 39: // right arrow
151
+ if ($(event.target).is('.fg-menu-indicator')) {
152
+ if (menuType == 'flyout') {
153
+ $(event.target).next().find('a:eq(0)').trigger('mouseover');
154
+ }
155
+ else if (menuType == 'ipod') {
156
+ $(event.target).trigger('click');
157
+ setTimeout(function(){
158
+ $(event.target).next().find('a:eq(0)').trigger('mouseover');
159
+ }, options.crossSpeed);
160
+ };
161
+ };
162
+ return false;
163
+ break;
164
+
165
+ case 40: // down arrow
166
+ if ($(event.target).is('.' + options.linkHover)) {
167
+ var nextLink = $(event.target).parent().next().find('a:eq(0)');
168
+ if (nextLink.size() > 0) {
169
+ $(event.target).trigger('mouseout');
170
+ nextLink.trigger('mouseover');
171
+ };
172
+ }
173
+ else { container.find('a:eq(0)').trigger('mouseover'); }
174
+ return false;
175
+ break;
176
+
177
+ case 27: // escape
178
+ killAllMenus();
179
+ break;
180
+
181
+ case 13: // enter
182
+ if ($(event.target).is('.fg-menu-indicator') && menuType == 'ipod') {
183
+ $(event.target).trigger('click');
184
+ setTimeout(function(){
185
+ $(event.target).next().find('a:eq(0)').trigger('mouseover');
186
+ }, options.crossSpeed);
187
+ };
188
+ break;
189
+ };
190
+ });
191
+ };
192
+
193
+ this.create = function(){
194
+ container.css({ width: options.width }).appendTo('body').find('ul:first').not('.fg-menu-breadcrumb').addClass('fg-menu');
195
+ container.find('ul, li a').addClass('ui-corner-all');
196
+
197
+ // aria roles & attributes
198
+ container.find('ul').attr('role', 'menu').eq(0).attr('aria-activedescendant','active-menuitem').attr('aria-labelledby', caller.attr('id'));
199
+ container.find('li').attr('role', 'menuitem');
200
+ container.find('li:has(ul)').attr('aria-haspopup', 'true').find('ul').attr('aria-expanded', 'false');
201
+ container.find('a').attr('tabindex', '-1');
202
+
203
+ // when there are multiple levels of hierarchy, create flyout or drilldown menu
204
+ if (container.find('ul').size() > 1) {
205
+ if (options.flyOut) { menu.flyout(container, options); }
206
+ else { menu.drilldown(container, options); }
207
+ }
208
+ else {
209
+ container.find('a').click(function(){
210
+ menu.chooseItem(this);
211
+ return false;
212
+ });
213
+ };
214
+
215
+ if (options.linkHover) {
216
+ var allLinks = container.find('.fg-menu li a');
217
+ allLinks.hover(
218
+ function(){
219
+ var menuitem = $(this);
220
+ $('.'+options.linkHover).removeClass(options.linkHover).blur().parent().removeAttr('id');
221
+ $(this).addClass(options.linkHover).focus().parent().attr('id','active-menuitem');
222
+ },
223
+ function(){
224
+ $(this).removeClass(options.linkHover).blur().parent().removeAttr('id');
225
+ }
226
+ );
227
+ };
228
+
229
+ if (options.linkHoverSecondary) {
230
+ container.find('.fg-menu li').hover(
231
+ function(){
232
+ $(this).siblings('li').removeClass(options.linkHoverSecondary);
233
+ if (options.flyOutOnState) { $(this).siblings('li').find('a').removeClass(options.flyOutOnState); }
234
+ $(this).addClass(options.linkHoverSecondary);
235
+ },
236
+ function(){ $(this).removeClass(options.linkHoverSecondary); }
237
+ );
238
+ };
239
+
240
+ menu.setPosition(container, caller, options);
241
+ menu.menuExists = true;
242
+ };
243
+
244
+ this.chooseItem = function(item){
245
+ // edit this for your own custom function/callback:
246
+ if ($(item).attr('alt') == "pop")
247
+ {
248
+ var d = jQuery('<div class="dialog"><div style="width:32px; margin:20px auto 0px auto"><img src="/images/loading-spinner.gif"/></div></div>').appendTo("body");
249
+ d.dialog({ modal: true, autoOpen: true, width: 'auto', title: $(item).attr('title') });
250
+ d.load($(item).attr('href'), '', function(){
251
+ d.dialog("open");
252
+ apply_ajax_forms();
253
+ });
254
+ }
255
+ else
256
+ {
257
+ location.href = $(item).attr('href');
258
+ }
259
+ menu.kill();
260
+ };
261
+ };
262
+
263
+ Menu.prototype.flyout = function(container, options) {
264
+ var menu = this;
265
+
266
+ this.resetFlyoutMenu = function(){
267
+ var allLists = container.find('ul ul');
268
+ allLists.removeClass('ui-widget-content').hide();
269
+ };
270
+
271
+ container.addClass('fg-menu-flyout').find('li:has(ul)').each(function(){
272
+ var linkWidth = container.width();
273
+ var showTimer, hideTimer;
274
+ var allSubLists = $(this).find('ul');
275
+
276
+ allSubLists.css({ left: linkWidth, width: linkWidth }).hide();
277
+
278
+ $(this).find('a:eq(0)').addClass('fg-menu-indicator').html('<span>' + $(this).find('a:eq(0)').text() + '</span><span class="ui-icon '+options.nextMenuLink+'"></span>').hover(
279
+ function(){
280
+ clearTimeout(hideTimer);
281
+ var subList = $(this).next();
282
+ if (!fitVertical(subList, $(this).offset().top)) { subList.css({ top: 'auto', bottom: 0 }); };
283
+ if (!fitHorizontal(subList, $(this).offset().left + 100)) { subList.css({ left: 'auto', right: linkWidth, 'z-index': 999 }); };
284
+ showTimer = setTimeout(function(){
285
+ subList.addClass('ui-widget-content').show(options.showSpeed).attr('aria-expanded', 'true');
286
+ }, 300);
287
+ },
288
+ function(){
289
+ clearTimeout(showTimer);
290
+ var subList = $(this).next();
291
+ hideTimer = setTimeout(function(){
292
+ subList.removeClass('ui-widget-content').hide(options.showSpeed).attr('aria-expanded', 'false');
293
+ }, 400);
294
+ }
295
+ );
296
+
297
+ $(this).find('ul a').hover(
298
+ function(){
299
+ clearTimeout(hideTimer);
300
+ if ($(this).parents('ul').prev().is('a.fg-menu-indicator')) {
301
+ $(this).parents('ul').prev().addClass(options.flyOutOnState);
302
+ }
303
+ },
304
+ function(){
305
+ hideTimer = setTimeout(function(){
306
+ allSubLists.hide(options.showSpeed);
307
+ container.find(options.flyOutOnState).removeClass(options.flyOutOnState);
308
+ }, 500);
309
+ }
310
+ );
311
+ });
312
+
313
+ container.find('a').click(function(){
314
+ menu.chooseItem(this);
315
+ alert("FOO");
316
+ return false;
317
+ });
318
+ };
319
+
320
+
321
+ /* Menu.prototype.setPosition parameters (defaults noted with *):
322
+ referrer = the link (or other element) used to show the overlaid object
323
+ settings = can override the defaults:
324
+ - posX/Y: where the top left corner of the object should be positioned in relation to its referrer.
325
+ X: left*, center, right
326
+ Y: top, center, bottom*
327
+ - offsetX/Y: the number of pixels to be offset from the x or y position. Can be a positive or negative number.
328
+ - directionH/V: where the entire menu should appear in relation to its referrer.
329
+ Horizontal: left*, right
330
+ Vertical: up, down*
331
+ - detectH/V: detect the viewport horizontally / vertically
332
+ - linkToFront: copy the menu link and place it on top of the menu (visual effect to make it look like it overlaps the object) */
333
+
334
+ Menu.prototype.setPosition = function(widget, caller, options) {
335
+ var el = widget;
336
+ var referrer = caller;
337
+ var dims = {
338
+ refX: referrer.offset().left,
339
+ refY: referrer.offset().top,
340
+ refW: referrer.getTotalWidth(),
341
+ refH: referrer.getTotalHeight()
342
+ };
343
+ var options = options;
344
+ var xVal, yVal;
345
+
346
+ var helper = $('<div class="positionHelper"></div>');
347
+ helper.css({ position: 'absolute', left: dims.refX, top: dims.refY, width: dims.refW, height: dims.refH });
348
+ el.wrap(helper);
349
+
350
+ // get X pos
351
+ switch(options.positionOpts.posX) {
352
+ case 'left': xVal = 0;
353
+ break;
354
+ case 'center': xVal = dims.refW / 2;
355
+ break;
356
+ case 'right': xVal = dims.refW;
357
+ break;
358
+ };
359
+
360
+ // get Y pos
361
+ switch(options.positionOpts.posY) {
362
+ case 'top': yVal = 0;
363
+ break;
364
+ case 'center': yVal = dims.refH / 2;
365
+ break;
366
+ case 'bottom': yVal = dims.refH;
367
+ break;
368
+ };
369
+
370
+ // add the offsets (zero by default)
371
+ xVal += options.positionOpts.offsetX;
372
+ yVal += options.positionOpts.offsetY;
373
+
374
+ // position the object vertically
375
+ if (options.positionOpts.directionV == 'up') {
376
+ el.css({ top: 'auto', bottom: yVal });
377
+ if (options.positionOpts.detectV && !fitVertical(el)) {
378
+ el.css({ bottom: 'auto', top: yVal });
379
+ }
380
+ }
381
+ else {
382
+ el.css({ bottom: 'auto', top: yVal });
383
+ if (options.positionOpts.detectV && !fitVertical(el)) {
384
+ el.css({ top: 'auto', bottom: yVal });
385
+ }
386
+ };
387
+
388
+ // and horizontally
389
+ if (options.positionOpts.directionH == 'left') {
390
+ el.css({ left: 'auto', right: xVal });
391
+ if (options.positionOpts.detectH && !fitHorizontal(el)) {
392
+ el.css({ right: 'auto', left: xVal });
393
+ }
394
+ }
395
+ else {
396
+ el.css({ right: 'auto', left: xVal });
397
+ if (options.positionOpts.detectH && !fitHorizontal(el)) {
398
+ el.css({ left: 'auto', right: xVal });
399
+ }
400
+ };
401
+
402
+ // if specified, clone the referring element and position it so that it appears on top of the menu
403
+ if (options.positionOpts.linkToFront) {
404
+ referrer.clone().addClass('linkClone').css({
405
+ position: 'absolute',
406
+ top: 0,
407
+ right: 'auto',
408
+ bottom: 'auto',
409
+ left: 0,
410
+ width: referrer.width(),
411
+ height: referrer.height()
412
+ }).insertAfter(el);
413
+ };
414
+ };
415
+
416
+
417
+ /* Utilities to sort and find viewport dimensions */
418
+
419
+ function sortBigToSmall(a, b) { return b - a; };
420
+
421
+ jQuery.fn.getTotalWidth = function(){
422
+ return $(this).width() + parseInt($(this).css('paddingRight')) + parseInt($(this).css('paddingLeft')) + parseInt($(this).css('borderRightWidth')) + parseInt($(this).css('borderLeftWidth'));
423
+ };
424
+
425
+ jQuery.fn.getTotalHeight = function(){
426
+ return $(this).height() + parseInt($(this).css('paddingTop')) + parseInt($(this).css('paddingBottom')) + parseInt($(this).css('borderTopWidth')) + parseInt($(this).css('borderBottomWidth'));
427
+ };
428
+
429
+ function getScrollTop(){
430
+ return self.pageYOffset || document.documentElement.scrollTop || document.body.scrollTop;
431
+ };
432
+
433
+ function getScrollLeft(){
434
+ return self.pageXOffset || document.documentElement.scrollLeft || document.body.scrollLeft;
435
+ };
436
+
437
+ function getWindowHeight(){
438
+ var de = document.documentElement;
439
+ return self.innerHeight || (de && de.clientHeight) || document.body.clientHeight;
440
+ };
441
+
442
+ function getWindowWidth(){
443
+ var de = document.documentElement;
444
+ return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
445
+ };
446
+
447
+ /* Utilities to test whether an element will fit in the viewport
448
+ Parameters:
449
+ el = element to position, required
450
+ leftOffset / topOffset = optional parameter if the offset cannot be calculated (i.e., if the object is in the DOM but is set to display: 'none') */
451
+
452
+ function fitHorizontal(el, leftOffset){
453
+ var leftVal = parseInt(leftOffset) || $(el).offset().left;
454
+ return (leftVal + $(el).width() <= getWindowWidth() + getScrollLeft() && leftVal - getScrollLeft() >= 0);
455
+ };
456
+
457
+ function fitVertical(el, topOffset){
458
+ var topVal = parseInt(topOffset) || $(el).offset().top;
459
+ return (topVal + $(el).height() <= getWindowHeight() + getScrollTop() && topVal - getScrollTop() >= 0);
460
+ };
461
+
462
+ /*--------------------------------------------------------------------
463
+ * javascript method: "pxToEm"
464
+ * by:
465
+ Scott Jehl (scott@filamentgroup.com)
466
+ Maggie Wachs (maggie@filamentgroup.com)
467
+ http://www.filamentgroup.com
468
+ *
469
+ * Copyright (c) 2008 Filament Group
470
+ * Dual licensed under the MIT (filamentgroup.com/examples/mit-license.txt) and GPL (filamentgroup.com/examples/gpl-license.txt) licenses.
471
+ *
472
+ * Description: Extends the native Number and String objects with pxToEm method. pxToEm converts a pixel value to ems depending on inherited font size.
473
+ * Article: http://www.filamentgroup.com/lab/retaining_scalable_interfaces_with_pixel_to_em_conversion/
474
+ * Demo: http://www.filamentgroup.com/examples/pxToEm/
475
+ *
476
+ * Options:
477
+ scope: string or jQuery selector for font-size scoping
478
+ reverse: Boolean, true reverses the conversion to em-px
479
+ * Dependencies: jQuery library
480
+ * Usage Example: myPixelValue.pxToEm(); or myPixelValue.pxToEm({'scope':'#navigation', reverse: true});
481
+ *
482
+ * Version: 2.0, 08.01.2008
483
+ * Changelog:
484
+ * 08.02.2007 initial Version 1.0
485
+ * 08.01.2008 - fixed font-size calculation for IE
486
+ --------------------------------------------------------------------*/
487
+
488
+ Number.prototype.pxToEm = String.prototype.pxToEm = function(settings){
489
+ //set defaults
490
+ settings = jQuery.extend({
491
+ scope: 'body',
492
+ reverse: false
493
+ }, settings);
494
+
495
+ var pxVal = (this == '') ? 0 : parseFloat(this);
496
+ var scopeVal;
497
+ var getWindowWidth = function(){
498
+ var de = document.documentElement;
499
+ return self.innerWidth || (de && de.clientWidth) || document.body.clientWidth;
500
+ };
501
+
502
+ /* When a percentage-based font-size is set on the body, IE returns that percent of the window width as the font-size.
503
+ For example, if the body font-size is 62.5% and the window width is 1000px, IE will return 625px as the font-size.
504
+ When this happens, we calculate the correct body font-size (%) and multiply it by 16 (the standard browser font size)
505
+ to get an accurate em value. */
506
+
507
+ if (settings.scope == 'body' && $.browser.msie && (parseFloat($('body').css('font-size')) / getWindowWidth()).toFixed(1) > 0.0) {
508
+ var calcFontSize = function(){
509
+ return (parseFloat($('body').css('font-size'))/getWindowWidth()).toFixed(3) * 16;
510
+ };
511
+ scopeVal = calcFontSize();
512
+ }
513
+ else { scopeVal = parseFloat(jQuery(settings.scope).css("font-size")); };
514
+
515
+ var result = (settings.reverse == true) ? (pxVal * scopeVal).toFixed(2) + 'px' : (pxVal / scopeVal).toFixed(2) + 'em';
516
+ return result;
517
+ };