ama_layout 1.1.13

Sign up to get free protection for your applications and to get access to all the features.
Files changed (89) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/.rspec +3 -0
  4. data/.simplecov +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +146 -0
  8. data/Rakefile +2 -0
  9. data/ama_layout.gemspec +33 -0
  10. data/app/assets/images/AMA-Logo.png +0 -0
  11. data/app/assets/images/alberta-blur.jpg +0 -0
  12. data/app/assets/images/footer-racetrack-big.png +0 -0
  13. data/app/assets/javascripts/ama_layout/ama_layout_namespace.js.coffee +1 -0
  14. data/app/assets/javascripts/ama_layout/desktop/drop_down.js.coffee +46 -0
  15. data/app/assets/javascripts/ama_layout/desktop/foundation-namespace.coffee +2 -0
  16. data/app/assets/javascripts/ama_layout/desktop/foundation-ready.js.coffee +2 -0
  17. data/app/assets/javascripts/ama_layout/desktop/header_menu.coffee +3 -0
  18. data/app/assets/javascripts/ama_layout/desktop/index.js +9 -0
  19. data/app/assets/javascripts/ama_layout/desktop/ready.js.coffee +3 -0
  20. data/app/assets/javascripts/ama_layout/desktop/sticky-footer.coffee +16 -0
  21. data/app/assets/javascripts/ama_layout/desktop/toggle_menu.js.coffee +8 -0
  22. data/app/assets/javascripts/ama_layout/mobile/index.js +4 -0
  23. data/app/assets/javascripts/ama_layout/mobile/mobile_menu.js.coffee +11 -0
  24. data/app/assets/javascripts/ama_layout/mobile/ready.js.coffee +2 -0
  25. data/app/assets/javascripts/ama_layout/mobile/tablesaw.stackonly.js +277 -0
  26. data/app/assets/stylesheets/ama_layout/application.scss +10 -0
  27. data/app/assets/stylesheets/ama_layout/foundation_and_overrides.scss +1486 -0
  28. data/app/assets/stylesheets/ama_layout/layout/base-styles.scss +60 -0
  29. data/app/assets/stylesheets/ama_layout/layout/helper-classes.scss +342 -0
  30. data/app/assets/stylesheets/ama_layout/layout/index.scss +3 -0
  31. data/app/assets/stylesheets/ama_layout/layout/variables.scss +32 -0
  32. data/app/assets/stylesheets/ama_layout/layout_components/accordions.scss +24 -0
  33. data/app/assets/stylesheets/ama_layout/layout_components/blue-boxes.scss +32 -0
  34. data/app/assets/stylesheets/ama_layout/layout_components/error-messages.scss +9 -0
  35. data/app/assets/stylesheets/ama_layout/layout_components/error-page.scss +25 -0
  36. data/app/assets/stylesheets/ama_layout/layout_components/forms.scss +189 -0
  37. data/app/assets/stylesheets/ama_layout/layout_components/index.scss +8 -0
  38. data/app/assets/stylesheets/ama_layout/layout_components/responsive-table.scss +175 -0
  39. data/app/assets/stylesheets/ama_layout/layout_components/sidebar.scss +170 -0
  40. data/app/assets/stylesheets/ama_layout/layout_components/siteheader.scss +14 -0
  41. data/app/assets/stylesheets/ama_layout/media_queries/index.scss +3 -0
  42. data/app/assets/stylesheets/ama_layout/media_queries/mobile-and-tablet.scss +14 -0
  43. data/app/assets/stylesheets/ama_layout/media_queries/mobile.scss +69 -0
  44. data/app/assets/stylesheets/ama_layout/media_queries/tablet.scss +13 -0
  45. data/app/assets/stylesheets/ama_layout/old-ie.scss +74 -0
  46. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons-block.eot +0 -0
  47. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons-block.scss +50 -0
  48. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons-block.svg +982 -0
  49. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons-block.ttf +0 -0
  50. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons-block.woff +0 -0
  51. data/app/assets/stylesheets/ama_layout/webfonts/ss-symbolicons.js +84 -0
  52. data/app/helpers/ama_layout_content_helper.rb +56 -0
  53. data/app/helpers/ama_layout_path_helper.rb +69 -0
  54. data/app/views/ama_layout/_alert.html.erb +3 -0
  55. data/app/views/ama_layout/_applogo.html.erb +3 -0
  56. data/app/views/ama_layout/_custom_nav_links.html.erb +0 -0
  57. data/app/views/ama_layout/_custom_sidebar.html.erb +1 -0
  58. data/app/views/ama_layout/_footer.html.erb +2 -0
  59. data/app/views/ama_layout/_main_nav_item.html.erb +7 -0
  60. data/app/views/ama_layout/_main_top_nav_item.html.erb +5 -0
  61. data/app/views/ama_layout/_notice.html.erb +5 -0
  62. data/app/views/ama_layout/_notices.html.erb +2 -0
  63. data/app/views/ama_layout/_sidebar.html.erb +11 -0
  64. data/app/views/ama_layout/_siteheader.html.erb +32 -0
  65. data/app/views/ama_layout/_sub_nav.html.erb +3 -0
  66. data/app/views/ama_layout/_sub_nav_item.html.erb +3 -0
  67. data/app/views/ama_layout/_top_nav.html.erb +12 -0
  68. data/app/views/ama_layout/_top_sub_nav.html.erb +3 -0
  69. data/app/views/ama_layout/_top_sub_nav_item.html.erb +4 -0
  70. data/lib/ama_layout.rb +19 -0
  71. data/lib/ama_layout/decorators/moneris_decorator.rb +9 -0
  72. data/lib/ama_layout/decorators/navigation_decorator.rb +24 -0
  73. data/lib/ama_layout/decorators/navigation_item_decorator.rb +30 -0
  74. data/lib/ama_layout/moneris.rb +12 -0
  75. data/lib/ama_layout/moneris/textbox.txt +61 -0
  76. data/lib/ama_layout/navigation.rb +33 -0
  77. data/lib/ama_layout/navigation.yml +66 -0
  78. data/lib/ama_layout/navigation_item.rb +21 -0
  79. data/lib/ama_layout/version.rb +3 -0
  80. data/spec/helpers/ama_layout_content_helper_spec.rb +131 -0
  81. data/spec/helpers/ama_layout_path_helper_spec.rb +117 -0
  82. data/spec/internal/config/database.yml +3 -0
  83. data/spec/internal/config/routes.rb +3 -0
  84. data/spec/internal/db/combustion_test.sqlite +0 -0
  85. data/spec/internal/db/schema.rb +3 -0
  86. data/spec/internal/log/.gitignore +1 -0
  87. data/spec/internal/public/favicon.ico +0 -0
  88. data/spec/spec_helper.rb +25 -0
  89. metadata +325 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b9c545737508074e9dcfac192c57af2bddc9d2d5
4
+ data.tar.gz: 94f5ca81e3a6546c64365b8554c9eba3c9c559bd
5
+ SHA512:
6
+ metadata.gz: 8c0f1f114ee2124fc76e8426087191e3b614d83a654be3f0ef26ea7679db64e117af6d42eb677a858183bdc9fed108766187b40f5fa9f5c27161009714650571
7
+ data.tar.gz: aa3b3ddb702e9ce87726ef39f2af1517aaee2ced9a22206f3ee150f4f3b8edc1f889a9aade01b1844e09ec573edd301c427f68306558107a6fae33c972b1e727
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --color
2
+ --require spec_helper
3
+ --format documentation
@@ -0,0 +1,5 @@
1
+ SimpleCov.start do
2
+ SimpleCov.minimum_coverage 100.0
3
+ add_filter "/spec"
4
+ add_filter "/vendor"
5
+ end
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in ama_layout.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michael van den Beuken
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,146 @@
1
+ # AmaLayout
2
+
3
+ The AmaLayout gem is used to add a standard layout and style to .ama.ab.ca sites.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'ama_layout'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install ama_layout
20
+
21
+ ## Usage
22
+
23
+ ### Configuration
24
+
25
+ Ensure that the app responds to:
26
+
27
+ Rails.configuration.gatekeeper_site
28
+
29
+ Rails.configuration.youraccount_site
30
+
31
+ Rails.configuration.insurance_site
32
+
33
+ Rails.configuration.membership_site
34
+
35
+ Rails.configuration.driveredonline_site
36
+
37
+ Rails.configuration.amaabca_site
38
+
39
+ Rails.configuration.forms_amaabca_site
40
+
41
+
42
+ ### Navigation
43
+
44
+ Navigation for each application has been built in custom made Navigation class and set as a hash to ama_layout gem:
45
+
46
+ Example:
47
+
48
+ class Navigation
49
+ include ActiveModel::Model
50
+
51
+ attr_accessor :current_user
52
+
53
+ def initialize args={}
54
+ self.current_user = args.fetch(:current_user)
55
+ end
56
+
57
+ def navigation
58
+ return nil unless current_user
59
+ return navigation_items["member-in-renewal"] if current_user.profile.in_billing?
60
+ return navigation_items["member"] if current_user.member?
61
+ navigation_items["non-member"]
62
+ end
63
+
64
+ private
65
+ def navigation_items
66
+ YAML.load(ERB.new(File.read("#{Rails.root}/config/locales/navigation.yml")).result)
67
+ end
68
+ end
69
+
70
+ Custom Navigation yaml file used to set all navigation:
71
+
72
+ member:
73
+ "Your Account Dashboard":
74
+ subtitle: "Member Exclusive Services"
75
+ alt: "Back to my dashboard"
76
+ link: "<%= Rails.configuration.youraccount_site %>/dashboard"
77
+ "Online Profile":
78
+ subtitle: "Email / Password Change"
79
+ link: "<%= Rails.configuration.gatekeeper_site %>/user/edit"
80
+ "Billing":
81
+ subtitle: "Statements / Reward Options"
82
+ link: "<%= Rails.configuration.youraccount_site %>/billing"
83
+ .
84
+ .
85
+ .
86
+ non-member:
87
+ "Joins":
88
+ alt: "Back to my dashboard"
89
+ link: <%= Rails.configuration.membership_site %>
90
+ "New Driver Online Program":
91
+ link: "<%= Rails.configuration.driveredonline_site %>/login"
92
+ target: "_blank"
93
+ member-in-renewal:
94
+ "Your Account Dashboard":
95
+ subtitle: "Member Exclusive Services"
96
+ alt: "Back to my dashboard"
97
+ link: "<%= Rails.configuration.youraccount_site %>/dashboard"
98
+ "Renew":
99
+ link: "<%= Rails.configuration.youraccount_site %>/renew"
100
+ "Help":
101
+ link: "<%= Rails.configuration.youraccount_site %>/help"
102
+ "Contact Us":
103
+ link: "<%= Rails.configuration.amaabca_site %>/membership/contact-us--centre-locations-hours-and-contact-information"
104
+ target: "_blank"
105
+
106
+
107
+ ### Layout
108
+
109
+ The following layout example will give you:
110
+ a header with appropriate navigation if applicable,
111
+ side navigation if applicable and footer
112
+
113
+ <body class="<%= controller_name %>" id="top">
114
+ <%= render partial: "ama_layout/siteheader", locals: { navigation: Navigation.new(current_user: current_user).navigation } %>
115
+ <%= render "ama_layout/notices" %>
116
+ <div class="row wrapper">
117
+ <%= render partial: "ama_layout/custom_sidebar", locals: { navigation: Navigation.new(current_user: current_user).navigation } %>
118
+ <%= yield %>
119
+ </div>
120
+ <%= render "ama_layout/footer" %>
121
+ </body>
122
+
123
+ ### Stylesheets
124
+
125
+ Add the following to your application.scss
126
+
127
+ @import "ama_layout/application";
128
+
129
+ ### Javascript
130
+
131
+ Add the following to your application.js
132
+
133
+ //= require ama_layout/desktop
134
+
135
+ ### Mobile Layouts
136
+
137
+ There is no need for you to set any specific code, values,... for mobile views.
138
+
139
+ ## Contributing
140
+
141
+ 1. Fork it ( https://github.com/amaabca/ama_layout/fork )
142
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
143
+ 3. Create rspec tests to cover your feature (100% coverage required)
144
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
145
+ 5. Push to the branch (`git push origin my-new-feature`)
146
+ 6. Create a new Pull Request
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,33 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'ama_layout/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "ama_layout"
8
+ spec.version = AmaLayout::VERSION
9
+ spec.authors = ["Michael van den Beuken", "Ruben Estevez", "Jordan Babe", "Mathieu Gilbert", "Ryan Jones", "Darko Dosenovic", "Jonathan Weyermann", "Adam Melnyk", "Kayt Campbell", "Kathleen Robertson"]
10
+ spec.email = ["michael.beuken@gmail.com", "ruben.a.estevez@gmail.com", "jorbabe@gmail.com", "mathieu.gilbert@ama.ab.ca", "ryan.michael.jones@gmail.com", "darko.dosenovic@ama.ab.ca", "jonathan.weyermann@ama.ab.ca" "adam.melnyk@ama.ab.ca", "kayt.campbell@ama.ab.ca", "kathleen.robertson@ama.ab.ca"]
11
+ spec.summary = %q{.ama.ab.ca site layouts}
12
+ spec.description = %q{.ama.ab.ca site layouts}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "foundation-rails", "5.4.5.0"
22
+ spec.add_dependency "rails", ">= 4"
23
+ spec.add_dependency "sass-rails"
24
+ spec.add_dependency "font-awesome-sass"
25
+ spec.add_dependency "draper"
26
+ spec.add_development_dependency "bundler", "~> 1.7"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+ spec.add_development_dependency "rspec-rails"
29
+ spec.add_development_dependency "simplecov"
30
+ spec.add_development_dependency "pry"
31
+ spec.add_development_dependency "combustion"
32
+ spec.add_development_dependency "sqlite3"
33
+ end
@@ -0,0 +1 @@
1
+ @AMALayout = window.AMALayout ? {}
@@ -0,0 +1,46 @@
1
+ class AMALayout.DropDown
2
+ constructor: (@menuDropDown, @pointerUp, @dropdowncontainer, @dropdownClose, @html) ->
3
+ @setupDropDown()
4
+
5
+ hideMenu = (element) ->
6
+ element.animate {opacity:0}, 0,
7
+ -> element.removeClass("show").addClass("hide")
8
+
9
+ showMenu = (element, heightoffset) ->
10
+ element.toggleClass("show hide").css top: heightoffset
11
+ element.animate {opacity:1}, 0
12
+
13
+ setupDropDown: ->
14
+ ishovered = false
15
+ @menuDropDown.mouseenter =>
16
+ if !ishovered
17
+ heightoffset = @dropdowncontainer.outerHeight() + 10
18
+ datavalue = @menuDropDown.attr("data-dropdown")
19
+ @menuDropDown.toggleClass("open closed")
20
+ showMenu $(datavalue), heightoffset
21
+ ishovered = true
22
+
23
+ @html.mouseleave =>
24
+ datavalue = @menuDropDown.attr("data-dropdown")
25
+ @menuDropDown.removeClass("open").addClass("closed")
26
+ hideMenu $(datavalue)
27
+ ishovered = false
28
+
29
+ $(document).bind 'mouseup', (event) =>
30
+ container = $(".menu-profile, .dropdown-link")
31
+ if ishovered and container.has(event.target).length is 0
32
+ datavalue = @menuDropDown.attr("data-dropdown")
33
+ @menuDropDown.removeClass("open").addClass("closed")
34
+ hideMenu $(datavalue)
35
+ ishovered = false
36
+
37
+ @dropdownClose.bind 'mouseup', (event) =>
38
+ if ishovered
39
+ datavalue = @menuDropDown.attr("data-dropdown")
40
+ @menuDropDown.removeClass("open").addClass("closed")
41
+ hideMenu $(datavalue)
42
+ ishovered = false
43
+
44
+ color = @pointerUp.parent().css("background-color")
45
+ @pointerUp.css
46
+ "border-bottom-color" : color
@@ -0,0 +1,2 @@
1
+ Foundation.set_namespace = ->
2
+ this.global.namespace = []
@@ -0,0 +1,2 @@
1
+ $ ->
2
+ $(document).foundation()
@@ -0,0 +1,3 @@
1
+ $(document).ready ->
2
+ $('.menu-link').click ->
3
+ $('#menu').toggleClass('active')
@@ -0,0 +1,9 @@
1
+ //= require ../ama_layout_namespace
2
+ //= require ./drop_down
3
+ //= require ./toggle_menu
4
+ //= require ./header_menu
5
+ //= require ./ready
6
+ //= require foundation
7
+ //= require ./foundation-ready
8
+ //= require ./sticky-footer
9
+ //= require ./foundation-namespace
@@ -0,0 +1,3 @@
1
+ $ ->
2
+ new AMALayout.DropDown($("a[data-dropdown='#dropdown']"),$(".pointer-up"),$(".dropdown-container"),$(".dropdown-close"),$("html"))
3
+ new AMALayout.ToggleMenu($(".menu-toggle"),$(".menu-profile-tablet"),$(".menu-www-tablet"))
@@ -0,0 +1,16 @@
1
+ $(window).bind "load", ->
2
+ adjustFooter = ->
3
+ $("footer").css({ 'margin-top': calcHeight() + 'px' })
4
+
5
+ calcHeight = ->
6
+ footer = $("footer")
7
+ position = footer.position()
8
+ footer_top = if position is undefined then 0 else position.top
9
+ height = $(window).height() - footer_top - footer.height()
10
+ Math.max(height, 50)
11
+
12
+ adjustFooter()
13
+ $("a.asset-link.clearfix").click ->
14
+ setTimeout ->
15
+ adjustFooter()
16
+ , 1
@@ -0,0 +1,8 @@
1
+ class AMALayout.ToggleMenu
2
+ constructor: (@menuToggle, @menuProfile, @menuWWW) ->
3
+ @showmenu()
4
+
5
+ showmenu: ->
6
+ @menuToggle.click =>
7
+ $(@menuProfile).toggle()
8
+ $(@menuWWW).toggle()
@@ -0,0 +1,4 @@
1
+ //= require ../ama_layout_namespace
2
+ //= require ./mobile_menu
3
+ //= require ./tablesaw.stackonly.js
4
+ //= require ./ready
@@ -0,0 +1,11 @@
1
+ class AMALayout.MobileMenu
2
+ constructor: (@menuToggle) ->
3
+ @mobileMenu()
4
+
5
+ mobileMenu: ->
6
+ @menuToggle.click =>
7
+ @menuToggle.parent().toggleClass("hide show")
8
+ if @menuToggle.parent().hasClass("show")
9
+ @menuToggle.parent().find(".ss-icon").html("close")
10
+ else
11
+ @menuToggle.parent().find(".ss-icon").html("list")
@@ -0,0 +1,2 @@
1
+ $ ->
2
+ new AMALayout.MobileMenu($(".menu-toggle"))
@@ -0,0 +1,277 @@
1
+ /*! Tablesaw - v1.0.4 - 2015-02-19
2
+ * https://github.com/filamentgroup/tablesaw
3
+ * Copyright (c) 2015 Filament Group; Licensed MIT */
4
+ ;(function( $ ) {
5
+ var div = document.createElement('div'),
6
+ all = div.getElementsByTagName('i'),
7
+ $doc = $( document.documentElement );
8
+
9
+ div.innerHTML = '<!--[if lte IE 8]><i></i><![endif]-->';
10
+ if( all[ 0 ] ) {
11
+ $doc.addClass( 'ie-lte8' );
12
+ }
13
+
14
+ // Cut the mustard
15
+ if( !( 'querySelector' in document ) ||
16
+ ( window.blackberry && !window.WebKitPoint ) ||
17
+ window.operamini ) {
18
+ return;
19
+ } else {
20
+ $doc.addClass( 'tablesaw-enhanced' );
21
+
22
+ // DOM-ready auto-init of plugins.
23
+ // Many plugins bind to an "enhance" event to init themselves on dom ready, or when new markup is inserted into the DOM
24
+ $( function(){
25
+ $( document ).trigger( "enhance.tablesaw" );
26
+ });
27
+ }
28
+
29
+ })( jQuery );
30
+ /*
31
+ * tablesaw: A set of plugins for responsive tables
32
+ * Stack and Column Toggle tables
33
+ * Copyright (c) 2013 Filament Group, Inc.
34
+ * MIT License
35
+ */
36
+
37
+ if( typeof Tablesaw === "undefined" ) {
38
+ Tablesaw = {
39
+ i18n: {
40
+ modes: [ 'Stack', 'Swipe', 'Toggle' ],
41
+ columns: 'Col<span class=\"a11y-sm\">umn</span>s',
42
+ columnBtnText: 'Columns',
43
+ columnsDialogError: 'No eligible columns.',
44
+ sort: 'Sort'
45
+ }
46
+ };
47
+ }
48
+ if( !Tablesaw.config ) {
49
+ Tablesaw.config = {};
50
+ }
51
+
52
+ ;(function( $ ) {
53
+ var pluginName = "table",
54
+ classes = {
55
+ toolbar: "tablesaw-bar"
56
+ },
57
+ events = {
58
+ create: "tablesawcreate",
59
+ destroy: "tablesawdestroy",
60
+ refresh: "tablesawrefresh"
61
+ },
62
+ defaultMode = "stack",
63
+ initSelector = "table[data-tablesaw-mode],table[data-tablesaw-sortable]";
64
+
65
+ var Table = function( element ) {
66
+ if( !element ) {
67
+ throw new Error( "Tablesaw requires an element." );
68
+ }
69
+
70
+ this.table = element;
71
+ this.$table = $( element );
72
+
73
+ this.mode = this.$table.attr( "data-tablesaw-mode" ) || defaultMode;
74
+
75
+ this.init();
76
+ };
77
+
78
+ Table.prototype.init = function() {
79
+ // assign an id if there is none
80
+ if ( !this.$table.attr( "id" ) ) {
81
+ this.$table.attr( "id", pluginName + "-" + Math.round( Math.random() * 10000 ) );
82
+ }
83
+
84
+ this.createToolbar();
85
+
86
+ var colstart = this._initCells();
87
+
88
+ this.$table.trigger( events.create, [ this, colstart ] );
89
+ };
90
+
91
+ Table.prototype._initCells = function() {
92
+ var colstart,
93
+ thrs = this.table.querySelectorAll( "thead tr" ),
94
+ self = this;
95
+
96
+ $( thrs ).each( function(){
97
+ var coltally = 0;
98
+
99
+ $( this ).children().each( function(){
100
+ var span = parseInt( this.getAttribute( "colspan" ), 10 ),
101
+ sel = ":nth-child(" + ( coltally + 1 ) + ")";
102
+
103
+ colstart = coltally + 1;
104
+
105
+ if( span ){
106
+ for( var k = 0; k < span - 1; k++ ){
107
+ coltally++;
108
+ sel += ", :nth-child(" + ( coltally + 1 ) + ")";
109
+ }
110
+ }
111
+
112
+ // Store "cells" data on header as a reference to all cells in the same column as this TH
113
+ this.cells = self.$table.find("tr").not( $( thrs ).eq( 0 ) ).not( this ).children( sel );
114
+ coltally++;
115
+ });
116
+ });
117
+
118
+ return colstart;
119
+ };
120
+
121
+ Table.prototype.refresh = function() {
122
+ this._initCells();
123
+
124
+ this.$table.trigger( events.refresh );
125
+ };
126
+
127
+ Table.prototype.createToolbar = function() {
128
+ // Insert the toolbar
129
+ // TODO move this into a separate component
130
+ var $toolbar = this.$table.prev( '.' + classes.toolbar );
131
+ if( !$toolbar.length ) {
132
+ $toolbar = $( '<div>' )
133
+ .addClass( classes.toolbar )
134
+ .insertBefore( this.$table );
135
+ }
136
+ this.$toolbar = $toolbar;
137
+
138
+ if( this.mode ) {
139
+ this.$toolbar.addClass( 'mode-' + this.mode );
140
+ }
141
+ };
142
+
143
+ Table.prototype.destroy = function() {
144
+ // Don’t remove the toolbar. Some of the table features are not yet destroy-friendly.
145
+ this.$table.prev( '.' + classes.toolbar ).each(function() {
146
+ this.className = this.className.replace( /\bmode\-\w*\b/gi, '' );
147
+ });
148
+
149
+ var tableId = this.$table.attr( 'id' );
150
+ $( document ).unbind( "." + tableId );
151
+ $( window ).unbind( "." + tableId );
152
+
153
+ // other plugins
154
+ this.$table.trigger( events.destroy, [ this ] );
155
+
156
+ this.$table.removeAttr( 'data-tablesaw-mode' );
157
+
158
+ this.$table.removeData( pluginName );
159
+ };
160
+
161
+ // Collection method.
162
+ $.fn[ pluginName ] = function() {
163
+ return this.each( function() {
164
+ var $t = $( this );
165
+
166
+ if( $t.data( pluginName ) ){
167
+ return;
168
+ }
169
+
170
+ var table = new Table( this );
171
+ $t.data( pluginName, table );
172
+ });
173
+ };
174
+
175
+ $( document ).on( "enhance.tablesaw", function( e ) {
176
+ $( e.target ).find( initSelector )[ pluginName ]();
177
+ });
178
+
179
+ }( jQuery ));
180
+
181
+ ;(function( win, $, undefined ){
182
+
183
+ var classes = {
184
+ stackTable: 'tablesaw-stack',
185
+ cellLabels: 'tablesaw-cell-label',
186
+ cellContentLabels: 'tablesaw-cell-content'
187
+ };
188
+
189
+ var data = {
190
+ obj: 'tablesaw-stack'
191
+ };
192
+
193
+ var attrs = {
194
+ labelless: 'data-tablesaw-no-labels',
195
+ hideempty: 'data-tablesaw-hide-empty'
196
+ };
197
+
198
+ var Stack = function( element ) {
199
+
200
+ this.$table = $( element );
201
+
202
+ this.labelless = this.$table.is( '[' + attrs.labelless + ']' );
203
+ this.hideempty = this.$table.is( '[' + attrs.hideempty + ']' );
204
+
205
+ if( !this.labelless ) {
206
+ // allHeaders references headers, plus all THs in the thead, which may include several rows, or not
207
+ this.allHeaders = this.$table.find( "th" );
208
+ }
209
+
210
+ this.$table.data( data.obj, this );
211
+ };
212
+
213
+ Stack.prototype.init = function( colstart ) {
214
+ this.$table.addClass( classes.stackTable );
215
+
216
+ if( this.labelless ) {
217
+ return;
218
+ }
219
+
220
+ // get headers in reverse order so that top-level headers are appended last
221
+ var reverseHeaders = $( this.allHeaders );
222
+ var hideempty = this.hideempty;
223
+
224
+ // create the hide/show toggles
225
+ reverseHeaders.each(function(){
226
+ var $t = $( this ),
227
+ $cells = $( this.cells ).filter(function() {
228
+ return !$( this ).parent().is( "[" + attrs.labelless + "]" ) && ( !hideempty || !$( this ).is( ":empty" ) );
229
+ }),
230
+ hierarchyClass = $cells.not( this ).filter( "thead th" ).length && " tablesaw-cell-label-top",
231
+ // TODO reduce coupling with sortable
232
+ $sortableButton = $t.find( ".tablesaw-sortable-btn" ),
233
+ html = $sortableButton.length ? $sortableButton.html() : $t.html();
234
+
235
+ if( html !== "" ){
236
+ if( hierarchyClass ){
237
+ var iteration = parseInt( $( this ).attr( "colspan" ), 10 ),
238
+ filter = "";
239
+
240
+ if( iteration ){
241
+ filter = "td:nth-child("+ iteration +"n + " + ( colstart ) +")";
242
+ }
243
+ $cells.filter( filter ).prepend( "<b class='" + classes.cellLabels + hierarchyClass + "'>" + html + "</b>" );
244
+ } else {
245
+ $cells.wrapInner( "<span class='" + classes.cellContentLabels + "'></span>" );
246
+ $cells.prepend( "<b class='" + classes.cellLabels + "'>" + html + "</b>" );
247
+ }
248
+ }
249
+ });
250
+ };
251
+
252
+ Stack.prototype.destroy = function() {
253
+ this.$table.removeClass( classes.stackTable );
254
+ this.$table.find( '.' + classes.cellLabels ).remove();
255
+ this.$table.find( '.' + classes.cellContentLabels ).each(function() {
256
+ $( this ).replaceWith( this.childNodes );
257
+ });
258
+ };
259
+
260
+ // on tablecreate, init
261
+ $( document ).on( "tablesawcreate", function( e, Tablesaw, colstart ){
262
+ if( Tablesaw.mode === 'stack' ){
263
+ var table = new Stack( Tablesaw.table );
264
+ table.init( colstart );
265
+ }
266
+
267
+ } );
268
+
269
+ $( document ).on( "tablesawdestroy", function( e, Tablesaw ){
270
+
271
+ if( Tablesaw.mode === 'stack' ){
272
+ $( Tablesaw.table ).data( data.obj ).destroy();
273
+ }
274
+
275
+ } );
276
+
277
+ }( this, jQuery ));