adamh-html_namespacing 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/Manifest CHANGED
@@ -7,6 +7,8 @@ ext/html_namespacing/html_namespacing.h
7
7
  ext/html_namespacing/html_namespacing.c
8
8
  ext/html_namespacing/html_namespacing_ext.c
9
9
  lib/html_namespacing.rb
10
+ lib/html_namespacing/plugin.rb
10
11
  lib/html_namespacing/plugin/rails.rb
12
+ lib/html_namespacing/plugin/sass.rb
11
13
  Manifest
12
14
  html_namespacing.gemspec
data/README.rdoc CHANGED
@@ -3,6 +3,10 @@
3
3
  HTML Namespacing automatically adds HTML class attributes to partial HTML
4
4
  code.
5
5
 
6
+ The intent is for HTML, CSS, and JavaScript files to be "namespaced" according
7
+ to their location in the filesystem. That way, CSS and JavaScript can be scoped
8
+ to individual HTML files--even automatically.
9
+
6
10
  == Installing
7
11
 
8
12
  gem install adamh-html_namespacing --source http://gems.github.com
@@ -21,21 +25,14 @@ HTML Namespacing can be used on its own for a snippet of code:
21
25
 
22
26
  == Details
23
27
 
24
- HTML namespacing expects valid, properly-nested HTML (not XML). It has no
25
- effect on doctype tags, XML declaration, comments, and the HTML tags which do
26
- not support the <tt>class</tt> attribute: <tt>html</tt>, <tt>head</tt>,
27
- <tt>base</tt>, <tt>meta</tt>, <tt>title</tt>, <tt>link</tt>, <tt>script</tt>,
28
- <tt>noscript</tt>, <tt>style</tt>.
29
-
30
- Only the root tags of the partial HTML will be namespaced. For instance, all
31
- <tt>p</tt> tags in this example will have a class added, but no other tags:
28
+ Only root tags will be namespaced. For instance, all <tt>p</tt> tags in this
29
+ example will have a class added, but no other tags:
32
30
 
33
31
  <p>This is a root tag. <b>This tag is nested.</b></p>
34
32
  <p>This is another root tag.</p>
35
33
 
36
- Remember, <tt>html</tt> (and other HTML tags which do not allow the
37
- <tt>class</tt> attribute) will be ignored. This HTML will pass through
38
- unchanged:
34
+ Because XML, DOCTYPE, comments, and <tt>html</tt> tags do not allow the
35
+ <tt>class</tt> attribute, the following HTML will pass through unchanged:
39
36
 
40
37
  <?xml version="1.0"?>
41
38
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
@@ -50,13 +47,17 @@ unchanged:
50
47
  </body>
51
48
  </html>
52
49
 
50
+ (The following elements do not support the <tt>class</tt> attribute:
51
+ <tt>html</tt>, <tt>head</tt>, <tt>base</tt>, <tt>meta</tt>, <tt>title</tt>,
52
+ <tt>link</tt>, <tt>script</tt>, <tt>noscript</tt>, <tt>style</tt>.)
53
+
53
54
  Though the actual namespacing functions are written in pure C with no
54
55
  dependencies, only Ruby bindings are available at this time.
55
56
 
56
- == Integrating in your Project
57
+ == Integrating in a Rails project
57
58
 
58
- More likely, you want to integrate HTML namespacing into a framework. Here is
59
- a Rails example:
59
+ HTML namespacing is meant to integrate into a framework. Here is a Rails
60
+ example:
60
61
 
61
62
  In <tt>config/environment.rb</tt>:
62
63
 
@@ -74,9 +75,9 @@ Now, all templates will have HTML namespacing applied. For instance, with a
74
75
  <%=h @foo.name %>
75
76
  </p>
76
77
 
77
- <%= render(:partial => 'details', :locals => { :foo => @foo }) %>
78
+ <%= render(:partial => @foo) %>
78
79
 
79
- <%= link_to 'Edit', foo_edit_path(@foo) %> |
80
+ <%= link_to 'Edit', edit_foo_path(@foo) %> |
80
81
  <%= link_to 'Back', foos_path %>
81
82
 
82
83
  The following HTML might be generated (depending on the <tt>_details</tt>
@@ -87,7 +88,7 @@ partial and the data in the actual <tt>Foo</tt> object):
87
88
  Foo
88
89
  </p>
89
90
 
90
- <p class="foos-_details foos-show">
91
+ <p class="foos-_foo foos-show">
91
92
  <b>Description:</b>
92
93
  Bar
93
94
  </p>
@@ -95,12 +96,59 @@ partial and the data in the actual <tt>Foo</tt> object):
95
96
  <a href="/foos/1/edit" class="hellos-show">Edit</a> |
96
97
  <a href="/foos" class="hellos-show">Back</a>
97
98
 
98
- Rails will integrate with all HTML templates, regardless of their
99
- implementation; feel free to use Haml.
99
+ == Integrating with Haml and Sass in Rails
100
+
101
+ With Haml:http://haml-lang.com/ and Sass:http://sass-lang.com/ namespacing can
102
+ be automated even further.
103
+
104
+ In your Rails project, implement the following:
105
+
106
+ In <tt>config/environment.rb</tt>:
107
+
108
+ config.gem 'haml', :version => '2.2.0'
109
+ config.gem 'adamh-html_namespacing', :library => 'html_namespacing'
110
+
111
+ In <tt>config/initializers/html_namespacing.rb</tt>:
112
+
113
+ HtmlNamespacing::Plugin::Rails.install
114
+ HtmlNamespacing::Plugin::Sass.install
115
+
116
+ Then add <tt>stylesheet_link_tag(:all, :recursive => true)</tt> to your layout.
117
+
118
+ Now, all templates will have HTML namespacing applied, and Sass files in
119
+ <tt>SASS_DIR/views</tt> (where <tt>SASS_DIR</tt> is Sass's
120
+ <tt>:template_location</tt>, default <tt>public/stylesheets/sass</tt>) will
121
+ also be HTML-namespaced. For example:
122
+
123
+ With a partial, <tt>app/views/foos/show.html.haml</tt> like this:
124
+
125
+ %p
126
+ %strong Name:
127
+ %span.name&= @foo.name
128
+
129
+ = render(:partial => @foo)
130
+
131
+ = link_to('Edit', edit_foo_path(@foo)
132
+ |
133
+ = link_to('Back', foos_path
134
+
135
+ And a Sass file in <tt>public/stylesheets/sass/views/foos/show.sass</tt>:
136
+
137
+ strong
138
+ :font-size 1.3em
139
+ span.name
140
+ :font-style italic
141
+ a&
142
+ :font-weight bold
143
+
144
+ The Sass rules will only apply to their corresponding partial.
145
+
146
+ (Note: to target root-level elements in a Sass partial, use the "&" rule,
147
+ which is standard Sass and will equate to ".NAMESPACE" in this context.)
100
148
 
101
149
  === Options
102
150
 
103
- Available options to <tt>install</tt> are:
151
+ Available options to <tt>HtmlNamespacing::Plugin::Rails.install</tt> are:
104
152
 
105
153
  <tt>:template_to_namespace_callback</tt>: Ruby lambda function which accepts an
106
154
  <tt>ActionView::Template</tt> and returns an HTML namespacing string. The
@@ -119,6 +167,14 @@ an <tt>Exception</tt>, an <tt>ActionView::Template</tt>, and an
119
167
  If your <tt>:handle_exception_callback</tt> does not raise an exception,
120
168
  the template will be rendered as if HtmlNamespacing were not installed.
121
169
 
170
+ Available options to <tt>HtmlNamespacing::Plugin::Sass.install</tt> are:
171
+
172
+ <tt>:prefix</tt> (default <tt>views</tt>): subdirectory of Sass directory for
173
+ which we want to namespace our Sass.
174
+ <tt>:callback</tt>: See <tt>:template_to_namespace_callback</tt> above; this
175
+ callback is similar, though it accepts a string path rather than an
176
+ <tt>ActionView::Template</tt>.
177
+
122
178
  == Why?
123
179
 
124
180
  HTML namespacing gives huge benefits when writing CSS and JavaScript:
@@ -237,9 +293,9 @@ rename or move the partial.
237
293
  == Tips and Tricks
238
294
 
239
295
  You may find that HTML namespacing works best when each HTML partial is wrapped
240
- in its own <tt>div</tt> tag. Both CSS's child selectors and jQuery's <tt>find()</tt> function
241
- will ordinarily ignore the element with the namespace class, only selecting
242
- sub-elements. For instance, with this HTML:
296
+ in its own <tt>div</tt> tag. Both CSS's child selectors and jQuery's
297
+ <tt>find()</tt> function will ordinarily ignore the element with the namespace
298
+ class, only selecting sub-elements. For instance, with this HTML:
243
299
 
244
300
  <div class="foos-show">
245
301
  <p>Hello</p>
@@ -249,6 +305,11 @@ If you wrote the following CSS:
249
305
 
250
306
  .foos-show div { font-weight: bold; }
251
307
 
308
+ Or this Sass:
309
+
310
+ div
311
+ :font-weight bold
312
+
252
313
  Or the following JavaScript (following the <tt>$NS</tt> example above):
253
314
 
254
315
  var $div = $NS.find('div');
@@ -258,6 +319,11 @@ would need the following CSS:
258
319
 
259
320
  div.foos-show { font-weight: bold; }
260
321
 
322
+ Or this sass:
323
+
324
+ div&
325
+ :font-weight bold
326
+
261
327
  Or the following JavaScript:
262
328
 
263
329
  var $div = $NS.filter('div');
@@ -266,10 +332,18 @@ Also, watch out for nesting: selectors with the <tt>foos-show</tt> namespace
266
332
  will match anything inside any partials rendered by
267
333
  <tt>foos/show.html.erb</tt>. As a rule of thumb to circumvent this problem: the
268
334
  wider the namespaces's scope, the less CSS and JavaScript you should write
269
- which depends on it. (Rule of thumb: use sub-partials very liberally.)
270
-
271
- These and similar strategies should be considered when building your automated
272
- HTML namespacing framework.
335
+ which depends on it. (Use sub-partials very liberally.)
336
+
337
+ HTML namespacing produces plenty of tiny CSS and/or JavaScript files. Best
338
+ practice is to bundle all namespaced files together: by virtue of being
339
+ namespaced, it is safe to concatenate them. (Advanced CSS users should
340
+ be thoughtful about
341
+ "cascading order and specificity":http://www.w3.org/TR/CSS2/cascade.html#cascading-order;
342
+ and anybody bundling JavaScript files together should wrap each with
343
+ <tt>(function() { ... })();</tt> to prevent variable leakage.)
344
+
345
+ These and similar strategies should be considered when building an HTML
346
+ namespacing framework.
273
347
 
274
348
  == License
275
349
 
data/Rakefile CHANGED
@@ -2,7 +2,7 @@ require 'rubygems'
2
2
  require 'rake'
3
3
  require 'echoe'
4
4
 
5
- Echoe.new('html_namespacing', '0.0.4') do |p|
5
+ Echoe.new('html_namespacing', '0.0.5') do |p|
6
6
  p.author = 'Adam Hooper'
7
7
  p.email = 'adam@adamhooper.com'
8
8
  p.summary = 'Automatic HTML namespacing'
@@ -2,16 +2,16 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{html_namespacing}
5
- s.version = "0.0.4"
5
+ s.version = "0.0.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Adam Hooper"]
9
- s.date = %q{2009-07-07}
9
+ s.date = %q{2009-07-10}
10
10
  s.description = %q{Inserts "class=" attributes within snippets of HTML so CSS and JavaScript can use automatic scopes}
11
11
  s.email = %q{adam@adamhooper.com}
12
12
  s.extensions = ["ext/html_namespacing/extconf.rb"]
13
13
  s.extra_rdoc_files = ["README.rdoc"]
14
- s.files = ["README.rdoc", "Rakefile", "test/c_extension_test.rb", "test/test_helper.rb", "ext/html_namespacing/extconf.rb", "ext/html_namespacing/html_namespacing.h", "ext/html_namespacing/html_namespacing.c", "ext/html_namespacing/html_namespacing_ext.c", "lib/html_namespacing.rb", "lib/html_namespacing/plugin/rails.rb", "Manifest", "html_namespacing.gemspec"]
14
+ s.files = ["README.rdoc", "Rakefile", "test/c_extension_test.rb", "test/test_helper.rb", "ext/html_namespacing/extconf.rb", "ext/html_namespacing/html_namespacing.h", "ext/html_namespacing/html_namespacing.c", "ext/html_namespacing/html_namespacing_ext.c", "lib/html_namespacing.rb", "lib/html_namespacing/plugin.rb", "lib/html_namespacing/plugin/rails.rb", "lib/html_namespacing/plugin/sass.rb", "Manifest", "html_namespacing.gemspec"]
15
15
  s.has_rdoc = true
16
16
  s.homepage = %q{http://github.com/adamh/html_namespacing}
17
17
  s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Html_namespacing", "--main", "README.rdoc"]
@@ -10,8 +10,8 @@ module HtmlNamespacing
10
10
  def self.path_to_namespace(template)
11
11
  if func = @options[:template_to_namespace_callback]
12
12
  func.call(template)
13
- elsif template.path =~ /^([^\.]+)/
14
- $1.gsub('/', '-')
13
+ else
14
+ HtmlNamespacing::Plugin.default_relative_path_to_namespace(template.path)
15
15
  end
16
16
  end
17
17
 
@@ -0,0 +1,76 @@
1
+ module HtmlNamespacing
2
+ module Plugin
3
+ module Sass
4
+ def self.install(options = {})
5
+ options[:prefix] ||= 'views'
6
+ options[:callback] ||= lambda { |p| HtmlNamespacing::Plugin.default_relative_path_to_namespace(p) }
7
+ Sass_2_2.install(options)
8
+ end
9
+
10
+ module Sass_2_2
11
+ def self.install(options = {})
12
+ self.allow_updating_partials
13
+ self.add_super_rule_to_tree_node(options)
14
+ self.try_to_enable_memoization
15
+ end
16
+
17
+ private
18
+
19
+ def self.allow_updating_partials
20
+ ::Sass::Plugin.module_eval do
21
+ private
22
+
23
+ # Though a bit over-zealous, who *cares* if we render partial
24
+ # Sass files?
25
+ def forbid_update?(*args)
26
+ false
27
+ end
28
+ end
29
+ end
30
+
31
+ def self.add_super_rule_to_tree_node(namespacing_options)
32
+ ::Sass::Tree::RuleNode.class_eval do
33
+ def to_s_with_namespacing(tabs, super_rules = nil)
34
+ super_rules ||= namespacing_rules
35
+ to_s_without_namespacing(tabs, super_rules)
36
+ end
37
+ alias_method_chain(:to_s, :namespacing)
38
+
39
+ private
40
+
41
+ define_method(:namespacing_prefix) do
42
+ namespacing_options[:prefix]
43
+ end
44
+ define_method(:namespacing_callback) do
45
+ namespacing_options[:callback]
46
+ end
47
+
48
+ def namespacing_regex
49
+ /^#{Regexp.quote(options[:css_location])}\/#{Regexp.quote(namespacing_prefix)}\/(.*)\.css$/
50
+ end
51
+
52
+ def namespace
53
+ @namespace ||= if options[:css_filename] =~ namespacing_regex
54
+ namespacing_callback.call($1.split('.')[0])
55
+ end
56
+ @namespace
57
+ end
58
+
59
+ def namespacing_rules
60
+ namespace && [ ".#{namespace}" ]
61
+ end
62
+ end
63
+ end
64
+
65
+ def self.try_to_enable_memoization
66
+ ::Sass::Tree::RuleNode.class_eval do
67
+ extend ActiveSupport::Memoizable
68
+ memoize :namespacing_rules
69
+ end
70
+ rescue NameError
71
+ # ActiveSupport isn't loaded
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,12 @@
1
+ module HtmlNamespacing
2
+ module Plugin
3
+ autoload(:Rails, File.dirname(__FILE__) + '/plugin/rails')
4
+ autoload(:Sass, File.dirname(__FILE__) + '/plugin/sass')
5
+
6
+ def self.default_relative_path_to_namespace(path)
7
+ if path =~ /^([^\.]+)/
8
+ $1.gsub(/\//, '-')
9
+ end
10
+ end
11
+ end
12
+ end
@@ -1,6 +1,5 @@
1
1
  require File.dirname(__FILE__) + '/../ext/html_namespacing/html_namespacing_ext'
2
2
 
3
- require 'html_namespacing/plugin/rails'
4
-
5
3
  module HtmlNamespacing
4
+ autoload(:Plugin, File.dirname(__FILE__) + '/html_namespacing/plugin')
6
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: adamh-html_namespacing
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.4
4
+ version: 0.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Adam Hooper
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-07-07 00:00:00 -07:00
12
+ date: 2009-07-10 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies: []
15
15
 
@@ -31,7 +31,9 @@ files:
31
31
  - ext/html_namespacing/html_namespacing.c
32
32
  - ext/html_namespacing/html_namespacing_ext.c
33
33
  - lib/html_namespacing.rb
34
+ - lib/html_namespacing/plugin.rb
34
35
  - lib/html_namespacing/plugin/rails.rb
36
+ - lib/html_namespacing/plugin/sass.rb
35
37
  - Manifest
36
38
  - html_namespacing.gemspec
37
39
  has_rdoc: true