├── .rspec
├── evil-front
├── spec
│ ├── sass
│ │ ├── empty.txt
│ │ ├── ruble.sass
│ │ ├── inline-ruble.sass
│ │ ├── size.sass
│ │ ├── load.sass
│ │ └── media.sass
│ ├── spec_helper.rb
│ ├── english_spec.rb
│ ├── sass_spec.rb
│ ├── russian_spec.rb
│ └── helpers_spec.rb
├── .rspec
├── lib
│ ├── evil-front
│ │ ├── version.rb
│ │ ├── slim.rb
│ │ ├── helpers
│ │ │ ├── capitalize_first.rb
│ │ │ ├── head_content.rb
│ │ │ ├── ruble.rb
│ │ │ ├── tel.rb
│ │ │ ├── typograph_by_locale.rb
│ │ │ ├── standard_assets.rb
│ │ │ ├── disable_mobile_zoom.rb
│ │ │ ├── auto_flying_quotes.rb
│ │ │ ├── flying_quotes.rb
│ │ │ ├── english_typograph.rb
│ │ │ ├── russian_typograph.rb
│ │ │ ├── title.rb
│ │ │ ├── head_tag.rb
│ │ │ └── title_tag.rb
│ │ ├── helpers.rb
│ │ ├── english.rb
│ │ ├── typograph.rb
│ │ └── russian.rb
│ ├── assets
│ │ ├── javascripts
│ │ │ ├── evil-front
│ │ │ │ ├── core.js
│ │ │ │ ├── detect-3d.js
│ │ │ │ ├── shortcuts.js
│ │ │ │ ├── after.js
│ │ │ │ ├── every.js
│ │ │ │ ├── links.js
│ │ │ │ ├── http.js
│ │ │ │ ├── transform3d.js
│ │ │ │ ├── queue.js
│ │ │ │ ├── outside.js
│ │ │ │ ├── jquery.js
│ │ │ │ ├── tappable.js
│ │ │ │ └── ajax.js
│ │ │ └── evil-front.js
│ │ └── stylesheets
│ │ │ ├── evil-front
│ │ │ ├── to-px.sass
│ │ │ ├── flying-quotes.sass
│ │ │ ├── hover.sass
│ │ │ ├── clearfix.sass
│ │ │ ├── size.sass
│ │ │ ├── stroke-text.sass
│ │ │ ├── height.sass
│ │ │ ├── colors.sass
│ │ │ ├── no-tap-highlight.sass
│ │ │ ├── styled-taps.sass
│ │ │ ├── no-hover.sass
│ │ │ ├── reset.sass
│ │ │ ├── sticky-footer.sass
│ │ │ ├── media.sass
│ │ │ ├── easings.sass
│ │ │ └── import-ruble.sass
│ │ │ └── evil-front.sass
│ └── evil-front.rb
├── vendor
│ └── assets
│ │ └── fonts
│ │ └── evil-front
│ │ ├── alsrubl-arial-bold.woff
│ │ ├── alsrubl-arial-italic.woff
│ │ ├── alsrubl-arial-regular.woff
│ │ └── alsrubl-arial-bolditalic.woff
├── Rakefile
├── evil-front.gemspec
├── LICENSE
└── ChangeLog.md
├── .gitignore
├── .travis.yml
├── evil-front-all
├── lib
│ ├── evil-front
│ │ └── all
│ │ │ └── version.rb
│ └── evil-front-all.rb
├── Rakefile
├── ChangeLog.md
├── LICENSE
└── evil-front-all.gemspec
├── evil-front-rails
├── lib
│ ├── evil-front
│ │ └── rails
│ │ │ └── version.rb
│ └── evil-front-rails.rb
├── Rakefile
├── ChangeLog.md
├── evil-front-rails.gemspec
└── LICENSE
├── Gemfile
├── Rakefile
└── README.md
/.rspec:
--------------------------------------------------------------------------------
1 | --colour
2 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/empty.txt:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/evil-front/.rspec:
--------------------------------------------------------------------------------
1 | --format documentation --colour
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.DS_Store
2 | *~
3 |
4 | pkg/
5 |
6 | .bundle
7 | Gemfile.lock
8 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | language: ruby
3 | rvm:
4 | - 2.2.2
5 | - 2.3.0
6 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/ruble.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front"
2 |
3 | +import-ruble("PT Sans, sans-serif")
4 |
--------------------------------------------------------------------------------
/evil-front/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require_relative '../lib/evil-front'
2 |
3 | I18n.enforce_available_locales = false
4 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/version.rb:
--------------------------------------------------------------------------------
1 | module EvilFront
2 | VERSION = '0.5.1' unless defined? EvilFront::VERSION
3 | end
4 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/inline-ruble.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front"
2 |
3 | +import-ruble("PT Sans, sans-serif", $italic: "inline")
4 |
--------------------------------------------------------------------------------
/evil-front-all/lib/evil-front/all/version.rb:
--------------------------------------------------------------------------------
1 | module EvilFront
2 | module All
3 | VERSION = '0.5.0' unless defined? EvilFront::All::VERSION
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/core.js:
--------------------------------------------------------------------------------
1 | // Add global `evil` namespace and common shortcuts.
2 |
3 | if ( !window.evil ) {
4 | window.evil = { };
5 | }
6 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/size.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front"
2 |
3 | .all
4 | +size(10px, 20px)
5 |
6 | .one
7 | +size(30px)
8 |
9 | .no-unit
10 | +size(15)
11 |
--------------------------------------------------------------------------------
/evil-front-rails/lib/evil-front/rails/version.rb:
--------------------------------------------------------------------------------
1 | module EvilFront
2 | module Rails
3 | VERSION = '0.5.0' unless defined? EvilFront::Rails::VERSION
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/load.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front"
2 |
3 | a
4 | content: inline("empty.txt")
5 | background: black(0.5)
6 | transition: all 1s $easeInSine
7 | +clearfix
8 |
--------------------------------------------------------------------------------
/evil-front/spec/sass/media.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front"
2 |
3 | .one
4 | +max-width(100)
5 | color: black
6 |
7 | .two
8 | +min-width(200px)
9 | color: white
10 |
--------------------------------------------------------------------------------
/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-bold.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ai/evil-front/HEAD/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-bold.woff
--------------------------------------------------------------------------------
/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-italic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ai/evil-front/HEAD/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-italic.woff
--------------------------------------------------------------------------------
/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-regular.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ai/evil-front/HEAD/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-regular.woff
--------------------------------------------------------------------------------
/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-bolditalic.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ai/evil-front/HEAD/evil-front/vendor/assets/fonts/evil-front/alsrubl-arial-bolditalic.woff
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/slim.rb:
--------------------------------------------------------------------------------
1 | module EvilFront
2 | # Set default options to Slim
3 | def self.set_slim_options!
4 | Slim::Engine.set_options(pretty: true, format: :html)
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/detect-3d.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/transform3d
2 |
3 | // Detect support 3D transform and add `transform3d` or `transform2s` class
4 | // to body.
5 | evil.transform3d.init();
6 |
--------------------------------------------------------------------------------
/evil-front-all/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | require 'bundler/setup'
4 | Bundler::GemHelper.install_tasks
5 |
6 | task :clobber_package do
7 | rm_r 'pkg' rescue nil
8 | end
9 | task clobber: [:clobber_package]
10 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/to-px.sass:
--------------------------------------------------------------------------------
1 | // Add "px" if unit is unitless. Used in +media and +size.
2 | @function to-px($var)
3 | @if unitless($var)
4 | @return $var * 1px
5 | @else
6 | @return $var
7 |
--------------------------------------------------------------------------------
/evil-front-rails/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | require 'bundler/setup'
4 | Bundler::GemHelper.install_tasks
5 |
6 | task :clobber_package do
7 | rm_r 'pkg' rescue nil
8 | end
9 | task clobber: [:clobber_package]
10 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/flying-quotes.sass:
--------------------------------------------------------------------------------
1 | // Mark quotes to move first quote before the text line.
2 | @mixin flying-quotes
3 | .space-before-quote
4 | margin-right: 0.35em
5 | .quotes
6 | margin-left: -0.35em
7 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/shortcuts.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/core
2 |
3 | evil.win = $(window),
4 | evil.doc = $(document),
5 | evil.body = null;
6 |
7 | evil.doc.ready(function() {
8 | evil.body = $('body');
9 | });
10 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front.js:
--------------------------------------------------------------------------------
1 | // Load libraries and core files.
2 |
3 | //= require evil-front/core
4 | //= require evil-front/jquery
5 | //= require evil-front/shortcuts
6 | //= require evil-front/after
7 |
8 | //= require evil-blocks
9 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/hover.sass:
--------------------------------------------------------------------------------
1 | // Alias for focus and hover states
2 | //
3 | // a
4 | // +no-hover
5 | // color: blue
6 | // +hover
7 | // color: red
8 | @mixin hover
9 | &:hover, &:focus
10 | @content
11 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/after.js:
--------------------------------------------------------------------------------
1 | // Alternate syntax for `setTimeout`, to be more useful in CoffeeScript.
2 | //
3 | // after 1000, ->
4 | // addSecond()
5 | window.after = function (ms, callback) {
6 | return setTimeout(callback, ms);
7 | };
8 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/every.js:
--------------------------------------------------------------------------------
1 | // Alternate syntax for `setInterval`, to be more useful in CoffeeScript.
2 | //
3 | // every 1000, ->
4 | // addSecond()
5 | window.every = function (ms, callback) {
6 | return setInterval(callback, ms);
7 | };
8 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/clearfix.sass:
--------------------------------------------------------------------------------
1 | // Clearfix to set block size from float inners.
2 | //
3 | // Based on http://nicolasgallagher.com/micro-clearfix-hack/
4 | @mixin clearfix
5 | &:after
6 | content: ""
7 | display: table
8 | clear: both
9 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/capitalize_first.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Capitalize only first letter (like titles in Russian).
3 | #
4 | # = capitalize_first post.title
5 | def capitalize_first(text)
6 | EvilFront::Russian.capitalize_first(text)
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | gem 'rake'
4 | gem 'rails', '>= 4'
5 |
6 | gem 'rspec-rails'
7 |
8 | gem 'evil-front', path: 'evil-front/'
9 | gem 'evil-front-all', path: 'evil-front-all/', require: false
10 | gem 'evil-front-rails', path: 'evil-front-rails/', require: false
11 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/size.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front/to-px"
2 |
3 | // Shortcut to set width and height
4 | //
5 | // +size(200, 100)
6 | // +size(32)
7 | // +size(50%, 10em)
8 | @mixin size($width, $height: $width)
9 | width: to-px($width)
10 | height: to-px($height)
11 |
--------------------------------------------------------------------------------
/evil-front/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 |
3 | require 'bundler/setup'
4 | Bundler::GemHelper.install_tasks
5 |
6 | require 'rspec/core/rake_task'
7 | RSpec::Core::RakeTask.new
8 | task default: :spec
9 |
10 | task :clobber_package do
11 | rm_r 'pkg' rescue nil
12 | end
13 | task clobber: [:clobber_package]
14 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/links.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/core
2 | // Prevent default in AJAX link with only # in href
3 |
4 | evil.doc.ready(function() {
5 | evil.body.on('click', 'a', function (e) {
6 | if ( this.getAttribute('href') == '#' ) {
7 | e.preventDefault();
8 | }
9 | });
10 | })
11 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/stroke-text.sass:
--------------------------------------------------------------------------------
1 | // Stroke text by some shadow. Useful, when you white on transparent background.
2 | //
3 | // .banner
4 | // background: black(0.2)
5 | // color: white
6 | // +stroke-text(black)
7 | @mixin stroke-text($color)
8 | text-shadow: 1px 1px 1px $color, 1px -1px 1px $color, -1px 1px 1px $color, -1px -1px 1px $color
9 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/height.sass:
--------------------------------------------------------------------------------
1 | // Shortcut to set `height` and `line-height` to vertical text centering.
2 | // You can also set `$line-diff` to have different `line-height`.
3 | //
4 | // .button
5 | // display: inline-block
6 | // +height(24px)
7 | @mixin height($height, $line-diff: 0)
8 | height: $height
9 | line-height: $height + $line-diff
10 |
--------------------------------------------------------------------------------
/evil-front-rails/ChangeLog.md:
--------------------------------------------------------------------------------
1 | ## 0.5 “Chryse Planitia”
2 |
3 | * Remove `clean-css`.
4 |
5 | ## 0.4 “Schiaparelli Crater”
6 |
7 | * Add Sprockets 3 support.
8 |
9 | ## 0.3 “Samara Vallis”
10 |
11 | * Bump version to use latest Evil Front core.
12 |
13 | ## 0.2 “Ptolemaeus Crater”
14 |
15 | * Fix gem dependencies.
16 |
17 | ## 0.1 “Hellespontus Montes”
18 |
19 | * Initial release.
20 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/head_content.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Add content to head tag. Will be useful in page views.
3 | #
4 | # - head_content do
5 | # meta name="description" content=page.seo.description
6 | # meta name="keywords" content=page.seo.keywords
7 | def head_content(&block)
8 | content_for(:evil_front_head, &block)
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/colors.sass:
--------------------------------------------------------------------------------
1 | // Shorcut to set black color with alpha in rgba()
2 | //
3 | // box-shadow: 0 0 5px black(0.7)
4 | @function black($opacity)
5 | @return rgba(0, 0, 0, $opacity)
6 |
7 | // Shorcut to set white color with alpha in rgba()
8 | //
9 | // box-shadow: 0 0 5px white(0.7)
10 | @function white($opacity)
11 | @return rgba(255, 255, 255, $opacity)
12 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/no-tap-highlight.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front/colors"
2 |
3 | // Hide link tap highlight on mobile browsers. Use it only if you define your
4 | // own pressed styles.
5 | //
6 | // .button
7 | // +no-tap-highlight
8 | //
9 | // If you disable all taps highlight, use `styled-taps` mixin.
10 | @mixin no-tap-highlight
11 | -webkit-tap-highlight-color: white(0)
12 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/ruble.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | module EvilFront::Helpers
4 | # Insert symbol of Russian currency.
5 | #
6 | # = order.price
7 | # = ruble
8 | #
9 | # Don’t forget to import ruble’s fonts and class in you Sass:
10 | #
11 | # +import-ruble("PT Sans, sans-serif", $regular: inline)
12 | def ruble
13 | EvilFront.html_safe('Р')
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/styled-taps.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front/no-tap-highlight"
2 |
3 | // Disable standard browser tap highlight and transitions for hover and tapped
4 | // states.
5 | //
6 | // +styled-taps
7 | //
8 | // Must be used with `evil-front/tappable` JS and `no-hover` Sass mixin.
9 | @mixin styled-taps
10 | .is-tapped, :active
11 | transition: none !important
12 | body
13 | +no-tap-highlight
14 |
--------------------------------------------------------------------------------
/evil-front-all/ChangeLog.md:
--------------------------------------------------------------------------------
1 | ## 0.5 “Chryse Planitia”
2 |
3 | * Remove `clean-css`.
4 |
5 | ## 0.4 “Schiaparelli Crater”
6 |
7 | * Add Sprockets 3 support.
8 |
9 | ## 0.3.1
10 |
11 | * Use new API for Autoprefixer 3.0.
12 |
13 | ## 0.3 “Samara Vallis”
14 |
15 | * Bump version to use latest Evil Front core.
16 |
17 | ## 0.2 “Ptolemaeus Crater”
18 |
19 | * Bump version to be used in Evil Front Rails.
20 |
21 | ## 0.1 “Hellespontus Montes”
22 |
23 | * Initial release.
24 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/tel.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Render link with phone number. It will remove all non-digits symbols from
3 | # phone number and format `tel:` protocol URI.
4 | #
5 | # label Contact us:
6 | # = tel('+7 (495) 660−83−79')
7 | def tel(number, args = { })
8 | args[:href] = "tel:" + number.gsub(/[^\d\+]/, '')
9 | args[:class] = (['tel', args[:class]]).compact.join(' ')
10 | content_tag(:a, number, args)
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/typograph_by_locale.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Add typograph rules to text by language in current locale.
3 | #
4 | # typograph_by_locale(post.body)
5 | def typograph_by_locale(text = nil, &block)
6 | text = capture(&block) if block_given?
7 |
8 | if I18n.locale == :ru
9 | russian_typograph(text)
10 | elsif I18n.locale == :en
11 | english_typograph(text)
12 | else
13 | text
14 | end
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/standard_assets.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Add `application.css`, jQuery from Google CDN and `application.js`.
3 | #
4 | # html
5 | # = head_tag do
6 | # = standard_assets
7 | def standard_assets(attributes = { })
8 | stylesheet_link_tag('application', media: 'all') +
9 | include_jquery(attributes.dup) +
10 | content_for(:evil_libraries) +
11 | javascript_include_tag('application', attributes)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/disable_mobile_zoom.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Disable user zoom in mobile browsers. You should use it only if your styles
3 | # are special optimized for mobile screens.
4 | #
5 | # html
6 | # head
7 | # = disable_mobile_zoom
8 | def disable_mobile_zoom
9 | html = ''
11 | EvilFront.html_safe(html)
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/auto_flying_quotes.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Find quotes and add tags to flying quotes
3 | #
4 | # = auto_flying_quotes post.body
5 | #
6 | # Don’t forget to install styles by `quotes` Sass mixin.
7 | def auto_flying_quotes(text = nil, &block)
8 | text = if block_given?
9 | capture(&block).strip
10 | else
11 | EvilFront.escape(text)
12 | end
13 | text = EvilFront::Russian.auto_flying_quotes(text)
14 | EvilFront.html_safe(text)
15 | end
16 | end
17 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/no-hover.sass:
--------------------------------------------------------------------------------
1 | // Add normal state, to prevent hover on touched elements
2 | //
3 | // a
4 | // display: inline-block
5 | // +no-hover
6 | // color: black
7 | // &:hover
8 | // color: gray
9 | // &:active, &.is-tapped
10 | // background: black
11 | //
12 | // To enable `.is-tapped` state, you need to require `evil-front/tappable` JS.
13 | // Don’t forget to disable transitions in `.is-tapped` and `:active` states by
14 | // `+styled-taps` mixin.
15 | @mixin no-hover
16 | &, &.was-tapped:hover, &.was-tapped:active
17 | @content
18 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/flying_quotes.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Mark quotes to move first quote before the text line.
3 | #
4 | # = flying_quotes feedback.text
5 | #
6 | # You can send block:
7 | #
8 | # = flying_quotes do
9 | # a href=course.url
10 | # = course.name
11 | def flying_quotes(text = nil, options = { }, &block)
12 | text = if block_given?
13 | capture(&block).strip
14 | else
15 | EvilFront.escape(text)
16 | end
17 | text = EvilFront::Russian.flying_quotes(text, options)
18 | EvilFront.html_safe(text)
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/reset.sass:
--------------------------------------------------------------------------------
1 | // Normalize browser default styles and clean some unnecessary styles
2 | //
3 | // +evil-reset
4 |
5 | @mixin evil-reset
6 | *
7 | margin: 0
8 | padding: 0
9 |
10 | a img
11 | border: none
12 |
13 | body
14 | background: white
15 | color: black
16 | line-height: 1.4
17 |
18 | a, input, textarea, button
19 | &:focus
20 | outline: none
21 | ::-moz-focus-inner
22 | border: 0
23 |
24 | h1, h2, h3, h4, h5, h6
25 | font-weight: normal
26 |
27 | li
28 | list-style: none
29 |
30 | cite
31 | font-style: normal
32 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/sticky-footer.sass:
--------------------------------------------------------------------------------
1 | // Sticky footer, which show on bottom of screen if content height is less,
2 | // that screen content
3 | //
4 | // +sticky-footer(100px)
5 | //
6 | // You can specify footer selector (`.footer-layout` by default):
7 | //
8 | // +sticky-footer(100px, 'footer')
9 | @mixin sticky-footer($height, $footer: unquote(".footer-layout"))
10 | html
11 | position: relative
12 | min-height: 100%
13 | body
14 | margin-bottom: $height
15 | #{$footer}
16 | position: absolute
17 | left: 0
18 | bottom: 0
19 | height: $height
20 | width: 100%
21 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front.sass:
--------------------------------------------------------------------------------
1 | @import "rails-sass-images"
2 |
3 | @import "evil-front/to-px"
4 |
5 | @import "evil-front/size"
6 | @import "evil-front/hover"
7 | @import "evil-front/reset"
8 | @import "evil-front/media"
9 | @import "evil-front/colors"
10 | @import "evil-front/height"
11 | @import "evil-front/easings"
12 | @import "evil-front/no-hover"
13 | @import "evil-front/clearfix"
14 | @import "evil-front/styled-taps"
15 | @import "evil-front/stroke-text"
16 | @import "evil-front/import-ruble"
17 | @import "evil-front/flying-quotes"
18 | @import "evil-front/sticky-footer"
19 | @import "evil-front/no-tap-highlight"
20 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/english_typograph.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Insert non-break spaces and mark quotes to have nice text.
3 | # Work only with English language.
4 | #
5 | # = english_typograph user.description
6 | #
7 | # You can send block:
8 | #
9 | # = english_typograph do
10 | # = user.name
11 | # = user.profession
12 | def english_typograph(text = nil, &block)
13 | text = if block_given?
14 | capture(&block)
15 | else
16 | EvilFront.escape(text)
17 | end
18 | text = EvilFront::English.typograph_html(text)
19 | EvilFront.html_safe(text)
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/russian_typograph.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Insert non-break spaces and mark quotes to have nice text.
3 | # Work only with Russian language.
4 | #
5 | # = russian_typograph user.description
6 | #
7 | # You can send block:
8 | #
9 | # = russian_typograph do
10 | # = user.name
11 | # = user.profession
12 | def russian_typograph(text = nil, &block)
13 | text = if block_given?
14 | capture(&block)
15 | else
16 | EvilFront.escape(text)
17 | end
18 | text = EvilFront::Russian.typograph_html(text)
19 | EvilFront.html_safe(text)
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/title.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Add page title. Will be used with site title in document title tag by
3 | # `title_tag`.
4 | #
5 | # - title 'FAQ'
6 | #
7 | # You can set subtitles (order will be reversed):
8 | #
9 | # - title 'FAQ', 'Ask'
10 | #
11 | # By default `title_tag` will add site name to page title. You can show only
12 | # page title by `no_site` option:
13 | #
14 | # - title 'Site Home', no_site: true
15 | def title(*titles)
16 | options = titles.extract_options!
17 | @evil_front_no_site_in_title = true if options[:no_site]
18 |
19 | @evil_front_titles ||= []
20 | @evil_front_titles += titles
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers.rb:
--------------------------------------------------------------------------------
1 | module EvilFront
2 | HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<' }
3 |
4 | # Call `html_safe` if String has this methods.
5 | def self.html_safe(string)
6 | if string.respond_to?(:html_safe)
7 | string.html_safe
8 | else
9 | string.to_s
10 | end
11 | end
12 |
13 | # Escape unsafe strings
14 | def self.escape(string)
15 | string = string.to_s
16 | if not string.respond_to?(:html_safe?) or string.html_safe?
17 | string
18 | else
19 | string.gsub(/[&><]/, HTML_ESCAPE).html_safe
20 | end
21 | end
22 | end
23 |
24 | dir = Pathname(__FILE__).dirname.join('helpers')
25 | Dir.glob(dir.join('*.rb').to_s) { |helper| require helper }
26 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/english.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require 'rubypants-unicode'
4 |
5 | module EvilFront
6 | # Helpers to work with English text.
7 | module English
8 | extend Typograph
9 |
10 | private
11 |
12 | # Replace symbols to right ones, like m-dash, quotes, etc.
13 | def self.use_right_symbols(text)
14 | RubyPants.new(text).to_html
15 | end
16 |
17 | # Small words to insert non-break space before them
18 | def self.tiny_words
19 | @tiny_words ||= begin
20 | tiny = %w(to is be the a an no if at on of in or and)
21 | tiny += tiny.map(&:capitalize)
22 | tiny.map { |i| Regexp.new("( | )(#{Regexp.quote i}) ") }
23 | end
24 | end
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/evil-front/spec/english_spec.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require_relative 'spec_helper'
4 |
5 | describe EvilFront::English do
6 | def nbsp_mark_typograph(str)
7 | EvilFront::English.typograph(str).gsub(' ', '_')
8 | end
9 |
10 | describe 'typograph' do
11 |
12 | it 'changes quotes' do
13 | expect(nbsp_mark_typograph('"a".')).to eq '“a”.'
14 | end
15 |
16 | it 'changes dashes' do
17 | expect(nbsp_mark_typograph('a - b')).to eq 'a - b'
18 | end
19 |
20 | it 'changes ellipsis' do
21 | expect(nbsp_mark_typograph('a...')).to eq 'a…'
22 | end
23 |
24 | it 'inserts non-break spaces' do
25 | expect(nbsp_mark_typograph('he is a hero')).to eq 'he is_a_hero'
26 | end
27 |
28 | end
29 |
30 | end
31 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/media.sass:
--------------------------------------------------------------------------------
1 | @import "evil-front/to-px"
2 |
3 | // Shortcuts for CSS Media Queries
4 |
5 | @mixin max-width($width)
6 | @media all and (max-width: to-px($width))
7 | @content
8 |
9 | @mixin min-width($width)
10 | @media all and (min-width: to-px($width))
11 | @content
12 |
13 | @mixin range-width($min-width, $max-width)
14 | @media all and (min-width: to-px($min-width)) and (max-width: to-px($max-width))
15 | @content
16 |
17 | @mixin max-height($height)
18 | @media all and (max-height: to-px($height))
19 | @content
20 |
21 | @mixin min-height($height)
22 | @media all and (min-height: to-px($height))
23 | @content
24 |
25 | @mixin range-height($min-height, $max-height)
26 | @media all and (min-height: to-px($min-height)) and (max-height: to-px($max-height))
27 | @content
28 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/head_tag.rb:
--------------------------------------------------------------------------------
1 | module EvilFront::Helpers
2 | # Add content from `head_content` and statistics counter in production,
3 | # if you set `:stats` option.
4 | #
5 | # html
6 | # head
7 | # = head_tag do
8 | # = title_tag(t.title)
9 | # = standard_assets
10 | #
11 | # You can disable statistics counter by options:
12 | #
13 | # = head_tag(statistics: false) do
14 | def head_tag(options = { }, &block)
15 | head = tag(:meta, charset: 'UTF-8')
16 | head += capture(&block) if block_given?
17 | head += content_for(:evil_front_head)
18 |
19 | options[:statistics] = true unless options.has_key? :statistics
20 | if options[:statistics] and Rails.env.production?
21 | head += render('layouts/statistics') rescue ''
22 | end
23 |
24 | content_tag(:head, head)
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/evil-front-all/lib/evil-front-all.rb:
--------------------------------------------------------------------------------
1 | require 'evil-front'
2 |
3 | require 'uglifier'
4 | require 'jquery-cdn'
5 | require 'coffee_script'
6 | require 'evil-blocks-rails'
7 | require 'autoprefixer-rails'
8 |
9 | module EvilFront
10 | # Install Evil Front, Autoprefixer, Evil Blocks, Rails Sass Images
11 | # and Csso to Sprockets.
12 | def self.install_all(sprockets, options = {})
13 | autoprefixer = { }
14 | autoprefixer[:browsers] = options[:browsers] if options.has_key? :browsers
15 |
16 | AutoprefixerRails.install(sprockets, autoprefixer)
17 | EvilBlocks.install(sprockets)
18 | JqueryCdn.install(sprockets)
19 | install(sprockets)
20 |
21 | EvilFront.set_slim_options!
22 | end
23 |
24 | unless defined? ::Rails
25 | module Helpers
26 | include JqueryCdn::Helpers
27 | end
28 | end
29 | end
30 |
31 | require_relative 'evil-front/all/version'
32 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/helpers/title_tag.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require 'i18n'
4 |
5 | module EvilFront::Helpers
6 | # Return title tag with current page title. It will just join page titles
7 | # from `title` helper and `site` name.
8 | #
9 | # By default, separator will be m-dash for Russian and n-dash for others.
10 | #
11 | # html
12 | # head
13 | # = title_tag('Foo Company')
14 | #
15 | # Separator will be taken by current locale. But, you can change it by
16 | # `separator` option:
17 | #
18 | # = title_tag('Foo Company', separator: ' * ')
19 | def title_tag(*site)
20 | options = site.extract_options!
21 | separator = options[:separator] || (I18n.locale == :ru ? ' — ' : ' - ')
22 |
23 | site = [] if @evil_front_no_site_in_title
24 |
25 | @evil_front_titles ||= []
26 | titles = (@evil_front_titles + site).compact
27 | titles = titles.join(separator)
28 | EvilFront.html_safe("
#{ EvilFront.escape(titles) }")
29 | end
30 | end
31 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front.rb:
--------------------------------------------------------------------------------
1 | require 'pathname'
2 |
3 | require 'slim'
4 | require 'sass'
5 | require 'sprockets'
6 | require 'rails-sass-images'
7 |
8 | module EvilFront
9 | autoload :Typograph, 'evil-front/typograph'
10 | autoload :Russian, 'evil-front/russian'
11 | autoload :English, 'evil-front/english'
12 |
13 | if defined?(::Rails)
14 | # Enable `lib/assets/` and `vendor/assets/` in Rails app.
15 | class Engine < ::Rails::Engine
16 | end
17 | end
18 |
19 | # Install Evil Front to standalone Sprockets environment.
20 | def self.install(sprockets)
21 | RailsSassImages.install(sprockets)
22 |
23 | root = Pathname(__FILE__).dirname.join('..')
24 | sprockets.append_path(root.join('lib/assets/javascripts'))
25 | sprockets.append_path(root.join('lib/assets/stylesheets'))
26 | sprockets.append_path(root.join('vendor/assets/fonts'))
27 | end
28 | end
29 |
30 | require_relative 'evil-front/version'
31 | require_relative 'evil-front/helpers'
32 | require_relative 'evil-front/slim'
33 |
--------------------------------------------------------------------------------
/evil-front-rails/evil-front-rails.gemspec:
--------------------------------------------------------------------------------
1 | require File.expand_path('../lib/evil-front/rails/version', __FILE__)
2 |
3 | Gem::Specification.new do |s|
4 | s.platform = Gem::Platform::RUBY
5 | s.name = 'evil-front-rails'
6 | s.version = EvilFront::Rails::VERSION
7 | s.date = Time.now.strftime('%Y-%m-%d')
8 | s.summary = 'Helpers, Sass mixins, JS shortcuts, workflow and ' +
9 | 'Rails settings from Evil Martians'
10 |
11 | s.author = 'Andrey Sitnik'
12 | s.email = 'andrey@sitnik.ru'
13 | s.homepage = 'https://github.com/ai/evil-front'
14 | s.license = 'MIT'
15 |
16 | s.files = `git ls-files`.split("\n")
17 | s.extra_rdoc_files = ['LICENSE']
18 | s.require_path = 'lib'
19 |
20 | min = EvilFront::Rails::VERSION.split('.')[0..1].concat(['0']).join('.')
21 | s.add_runtime_dependency 'evil-front-all', "~> #{min}"
22 |
23 | s.add_dependency 'rails', '>= 3'
24 | s.add_dependency 'sass-rails', '>= 3.2.6'
25 | s.add_dependency 'slim-rails', '>= 1.1.0'
26 | s.add_dependency 'coffee-rails', '>= 3.2.2'
27 | end
28 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/http.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/core
2 | // Add `evil.patch`, `evil.del`, `evil.put`, `evil.post` to send AJAX request
3 | // with RESTful HTTP verb by Rails X-HTTP-Method-Override header
4 | // and with CSRF token.
5 |
6 | (function($) {
7 | var props = { patch: 'PATCH', put: 'PUT', del: 'DELETE', post: 'POST' }
8 | $.each(props, function(prop, method) {
9 | evil[prop] = function(url, data, callback, type) {
10 | if ($.isFunction(data)) {
11 | type = type || callback;
12 | callback = data;
13 | data = { };
14 | }
15 |
16 | return $.ajax({
17 | headers: {
18 | 'X-HTTP-Method-Override': method,
19 | 'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
20 | },
21 | type: 'POST',
22 | url: url,
23 | data: data,
24 | success: callback,
25 | dataType: type
26 | });
27 | }
28 | })
29 | })(jQuery);
30 |
--------------------------------------------------------------------------------
/evil-front/evil-front.gemspec:
--------------------------------------------------------------------------------
1 | require File.expand_path('../lib/evil-front/version', __FILE__)
2 |
3 | Gem::Specification.new do |s|
4 | s.platform = Gem::Platform::RUBY
5 | s.name = 'evil-front'
6 | s.version = EvilFront::VERSION
7 | s.date = Time.now.strftime('%Y-%m-%d')
8 | s.summary = 'Helpers, Sass mixins and JS shortcuts from Evil Martians'
9 |
10 | s.author = 'Andrey Sitnik'
11 | s.email = 'andrey@sitnik.ru'
12 | s.homepage = 'https://github.com/ai/evil-front'
13 | s.license = 'MIT'
14 |
15 | s.files = `git ls-files`.split("\n")
16 | s.extra_rdoc_files = ['LICENSE']
17 | s.require_path = 'lib'
18 |
19 | s.add_dependency 'i18n', '>= 0'
20 | s.add_dependency 'slim', '>= 1.3.9'
21 | s.add_dependency 'sass', '>= 3.2.9'
22 | s.add_dependency 'nokogiri', '>= 1'
23 | s.add_dependency 'sprockets', '>= 1'
24 | s.add_dependency 'unicode_utils', '>= 1.4'
25 | s.add_dependency 'rubypants-unicode', '>= 0'
26 | s.add_dependency 'rails-sass-images', '>= 0.3'
27 | s.add_dependency 'standalone_typograf', '>= 3.0.1'
28 | end
29 |
--------------------------------------------------------------------------------
/evil-front-all/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright 2013 Andrey Sitnik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/evil-front/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright 2013 Andrey Sitnik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/evil-front-rails/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright 2013 Andrey Sitnik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/evil-front-rails/lib/evil-front-rails.rb:
--------------------------------------------------------------------------------
1 | require 'evil-front-all'
2 |
3 | require 'sass-rails'
4 | require 'slim-rails'
5 |
6 | module EvilFront
7 | class Railtie < ::Rails::Railtie
8 | initializer 'evil_front.config' do |app|
9 | # Disable assets and helper per controller
10 | app.config.generators.stylesheets = false
11 | app.config.generators.javascripts = false
12 | app.config.generators.helper = false
13 |
14 | # Precompile all JS/CSS in root of app assets dirs.
15 | app.config.assets.precompile +=
16 | Dir[::Rails.root.join('app/assets/*/*.{js,css,coffee,sass,scss}*')].
17 | map { |i| File.basename(i).sub(/(\.js)?\.coffee$/, '.js') }.
18 | map { |i| File.basename(i).sub(/(\.css)?\.(sass|scss)$/, '.css') }.
19 | reject { |i| i =~ /^application\.(js|css)$/ }
20 |
21 | # Sass debug in Chrome
22 | if ::Rails.env.development?
23 | app.config.sass.debug_info = true
24 | end
25 | end
26 |
27 | initializer 'evil_front.action_view' do
28 | ActiveSupport.on_load(:action_view) { include Helpers }
29 | end
30 | end
31 | end
32 |
33 | require_relative 'evil-front/rails/version'
34 |
--------------------------------------------------------------------------------
/evil-front-all/evil-front-all.gemspec:
--------------------------------------------------------------------------------
1 | require File.expand_path('../lib/evil-front/all/version', __FILE__)
2 |
3 | Gem::Specification.new do |s|
4 | s.platform = Gem::Platform::RUBY
5 | s.name = 'evil-front-all'
6 | s.version = EvilFront::All::VERSION
7 | s.date = Time.now.strftime('%Y-%m-%d')
8 | s.summary = 'Helpers, Sass mixins, JS shortcuts and workflow ' +
9 | 'from Evil Martians'
10 |
11 | s.author = 'Andrey Sitnik'
12 | s.email = 'andrey@sitnik.ru'
13 | s.homepage = 'https://github.com/ai/evil-front'
14 | s.license = 'MIT'
15 |
16 | s.files = `git ls-files`.split("\n")
17 | s.extra_rdoc_files = ['LICENSE']
18 | s.require_path = 'lib'
19 |
20 | min = EvilFront::All::VERSION.split('.')[0..1].concat(['0']).join('.')
21 | s.add_runtime_dependency 'evil-front', "~> #{min}"
22 |
23 | s.add_dependency 'uglifier', '>= 2.1.1'
24 | s.add_dependency 'sprockets', '>= 1'
25 | s.add_dependency 'jquery-cdn', '>= 1'
26 | s.add_dependency 'coffee-script', '>= 2.2.0'
27 | s.add_dependency 'evil-blocks-rails', '>= 0.2'
28 | s.add_dependency 'autoprefixer-rails', '>= 3.0'
29 | end
30 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/transform3d.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/core
2 |
3 | (function() {
4 | var cache = undefined;
5 | var inited = false;
6 |
7 | evil.transform3d = {
8 |
9 | // Check support for 3D transforms.
10 | check: function () {
11 | if ( typeof(cache) != 'undefined' ) {
12 | return cache;
13 | }
14 |
15 | var cache = typeof(evil.body.css('perspective')) != 'undefined';
16 | var style = document.body;
17 | if ( cache && typeof(style.webkitPerspective) != 'undefined' ) {
18 | cache = matchMedia("(transform-3d), (-webkit-transform-3d)");
19 | cache = cache.matches;
20 | }
21 | return cache;
22 | },
23 |
24 | // Add `transform3d` or `transform2s` class to body.
25 | init: function () {
26 | if ( inited ) {
27 | return;
28 | }
29 | inited = true;
30 |
31 | evil.doc.ready(function () {
32 | var type = evil.transform3d.check() ? '3d' : '2d'
33 | evil.body.addClass('transform-' + type);
34 | });
35 | }
36 | }
37 |
38 | })();
39 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/queue.js:
--------------------------------------------------------------------------------
1 | //= evil-front/core
2 |
3 | (function() {
4 | // Call `callback` only after previous callback of `name` queue
5 | // will be finished. It is useful to animation.
6 | //
7 | // b.link.click ->
8 | // evil.queue 'link', (done) ->
9 | // $.get $(@).url, (html) ->
10 | // animation html, ->
11 | // done()
12 | evil.queue = function(name, callback) {
13 | if ( typeof(name) == 'function' ) {
14 | callback = name;
15 | name = 'default';
16 | }
17 |
18 | if ( typeof(waiters[name]) == 'undefined' ) {
19 | waiting[name] = false;
20 | waiters[name] = [];
21 | }
22 |
23 | if ( waiting[name] ) {
24 | waiters[name].push(callback);
25 | } else {
26 | call(name, callback);
27 | }
28 | };
29 |
30 | var waiting = { };
31 | var waiters = { };
32 |
33 | var call = function(name, callback) {
34 | waiting[name] = true;
35 | callback(function () {
36 | waiting[name] = false;
37 | var waiter = waiters[name].pop();
38 | if ( waiter ) {
39 | call(name, waiter);
40 | }
41 | });
42 | };
43 | })();
44 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/outside.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/jquery
2 |
3 | (function() {
4 | evil.$.extend('outside', function (callback) {
5 | var parent = this;
6 |
7 | var event = function(e) {
8 | var el = $(e.target);
9 | if ( !el.closest(parent).length ) {
10 | callback();
11 | off();
12 | }
13 | };
14 |
15 | if ( document.body.addEventListener ) {
16 | var set = function () {
17 | document.body.addEventListener('click', event, true);
18 | document.body.addEventListener('focus', event, true);
19 | }
20 | var off = function () {
21 | document.body.removeEventListener('click', event, true);
22 | document.body.removeEventListener('focus', event, true);
23 | };
24 |
25 | } else {
26 | var name = '.evil-outside-' + (new Date()).valueOf();
27 |
28 | var set = function () {
29 | evil.body.on('click' + name + ' focus' + name, event);
30 | }
31 | var off = function () {
32 | evil.body.off(name);
33 | };
34 | }
35 |
36 | setTimeout(set, 10);
37 | return off;
38 | });
39 |
40 | })();
41 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | require 'bundler/setup'
3 |
4 | GEMS = %w(evil-front evil-front-rails evil-front-all)
5 | SPECS = GEMS - ['evil-front-all', 'evil-front-rails']
6 |
7 | def each_gem(&block)
8 | GEMS.each do |dir|
9 | Dir.chdir(dir, &block)
10 | end
11 | end
12 |
13 | def rake(task)
14 | sh "#{Rake::DSL::RUBY} -S bundle exec rake #{task}", verbose: false
15 | end
16 |
17 | def each_rake(task)
18 | each_gem { rake task }
19 | end
20 |
21 | require 'rspec/core/rake_task'
22 |
23 | class SubgemSpecTask < RSpec::Core::RakeTask
24 | attr_accessor :gem
25 |
26 | def initialize(gem)
27 | @gem = gem
28 | super("spec_#{@gem}")
29 | end
30 |
31 | def desc(text); end # Monkey patch to hide task desc
32 |
33 | def pattern
34 | "#{@gem}/spec{,/*/**}/*_spec.rb"
35 | end
36 | end
37 |
38 | SPECS.each { |gem| SubgemSpecTask.new(gem) }
39 |
40 | desc 'Run all specs'
41 | task :spec => (SPECS.map { |i| "spec_#{i}" })
42 | task :default => :spec
43 |
44 |
45 | task :build do
46 | each_rake 'build'
47 | end
48 |
49 | desc 'Build gems and push thems to RubyGems'
50 | task :release => [:clobber, :build] do
51 | each_gem { sh 'gem push `ls pkg/*`' }
52 | each_rake 'clobber'
53 | end
54 |
55 | desc 'Remove all generated files'
56 | task :clobber do
57 | rm_r 'log' if File.exists? 'log'
58 | each_rake 'clobber'
59 | end
60 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/jquery.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/core
2 |
3 | (function ($) {
4 |
5 | // Create namespace for jQuery
6 | evil.jquery = function(global, namespace) {
7 | // Namespace inside jQuery.
8 | global.$ = function (nodes) {
9 | this.nodes = nodes;
10 | };
11 |
12 | // Syntax sugar to add own method to `$.fn.evil`.
13 | global.$.extend = function (name, value) {
14 | if ( $.isPlainObject(name) ) {
15 | for ( key in name ) {
16 | global.$.extend(key, name[key]);
17 | }
18 | return;
19 | }
20 |
21 | if ( $.isFunction(value) ) {
22 | var callback = value;
23 | value = function () {
24 | return callback.apply(this.nodes, arguments);
25 | };
26 | }
27 | this.prototype[name] = value;
28 | };
29 |
30 | // Hack to add `$.fn.evil` namespace.
31 | var originaljQuery = $.fn.init;
32 | $.fn.init = function () {
33 | nodes = originaljQuery.apply(this, arguments);
34 | nodes[namespace] = new global.$(nodes);
35 | return nodes;
36 | };
37 | $.fn.init.prototype = originaljQuery.prototype;
38 | };
39 |
40 | // Create `evil.$` namespace.
41 | evil.jquery(evil, 'evil');
42 |
43 | })(jQuery);
44 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/easings.sass:
--------------------------------------------------------------------------------
1 | // Variables with easings Bezier curves
2 | //
3 | // transition: all 1s $easeInOutBack
4 |
5 | $easeInSine: cubic-bezier(0.47, 0, 0.745, 0.715)
6 | $easeOutSine: cubic-bezier(0.39, 0.575, 0.565, 1)
7 | $easeInOutSine: cubic-bezier(0.445, 0.05, 0.55, 0.95)
8 |
9 | $easeInQuad: cubic-bezier(0.55, 0.085, 0.68, 0.53)
10 | $easeOutQuad: cubic-bezier(0.25, 0.46, 0.45, 0.94)
11 | $easeInOutQuad: cubic-bezier(0.455, 0.03, 0.515, 0.955)
12 |
13 | $easeInCubic: cubic-bezier(0.55, 0.055, 0.675, 0.19)
14 | $easeOutCubic: cubic-bezier(0.215, 0.61, 0.355, 1)
15 | $easeInOutCubic: cubic-bezier(0.645, 0.045, 0.355, 1)
16 |
17 | $easeInQuart: cubic-bezier(0.895, 0.03, 0.685, 0.22)
18 | $easeOutQuart: cubic-bezier(0.165, 0.84, 0.44, 1)
19 | $easeInOutQuart: cubic-bezier(0.77, 0, 0.175, 1)
20 |
21 | $easeInQuint: cubic-bezier(0.755, 0.05, 0.855, 0.06)
22 | $easeOutQuint: cubic-bezier(0.23, 1, 0.32, 1)
23 | $easeInOutQuint: cubic-bezier(0.86, 0, 0.07, 1)
24 |
25 | $easeInExpo: cubic-bezier(0.95, 0.05, 0.795, 0.035)
26 | $easeOutExpo: cubic-bezier(0.19, 1, 0.22, 1)
27 | $easeInOutExpo: cubic-bezier(1, 0, 0, 1)
28 |
29 | $easeInCirc: cubic-bezier(0.6, 0.04, 0.98, 0.335)
30 | $easeOutCirc: cubic-bezier(0.075, 0.82, 0.165, 1)
31 | $easeInOutCirc: cubic-bezier(0.785, 0.135, 0.15, 0.86)
32 |
33 | $easeInBack: cubic-bezier(0.6, -0.28, 0.735, 0.045)
34 | $easeOutBack: cubic-bezier(0.175, 0.885, 0.32, 1.275)
35 | $easeInOutBack: cubic-bezier(0.68, -0.55, 0.265, 1.55)
36 |
--------------------------------------------------------------------------------
/evil-front/ChangeLog.md:
--------------------------------------------------------------------------------
1 | ## 0.5.1
2 |
3 | * Fix `evil.body` initializing (by Vladimir Dementyev).
4 |
5 | ## 0.5 “Chryse Planitia”
6 |
7 | * Remove `clean-css`.
8 |
9 | ## 0.4 “Schiaparelli Crater”
10 |
11 | * Add Sprockets 3 support.
12 |
13 | ## 0.3.10
14 |
15 | * Add Slim 3.0 support.
16 |
17 | ## 0.3.9
18 |
19 | * Fix typograph on new line before m-dash.
20 |
21 | ## 0.3.8
22 |
23 | * Import all inner dependenies in mixins to import only necessary mixin.
24 |
25 | ## 0.3.7
26 |
27 | * Use non-break dash only in Russian words.
28 |
29 | ## 0.3.6
30 |
31 | * Russian typograph inserts non-break space before m-dash.
32 |
33 | ## 0.3.5
34 |
35 | * `$.fn.evil.ajax` and `$.fn.evil.tappable` return element’s jQuery node
36 | to be used in chains.
37 |
38 | ## 0.3.4
39 |
40 | * Add `no_site` option to `title` helper.
41 | * Better `+stroke-text` by Vadim Sikora.
42 |
43 | ## 0.3.3
44 |
45 | * Fix `+hover` mixin loading.
46 |
47 | ## 0.3.2
48 |
49 | * Add `+hover` Sass mixin.
50 |
51 | ## 0.3.1
52 |
53 | * Add labels to tappable by default.
54 |
55 | ## 0.3 “Samara Vallis”
56 |
57 | * Russian typograph doesn’t insert flying quotes tag anymore.
58 | * Add separated `auto_flying_quotes` helper.
59 |
60 | ## 0.2.1
61 |
62 | * Fix encoding issue with Nokogiri in `english_typograph`.
63 |
64 | ## 0.2 “Ptolemaeus Crater”
65 |
66 | * Add `english_typograph` helper.
67 | * Add `typograph_by_locale` helper to use typographer for current I18n locale.
68 | * Increase `russian_typograph` speed.
69 | * Increase `evil-front/links.js` speed.
70 |
71 | ## 0.1 “Hellespontus Montes”
72 |
73 | * Initial release.
74 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/tappable.js:
--------------------------------------------------------------------------------
1 | //= require evil-front/jquery
2 |
3 | // Add events to add special class on touch events. It will much faster, than
4 | // `:hover` selector. It returns jQuery node of element for chains.
5 | //
6 | // By default it add listener to all links and inputs on body.
7 | // But you can add it to any elements:
8 | //
9 | // $('.pseudolink').evil.tappable();
10 | //
11 | // Or you can set listeners as “live” delegate:
12 | //
13 | // $('.ajax-updated').evil.tappable('.pseudolink');
14 | //
15 | // Don’t forget about `no-hover` and `styled-taps` Sass mixins.
16 | (function () {
17 | var start = function () {
18 | this.classList.add('is-tapped');
19 | };
20 | var end = function () {
21 | var link = $(this);
22 | setTimeout(function () {
23 | link.removeClass('is-tapped').
24 | addClass('was-tapped').
25 | one('mouseenter', function () {
26 | link.removeClass('was-tapped');
27 | });
28 | }, 100);
29 | };
30 |
31 | evil.$.extend({
32 | tappable: function (selector) {
33 | if ( selector ) {
34 | this.on('touchstart', selector, start);
35 | this.on('touchend touchmove', selector, end);
36 | } else {
37 | this.on('touchstart', start);
38 | this.on('touchend touchmove', end);
39 | }
40 | return this;
41 | }
42 | });
43 |
44 | evil.doc.ready(function ($) {
45 | evil.body.evil.tappable('a, input, label');
46 | });
47 | })();
48 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/stylesheets/evil-front/import-ruble.sass:
--------------------------------------------------------------------------------
1 | // Define special class and fonts for Russian currency symbol.
2 | //
3 | // You must set you body fonts for `$defaults` argument. Also you can inline
4 | // in `data:uri` fonts styles, which you will use.
5 | //
6 | // +import-ruble("PT Sans, sans-serif", $regular: inline)
7 | @mixin import-ruble($defaults: sans-serif, $regular: false, $italic: false, $bold: false, $bolditalic: false)
8 | @font-face
9 | font-family: 'ALSRubl-Arial'
10 | @if $regular
11 | src: inline("evil-front/alsrubl-arial-regular.woff") format("woff")
12 | @else
13 | src: font-url("evil-front/alsrubl-arial-regular.woff") format("woff")
14 |
15 | @font-face
16 | font-family: 'ALSRubl-Arial'
17 | font-style: italic
18 | @if $italic
19 | src: inline("evil-front/alsrubl-arial-italic.woff") format("woff")
20 | @else
21 | src: font-url("evil-front/alsrubl-arial-italic.woff") format("woff")
22 |
23 | @font-face
24 | font-family: 'ALSRubl-Arial'
25 | font-weight: bold
26 | @if $bold
27 | src: inline("evil-front/alsrubl-arial-bold.woff") format("woff")
28 | @else
29 | src: font-url("evil-front/alsrubl-arial-bold.woff") format("woff")
30 |
31 | @font-face
32 | font-family: 'ALSRubl-Arial'
33 | font-style: italic
34 | font-weight: bold
35 | @if $bolditalic
36 | src: inline("evil-front/alsrubl-arial-bolditalic.woff") format("woff")
37 | @else
38 | src: font-url("evil-front/alsrubl-arial-bolditalic.woff") format("woff")
39 |
40 | .ruble
41 | font-family: ALSRubl-Arial, unquote($defaults)
42 | line-height: 1
43 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/typograph.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require 'nokogiri'
4 |
5 | module EvilFront
6 | # Abstract module to be used in `Russian` and `English` typographs.
7 | module Typograph
8 | # Like `typograph`, but process only text nodes in HTML.
9 | #
10 | # EvilFront::Russian.typograph_html(article.html)
11 | def typograph_html(html)
12 | process_html(html) { |text| typograph(text) }
13 | end
14 |
15 | # Insert non-break spaces and mark quotes to have nice text.
16 | #
17 | # EvilFront::Russian.typograph(article)
18 | def typograph(text)
19 | return text if text.nil? or text.empty?
20 |
21 | text.gsub! '"', '"'
22 | text = use_right_symbols(text)
23 | tiny_words.each { |regexp| text.gsub! regexp, "\\1\\2 " }
24 |
25 | text
26 | end
27 |
28 | private
29 |
30 | # Parse HTML and run block only on texts
31 | def process_html(html, &block)
32 | return html if html.nil? or html.empty?
33 |
34 | if html.include? '<'
35 | nodes = Nokogiri::HTML::DocumentFragment.parse(html, 'utf-8')
36 | process_node!(nodes, &block)
37 | nodes.to_html
38 | else
39 | yield(html)
40 | end
41 | end
42 |
43 | # Run block on every text node recursively
44 | def process_node!(node, &block)
45 | return if %w(pre code kbd script style math).include? node.name
46 |
47 | node.children.each do |child|
48 | if child.is_a? Nokogiri::XML::Text
49 | text = EvilFront.escape(child.content)
50 | child.replace( yield(text) )
51 | else
52 | process_node! child, &block
53 | end
54 | end
55 | end
56 | end
57 | end
58 |
--------------------------------------------------------------------------------
/evil-front/lib/assets/javascripts/evil-front/ajax.js:
--------------------------------------------------------------------------------
1 | //= evil-front/jquery
2 |
3 | // Change selected form to be sent by AJAX.
4 | // It returns jQuery node of form for chains.
5 | //
6 | // $('form').evil.ajax
7 | // success: -> message('success')
8 | // error: (text) -> message('error' + text)
9 | //
10 | // While AJAX is loading, form will has `is-submitting` class.
11 | // Don’t forget to show loader.
12 | evil.$.extend('ajax', function (opts) {
13 | if ( !opts ) {
14 | opts = { };
15 | }
16 |
17 | return this.submit(function (event) {
18 | if ( event.isPropagationStopped() ) {
19 | return false;
20 | }
21 |
22 | var form = $(this);
23 |
24 | if ( form.hasClass('is-submitting') ) {
25 | return false;
26 | }
27 | form.addClass('is-submitting');
28 |
29 | var check = true;
30 | if ( opts.submitting ) {
31 | check = opts.submitting(form);
32 | }
33 | if ( !check ) {
34 | return false;
35 | }
36 |
37 | $.ajax({
38 | url: form.attr('action'),
39 | type: form.attr('method').toUpperCase(),
40 | data: form.serialize(),
41 | success: function (data) {
42 | if ( opts.success ) {
43 | opts.success(data, form);
44 | }
45 | },
46 | error: function (e) {
47 | if ( e.status == 500 ) {
48 | if ( opts.serverError ) {
49 | opts.serverError(form);
50 | }
51 | } else if ( opts.error ) {
52 | opts.error(e.responseText, form);
53 | }
54 | },
55 | complete: function () {
56 | form.removeClass('is-submitting');
57 | }
58 | });
59 |
60 | return false;
61 | });
62 | });
63 |
--------------------------------------------------------------------------------
/evil-front/lib/evil-front/russian.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require 'unicode_utils'
4 | # encoding: utf-8
5 |
6 | require 'standalone_typograf'
7 |
8 | module EvilFront
9 | # Helpers to work with Russian text.
10 | module Russian
11 | extend Typograph
12 |
13 | # Capitalize only first letter (like titles in Russian).
14 | #
15 | # = EvilFront::Russian.capitalize_first(title)
16 | def self.capitalize_first(text)
17 | UnicodeUtils.upcase(text[0]) + text[1..-1]
18 | end
19 |
20 | # Find quotes in text and make them flying
21 | def self.auto_flying_quotes(html)
22 | process_html(html) do |text|
23 | text.gsub(/\s«[^»]+»/) { |i| flying_quotes i[2..-2], space: i[0] }.
24 | gsub(/^«[^»]+»/) { |i| flying_quotes i[1..-2], space: '' }
25 | end
26 | end
27 |
28 | # Mark quotes to move first quote before the text line.
29 | def self.flying_quotes(text, options = { })
30 | sp = options[:space] || ' '
31 | sp = "#{sp}" if sp != ''
32 | "#{ sp }«#{ text }»"
33 | end
34 |
35 | private
36 |
37 | # Small words to insert non-break space before them
38 | def self.tiny_words
39 | @tiny_words ||= begin
40 | tiny = %w(ни не и но а или да как из-за про по за для
41 | на до при меж о у в во с со от ото из без
42 | безо к ко об обо под подо над перед передо это)
43 | tiny += tiny.map { |i| capitalize_first(i) }
44 | tiny.map { |i| Regexp.new("( | )(#{Regexp.quote i}) ") }
45 | end
46 | end
47 |
48 | # Replace symbols to right ones, like m-dash, quotes, etc.
49 | def self.use_right_symbols(text)
50 | StandaloneTypograf::Typograf.new(text)
51 | .processor(:dashes, :quotes, :mnemonics, :fractions, :ellipsis)
52 | .gsub(' —', ' —') # nbsp before m-dash
53 | .gsub(/([а-яА-Я])-([а-яА-Я])/, '\1‑\2') # non-break dash
54 | end
55 | end
56 | end
57 |
--------------------------------------------------------------------------------
/evil-front/spec/sass_spec.rb:
--------------------------------------------------------------------------------
1 | require_relative 'spec_helper'
2 |
3 | describe 'Sass Helpers' do
4 | before(:all) do
5 | @assets = Sprockets::Environment.new
6 | @assets.append_path File.expand_path('../sass', __FILE__)
7 | EvilFront.install(@assets)
8 |
9 | @assets.context_class.class_eval do
10 | def asset_path(path, options = {})
11 | ''
12 | end
13 | end
14 | end
15 |
16 | it 'loads Rails Sass Images' do
17 | expect(@assets['load'].to_s).to match(/data:text\/plain/)
18 | end
19 |
20 | it 'loads variables, functions and mixins' do
21 | load = @assets['load'].to_s
22 | expect(load).to match(/rgba\(0, 0, 0, 0.5\)/)
23 | expect(load).to match(/cubic-bezier\(0.47, 0, 0.745, 0.715\)/)
24 | expect(load).to match(/a:after/)
25 | end
26 |
27 | describe '+import-ruble' do
28 |
29 | it 'adds font-faces and .ruble' do
30 | ruble = @assets['ruble'].to_s
31 | expect(ruble).to match(/font-family: ALSRubl-Arial, PT Sans, sans-serif/)
32 | expect(ruble).not_to match(/font-woff;base64/)
33 | end
34 |
35 | it 'inlines specified fonts' do
36 | ruble = @assets['inline-ruble'].to_s
37 | expect(ruble).to match(/font-style: italic;\s*src: url\('data/n)
38 | end
39 |
40 | end
41 |
42 | describe 'media mixins' do
43 | before(:all) do
44 | @media = @assets['media'].to_s
45 | end
46 |
47 | it 'receives size without units' do
48 | expect(@media).to match(/max-width: 100px/)
49 | end
50 |
51 | it 'receives size with units' do
52 | expect(@media).to match(/min-width: 200px/)
53 | end
54 |
55 | end
56 |
57 | describe '+size' do
58 | before(:all) do
59 | @size = @assets['size'].to_s
60 | end
61 |
62 | it 'receives 2 sizes' do
63 | expect(@size).to match(/.all {\s*width: 10px;\s*height: 20px; }/)
64 | end
65 |
66 | it 'receives 1 sizes' do
67 | expect(@size).to match(/.one {\s*width: 30px;\s*height: 30px; }/)
68 | end
69 |
70 | it 'receives size without unit' do
71 | expect(@size).to match(/.no-unit {\s*width: 15px;\s*height: 15px; }/)
72 | end
73 |
74 | end
75 | end
76 |
--------------------------------------------------------------------------------
/evil-front/spec/russian_spec.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require_relative 'spec_helper'
4 |
5 | describe EvilFront::Russian do
6 |
7 | describe 'capitalize_first' do
8 |
9 | it 'capitalizes first letter in russian text' do
10 | expect(EvilFront::Russian.capitalize_first('тест тест')).to eq 'Тест тест'
11 | end
12 |
13 | end
14 |
15 | describe 'flying_quotes' do
16 |
17 | it 'inserts tags and quotes with space by default' do
18 | expect(EvilFront::Russian.flying_quotes('тест')).to eq(
19 | ' ' +
20 | '«тест»')
21 | end
22 |
23 | it 'inserts specified space' do
24 | expect(EvilFront::Russian.flying_quotes('тест', space: '-')).to eq(
25 | '-' +
26 | '«тест»')
27 | end
28 |
29 | it 'ignores space on request' do
30 | expect(EvilFront::Russian.flying_quotes('тест', space: '')).to eq(
31 | '«тест»')
32 | end
33 |
34 | end
35 |
36 | describe 'auto_flying_quotes' do
37 |
38 | it 'replaces quotes on start' do
39 | expect(EvilFront::Russian.auto_flying_quotes('«тест»')).to eq(
40 | '«тест»')
41 | end
42 |
43 | it 'replaces quotes in middle' do
44 | expect(EvilFront::Russian.auto_flying_quotes('на «тесте».')).to eq(
45 | 'на ' +
46 | '«тесте».')
47 | end
48 |
49 | it 'works with HTML' do
50 | expect(EvilFront::Russian.auto_flying_quotes('«ссылка»')).to eq(
51 | '«ссылка»')
52 | end
53 |
54 | end
55 |
56 | describe 'typograph' do
57 | def nbsp_mark_typograph(str)
58 | EvilFront::Russian.typograph(str).gsub(' ', '_')
59 | end
60 |
61 | it 'changes quotes' do
62 | expect(nbsp_mark_typograph('сказал "смотри "зорко"".')).to eq(
63 | 'сказал «смотри „зорко“».')
64 | end
65 |
66 | it 'changes dashes' do
67 | expect(nbsp_mark_typograph('а - это б')).to eq 'а_— это_б'
68 | end
69 |
70 | it 'changes ellipsis' do
71 | expect(nbsp_mark_typograph('а...')).to eq 'а…'
72 | end
73 |
74 | it 'keeps new line before dash' do
75 | expect(nbsp_mark_typograph("- Что?\n- То!")).to eq "— Что?\n— То!"
76 | end
77 |
78 | it 'uses non-break dash on for Russian' do
79 | expect(nbsp_mark_typograph('web-standards.ru')).to eq 'web-standards.ru'
80 | expect(nbsp_mark_typograph('а-то')).to eq 'а‑то'
81 | end
82 |
83 | end
84 |
85 | describe 'typograph_html' do
86 |
87 | it 'typographs plain text' do
88 | expect(EvilFront::Russian.typograph_html('а...')).to eq 'а…'
89 | end
90 |
91 | it 'typographs only in text nodes' do
92 | expect(EvilFront::Russian.typograph_html('а...')).
93 | to eq 'а…'
94 | end
95 |
96 | it 'ignores code tags' do
97 | expect(EvilFront::Russian.typograph_html('а...')).
98 | to eq 'а...'
99 | end
100 |
101 | it 'keeps escaping' do
102 | expect(EvilFront::Russian.typograph_html('<a>')).
103 | to eq '<a>'
104 | end
105 |
106 | end
107 |
108 | end
109 |
--------------------------------------------------------------------------------
/evil-front/spec/helpers_spec.rb:
--------------------------------------------------------------------------------
1 | # encoding: utf-8
2 |
3 | require_relative 'spec_helper'
4 | require 'slim'
5 |
6 | describe EvilFront::Helpers do
7 | include EvilFront::Helpers
8 |
9 | describe 'capitalize_first' do
10 |
11 | it 'capitalizes Russian' do
12 | expect(capitalize_first('тест')).to eq 'Тест'
13 | end
14 |
15 | end
16 |
17 | describe 'disable_mobile_zoom' do
18 |
19 | it 'returns viewport meta tag' do
20 | expect(disable_mobile_zoom).to match(/^ ' +
30 | '«a»')
31 | end
32 |
33 | it 'escapes HTML' do
34 | expect(flying_quotes('
')).to eq(
35 | ' ' +
36 | '«<br>»')
37 | end
38 |
39 | end
40 |
41 | describe 'auto_flying_quotes' do
42 |
43 | it 'set quotes to text' do
44 | expect(auto_flying_quotes('от «a»')).to eq(
45 | 'от ' +
46 | '«a»')
47 | end
48 |
49 | it 'escapes HTML' do
50 | expect(auto_flying_quotes('от «
»')).to eq(
51 | 'от ' +
52 | '«<br>»')
53 | end
54 |
55 | end
56 |
57 | describe 'ruble' do
58 |
59 | it 'returns span' do
60 | expect(ruble).to be_a(String)
61 | end
62 |
63 | end
64 |
65 | describe 'russian_typograph' do
66 |
67 | it 'typographs text inside tags' do
68 | tag = 'а...'.html_safe
69 | expect(russian_typograph(tag)).to eq'а…'
70 | end
71 |
72 | it 'escapes HTML' do
73 | expect(russian_typograph('')).to eq '<a>'
74 | end
75 |
76 | end
77 |
78 | describe 'english_typograph' do
79 |
80 | it 'typographs text inside tags' do
81 | tag = 'a...'.html_safe
82 | expect(english_typograph(tag)).to eq 'a…'
83 | end
84 |
85 | it 'escapes HTML' do
86 | expect(english_typograph('')).to eq '<a>'
87 | end
88 |
89 | end
90 |
91 | describe 'typograph_by_locale' do
92 | after do
93 | I18n.locale = :en
94 | end
95 |
96 | it 'typographs by current locale' do
97 | I18n.locale = :en
98 | expect(typograph_by_locale('"a"')).to eq '“a”'
99 |
100 | I18n.locale = :ru
101 | expect(typograph_by_locale('"a"')).to eq '«a»'
102 | end
103 |
104 | it 'returns origin text on unknown locale' do
105 | I18n.locale = :fr
106 | expect(typograph_by_locale('"a"')).to eq '"a"'
107 | end
108 |
109 | end
110 |
111 | describe 'title' do
112 | after do
113 | I18n.locale = :en
114 | @evil_front_titles = nil
115 | end
116 |
117 | it 'shows site name' do
118 | expect(title_tag('Site')).to eq 'Site'
119 | end
120 |
121 | it 'shows site names' do
122 | expect(title_tag('One', 'Two')).to eq 'One - Two'
123 | end
124 |
125 | it 'shows page name' do
126 | title 'Page', 'Section'
127 | expect(title_tag('Site')).to eq 'Page - Section - Site'
128 | end
129 |
130 | it 'shows Russian separator' do
131 | I18n.locale = :ru
132 | title 'Страница', 'Раздел'
133 | expect(title_tag('Сайт')).to eq 'Страница — Раздел — Сайт'
134 | end
135 |
136 | it 'shows custom separator' do
137 | title 'One', 'Two'
138 | expect(title_tag(separator: ' | ')).to eq 'One | Two'
139 | end
140 |
141 | it 'escapes HTML' do
142 | title ''
143 | expect(title_tag).to eq '<B>'
144 | end
145 |
146 | it 'hides site name on request' do
147 | title 'Page', no_site: true
148 | expect(title_tag('Site')).to eq 'Page'
149 | end
150 |
151 | end
152 |
153 | end
154 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Evil Front [](https://travis-ci.org/ai/evil-front)
2 |
3 | Helpers, shortcuts and my common frontend workflows
4 | from [Evil Martians](http://evilmartians.com/).
5 |
6 | The project is separated into 3 gems:
7 | * [Evil Front](evil-front/) only contains helpers and doesn’t change
8 | the application environment.
9 | * [Evil Front All](evil-front-all/) loads the workflow gems: Autoprefixer, Csso,
10 | Slim, JqueryCdn, Evil Blocks, Uglifier.
11 | * [Evil Front Rails](evil-front-rails/) loads the workflow gems and changes\
12 | Rails settings to create my common frontend workflow
13 | with a single line of code.
14 |
15 | You can safely use Evil Front Core, but the other two gems have side effects,
16 | so I recommend to only use them for new projects.
17 |
18 | Some of the view helpers from Evil Front Core may require Rails, but most of them
19 | work with any Ruby application.
20 |
21 |
22 |
23 |
24 |
25 | ## Helpers
26 |
27 | The Evil Front Core gem contains assets and view helpers:
28 |
29 | ### View Helpers
30 |
31 | #### Typography
32 |
33 | * [russian_typograph](evil-front/lib/evil-front/helpers/russian_typograph.rb)
34 | to add typographical symbols (like Russian quotes, em-dash),
35 | non-breaking spaces.
36 | * [english_typograph](evil-front/lib/evil-front/helpers/english_typograph.rb)
37 | to add typographical symbols (like quotes, ellipsis), non-breaking spaces.
38 | * [typograph_by_locale](evil-front/lib/evil-front/helpers/typograph_by_locale.rb)
39 | uses `russian_typograph` or `english_typograph` depend on current locale.
40 | * [auto_flying_quotes](evil-front/lib/evil-front/helpers/auto_flying_quotes.rb)
41 | add tags to quotes to move it from text left horizontal line.
42 | * [ruble](evil-front/lib/evil-front/helpers/ruble.rb) to insert the Russian
43 | currency character.
44 | * [capitalize_first](evil-front/lib/evil-front/helpers/capitalize_first.rb)
45 | to capitalize only first letter.
46 |
47 | #### Head Tags
48 |
49 | * [title](evil-front/lib/evil-front/helpers/title.rb) to set page title
50 | in view file and [title_tag](evil-front/lib/evil-front/helpers/title_tag.rb)
51 | to use title from view in layout.
52 | * [standard_assets](evil-front/lib/evil-front/helpers/standard_assets.rb)
53 | shortcut to add `application.css`, jQuery from CDN and `application.js`.
54 | * [head_content](evil-front/lib/evil-front/helpers/head_content.rb)
55 | to add some tags to head from view and
56 | [head_tag](evil-front/lib/evil-front/helpers/head_tag.rb) to use views
57 | head tags in layout.
58 | * [disable_mobile_zoom](evil-front/lib/evil-front/helpers/disable_mobile_zoom.rb)
59 | shortcut for common viewport usage.
60 |
61 | #### Other
62 |
63 | * [tel](evil-front/lib/evil-front/helpers/tel.rb) to insert phone numbers as
64 | links with the `tel:` protocol.
65 |
66 | ### Sass Helpers
67 |
68 | * `black(alpha)` and `white(alpha)` shortcut
69 | [functions](evil-front/lib/assets/stylesheets/evil-front/colors.sass).
70 | * [+import-ruble](evil-front/lib/assets/stylesheets/evil-front/import-ruble.sass)
71 | mixin to enable `ruble` helper.
72 | * [+flying-quotes](evil-front/lib/assets/stylesheets/evil-front/flying-quotes.sass)
73 | mixin to enable `auto_flying_quotes` helper.
74 | * [+no-hover](evil-front/lib/assets/stylesheets/evil-front/no-hover.sass),
75 | [+hover](evil-front/lib/assets/stylesheets/evil-front/hover.sass) and
76 | [+styled-taps](evil-front/lib/assets/stylesheets/evil-front/styled-taps.sass)
77 | mixin to work with hover/tap styles on touch devices.
78 | * [Variables](evil-front/lib/assets/stylesheets/evil-front/easings.sass)
79 | with [easings](http://easings.net/).
80 | * CSS Media Queries
81 | [shortcuts](evil-front/lib/assets/stylesheets/evil-front/media.sass).
82 | * [+stroke-text(color)](evil-front/lib/assets/stylesheets/evil-front/stroke-text.sass)
83 | shortuct to add text shadow for every side of text.
84 | * [+height(size)](evil-front/lib/assets/stylesheets/evil-front/height.sass)
85 | shortcut to set `height` and `line-height` properties.
86 | * [+size(width, height)](evil-front/lib/assets/stylesheets/evil-front/size.sass)
87 | shortcut.
88 | * Compact and nice
89 | [+sticky-footer](evil-front/lib/assets/stylesheets/evil-front/sticky-footer.sass)
90 | mixin.
91 | * [+clearfix](evil-front/lib/assets/stylesheets/evil-front/clearfix.sass)
92 | by `::after` with `clear: both`.
93 |
94 | ### JS Helpers
95 |
96 | * [after(ms, callback)](evil-front/lib/assets/javascripts/evil-front/after.js)
97 | and
98 | [every(ms, callback)](evil-front/lib/assets/javascripts/evil-front/every.js)
99 | syntax sugar to clean up `setTimeout` and `setInterval` in CoffeeScript.
100 | * [Script](evil-front/lib/assets/javascripts/evil-front/links.js) to prevent
101 | default behavior for AJAX links with `href="#"` to clean event listeners from
102 | noisy `return false`.
103 | * [$.fn.evil.outside](evil-front/lib/assets/javascripts/evil-front/outside.js)
104 | to listen click outside element.
105 | * [$.fn.evil.ajax(opts)](evil-front/lib/assets/javascripts/evil-front/ajax.js)
106 | to create AJAX forms.
107 | * [evil.queue(name, callback)](evil-front/lib/assets/javascripts/evil-front/queue.js)
108 | to synchronizate animations.
109 | * [Script](evil-front/lib/assets/javascripts/evil-front/tappable.js)
110 | to enable tapped styles for touch devices.
111 | * [Script](evil-front/lib/assets/javascripts/evil-front/detect-3d.js)
112 | to detect 3D support.
113 | * `evil.post`, `evil.del` and `evil.put`
114 | [shortcuts](evil-front/lib/assets/javascripts/evil-front/http.js).
115 | * `evil.win`, `evil.body` and `evil.doc`
116 | [shortcuts](evil-front/lib/assets/javascripts/evil-front/core.js).
117 |
118 | ## Workflow
119 |
120 | The Evil Front All gem loads my must-have tools:
121 |
122 | * [Sass](http://sass-lang.com/) to write pretty styles.
123 | * [Slim](http://slim-lang.com/) to write pretty views.
124 | * [CoffeeScript](http://coffeescript.org/) to write pretty scripts.
125 | * [Uglifier](https://github.com/lautis/uglifier) to compress JS.
126 | * [CSSO](http://bem.info/tools/csso/) to compress CSS.
127 | * [Sprockets](https://github.com/sstephenson/sprockets) to work with assets
128 | in best way.
129 | * [jQueryCDN](https://github.com/ai/jquery-cdn) to load latest jQuery
130 | in best way.
131 | * [Autoprefixer](https://github.com/ai/autoprefixer) to add CSS3 prefixes.
132 | * [Rails Sass Images](https://github.com/ai/rails-sass-images) to inline images
133 | and get their sizes from Sass.
134 | * [Evil Blocks](https://github.com/ai/evil-blocks) to manage your scripts.
135 |
136 | ## Rails Settings
137 |
138 | The Evil Front Rails gem changes default Rails settings:
139 |
140 | * **Autoprecompile** adds all files in root of `app/assets/stylesheets`
141 | and `app/assets/javascripts` to precompile. You should only store loadable
142 | files in subdirs.
143 | * **Disable assets generation** on controller and action generation.
144 |
--------------------------------------------------------------------------------