ama_layout 1.1.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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 ));