├── .gitignore ├── CHANGES.md ├── Gemfile ├── LICENSE.txt ├── README.md ├── Rakefile ├── app └── assets │ └── javascripts │ ├── grayscale-favicon.js │ └── rails_env_favicon.js.erb ├── config └── initializers │ └── rails_env_favicon.rb ├── doc └── img │ ├── sample-grayscale.png │ └── sample.png ├── lib ├── generators │ └── rails_env_favicon │ │ └── install_generator.rb ├── rails-env-favicon.rb └── rails-env-favicon │ ├── rails.rb │ └── version.rb └── rails-env-favicon.gemspec /.gitignore: -------------------------------------------------------------------------------- 1 | *.gem 2 | *.rbc 3 | .bundle 4 | .config 5 | .yardoc 6 | Gemfile.lock 7 | InstalledFiles 8 | _yardoc 9 | coverage 10 | lib/bundler/man 11 | pkg 12 | rdoc 13 | spec/reports 14 | test/tmp 15 | test/version_tmp 16 | tmp 17 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | ## v0.0.5 2 | 3 | * added the ability to configure the conditions of changing favicon and badge label 4 | 5 | ## v0.0.4 6 | 7 | * add option for grayscale favicon 8 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | # Specify your gem's dependencies in rails_env_favicon.gemspec 4 | gemspec 5 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Accessd 2 | 3 | MIT License 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 19 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 20 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 21 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 22 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Rails Env Favicon 2 | ================================ 3 | 4 | [![Gem Version](https://badge.fury.io/rb/rails-env-favicon.svg)](http://badge.fury.io/rb/rails-env-favicon) 5 | 6 | Made changes in the code to debug and do not understand what's wrong. 7 | Hell, I'm on the debug production! This happened to you? To me several times. 8 | Library offers one of the ways to solve this problem. 9 | 10 | Most everyone will understand from one picture: 11 | 12 | ![ScreenShot](https://raw.github.com/accessd/rails-env-favicon/master/doc/img/sample.png) 13 | 14 | This means that on the first tab we have development environment, on second stage, and third it's production(we don't need change this favicon). 15 | 16 | It uses [Tinycon](https://github.com/tommoor/tinycon) - A small library for manipulating the favicon. 17 | 18 | And one more option: 19 | 20 | ![ScreenShot](https://raw.github.com/accessd/rails-env-favicon/master/doc/img/sample-grayscale.png) 21 | 22 | Icon will be gray on non production environment. 23 | 24 | It you need this separately you can use [Grayscale-Favicon](https://github.com/khusnetdinov/grayscale-favicon) - adopted for node package managers version. 25 | 26 | __Js usage for this task justified by the fact that more often than not have to worry about favicon caching, because favicon changes on the fly after it's loaded. However, if you do not like to use js for this problem, you may use alternative version of gem which uses https://github.com/rmagick/rmagick, follow to branch [rmagick](https://github.com/accessd/rails-env-favicon/tree/rmagick)__ 27 | 28 | Installation 29 | ------------ 30 | 31 | Add this line to your application's Gemfile: 32 | 33 | gem 'rails-env-favicon' 34 | 35 | And then execute: 36 | 37 | $ bundle 38 | 39 | Setup: 40 | 41 | # adds initializer 42 | rails g rails_env_favicon:install 43 | 44 | In your JavaScript manifest (e.g. `application.js`): 45 | 46 | //= require rails_env_favicon 47 | 48 | Config 49 | ------------ 50 | 51 | In config/initializers/rails_env_favicon.rb 52 | 53 | RailsEnvFavicon.setup do |config| 54 | # If true then favicon will be gray on non production env 55 | config.make_grayscale = false 56 | # or if make_grayscale = false then draw badge on favicon with this options: 57 | config.text_color = '#ffffff' 58 | config.background_color = '#549a2f' 59 | end 60 | 61 | You can also configure the condition of changing favicon and badge label, just override `RailsEnvFavicon` module methods. For example: 62 | 63 | module RailsEnvFavicon 64 | def self.badge_label 65 | ENV['TEATRO'].present? ? 'T' : ::Rails.env.first.upcase 66 | end 67 | 68 | def self.applicable? 69 | !::Rails.env.production? || ENV['TEATRO'].present? 70 | end 71 | end 72 | 73 | Issues 74 | ------------- 75 | 76 | * If you change a configuration to apply changes, you have to: 77 | 78 | * Execute `rm -rf tmp/cache/*` in app directory, for assets cache cleaning. 79 | * Restart web server. 80 | 81 | Contributing 82 | ------------- 83 | 84 | 1. Fork it ( http://github.com/accessd/rails_env_favicon/fork ) 85 | 2. Create your feature branch (`git checkout -b my-new-feature`) 86 | 3. Commit your changes (`git commit -am 'Add some feature'`) 87 | 4. Push to the branch (`git push origin my-new-feature`) 88 | 5. Create new Pull Request 89 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | -------------------------------------------------------------------------------- /app/assets/javascripts/grayscale-favicon.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * GrayscaleFavicon - A small library for make the Favicon grayscale 3 | * Accessd, https://github.com/accessd 4 | * Copyright (c) 2014 Accessd 5 | * @license MIT Licensed 6 | * @version 0.0.1 7 | */ 8 | 9 | (function(){ 10 | 11 | var GrayscaleFavicon = {}; 12 | var currentFavicon = null; 13 | var originalFavicon = null; 14 | var faviconImage = null; 15 | var canvas = null; 16 | var size = 32; 17 | 18 | // private methods 19 | var getFaviconTag = function(){ 20 | 21 | var links = document.getElementsByTagName('link'); 22 | 23 | for(var i=0, len=links.length; i < len; i++) { 24 | if ((links[i].getAttribute('rel') || '').match(/\bicon\b/)) { 25 | return links[i]; 26 | } 27 | } 28 | 29 | return false; 30 | }; 31 | 32 | var removeFaviconTag = function(){ 33 | 34 | var links = document.getElementsByTagName('link'); 35 | var head = document.getElementsByTagName('head')[0]; 36 | 37 | for(var i=0, len=links.length; i < len; i++) { 38 | var exists = (typeof(links[i]) !== 'undefined'); 39 | if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) { 40 | head.removeChild(links[i]); 41 | } 42 | } 43 | }; 44 | 45 | var getCurrentFavicon = function(){ 46 | 47 | if (!originalFavicon || !currentFavicon) { 48 | var tag = getFaviconTag(); 49 | originalFavicon = currentFavicon = tag ? tag.getAttribute('href') : './favicon.ico'; 50 | } 51 | 52 | return currentFavicon; 53 | }; 54 | 55 | var getCanvas = function (){ 56 | 57 | if (!canvas) { 58 | canvas = document.createElement("canvas"); 59 | canvas.width = size; 60 | canvas.height = size; 61 | } 62 | 63 | return canvas; 64 | }; 65 | 66 | var setFaviconTag = function(url){ 67 | removeFaviconTag(); 68 | 69 | var link = document.createElement('link'); 70 | link.type = 'image/x-icon'; 71 | link.rel = 'icon'; 72 | link.href = url; 73 | document.getElementsByTagName('head')[0].appendChild(link); 74 | }; 75 | 76 | var log = function(message){ 77 | if (window.console) window.console.log(message); 78 | }; 79 | 80 | var drawFavicon = function(label, colour) { 81 | 82 | var context = getCanvas().getContext("2d"); 83 | var colour = colour || '#000000'; 84 | var src = getCurrentFavicon(); 85 | 86 | faviconImage = document.createElement('img'); 87 | faviconImage.onload = function() { 88 | 89 | // clear canvas 90 | context.clearRect(0, 0, size, size); 91 | 92 | // draw the favicon 93 | context.drawImage(faviconImage, 0, 0, faviconImage.width, faviconImage.height, 0, 0, size, size); 94 | 95 | var imgPixels = context.getImageData(0, 0, faviconImage.width, faviconImage.height); 96 | 97 | for(var y = 0; y < imgPixels.height; y++){ 98 | for(var x = 0; x < imgPixels.width; x++){ 99 | var i = (y * 4) * imgPixels.width + x * 4; 100 | var avg = (imgPixels.data[i] + imgPixels.data[i + 1] + imgPixels.data[i + 2]) / 3; 101 | imgPixels.data[i] = avg; 102 | imgPixels.data[i + 1] = avg; 103 | imgPixels.data[i + 2] = avg; 104 | } 105 | } 106 | context.putImageData(imgPixels, 0, 0, 0, 0, imgPixels.width, imgPixels.height); 107 | 108 | // refresh tag in page 109 | refreshFavicon(); 110 | }; 111 | 112 | // allow cross origin resource requests if the image is not a data:uri 113 | // as detailed here: https://github.com/mrdoob/three.js/issues/1305 114 | if (!src.match(/^data/)) { 115 | faviconImage.crossOrigin = 'anonymous'; 116 | } 117 | 118 | faviconImage.src = src; 119 | }; 120 | 121 | var refreshFavicon = function(){ 122 | // check support 123 | if (!getCanvas().getContext) return; 124 | 125 | setFaviconTag(getCanvas().toDataURL()); 126 | }; 127 | 128 | GrayscaleFavicon.grayscale = function(){ 129 | drawFavicon(); 130 | return this; 131 | }; 132 | 133 | GrayscaleFavicon.reset = function(){ 134 | setFaviconTag(originalFavicon); 135 | }; 136 | 137 | window.GrayscaleFavicon = GrayscaleFavicon; 138 | 139 | if(typeof define === 'function' && define.amd) { 140 | define(GrayscaleFavicon); 141 | } 142 | 143 | })(); 144 | -------------------------------------------------------------------------------- /app/assets/javascripts/rails_env_favicon.js.erb: -------------------------------------------------------------------------------- 1 | <% if RailsEnvFavicon.applicable? %> 2 | <% if RailsEnvFavicon.make_grayscale %> 3 | <%= require_asset "grayscale-favicon.js" %> 4 | GrayscaleFavicon.grayscale(); 5 | <% else %> 6 | <%= require_asset "tinycon.min.js" %> 7 | Tinycon.setOptions({ 8 | width: 8, 9 | height: 9, 10 | color: '<%= RailsEnvFavicon.text_color %>', 11 | background: '<%= RailsEnvFavicon.background_color %>', 12 | fallback: true 13 | }); 14 | 15 | Tinycon.setBubble("<%= RailsEnvFavicon.badge_label %>"); 16 | <% end %> 17 | <% end %> 18 | -------------------------------------------------------------------------------- /config/initializers/rails_env_favicon.rb: -------------------------------------------------------------------------------- 1 | require 'rails-env-favicon' 2 | 3 | RailsEnvFavicon.setup do |config| 4 | # If true then favicon will be gray on non production env 5 | config.make_grayscale = false 6 | # or if make_grayscale = false then draw badge on favicon with this options: 7 | config.text_color = '#ffffff' 8 | config.background_color = '#549a2f' 9 | end 10 | -------------------------------------------------------------------------------- /doc/img/sample-grayscale.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessd/rails-env-favicon/712970f5602094b0c73b75c860aa7f8b8adf9fc5/doc/img/sample-grayscale.png -------------------------------------------------------------------------------- /doc/img/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/accessd/rails-env-favicon/712970f5602094b0c73b75c860aa7f8b8adf9fc5/doc/img/sample.png -------------------------------------------------------------------------------- /lib/generators/rails_env_favicon/install_generator.rb: -------------------------------------------------------------------------------- 1 | module RailsEnvFavicon 2 | module Generators 3 | class InstallGenerator < ::Rails::Generators::Base 4 | desc "creates an initializer file at config/initializers/rails_env_favicon.rb" 5 | source_root File.expand_path('../../../..', __FILE__) 6 | 7 | def generate_initialization 8 | copy_file 'config/initializers/rails_env_favicon.rb', 'config/initializers/rails_env_favicon.rb' 9 | end 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/rails-env-favicon.rb: -------------------------------------------------------------------------------- 1 | require "rails-env-favicon/version" 2 | require "rails-env-favicon/rails" 3 | 4 | module RailsEnvFavicon 5 | mattr_accessor :text_color 6 | self.text_color = '#ffffff' 7 | mattr_accessor :background_color 8 | self.background_color = '#549a2f' 9 | 10 | mattr_accessor :make_grayscale 11 | self.make_grayscale = false 12 | 13 | def self.badge_label 14 | ::Rails.env.first.upcase 15 | end 16 | 17 | def self.applicable? 18 | !::Rails.env.production? 19 | end 20 | 21 | class << self 22 | def setup 23 | yield self 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/rails-env-favicon/rails.rb: -------------------------------------------------------------------------------- 1 | module RailsEnvFavicon 2 | module Rails 3 | class Engine < ::Rails::Engine 4 | require 'tinycon-rails' 5 | end 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /lib/rails-env-favicon/version.rb: -------------------------------------------------------------------------------- 1 | module RailsEnvFavicon 2 | VERSION = "0.0.5" 3 | end 4 | -------------------------------------------------------------------------------- /rails-env-favicon.gemspec: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | lib = File.expand_path('../lib', __FILE__) 3 | $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) 4 | require 'rails-env-favicon/version' 5 | 6 | Gem::Specification.new do |spec| 7 | spec.name = "rails-env-favicon" 8 | spec.version = RailsEnvFavicon::VERSION 9 | spec.authors = ["Accessd"] 10 | spec.email = ["accessd0@gmail.com"] 11 | spec.summary = %q{Gem to display the rails environment on the favicon} 12 | spec.description = %q{Gem to display the rails environment on the favicon} 13 | spec.homepage = "https://github.com/accessd/rails-env-favicon" 14 | spec.license = "MIT" 15 | 16 | spec.files = `git ls-files -z`.split("\x0") 17 | spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } 18 | spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) 19 | spec.require_paths = ["lib"] 20 | 21 | spec.add_dependency "rails", ">= 3.0" 22 | spec.add_dependency "tinycon-rails" 23 | spec.add_development_dependency "bundler", "~> 1.6" 24 | spec.add_development_dependency "rake" 25 | end 26 | --------------------------------------------------------------------------------