caliber 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 0e79ebafa4fca291ccd0b6e22e08d6e2d66ed0cd
4
+ data.tar.gz: 96bd122309fb87e486c97e881bf6b96bf0e711b9
5
+ SHA512:
6
+ metadata.gz: 3cf7697b5b70b3dfecd5879f265a4157e8c792acdd4b149c473713c506febdb4edaff830867f48df770845477f1f48140381ea49de4cf7b138d6c01e54582220
7
+ data.tar.gz: 3dd9f1f69a44b026abfadcb48e8f80df0a221665813e2f961508924ef9d104845de2cb29166f4af2a8929a697d84f96870eeb36241c707718b16140fa02bf7d8
data/.gitignore ADDED
@@ -0,0 +1,10 @@
1
+ .bundle/
2
+ log/*.log
3
+ pkg/
4
+ test/dummy/db/*.sqlite3
5
+ test/dummy/log/*.log
6
+ test/dummy/tmp/
7
+ .DS_Store
8
+ .rvmrc
9
+ /.idea
10
+ /Gemfile.lock
data/Gemfile ADDED
@@ -0,0 +1,17 @@
1
+ source "https://rubygems.org"
2
+
3
+ rails_version = ENV["RAILS_VERSION"] || "default"
4
+
5
+ rails = case rails_version
6
+ when "master"
7
+ {github: "rails/rails"}
8
+ when "default"
9
+ ">= 3.2"
10
+ else
11
+ "~> #{rails_version}"
12
+ end
13
+
14
+ gem "rails", rails
15
+
16
+
17
+ gemspec
data/README.md ADDED
@@ -0,0 +1,35 @@
1
+ # Caliber
2
+
3
+ ## What
4
+
5
+ Show CSS classes in your Rails application while working in development. Visit `http://localhost:3000/rails/css` and you'll see an output to browse you application CSS, SASS, SCSS, LESS and other stylesheet files.
6
+
7
+ ![Caliber Gem](http://cl.ly/image/3Y0z1B411C1G/Image%202014-03-09%20at%209.00.46%20pm.png)
8
+
9
+
10
+ ## Why?
11
+
12
+ Sometimes you would like to have a convenient way to search stylesheets in your application. That could be because you are using external libraries or SCSS mixins compile to a list of classes. Caliber gives you an easy interface to browse all CSS rules in your Rails application.
13
+
14
+ ## Install
15
+
16
+ Add this to the development group in your Gemfile
17
+
18
+ ```ruby
19
+ group :development do
20
+ gem 'caliber'
21
+ end
22
+ ```
23
+
24
+ Then run `bundle install` and you're ready to start
25
+
26
+ ## Use
27
+
28
+ Visit `/rails/css` in your app and you'll see your stylesheets. It's that simple.
29
+
30
+
31
+ ## About
32
+
33
+ If you have a question file an issue or find me on the Twitters [@antulik](http://twitter.com/antulik).
34
+
35
+ This project rocks and uses MIT-LICENSE.
data/Rakefile ADDED
@@ -0,0 +1,33 @@
1
+ # encoding: UTF-8
2
+ require 'rubygems'
3
+ require 'bundler'
4
+
5
+ begin
6
+ Bundler.setup(:default, :development, :test)
7
+ rescue Bundler::BundlerError => e
8
+ $stderr.puts e.message
9
+ $stderr.puts "Run `bundle install` to install missing gems"
10
+ exit e.status_code
11
+ end
12
+
13
+ require 'rake'
14
+ require 'rdoc/task'
15
+
16
+ require 'rake/testtask'
17
+
18
+ Rake::TestTask.new(:test) do |t|
19
+ t.libs << 'lib'
20
+ t.libs << 'test'
21
+ t.pattern = 'test/**/*_test.rb'
22
+ t.verbose = false
23
+ end
24
+
25
+ task :default => :test
26
+
27
+ Rake::RDocTask.new(:rdoc) do |rdoc|
28
+ rdoc.rdoc_dir = 'rdoc'
29
+ rdoc.title = 'Caliber'
30
+ rdoc.options << '--line-numbers' << '--inline-source'
31
+ rdoc.rdoc_files.include('README.rdoc')
32
+ rdoc.rdoc_files.include('lib/**/*.rb')
33
+ end
@@ -0,0 +1 @@
1
+ //= require_tree .
@@ -0,0 +1,28 @@
1
+ function each(elems, func) {
2
+ if (!elems instanceof Array) { elems = [elems]; }
3
+ for (var i = elems.length; i--; ) {
4
+ func(elems[i]);
5
+ }
6
+ }
7
+
8
+ function setValOn(elems, val) {
9
+ each(elems, function(elem) {
10
+ elem.innerHTML = val;
11
+ });
12
+ }
13
+
14
+ function onClick(elems, func) {
15
+ each(elems, function(elem) {
16
+ elem.onclick = func;
17
+ });
18
+ }
19
+
20
+ // Enables functionality to toggle between `_path` and `_url` helper suffixes
21
+ function setupRouteToggleHelperLinks() {
22
+ var toggleLinks = document.querySelectorAll('#route_table [data-route-helper]');
23
+ onClick(toggleLinks, function(){
24
+ var helperTxt = this.getAttribute("data-route-helper");
25
+ var helperElems = document.querySelectorAll('[data-route-name] span.helper');
26
+ setValOn(helperElems, helperTxt);
27
+ });
28
+ }
@@ -0,0 +1 @@
1
+ var hljs=new function(){function k(v){return v.replace(/&/gm,"&amp;").replace(/</gm,"&lt;").replace(/>/gm,"&gt;")}function t(v){return v.nodeName.toLowerCase()}function i(w,x){var v=w&&w.exec(x);return v&&v.index==0}function d(v){return Array.prototype.map.call(v.childNodes,function(w){if(w.nodeType==3){return b.useBR?w.nodeValue.replace(/\n/g,""):w.nodeValue}if(t(w)=="br"){return"\n"}return d(w)}).join("")}function r(w){var v=(w.className+" "+(w.parentNode?w.parentNode.className:"")).split(/\s+/);v=v.map(function(x){return x.replace(/^language-/,"")});return v.filter(function(x){return j(x)||x=="no-highlight"})[0]}function o(x,y){var v={};for(var w in x){v[w]=x[w]}if(y){for(var w in y){v[w]=y[w]}}return v}function u(x){var v=[];(function w(y,z){for(var A=y.firstChild;A;A=A.nextSibling){if(A.nodeType==3){z+=A.nodeValue.length}else{if(t(A)=="br"){z+=1}else{if(A.nodeType==1){v.push({event:"start",offset:z,node:A});z=w(A,z);v.push({event:"stop",offset:z,node:A})}}}}return z})(x,0);return v}function q(w,y,C){var x=0;var F="";var z=[];function B(){if(!w.length||!y.length){return w.length?w:y}if(w[0].offset!=y[0].offset){return(w[0].offset<y[0].offset)?w:y}return y[0].event=="start"?w:y}function A(H){function G(I){return" "+I.nodeName+'="'+k(I.value)+'"'}F+="<"+t(H)+Array.prototype.map.call(H.attributes,G).join("")+">"}function E(G){F+="</"+t(G)+">"}function v(G){(G.event=="start"?A:E)(G.node)}while(w.length||y.length){var D=B();F+=k(C.substr(x,D[0].offset-x));x=D[0].offset;if(D==w){z.reverse().forEach(E);do{v(D.splice(0,1)[0]);D=B()}while(D==w&&D.length&&D[0].offset==x);z.reverse().forEach(A)}else{if(D[0].event=="start"){z.push(D[0].node)}else{z.pop()}v(D.splice(0,1)[0])}}return F+k(C.substr(x))}function m(y){function v(z){return(z&&z.source)||z}function w(A,z){return RegExp(v(A),"m"+(y.cI?"i":"")+(z?"g":""))}function x(D,C){if(D.compiled){return}D.compiled=true;D.k=D.k||D.bK;if(D.k){var z={};function E(G,F){if(y.cI){F=F.toLowerCase()}F.split(" ").forEach(function(H){var I=H.split("|");z[I[0]]=[G,I[1]?Number(I[1]):1]})}if(typeof D.k=="string"){E("keyword",D.k)}else{Object.keys(D.k).forEach(function(F){E(F,D.k[F])})}D.k=z}D.lR=w(D.l||/\b[A-Za-z0-9_]+\b/,true);if(C){if(D.bK){D.b=D.bK.split(" ").join("|")}if(!D.b){D.b=/\B|\b/}D.bR=w(D.b);if(!D.e&&!D.eW){D.e=/\B|\b/}if(D.e){D.eR=w(D.e)}D.tE=v(D.e)||"";if(D.eW&&C.tE){D.tE+=(D.e?"|":"")+C.tE}}if(D.i){D.iR=w(D.i)}if(D.r===undefined){D.r=1}if(!D.c){D.c=[]}var B=[];D.c.forEach(function(F){if(F.v){F.v.forEach(function(G){B.push(o(F,G))})}else{B.push(F=="self"?D:F)}});D.c=B;D.c.forEach(function(F){x(F,D)});if(D.starts){x(D.starts,C)}var A=D.c.map(function(F){return F.bK?"\\.?\\b("+F.b+")\\b\\.?":F.b}).concat([D.tE]).concat([D.i]).map(v).filter(Boolean);D.t=A.length?w(A.join("|"),true):{exec:function(F){return null}};D.continuation={}}x(y)}function c(S,L,J,R){function v(U,V){for(var T=0;T<V.c.length;T++){if(i(V.c[T].bR,U)){return V.c[T]}}}function z(U,T){if(i(U.eR,T)){return U}if(U.eW){return z(U.parent,T)}}function A(T,U){return !J&&i(U.iR,T)}function E(V,T){var U=M.cI?T[0].toLowerCase():T[0];return V.k.hasOwnProperty(U)&&V.k[U]}function w(Z,X,W,V){var T=V?"":b.classPrefix,U='<span class="'+T,Y=W?"":"</span>";U+=Z+'">';return U+X+Y}function N(){var U=k(C);if(!I.k){return U}var T="";var X=0;I.lR.lastIndex=0;var V=I.lR.exec(U);while(V){T+=U.substr(X,V.index-X);var W=E(I,V);if(W){H+=W[1];T+=w(W[0],V[0])}else{T+=V[0]}X=I.lR.lastIndex;V=I.lR.exec(U)}return T+U.substr(X)}function F(){if(I.sL&&!f[I.sL]){return k(C)}var T=I.sL?c(I.sL,C,true,I.continuation.top):g(C);if(I.r>0){H+=T.r}if(I.subLanguageMode=="continuous"){I.continuation.top=T.top}return w(T.language,T.value,false,true)}function Q(){return I.sL!==undefined?F():N()}function P(V,U){var T=V.cN?w(V.cN,"",true):"";if(V.rB){D+=T;C=""}else{if(V.eB){D+=k(U)+T;C=""}else{D+=T;C=U}}I=Object.create(V,{parent:{value:I}})}function G(T,X){C+=T;if(X===undefined){D+=Q();return 0}var V=v(X,I);if(V){D+=Q();P(V,X);return V.rB?0:X.length}var W=z(I,X);if(W){var U=I;if(!(U.rE||U.eE)){C+=X}D+=Q();do{if(I.cN){D+="</span>"}H+=I.r;I=I.parent}while(I!=W.parent);if(U.eE){D+=k(X)}C="";if(W.starts){P(W.starts,"")}return U.rE?0:X.length}if(A(X,I)){throw new Error('Illegal lexeme "'+X+'" for mode "'+(I.cN||"<unnamed>")+'"')}C+=X;return X.length||1}var M=j(S);if(!M){throw new Error('Unknown language: "'+S+'"')}m(M);var I=R||M;var D="";for(var K=I;K!=M;K=K.parent){if(K.cN){D=w(K.cN,D,true)}}var C="";var H=0;try{var B,y,x=0;while(true){I.t.lastIndex=x;B=I.t.exec(L);if(!B){break}y=G(L.substr(x,B.index-x),B[0]);x=B.index+y}G(L.substr(x));for(var K=I;K.parent;K=K.parent){if(K.cN){D+="</span>"}}return{r:H,value:D,language:S,top:I}}catch(O){if(O.message.indexOf("Illegal")!=-1){return{r:0,value:k(L)}}else{throw O}}}function g(y,x){x=x||b.languages||Object.keys(f);var v={r:0,value:k(y)};var w=v;x.forEach(function(z){if(!j(z)){return}var A=c(z,y,false);A.language=z;if(A.r>w.r){w=A}if(A.r>v.r){w=v;v=A}});if(w.language){v.second_best=w}return v}function h(v){if(b.tabReplace){v=v.replace(/^((<[^>]+>|\t)+)/gm,function(w,z,y,x){return z.replace(/\t/g,b.tabReplace)})}if(b.useBR){v=v.replace(/\n/g,"<br>")}return v}function p(z){var y=d(z);var A=r(z);if(A=="no-highlight"){return}var v=A?c(A,y,true):g(y);var w=u(z);if(w.length){var x=document.createElementNS("http://www.w3.org/1999/xhtml","pre");x.innerHTML=v.value;v.value=q(w,u(x),y)}v.value=h(v.value);z.innerHTML=v.value;z.className+=" hljs "+(!A&&v.language||"");z.result={language:v.language,re:v.r};if(v.second_best){z.second_best={language:v.second_best.language,re:v.second_best.r}}}var b={classPrefix:"hljs-",tabReplace:null,useBR:false,languages:undefined};function s(v){b=o(b,v)}function l(){if(l.called){return}l.called=true;var v=document.querySelectorAll("pre code");Array.prototype.forEach.call(v,p)}function a(){addEventListener("DOMContentLoaded",l,false);addEventListener("load",l,false)}var f={};var n={};function e(v,x){var w=f[v]=x(this);if(w.aliases){w.aliases.forEach(function(y){n[y]=v})}}function j(v){return f[v]||f[n[v]]}this.highlight=c;this.highlightAuto=g;this.fixMarkup=h;this.highlightBlock=p;this.configure=s;this.initHighlighting=l;this.initHighlightingOnLoad=a;this.registerLanguage=e;this.getLanguage=j;this.inherit=o;this.IR="[a-zA-Z][a-zA-Z0-9_]*";this.UIR="[a-zA-Z_][a-zA-Z0-9_]*";this.NR="\\b\\d+(\\.\\d+)?";this.CNR="(\\b0[xX][a-fA-F0-9]+|(\\b\\d+(\\.\\d*)?|\\.\\d+)([eE][-+]?\\d+)?)";this.BNR="\\b(0b[01]+)";this.RSR="!|!=|!==|%|%=|&|&&|&=|\\*|\\*=|\\+|\\+=|,|-|-=|/=|/|:|;|<<|<<=|<=|<|===|==|=|>>>=|>>=|>=|>>>|>>|>|\\?|\\[|\\{|\\(|\\^|\\^=|\\||\\|=|\\|\\||~";this.BE={b:"\\\\[\\s\\S]",r:0};this.ASM={cN:"string",b:"'",e:"'",i:"\\n",c:[this.BE]};this.QSM={cN:"string",b:'"',e:'"',i:"\\n",c:[this.BE]};this.CLCM={cN:"comment",b:"//",e:"$"};this.CBLCLM={cN:"comment",b:"/\\*",e:"\\*/"};this.HCM={cN:"comment",b:"#",e:"$"};this.NM={cN:"number",b:this.NR,r:0};this.CNM={cN:"number",b:this.CNR,r:0};this.BNM={cN:"number",b:this.BNR,r:0};this.REGEXP_MODE={cN:"regexp",b:/\//,e:/\/[gim]*/,i:/\n/,c:[this.BE,{b:/\[/,e:/\]/,r:0,c:[this.BE]}]};this.TM={cN:"title",b:this.IR,r:0};this.UTM={cN:"title",b:this.UIR,r:0}}();hljs.registerLanguage("css",function(a){var b="[a-zA-Z-][a-zA-Z0-9_-]*";var c={cN:"function",b:b+"\\(",e:"\\)",c:["self",a.NM,a.ASM,a.QSM]};return{cI:true,i:"[=/|']",c:[a.CBLCLM,{cN:"id",b:"\\#[A-Za-z0-9_-]+"},{cN:"class",b:"\\.[A-Za-z0-9_-]+",r:0},{cN:"attr_selector",b:"\\[",e:"\\]",i:"$"},{cN:"pseudo",b:":(:)?[a-zA-Z0-9\\_\\-\\+\\(\\)\\\"\\']+"},{cN:"at_rule",b:"@(font-face|page)",l:"[a-z-]+",k:"font-face page"},{cN:"at_rule",b:"@",e:"[{;]",c:[{cN:"keyword",b:/\S+/},{b:/\s/,eW:true,eE:true,r:0,c:[c,a.ASM,a.QSM,a.NM]}]},{cN:"tag",b:b,r:0},{cN:"rules",b:"{",e:"}",i:"[^\\s]",r:0,c:[a.CBLCLM,{cN:"rule",b:"[^\\s]",rB:true,e:";",eW:true,c:[{cN:"attribute",b:"[A-Z\\_\\.\\-]+",e:":",eE:true,i:"[^\\s]",starts:{cN:"value",eW:true,eE:true,c:[c,a.NM,a.QSM,a.ASM,a.CBLCLM,{cN:"hexcolor",b:"#[0-9A-Fa-f]+"},{cN:"important",b:"!important"}]}}]}]}]}});
@@ -0,0 +1,182 @@
1
+ /*
2
+
3
+ Railscasts-like style (c) Visoft, Inc. (Damien White)
4
+
5
+ */
6
+
7
+ .hljs {
8
+ display: block;
9
+ padding: 0.5em;
10
+ background: #232323;
11
+ color: #E6E1DC;
12
+ }
13
+
14
+ .hljs-comment,
15
+ .hljs-template_comment,
16
+ .hljs-javadoc,
17
+ .hljs-shebang {
18
+ color: #BC9458;
19
+ font-style: italic;
20
+ }
21
+
22
+ .hljs-keyword,
23
+ .ruby .hljs-function .hljs-keyword,
24
+ .hljs-request,
25
+ .hljs-status,
26
+ .nginx .hljs-title,
27
+ .method,
28
+ .hljs-list .hljs-title {
29
+ color: #C26230;
30
+ }
31
+
32
+ .hljs-string,
33
+ .hljs-number,
34
+ .hljs-regexp,
35
+ .hljs-tag .hljs-value,
36
+ .hljs-cdata,
37
+ .hljs-filter .hljs-argument,
38
+ .hljs-attr_selector,
39
+ .apache .hljs-cbracket,
40
+ .hljs-date,
41
+ .tex .hljs-command,
42
+ .markdown .hljs-link_label {
43
+ color: #A5C261;
44
+ }
45
+
46
+ .hljs-subst {
47
+ color: #519F50;
48
+ }
49
+
50
+ .hljs-tag,
51
+ .hljs-tag .hljs-keyword,
52
+ .hljs-tag .hljs-title,
53
+ .hljs-doctype,
54
+ .hljs-sub .hljs-identifier,
55
+ .hljs-pi,
56
+ .input_number {
57
+ color: #E8BF6A;
58
+ }
59
+
60
+ .hljs-identifier {
61
+ color: #D0D0FF;
62
+ }
63
+
64
+ .hljs-class .hljs-title,
65
+ .haskell .hljs-type,
66
+ .smalltalk .hljs-class,
67
+ .hljs-javadoctag,
68
+ .hljs-yardoctag,
69
+ .hljs-phpdoc {
70
+ text-decoration: none;
71
+ }
72
+
73
+ .hljs-constant {
74
+ color: #DA4939;
75
+ }
76
+
77
+
78
+ .hljs-symbol,
79
+ .hljs-built_in,
80
+ .ruby .hljs-symbol .hljs-string,
81
+ .ruby .hljs-symbol .hljs-identifier,
82
+ .markdown .hljs-link_url,
83
+ .hljs-attribute {
84
+ color: #6D9CBE;
85
+ }
86
+
87
+ .markdown .hljs-link_url {
88
+ text-decoration: underline;
89
+ }
90
+
91
+
92
+
93
+ .hljs-params,
94
+ .hljs-variable,
95
+ .clojure .hljs-attribute {
96
+ color: #D0D0FF;
97
+ }
98
+
99
+ .css .hljs-tag,
100
+ .hljs-rules .hljs-property,
101
+ .hljs-pseudo,
102
+ .tex .hljs-special {
103
+ color: #CDA869;
104
+ }
105
+
106
+ .css .hljs-class {
107
+ color: #9B703F;
108
+ }
109
+
110
+ .hljs-rules .hljs-keyword {
111
+ color: #C5AF75;
112
+ }
113
+
114
+ .hljs-rules .hljs-value {
115
+ color: #CF6A4C;
116
+ }
117
+
118
+ .css .hljs-id {
119
+ color: #8B98AB;
120
+ }
121
+
122
+ .hljs-annotation,
123
+ .apache .hljs-sqbracket,
124
+ .nginx .hljs-built_in {
125
+ color: #9B859D;
126
+ }
127
+
128
+ .hljs-preprocessor,
129
+ .hljs-preprocessor *,
130
+ .hljs-pragma {
131
+ color: #8996A8 !important;
132
+ }
133
+
134
+ .hljs-hexcolor,
135
+ .css .hljs-value .hljs-number {
136
+ color: #A5C261;
137
+ }
138
+
139
+ .hljs-title,
140
+ .hljs-decorator,
141
+ .css .hljs-function {
142
+ color: #FFC66D;
143
+ }
144
+
145
+ .diff .hljs-header,
146
+ .hljs-chunk {
147
+ background-color: #2F33AB;
148
+ color: #E6E1DC;
149
+ display: inline-block;
150
+ width: 100%;
151
+ }
152
+
153
+ .diff .hljs-change {
154
+ background-color: #4A410D;
155
+ color: #F8F8F8;
156
+ display: inline-block;
157
+ width: 100%;
158
+ }
159
+
160
+ .hljs-addition {
161
+ background-color: #144212;
162
+ color: #E6E1DC;
163
+ display: inline-block;
164
+ width: 100%;
165
+ }
166
+
167
+ .hljs-deletion {
168
+ background-color: #600;
169
+ color: #E6E1DC;
170
+ display: inline-block;
171
+ width: 100%;
172
+ }
173
+
174
+ .coffeescript .javascript,
175
+ .javascript .xml,
176
+ .tex .hljs-formula,
177
+ .xml .javascript,
178
+ .xml .vbscript,
179
+ .xml .css,
180
+ .xml .hljs-cdata {
181
+ opacity: 0.7;
182
+ }
@@ -0,0 +1,4 @@
1
+ module Caliber
2
+ class ApplicationController < ActionController::Base
3
+ end
4
+ end
@@ -0,0 +1,54 @@
1
+ require 'css_parser'
2
+
3
+ module Caliber
4
+ class CaliberController < Caliber::ApplicationController
5
+ include ::CssParser
6
+
7
+ layout 'caliber/application'
8
+
9
+ before_filter :require_local!
10
+
11
+ def index
12
+ @css_selectors = []
13
+
14
+ Rails.application.assets.each_file do |pathname|
15
+
16
+ next unless Rails.application.assets.content_type_of(pathname) == 'text/css'
17
+
18
+ parser = CssParser::Parser.new
19
+
20
+ begin
21
+ link = Rails.application.assets[pathname].to_s
22
+ parser.add_block! link
23
+
24
+ selectors = parser.to_enum(:each_selector).map do |selectors, declarations, specificity, media_types|
25
+ declarations = declarations.gsub ";", ";<br>"
26
+ {
27
+ pathname: pathname.to_s,
28
+ selector: selectors,
29
+ declarations: declarations,
30
+ specificity: specificity,
31
+ media_types: media_types
32
+ }
33
+ end
34
+
35
+ @css_selectors.concat selectors
36
+ rescue
37
+ end
38
+ end
39
+ end
40
+
41
+ private
42
+ def require_local!
43
+ unless local_request?
44
+ render :text => '<p>For security purposes, this information is only available to local requests.</p>', :status => :forbidden
45
+ end
46
+ end
47
+
48
+ def local_request?
49
+ Rails.application.config.consider_all_requests_local || request.local?
50
+ end
51
+
52
+ end
53
+ end
54
+
@@ -0,0 +1,189 @@
1
+ <style type="text/css">
2
+ .result {
3
+ width: 500px;
4
+ padding: 10px;
5
+ }
6
+
7
+ .selector,
8
+ .selector > input {
9
+ font-size: 20px;
10
+ font-weight: bold;
11
+ }
12
+
13
+ .pathname,
14
+ .pathname > input {
15
+ color: grey;
16
+ font-size: 0.8em;
17
+ }
18
+
19
+ .mediatypes {
20
+ color: grey;
21
+ float:right;
22
+ }
23
+
24
+ .mediatypes input {
25
+ text-align: right;
26
+ }
27
+
28
+ .results-list {
29
+ list-style-type: none;
30
+ padding: 0;
31
+ }
32
+
33
+ .results-list > li:nth-child(odd) {
34
+ background-color: #f9f9f9;
35
+ }
36
+
37
+ .results-list > li:hover {
38
+ background-color: #f5f5f5;
39
+ }
40
+
41
+ .filter {
42
+ background-color: lightgrey;
43
+ }
44
+
45
+ .filter input {
46
+ border: none;
47
+ background-color: lightgrey;
48
+ color: black;
49
+ border-bottom-width: 1px;
50
+ border-bottom-style: dashed;
51
+ border-bottom-color: grey;
52
+ }
53
+
54
+ .pathname > input {
55
+ width: 350px;
56
+ }
57
+ .selector > input {
58
+ width: 300px;
59
+ }
60
+ </style>
61
+
62
+ <div class="result filter">
63
+ <div class="mediatypes">
64
+ <input type="text" id='mediatype' value='' placeholder='media type'>
65
+ </div>
66
+ <div class="selector">
67
+ <input type="text" id='selector' value='' placeholder='css selector'>
68
+ </div>
69
+ <div class="pathname">
70
+ <input type="text" id='pathname' placeholder='css file path'>
71
+ </div>
72
+ </div>
73
+
74
+ <ul class="results-list">
75
+
76
+ </ul>
77
+
78
+ <div class="template-result" style="display:none;">
79
+ <li class="result">
80
+ <div class="mediatypes"></div>
81
+ <div class="selector"></div>
82
+ <div class="pathname"></div>
83
+ </li>
84
+ </div>
85
+
86
+ <script type="text/javascript">
87
+ $(function(){
88
+ var data = <%= @css_selectors.to_json.html_safe %>;
89
+
90
+ window.gg = data;
91
+
92
+ function debounce(fn, delay) {
93
+ var timer = null;
94
+ return function () {
95
+ var context = this, args = arguments;
96
+ clearTimeout(timer);
97
+ timer = setTimeout(function () {
98
+ fn.apply(context, args);
99
+ }, delay);
100
+ };
101
+ }
102
+
103
+ var filterData = function() {
104
+ var filter_selector = $("#selector").val();
105
+ var filter_pathname = $("#pathname").val();
106
+ var filter_mediatype = $("#mediatype").val();
107
+ var max_results = 200;
108
+
109
+ var result = [];
110
+
111
+ for (var i = 0; i < data.length; i++) {
112
+ if (result.length >= max_results) {
113
+ break;
114
+ }
115
+ var item = data[i];
116
+ if (item.selector.indexOf(filter_selector) != -1 &&
117
+ item.pathname.indexOf(filter_pathname) != -1) {
118
+
119
+ var media_match = false;
120
+ for (var b = 0; b < item.media_types.length; b++) {
121
+ if (item.media_types[b].indexOf(filter_mediatype) != -1) {
122
+ media_match = true;
123
+ }
124
+ }
125
+
126
+ if (media_match || (item.media_types.length == 0 && filter_mediatype.length == 0)) {
127
+ item.index_id = i;
128
+ result.push(item);
129
+ }
130
+ }
131
+ }
132
+
133
+ return result;
134
+ }
135
+
136
+ var render = function(list) {
137
+ var results_list = $('.results-list');
138
+ var template = $('.template-result');
139
+ template = $(template.html());
140
+
141
+ results_list.html('');
142
+ for (var i = 0; i < list.length; i++) {
143
+ var item = list[i];
144
+
145
+ var html = template.clone();
146
+ html.data('index-id', item.index_id)
147
+ html.find('.selector').text(item.selector);
148
+ html.find('.pathname').text(item.pathname);
149
+ html.find('.mediatypes').text(item.media_types.join(','));
150
+
151
+ results_list.append(html);
152
+ }
153
+
154
+ }
155
+
156
+ $('.filter').on('keyup', 'input', debounce(function(){
157
+ var filteredData = filterData();
158
+ render(filteredData);
159
+ }, 500));
160
+
161
+
162
+ var last_mouse_enter = null;
163
+ $('.results-list').on('mouseenter', 'li', function(e) {
164
+ $(last_mouse_enter).popover('destroy');
165
+
166
+ last_mouse_enter = this;
167
+
168
+ var elem = $(last_mouse_enter);
169
+ var item = data[elem.data('index-id')];
170
+
171
+ var html = '<pre><code class="css">';
172
+ html += item.selector + ' {\n ';
173
+ html += item.declarations;
174
+ html += '};';
175
+ html += '</code></pre>';
176
+
177
+ elem.popover({
178
+ html: true,
179
+ content: html,
180
+ trigger: 'manual',
181
+ animation: false,
182
+ }).popover('show');
183
+
184
+ $('pre code').each(function(i, e) {hljs.highlightBlock(e)});
185
+
186
+ });
187
+ });
188
+
189
+ </script>
@@ -0,0 +1,22 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8" />
5
+ <title>Caliber of CSS rules</title>
6
+
7
+ <%= csrf_meta_tags %>
8
+
9
+ <%= javascript_include_tag 'http://code.jquery.com/jquery-1.11.0.min.js' %>
10
+ <%= javascript_include_tag "caliber/application" %>
11
+ <%= stylesheet_link_tag "caliber/railscasts.css" %>
12
+
13
+ <link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
14
+ <script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
15
+
16
+ </head>
17
+ <body>
18
+
19
+ <%= yield %>
20
+
21
+ </body>
22
+ </html>
data/caliber.gemspec ADDED
@@ -0,0 +1,26 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+ require 'caliber/version'
6
+
7
+ Gem::Specification.new do |gem|
8
+ gem.name = "caliber"
9
+ gem.version = Caliber::VERSION
10
+ gem.authors = ["Anton Katunin"]
11
+ gem.email = ["katunin.anton+rubygems@gmail.com"]
12
+ gem.description = %q{Caliber is a Rails engine that shows css classes}
13
+ gem.summary = %q{Caliber is a Rails engine that shows css classes.}
14
+ gem.homepage = "https://github.com/antulik/caliber"
15
+ gem.license = "MIT"
16
+
17
+ gem.files = `git ls-files`.split($/)
18
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
19
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
+ gem.require_paths = ["lib"]
21
+
22
+ gem.add_dependency "rails", ">= 3.2"
23
+ gem.add_dependency "css_parser", ">= 1.3.5"
24
+
25
+ gem.add_development_dependency "rake"
26
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,4 @@
1
+ Rails.application.routes.draw do
2
+ get "rails/css" => "caliber/caliber#index"
3
+ mount Caliber::Engine => "/caliber", :as => "caliber_engine"
4
+ end
data/lib/caliber.rb ADDED
@@ -0,0 +1,23 @@
1
+ require 'caliber/engine'
2
+
3
+ module Caliber
4
+
5
+ begin
6
+ require 'rails/application/route_inspector'
7
+ ROUTE_INSPECTOR = Rails::Application::RouteInspector.new
8
+ rescue LoadError
9
+ require 'action_dispatch/routing/inspector'
10
+ ROUTE_INSPECTOR = ActionDispatch::Routing::RoutesInspector.new([])
11
+ end
12
+
13
+ def self.format_routes(routes = all_routes)
14
+ # ActionDispatch::Routing::RoutesInspector.new.collect_routes(_routes.routes)
15
+ ROUTE_INSPECTOR.send :collect_routes, routes
16
+ end
17
+
18
+ def self.all_routes
19
+ Rails.application.reload_routes!
20
+ Rails.application.routes.routes
21
+ end
22
+ end
23
+
@@ -0,0 +1,5 @@
1
+ module Caliber
2
+ class Engine < Rails::Engine
3
+ isolate_namespace Caliber
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ module Caliber
2
+ VERSION = "0.0.1"
3
+ end
metadata ADDED
@@ -0,0 +1,103 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: caliber
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Anton Katunin
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-03-09 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '>='
18
+ - !ruby/object:Gem::Version
19
+ version: '3.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - '>='
25
+ - !ruby/object:Gem::Version
26
+ version: '3.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: css_parser
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: 1.3.5
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: 1.3.5
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '>='
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: Caliber is a Rails engine that shows css classes
56
+ email:
57
+ - katunin.anton+rubygems@gmail.com
58
+ executables: []
59
+ extensions: []
60
+ extra_rdoc_files: []
61
+ files:
62
+ - .gitignore
63
+ - Gemfile
64
+ - README.md
65
+ - Rakefile
66
+ - app/assets/javascripts/caliber/application.js
67
+ - app/assets/javascripts/caliber/caliber.js
68
+ - app/assets/javascripts/caliber/highlight.pack.js
69
+ - app/assets/stylesheets/caliber/railscasts.css
70
+ - app/controllers/caliber/application_controller.rb
71
+ - app/controllers/caliber/caliber_controller.rb
72
+ - app/views/caliber/caliber/index.html.erb
73
+ - app/views/layouts/caliber/application.html.erb
74
+ - caliber.gemspec
75
+ - config/routes.rb
76
+ - lib/caliber.rb
77
+ - lib/caliber/engine.rb
78
+ - lib/caliber/version.rb
79
+ homepage: https://github.com/antulik/caliber
80
+ licenses:
81
+ - MIT
82
+ metadata: {}
83
+ post_install_message:
84
+ rdoc_options: []
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ requirements:
89
+ - - '>='
90
+ - !ruby/object:Gem::Version
91
+ version: '0'
92
+ required_rubygems_version: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ requirements: []
98
+ rubyforge_project:
99
+ rubygems_version: 2.2.2
100
+ signing_key:
101
+ specification_version: 4
102
+ summary: Caliber is a Rails engine that shows css classes.
103
+ test_files: []