Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
jastkand committed Jan 5, 2015
0 parents commit 3ec612f
Show file tree
Hide file tree
Showing 12 changed files with 416 additions and 0 deletions.
14 changes: 14 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/.bundle/
/.yardoc
/Gemfile.lock
/_yardoc/
/coverage/
/doc/
/pkg/
/spec/reports/
/tmp/
*.bundle
*.so
*.o
*.a
mkmf.log
4 changes: 4 additions & 0 deletions Gemfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
source 'https://rubygems.org'

# Specify your gem's dependencies in live-front-rails.gemspec
gemspec
22 changes: 22 additions & 0 deletions LICENSE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
Copyright (c) 2014 Andrey Krivko

MIT License

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
104 changes: 104 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# Live Front

Useful helpers used at [Live Typing](http://ltst.ru).

## List of helpers

### TabHelper

Navigation link helper. Returns an `li` element with an 'active' class if the supplied
controller(s) and/or action(s) are currently active. The content of the
element is the value passed to the block. Initially was copied from
[GitLab project](https://gitlab.com/gitlab-org/gitlab-ce). Also it was added ability to specify
`params` option to make link active when current path suits specified params.

**options**

The options hash used to determine if the element is "active" (default: {})

`:controller` - One or more controller names to check (optional).

`:action` - One or more action names to check (optional).

`:path` - A shorthand path, such as 'dashboard#index', to check (optional).

`:params` - One or more params to check. It also can be specified `:_blank` value to be able to specify either blank or non-blank param (optional).

`:html_options` - Extra options to be passed to the list element (optional).

**block**

An optional block that will become the contents of the returned `li` element.

When both `:controller` and `:action` are specified, BOTH must match in order
to be marked as active. When only one is given, either can match.

#### Examples:

Assuming we're on `TreeController#show`

```
# Controller matches, but action doesn't
nav_link(controller: [:tree, :refs], action: :edit) { "Hello" }
# => '<li>Hello</li>'
```

```
# Controller matches
nav_link(controller: [:tree, :refs]) { "Hello" }
# => '<li class="active">Hello</li>'
```

```
# Shorthand path
nav_link(path: 'tree#show') { "Hello" }
# => '<li class="active">Hello</li>'
```

```
# Supplying custom options for the list element
nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
# => '<li class="home active">Hello</li>'
```

```
# Supplying params options when `params[:state] # => 'archived'`
nav_link(path: 'tree#show', params: {state: 'archived'}) { "Hello" }
# => '<li class="home active">Hello</li>'
```

```
# Supplying params options when `params[:state] # => nil`
nav_link(path: 'tree#show', params: {state: 'archived'}) { "Hello" }
# => '<li class="home">Hello</li>'
```

```
# Supplying params options when `params[:state] # => nil`
nav_link(path: 'tree#show', params: {state: [:_blank, :active]}) { "Hello" }
# => '<li class="home active">Hello</li>'
```

## Installation

Add this line to your application's Gemfile:

```ruby
gem 'live-front-rails'
```

And then execute:

$ bundle

Or install it yourself as:

$ gem install live-front-rails

## Contributing

1. Fork it ( https://github.com/LiveTyping/live-front-rails/fork )
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create a new Pull Request
10 changes: 10 additions & 0 deletions Rakefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
require 'rspec/core/rake_task'
require 'bundler/gem_tasks'

# Default directory to look in is `/specs`
# Run with `rake spec`
RSpec::Core::RakeTask.new(:spec) do |task|
task.rspec_opts = ['--color']
end

task default: :spec
13 changes: 13 additions & 0 deletions lib/live_front.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
require 'live_front/version'
require 'rails'
require 'live_front/application_helper'
require 'live_front/tab_helper'

module LiveFront
class Engine < ::Rails::Engine
initializer 'live_front.view_helpers' do
ActionView::Base.send :include, LiveFront::ApplicationHelper
ActionView::Base.send :include, LiveFront::TabHelper
end
end
end
31 changes: 31 additions & 0 deletions lib/live_front/application_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
module LiveFront
module ApplicationHelper
# Check if a particular controller is the current one
#
# args - One or more controller names to check
#
# Examples
#
# # On TreeController
# current_controller?(:tree) # => true
# current_controller?(:commits) # => false
# current_controller?(:commits, :tree) # => true
def current_controller?(*args)
args.any? { |v| v.to_s.downcase == controller.controller_name }
end

# Check if a particular action is the current one
#
# args - One or more action names to check
#
# Examples
#
# # On Projects#new
# current_action?(:new) # => true
# current_action?(:create) # => false
# current_action?(:new, :create) # => true
def current_action?(*args)
args.any? { |v| v.to_s.downcase == action_name }
end
end
end
102 changes: 102 additions & 0 deletions lib/live_front/tab_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
module LiveFront
# Copied from GitLab project
# https://gitlab.com/gitlab-org/gitlab-ce
module TabHelper
# Navigation link helper
#
# Returns an `li` element with an 'active' class if the supplied
# controller(s) and/or action(s) are currently active. The content of the
# element is the value passed to the block.
#
# options - The options hash used to determine if the element is "active" (default: {})
# :controller - One or more controller names to check (optional).
# :action - One or more action names to check (optional).
# :path - A shorthand path, such as 'dashboard#index', to check (optional).
# :html_options - Extra options to be passed to the list element (optional).
# block - An optional block that will become the contents of the returned
# `li` element.
#
# When both :controller and :action are specified, BOTH must match in order
# to be marked as active. When only one is given, either can match.
#
# Examples
#
# # Assuming we're on TreeController#show
#
# # Controller matches, but action doesn't
# nav_link(controller: [:tree, :refs], action: :edit) { "Hello" }
# # => '<li>Hello</li>'
#
# # Controller matches
# nav_link(controller: [:tree, :refs]) { "Hello" }
# # => '<li class="active">Hello</li>'
#
# # Shorthand path
# nav_link(path: 'tree#show') { "Hello" }
# # => '<li class="active">Hello</li>'
#
# # Supplying custom options for the list element
# nav_link(controller: :tree, html_options: {class: 'home'}) { "Hello" }
# # => '<li class="home active">Hello</li>'
#
# Returns a list item element String
def nav_link(options = {}, &block)
c, a = fetch_controller_and_action(options)
p = options.delete(:params) || {}

klass = page_active?(c, a, p) ? 'active' : ''


# Add our custom class into the html_options, which may or may not exist
# and which may or may not already have a :class key
o = options.delete(:html_options) || {}
o[:class] = "#{o[:class]} #{klass}".strip

if block_given?
content_tag(:li, capture(&block), o)
else
content_tag(:li, nil, o)
end
end

private

def fetch_controller_and_action(options)
path = options.delete(:path)

if path
if path.respond_to?(:each)
c = path.map { |p| p.split('#').first }
a = path.map { |p| p.split('#').last }
else
c, a, _ = path.split('#')
end
else
c = options.delete(:controller)
a = options.delete(:action)
end
[c, a]
end

def page_active?(controller, action, parameters = {})
match_action_controller = if controller && action
# When given both options, make sure BOTH are active
current_controller?(*controller) && current_action?(*action)
else
# Otherwise check EITHER option
current_controller?(*controller) || current_action?(*action)
end

match_action_controller && match_params?(parameters)
end

def match_params?(parameters)
return true if parameters.empty?

parameters.all? do |key, value|
value = *value
value.any? { |v| v == :_blank ? params[key].to_s.blank? : v.to_s == params[key].to_s }
end
end
end
end
3 changes: 3 additions & 0 deletions lib/live_front/version.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module LiveFront
VERSION = '0.0.1'.freeze
end
27 changes: 27 additions & 0 deletions live-front-rails.gemspec
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
# coding: utf-8
lib = File.expand_path('../lib', __FILE__)
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
require 'live_front/version'

Gem::Specification.new do |spec|
spec.name = 'live-front-rails'
spec.version = LiveFront::VERSION
spec.authors = ['Andrey Krivko']
spec.email = ['[email protected]']
spec.summary = %q{Useful helpers used at Live Typing}
spec.description = %q{Useful helpers used at Live Typing}
spec.homepage = ''
spec.license = 'MIT'

spec.files = `git ls-files -z`.split("\x0")
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
spec.require_paths = ['lib']

spec.add_dependency 'rails', '~> 4.1'

spec.add_development_dependency 'bundler', '~> 1.7'
spec.add_development_dependency 'rake', '~> 10.0'
spec.add_development_dependency 'rspec', '~> 3.1.0'
spec.add_development_dependency 'rspec-mocks', '~> 3.1.0'
end
49 changes: 49 additions & 0 deletions spec/helpers/tab_helper_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
require 'spec_helper'

describe LiveFront::TabHelper do
describe '#nav_link' do
before do
allow(self).to receive(:action_name).and_return('foo')
end

it 'captures block output' do
expect(nav_link { 'Testing Blocks' }).to match(/Testing Blocks/)
end

it 'performs checks on the current controller' do
expect(nav_link(controller: :foo)).to match(/<li class="active">/)
expect(nav_link(controller: :bar)).not_to match(/active/)
expect(nav_link(controller: [:foo, :bar])).to match(/active/)
end

it 'performs checks on the current action' do
expect(nav_link(action: :foo)).to match(/<li class="active">/)
expect(nav_link(action: :bar)).not_to match(/active/)
expect(nav_link(action: [:foo, :bar])).to match(/active/)
end

it 'performs checks on both controller and action when both are present' do
expect(nav_link(controller: :bar, action: :foo)).not_to match(/active/)
expect(nav_link(controller: :foo, action: :bar)).not_to match(/active/)
expect(nav_link(controller: :foo, action: :foo)).to match(/active/)
end

it 'accepts a path shorthand' do
expect(nav_link(path: 'foo#bar')).not_to match(/active/)
expect(nav_link(path: 'foo#foo')).to match(/active/)
end

it 'accepts a params value and checks if they are correct' do
expect(nav_link(path: 'foo#foo', params: { p1: :s1 })).to match(/active/)
expect(nav_link(path: 'foo#foo', params: { p2: [:_blank, :s2] })).to match(/active/)
expect(nav_link(path: 'foo#foo', params: { p2: :s1 })).not_to match(/active/)
end

it 'passes extra html options to the list element' do
expect(
nav_link(action: :foo, html_options: { class: 'home' })
).to match(/<li class="home active">/)
expect(nav_link(html_options: { class: 'active' })).to match(/<li class="active">/)
end
end
end
Loading

0 comments on commit 3ec612f

Please sign in to comment.