cssplop 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source :rubygems
2
+
3
+ gemspec
data/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # CSSPlop #
2
+ Inline CSS declarations into HTML element attributes using [Nokogiri](https://github.com/tenderlove/nokogiri) and [CSSPool](https://github.com/tenderlove/csspool). Use this to keep the email markup you edit sane. *Using this anywhere else is probably not recommended.*
3
+
4
+ ```html
5
+ <style>
6
+ ul {
7
+ margin: 0 0 1em 0;
8
+ padding: 0;
9
+ }
10
+
11
+ .lined-list li {
12
+ border-bottom: 1px solid gray;
13
+ }
14
+
15
+ .lined-list li:first-child {
16
+ border-top: 1px solid gray;
17
+ }
18
+ </style>
19
+
20
+ <ul class="lined-list">
21
+ <li>one</li>
22
+ <li>two</li>
23
+ <li>three</li>
24
+ </ul>
25
+ ```
26
+
27
+ ```ruby
28
+ CSSPlop.apply(stylesheet, document)
29
+ ```
30
+
31
+ ```html
32
+ <ul class="lined-list" style="padding: 0; margin: 0 0 1em 0;">
33
+ <li style="border-bottom: 1px solid gray; border-top: 1px solid gray;">red</li>
34
+ <li style="border-bottom: 1px solid gray;">green</li>
35
+ <li style="border-bottom: 1px solid gray;">blue</li>
36
+ </ul>
37
+ ```
38
+
39
+ ## License ##
40
+ Released under the MIT license.
41
+
42
+ Copyright (c) 2011 Chad Weider
43
+
44
+ Permission is hereby granted, free of charge, to any person obtaining a
45
+ copy of this software and associated documentation files (the "Software"),
46
+ to deal in the Software without restriction, including without limitation
47
+ the rights to use, copy, modify, merge, publish, distribute, sublicense,
48
+ and/or sell copies of the Software, and to permit persons to whom the
49
+ Software is furnished to do so, subject to the following conditions:
50
+
51
+ The above copyright notice and this permission notice shall be included in
52
+ all copies or substantial portions of the Software.
53
+
54
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
55
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
56
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
57
+ THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
58
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
59
+ FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
60
+ DEALINGS IN THE SOFTWARE.
61
+
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
data/cssplop.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path("../lib/cssplop/version", __FILE__)
3
+
4
+ Gem::Specification.new do |s|
5
+ s.name = "cssplop"
6
+ s.version = CSSPlop::VERSION
7
+ s.platform = Gem::Platform::RUBY
8
+ s.authors = ["Chad Weider"]
9
+ s.email = ["cweider@oofn.net"]
10
+ s.homepage = "http://rubygems.org/gems/cssplop"
11
+ s.summary = "Inline CSS declarations into HTML element attributes."
12
+ s.description = ""
13
+ s.license = "MIT"
14
+
15
+ s.required_rubygems_version = ">= 1.3.6"
16
+ s.rubyforge_project = "cssplop"
17
+
18
+ s.add_dependency "csspool", "~> 3.0"
19
+ s.add_development_dependency "nokogiri", "~> 1.5"
20
+
21
+ s.add_development_dependency "bundler", ">= 1.0.0"
22
+ s.add_development_dependency "rspec", "~> 2.6"
23
+
24
+ s.files = `git ls-files`.split("\n")
25
+ s.executables = `git ls-files`.split("\n").map{|f| f =~ /^bin\/(.*)/ ? $1 : nil}.compact
26
+ s.require_path = 'lib'
27
+ end
data/lib/cssplop.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'csspool'
2
+ require 'nokogiri'
3
+
4
+ module CSSPlop
5
+ def self.inline_styles document
6
+ html_doc = Nokogiri::HTML.fragment document
7
+
8
+ # All styles that don't have sources.
9
+ styles = html_doc.xpath 'descendant-or-self::style[not(@src)]'
10
+ styles.each do |style|
11
+ begin
12
+ stylesheet = CSSPool::CSS style.text
13
+ self.apply! stylesheet, html_doc
14
+ style.remove
15
+ end
16
+ end
17
+
18
+ return html_doc.to_html
19
+ end
20
+
21
+ def self.apply stylesheet, document
22
+ css_doc = if stylesheet.is_a? CSSPool::CSS::Document
23
+ stylesheet
24
+ else
25
+ CSSPool.CSS stylesheet
26
+ end
27
+
28
+ html_doc = if document.is_a? Nokogiri::XML::Node
29
+ document.dup # no sideeffects
30
+ else
31
+ Nokogiri::HTML.fragment document
32
+ end
33
+
34
+ self.apply! css_doc, html_doc
35
+
36
+ if document.is_a? Nokogiri::XML::Node
37
+ return html_doc
38
+ else
39
+ return html_doc.to_html
40
+ end
41
+ end
42
+
43
+ def self.apply! stylesheet, document
44
+ elements_declarations_map = {}
45
+
46
+ stylesheet.rule_sets.each do |rule_set|
47
+ selectors = rule_set.selectors.map &:to_css
48
+ elements = document.css *selectors
49
+ elements.each do |element|
50
+ elements_declarations_map[element] ||= []
51
+ elements_declarations_map[element].concat rule_set.declarations
52
+ end
53
+ end
54
+
55
+ elements_declarations_map.each do |element, declarations|
56
+ element_style_doc = CSSPool.CSS "* {#{element[:style]}}"
57
+ element_declarations = element_style_doc.rule_sets.first.declarations
58
+ element_declarations.concat declarations.flatten
59
+
60
+ element[:style] = element_declarations.map(&:to_css).join.strip
61
+ end
62
+
63
+ return document
64
+ end
65
+ end
@@ -0,0 +1,3 @@
1
+ module CSSPlop
2
+ VERSION = "0.1.0"
3
+ end
@@ -0,0 +1,84 @@
1
+ require 'cssplop'
2
+
3
+ describe CSSPlop do
4
+ it "passes the gauntlet" do
5
+ stylesheet = <<EOF
6
+ ul {
7
+ padding: 0;
8
+ margin: 0 0 1em 0;
9
+ }
10
+
11
+ #color-list {
12
+ background-color: lightgray;
13
+ }
14
+
15
+ #color-list li {
16
+ border-bottom: 1px solid gray;
17
+ }
18
+
19
+ #color-list li.first {
20
+ border-top: 1px solid gray;
21
+ }
22
+ EOF
23
+
24
+ document = <<EOF
25
+ <ul id="color-list">
26
+ <li class="first">red</li>
27
+ <li>green</li>
28
+ <li class="last">blue</li>
29
+ </ul>
30
+ EOF
31
+
32
+ expected = <<EOF
33
+ <ul id="color-list" style="padding: 0; margin: 0 0 1em 0; background-color: lightgray;">
34
+ <li class="first" style="border-bottom: 1px solid gray; border-top: 1px solid gray;">red</li>
35
+ <li style="border-bottom: 1px solid gray;">green</li>
36
+ <li class="last" style="border-bottom: 1px solid gray;">blue</li>
37
+ </ul>
38
+ EOF
39
+
40
+ CSSPlop.apply(stylesheet, document).should eql(expected.strip)
41
+ end
42
+
43
+ it "supports rulesets with multiple selectors" do
44
+ stylesheet = <<EOF
45
+ .selector1, .selector2 {property: value;}
46
+ EOF
47
+
48
+ document = <<EOF
49
+ <div class="selector1 selector2"></div>
50
+ <div class="selector2"></div>
51
+ EOF
52
+
53
+ expected = <<EOF
54
+ <div class="selector1 selector2" style="property: value;"></div>
55
+ <div class="selector2" style="property: value;"></div>
56
+ EOF
57
+
58
+ CSSPlop.apply(stylesheet, document).should eql(expected.strip)
59
+ end
60
+
61
+ it "supports rulesets with multiple selectors" do
62
+ document = <<EOF
63
+ <style>* { property: value;}</style>
64
+ <div></div>
65
+ EOF
66
+
67
+ expected = <<EOF
68
+ <div style="property: value;"></div>
69
+ EOF
70
+
71
+ CSSPlop.inline_styles(document).should eql(expected.strip)
72
+
73
+ document = <<EOF
74
+ <style src="http://example.com/stylesheet.css">* { nonsense: value;}</style>
75
+ <div></div>
76
+ EOF
77
+
78
+ expected = <<EOF
79
+ <style src="http://example.com/stylesheet.css">* { nonsense: value;}</style><div></div>
80
+ EOF
81
+
82
+ CSSPlop.inline_styles(document).should eql(expected.strip)
83
+ end
84
+ end
metadata ADDED
@@ -0,0 +1,134 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cssplop
3
+ version: !ruby/object:Gem::Version
4
+ hash: 27
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 0
10
+ version: 0.1.0
11
+ platform: ruby
12
+ authors:
13
+ - Chad Weider
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2012-04-29 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ name: csspool
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
24
+ none: false
25
+ requirements:
26
+ - - ~>
27
+ - !ruby/object:Gem::Version
28
+ hash: 7
29
+ segments:
30
+ - 3
31
+ - 0
32
+ version: "3.0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: nokogiri
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ hash: 5
44
+ segments:
45
+ - 1
46
+ - 5
47
+ version: "1.5"
48
+ type: :development
49
+ version_requirements: *id002
50
+ - !ruby/object:Gem::Dependency
51
+ name: bundler
52
+ prerelease: false
53
+ requirement: &id003 !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ hash: 23
59
+ segments:
60
+ - 1
61
+ - 0
62
+ - 0
63
+ version: 1.0.0
64
+ type: :development
65
+ version_requirements: *id003
66
+ - !ruby/object:Gem::Dependency
67
+ name: rspec
68
+ prerelease: false
69
+ requirement: &id004 !ruby/object:Gem::Requirement
70
+ none: false
71
+ requirements:
72
+ - - ~>
73
+ - !ruby/object:Gem::Version
74
+ hash: 15
75
+ segments:
76
+ - 2
77
+ - 6
78
+ version: "2.6"
79
+ type: :development
80
+ version_requirements: *id004
81
+ description: ""
82
+ email:
83
+ - cweider@oofn.net
84
+ executables: []
85
+
86
+ extensions: []
87
+
88
+ extra_rdoc_files: []
89
+
90
+ files:
91
+ - Gemfile
92
+ - README.md
93
+ - Rakefile
94
+ - cssplop.gemspec
95
+ - lib/cssplop.rb
96
+ - lib/cssplop/version.rb
97
+ - spec/cssplop_spec.rb
98
+ homepage: http://rubygems.org/gems/cssplop
99
+ licenses:
100
+ - MIT
101
+ post_install_message:
102
+ rdoc_options: []
103
+
104
+ require_paths:
105
+ - lib
106
+ required_ruby_version: !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ hash: 3
112
+ segments:
113
+ - 0
114
+ version: "0"
115
+ required_rubygems_version: !ruby/object:Gem::Requirement
116
+ none: false
117
+ requirements:
118
+ - - ">="
119
+ - !ruby/object:Gem::Version
120
+ hash: 23
121
+ segments:
122
+ - 1
123
+ - 3
124
+ - 6
125
+ version: 1.3.6
126
+ requirements: []
127
+
128
+ rubyforge_project: cssplop
129
+ rubygems_version: 1.8.11
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Inline CSS declarations into HTML element attributes.
133
+ test_files: []
134
+