makandra-navy 0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Rakefile +1 -0
- data/assets/sass/_navy.sass +141 -0
- data/lib/navy.rb +12 -0
- data/lib/navy/description.rb +21 -0
- data/lib/navy/navigation.rb +17 -0
- data/lib/navy/parser.rb +18 -0
- data/lib/navy/renderer.rb +97 -0
- data/lib/navy/renderer_helper.rb +10 -0
- data/lib/navy/section.rb +21 -0
- data/lib/navy/section_activator.rb +48 -0
- data/lib/navy/section_container.rb +21 -0
- data/lib/navy/section_parser.rb +37 -0
- data/lib/navy/version.rb +3 -0
- data/navy.gemspec +24 -0
- metadata +95 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
@@ -0,0 +1,141 @@
|
|
1
|
+
!navy_tab_navigation_height = 28px
|
2
|
+
!navy_tab_spacing = 6px
|
3
|
+
!navy_bubble_navigation_height = 24px
|
4
|
+
|
5
|
+
!navy_color_tab_text = #fff
|
6
|
+
!navy_color_tab_active = #fff
|
7
|
+
!navy_color_tab_active_text = #224
|
8
|
+
!navy_color_dropdown_text = #224
|
9
|
+
|
10
|
+
!navy_color_bubble_text = #334
|
11
|
+
!navy_color_bubble_text_hover = #428000
|
12
|
+
!navy_color_bubble_active = #64A21D
|
13
|
+
!navy_color_bubble_active_text = white
|
14
|
+
|
15
|
+
!navy_color_tab_text_hover = darken(!navy_color_tab_text, 20%)
|
16
|
+
!navy_color_dropdown_text_hover = !navy_color_dropdown_text + #333
|
17
|
+
|
18
|
+
|
19
|
+
.navy-tab-navigation
|
20
|
+
height = $navy_tab_navigation_height + 4px
|
21
|
+
&.navy-hidden, .navy-hidden
|
22
|
+
display: none
|
23
|
+
.navy-layouted-sections
|
24
|
+
float: left
|
25
|
+
height: $navy_tab_navigation_height + 4px
|
26
|
+
overflow: hidden
|
27
|
+
a
|
28
|
+
float: left
|
29
|
+
padding: 0 10px
|
30
|
+
height: $navy_tab_navigation_height
|
31
|
+
line-height: $navy_tab_navigation_height
|
32
|
+
font-weight: bold
|
33
|
+
text-decoration: none
|
34
|
+
color: !navy_color_tab_text
|
35
|
+
background-color: rgba(0, 0, 0, 0.35)
|
36
|
+
.navy-section-expander
|
37
|
+
display: block
|
38
|
+
float: right
|
39
|
+
height: $navy_tab_navigation_height
|
40
|
+
padding: 0 10px
|
41
|
+
margin-right: -10px
|
42
|
+
&:hover
|
43
|
+
color: !navy_color_tab_text_hover
|
44
|
+
&.navy-current
|
45
|
+
.navy-section-expander
|
46
|
+
display: none
|
47
|
+
&.navy-expanded
|
48
|
+
padding-bottom: 4px
|
49
|
+
.navy-layouted-sections a
|
50
|
+
margin-right: $navy_tab_spacing
|
51
|
+
.navy-layouted-sections a, .navy-dropdown-expander
|
52
|
+
&.navy-active
|
53
|
+
color: $navy_color_tab_active_text
|
54
|
+
background-color: $navy_color_tab_active
|
55
|
+
.navy-section-expander:hover
|
56
|
+
color: $navy_color_tab_active_text
|
57
|
+
margin-top: 4px
|
58
|
+
&:last-child
|
59
|
+
padding-right: 10px
|
60
|
+
&:hover
|
61
|
+
margin-top: 0
|
62
|
+
padding-bottom: 4px
|
63
|
+
.navy-dropdown-expander
|
64
|
+
position: relative
|
65
|
+
z-index: 100
|
66
|
+
.navy-navigation-dropdown
|
67
|
+
visibility: hidden
|
68
|
+
float: left
|
69
|
+
position: relative
|
70
|
+
.navy-dropdown-sections
|
71
|
+
border: 1px solid rgba(0, 0, 0, 0.35)
|
72
|
+
border-top: none
|
73
|
+
padding: 6px
|
74
|
+
position: absolute
|
75
|
+
top: $navy_tab_navigation_height + 4px
|
76
|
+
right: 0
|
77
|
+
z-index: 99
|
78
|
+
background: white
|
79
|
+
.navy-section-expander
|
80
|
+
display: none
|
81
|
+
.navy-section
|
82
|
+
line-height: 24px
|
83
|
+
height: 24px
|
84
|
+
background: white
|
85
|
+
color: $navy_color_dropdown_text
|
86
|
+
margin-top: 0
|
87
|
+
float: none
|
88
|
+
display: block
|
89
|
+
&:hover
|
90
|
+
color: $navy_color_dropdown_text_hover
|
91
|
+
.navy-end
|
92
|
+
clear: both
|
93
|
+
height: 0
|
94
|
+
display: block
|
95
|
+
|
96
|
+
|
97
|
+
.navy-bubble-navigation
|
98
|
+
&.navy-hidden, .navy-hidden
|
99
|
+
display: none
|
100
|
+
a
|
101
|
+
height: $navy_bubble_navigation_height
|
102
|
+
line-height: $navy_bubble_navigation_height
|
103
|
+
color: $navy_color_bubble_text
|
104
|
+
float: left
|
105
|
+
margin-right: 10px
|
106
|
+
&:hover
|
107
|
+
color = $navy_color_bubble_text_hover
|
108
|
+
&.navy-current
|
109
|
+
padding: 0 7px
|
110
|
+
background-color: $navy_color_bubble_active
|
111
|
+
color: $navy_color_bubble_active_text
|
112
|
+
.navy-inner-navigation-bar
|
113
|
+
padding: 6px 0 5px 0
|
114
|
+
.navy-end
|
115
|
+
display: block
|
116
|
+
clear: both
|
117
|
+
height: 0
|
118
|
+
|
119
|
+
|
120
|
+
.navy-tab-navigation-extra
|
121
|
+
a
|
122
|
+
+gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.5))
|
123
|
+
+round_top_corners(2px)
|
124
|
+
&.navy-expanded
|
125
|
+
a
|
126
|
+
+round_corners(5px)
|
127
|
+
.navy-layouted-sections a, .navy-dropdown-expander
|
128
|
+
&.navy-active
|
129
|
+
+gradient($navy_color_tab_active, $navy_color_tab_active)
|
130
|
+
+box_shadow(0 0 10px $navy_color_tab_active)
|
131
|
+
.navy-navigation-dropdown
|
132
|
+
.navy-dropdown-sections
|
133
|
+
border: none
|
134
|
+
+box_shadow(0 0 8px rgba(0, 0, 0, 0.3))
|
135
|
+
|
136
|
+
|
137
|
+
.navy-bubble-navigation-extra
|
138
|
+
a
|
139
|
+
&.navy-current
|
140
|
+
+gradient(lighten($navy_color_bubble_active, 5%), darken($navy_color_bubble_active, 5%))
|
141
|
+
+round_corners(5px)
|
data/lib/navy.rb
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'navy/section_container'
|
2
|
+
require 'navy/description'
|
3
|
+
require 'navy/navigation'
|
4
|
+
require 'navy/parser'
|
5
|
+
require 'navy/renderer'
|
6
|
+
require 'navy/section'
|
7
|
+
require 'navy/section_activator'
|
8
|
+
require 'navy/section_parser'
|
9
|
+
require 'navy/renderer_helper'
|
10
|
+
|
11
|
+
ActionView::Base.send :include, Navy::RendererHelper
|
12
|
+
ActionController::Base.send :include, Navy::SectionActivator
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Navy
|
2
|
+
module Description
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
|
10
|
+
def navigation(name, &children)
|
11
|
+
navigation = Navy::Navigation.new(name, &children)
|
12
|
+
singleton_class.send(:define_method, name) do |*args|
|
13
|
+
navigation.block_args = args
|
14
|
+
navigation
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
data/lib/navy/parser.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
module Navy
|
2
|
+
module Parser
|
3
|
+
|
4
|
+
def navigation(name, &children)
|
5
|
+
navigation = Navy::Navigation.new(name, &children)
|
6
|
+
singleton_class.send(:define_method, name) { navigation }
|
7
|
+
end
|
8
|
+
|
9
|
+
def section(name, label, url)
|
10
|
+
sections << Navy::Section.new()
|
11
|
+
end
|
12
|
+
|
13
|
+
def sections
|
14
|
+
@sections ||= []
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
module Navy
|
2
|
+
class Renderer
|
3
|
+
|
4
|
+
include ActionView::Helpers::TagHelper
|
5
|
+
include ActionView::Helpers::UrlHelper
|
6
|
+
|
7
|
+
def initialize(context, options = {})
|
8
|
+
@context = context
|
9
|
+
@html_to_append = []
|
10
|
+
@id_counter = 0
|
11
|
+
@collapse = options[:collapse]
|
12
|
+
end
|
13
|
+
|
14
|
+
def next_id
|
15
|
+
@id_counter += 1
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
def render_navigation(navigation)
|
20
|
+
div_tag(:id => "navy-#{navigation.name}-navigation", :class => 'navy-navigation') do
|
21
|
+
html = ''.html_safe
|
22
|
+
html << render_section_container(navigation, 1)
|
23
|
+
@html_to_append.each do |append|
|
24
|
+
html << append
|
25
|
+
end
|
26
|
+
html
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def append(html)
|
34
|
+
@html_to_append << html
|
35
|
+
end
|
36
|
+
|
37
|
+
def render_section_containers
|
38
|
+
html = ''.html_safe
|
39
|
+
while @section_containers_to_render.any?
|
40
|
+
html << render_section_container(*@section_containers_to_render.shift)
|
41
|
+
end
|
42
|
+
html
|
43
|
+
end
|
44
|
+
|
45
|
+
def render_section_container(section_container, level, parent_id = nil, parent_url = nil)
|
46
|
+
sections = section_container.sections(@context)
|
47
|
+
section_classes = ["navy-level-#{level}", "navy-navigation-bar"]
|
48
|
+
section_classes << (section_container.active? ? 'navy-current' : 'navy-hidden')
|
49
|
+
unless sections.size == 0 or (sections.size == 1 and sections.first.url == parent_url)
|
50
|
+
div_tag(:class => section_classes.join(' '), :"data-navy-opened-by" => parent_id, :"data-navy-navigation-level" => level) do
|
51
|
+
div_tag(:class => 'navy-inner-navigation-bar') do
|
52
|
+
html = ''.html_safe
|
53
|
+
html << div_tag(:class => "navy-layouted-sections") do
|
54
|
+
inner_html = ''.html_safe
|
55
|
+
sections.each do |section|
|
56
|
+
inner_html << render_section(section, level, parent_id)
|
57
|
+
end
|
58
|
+
inner_html
|
59
|
+
end
|
60
|
+
if level == 1 and !Rails.env.test? and !Rails.env.cucumber? and @collapse
|
61
|
+
html << div_tag(:class => "navy-navigation-dropdown") do
|
62
|
+
inner_html = ''.html_safe
|
63
|
+
inner_html << '<a class="navy-dropdown-expander" href="#">▾</a>'.html_safe
|
64
|
+
inner_html << '<div class="navy-dropdown-sections navy-hidden"></div>'.html_safe
|
65
|
+
inner_html
|
66
|
+
end
|
67
|
+
end
|
68
|
+
html << '<span class="navy-end"></span>'.html_safe
|
69
|
+
html
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def render_section(section, level, parent_id)
|
76
|
+
id = next_id
|
77
|
+
link_classes = ['navy-section']
|
78
|
+
link_classes << 'navy-current navy-active' if section.active?
|
79
|
+
label = ''.html_safe
|
80
|
+
if section.children?
|
81
|
+
children_html = render_section_container(section, level + 1, id, section.url)
|
82
|
+
if children_html.present?
|
83
|
+
append(children_html)
|
84
|
+
label << ' <span class="navy-section-expander">▾</span>'.html_safe
|
85
|
+
end
|
86
|
+
end
|
87
|
+
label << section.label
|
88
|
+
link_to(label, section.url, :class => link_classes.join(' '), :"data-navy-opens" => id)
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
def div_tag(options, &block)
|
93
|
+
content_tag_string(:div, block.call, options, true)
|
94
|
+
end
|
95
|
+
|
96
|
+
end
|
97
|
+
end
|
data/lib/navy/section.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Navy
|
2
|
+
class Section
|
3
|
+
include SectionContainer
|
4
|
+
|
5
|
+
attr_reader :name, :label
|
6
|
+
attr_accessor :url
|
7
|
+
|
8
|
+
def initialize(name, label, url, active, &children)
|
9
|
+
@name = name
|
10
|
+
@label = label
|
11
|
+
@url = url
|
12
|
+
@active = active
|
13
|
+
@children = children
|
14
|
+
end
|
15
|
+
|
16
|
+
def active?
|
17
|
+
@active
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
module Navy
|
2
|
+
module SectionActivator
|
3
|
+
|
4
|
+
def self.included(base)
|
5
|
+
base.send :extend, ClassMethods
|
6
|
+
base.send :include, InstanceMethods
|
7
|
+
base.helper_method :section_active?
|
8
|
+
end
|
9
|
+
|
10
|
+
module ClassMethods
|
11
|
+
|
12
|
+
def default_active_sections
|
13
|
+
@default_active_sections
|
14
|
+
end
|
15
|
+
|
16
|
+
private
|
17
|
+
|
18
|
+
def in_sections(*sections)
|
19
|
+
@default_active_sections ||= []
|
20
|
+
@default_active_sections += sections.collect(&:to_s)
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
module InstanceMethods
|
26
|
+
|
27
|
+
def active_sections
|
28
|
+
sections = []
|
29
|
+
sections += self.class.default_active_sections || []
|
30
|
+
sections += @active_sections || []
|
31
|
+
sections.uniq
|
32
|
+
end
|
33
|
+
|
34
|
+
def section_active?(section)
|
35
|
+
active_sections.include?(section.to_s)
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def in_sections(*sections)
|
41
|
+
@active_sections ||= []
|
42
|
+
@active_sections += sections.collect(&:to_s)
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module Navy
|
2
|
+
module SectionContainer
|
3
|
+
|
4
|
+
attr_accessor :block_args
|
5
|
+
|
6
|
+
def sections(context)
|
7
|
+
@sections ||= {}
|
8
|
+
@sections[context] ||=
|
9
|
+
if children?
|
10
|
+
SectionParser.new(context).parse(block_args || [], &@children).sections
|
11
|
+
else
|
12
|
+
[]
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def children?
|
17
|
+
@children.present?
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
module Navy
|
2
|
+
class SectionParser
|
3
|
+
|
4
|
+
attr_reader :sections
|
5
|
+
|
6
|
+
def initialize(context)
|
7
|
+
@context = context
|
8
|
+
@sections = []
|
9
|
+
end
|
10
|
+
|
11
|
+
def parse(block_args, &block)
|
12
|
+
instance_exec(*block_args, &block)
|
13
|
+
self
|
14
|
+
end
|
15
|
+
|
16
|
+
def section(name, label, url = nil, &children)
|
17
|
+
section = Navy::Section.new(name, label, url, @context.section_active?(name), &children)
|
18
|
+
if url.nil?
|
19
|
+
section.url = section.sections(@context).first.url
|
20
|
+
end
|
21
|
+
sections << section
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(method, include_private = false)
|
25
|
+
super || context.respond_to?(method, false) # don't forward private messages
|
26
|
+
end
|
27
|
+
|
28
|
+
def method_missing(method, *args, &block)
|
29
|
+
if @context.respond_to?(method, false)
|
30
|
+
@context.send(method, *args, &block)
|
31
|
+
else
|
32
|
+
super
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
data/lib/navy/version.rb
ADDED
data/navy.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "navy/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "makandra-navy"
|
7
|
+
s.version = Navy::VERSION
|
8
|
+
s.authors = ["Tobias Kraze", "Henning Koch"]
|
9
|
+
s.email = ["tobias@kraze.eu"]
|
10
|
+
s.homepage = ""
|
11
|
+
s.summary = %q{Comprehensive solution for multi-level horizontal navigation bars.}
|
12
|
+
s.description = s.summary
|
13
|
+
|
14
|
+
s.rubyforge_project = "navy"
|
15
|
+
|
16
|
+
s.files = `git ls-files`.split("\n")
|
17
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
19
|
+
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
# specify any dependencies here; for example:
|
22
|
+
# s.add_development_dependency "rspec"
|
23
|
+
s.add_runtime_dependency "actionpack"
|
24
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: makandra-navy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 9
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
version: "0.1"
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Tobias Kraze
|
13
|
+
- Henning Koch
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2012-04-13 00:00:00 Z
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: actionpack
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
none: false
|
25
|
+
requirements:
|
26
|
+
- - ">="
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
hash: 3
|
29
|
+
segments:
|
30
|
+
- 0
|
31
|
+
version: "0"
|
32
|
+
type: :runtime
|
33
|
+
version_requirements: *id001
|
34
|
+
description: Comprehensive solution for multi-level horizontal navigation bars.
|
35
|
+
email:
|
36
|
+
- tobias@kraze.eu
|
37
|
+
executables: []
|
38
|
+
|
39
|
+
extensions: []
|
40
|
+
|
41
|
+
extra_rdoc_files: []
|
42
|
+
|
43
|
+
files:
|
44
|
+
- .gitignore
|
45
|
+
- Gemfile
|
46
|
+
- Rakefile
|
47
|
+
- assets/sass/_navy.sass
|
48
|
+
- lib/navy.rb
|
49
|
+
- lib/navy/description.rb
|
50
|
+
- lib/navy/navigation.rb
|
51
|
+
- lib/navy/parser.rb
|
52
|
+
- lib/navy/renderer.rb
|
53
|
+
- lib/navy/renderer_helper.rb
|
54
|
+
- lib/navy/section.rb
|
55
|
+
- lib/navy/section_activator.rb
|
56
|
+
- lib/navy/section_container.rb
|
57
|
+
- lib/navy/section_parser.rb
|
58
|
+
- lib/navy/version.rb
|
59
|
+
- navy.gemspec
|
60
|
+
homepage: ""
|
61
|
+
licenses: []
|
62
|
+
|
63
|
+
post_install_message:
|
64
|
+
rdoc_options: []
|
65
|
+
|
66
|
+
require_paths:
|
67
|
+
- lib
|
68
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
hash: 3
|
74
|
+
segments:
|
75
|
+
- 0
|
76
|
+
version: "0"
|
77
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
hash: 3
|
83
|
+
segments:
|
84
|
+
- 0
|
85
|
+
version: "0"
|
86
|
+
requirements: []
|
87
|
+
|
88
|
+
rubyforge_project: navy
|
89
|
+
rubygems_version: 1.8.10
|
90
|
+
signing_key:
|
91
|
+
specification_version: 3
|
92
|
+
summary: Comprehensive solution for multi-level horizontal navigation bars.
|
93
|
+
test_files: []
|
94
|
+
|
95
|
+
has_rdoc:
|