adamh-html_namespacing 0.0.4 → 0.0.5

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.
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