widget_builder 0.1.0.alpha

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 90f4cc2d815c5777c210e44d1ba56ada0aaa31d6
4
+ data.tar.gz: b02ca2bee98891fcfd4ad0c67e6f5e777fe97ee1
5
+ SHA512:
6
+ metadata.gz: d1d859a96e2c5304e143996285bfba1f281d2621edc076734dda1a91ffce298ece03e52d5c6c024892fa62b40698e3067a92609ae8be7192f03c50e4058a9b7a
7
+ data.tar.gz: 6a3da34735f718f98adaf536434dc9f06b8a146499581e09124e15a3ba070490128e0c5abb0ffe8f3ccd5b93189c7322e31374fb0f6704338eb4db072fe6a761
data/.gitignore ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/CHANGELOG.md ADDED
@@ -0,0 +1,3 @@
1
+ ## 0.1.0
2
+
3
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in widget_builder.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Endri Gjiri
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.
data/README.md ADDED
@@ -0,0 +1,141 @@
1
+ # WidgetBuilder
2
+
3
+ By: Endri Gjiri *www.name-reaction.com*
4
+
5
+ **WidgetBuilder** aims to be a simple way to create javascript widgets. It allows developers to work separately on the html, css, and javascript files for their widgets. WidgetBuilder combines all of these files into a single minified javascript file, ready to be loaded by the end user. WidgetBuilder also wraps everything with a javascript Widget class, namespacing everything, and allows the display of multiple widgets in the same page without conflicts.
6
+ #### Other Features include:
7
+ - Provides a simple and small snippet for the user on which to load the widget. It only consists of an anchor tag with a class of the specific ```widget_name``` and the script tag to load the generated widget javascript.
8
+ - The a tag on which the widget is loaded on top of can serve as a way to pass options to the widget js through the a tag's data attributes. This data can be used to customize the widget's function or style.
9
+ - Provides a ```validateReference``` function that checks if the developer's site is referenced properly SEO-wise and if not it destroys the widget. This function needs to be called explicitly in the developer's custom javascript.
10
+ - Provides a ```resetCSS``` function which minimizes style conflicts with the sites that the widget ultimately ends up in.
11
+
12
+ ## Installation
13
+
14
+ Add this line to your application's Gemfile:
15
+ ```ruby
16
+ gem 'widget_builder'
17
+ ```
18
+
19
+ And then execute:
20
+ ```console
21
+ $ bundle install
22
+ ```
23
+
24
+ Or install it yourself as:
25
+ ```console
26
+ $ gem install widget_builder
27
+ ```
28
+
29
+ ### Brief description of the Ruby classes
30
+
31
+ WidgetBuilder consists of a Ruby module of the same name which contains two classes named **Widget** and **Widgets** (plural).
32
+
33
+ The main class is the **Widget** class which needs 3 arguments, the html_path, css_path, and js_path respectively. It also has a forth optional argument which is an options hash. This class essentially reads all of these files, includes the css inline into the html, and then adds this combined html_and_css string into the javascript. This class also wraps the javascript with the gem's own ```widget_loader``` javascript which provides additional functionality to the widget. Instance methods include: ```save```, ```show_snippet```, ```report```, and ```compile```, among others.
34
+
35
+ The **Widgets** (plural) class is designed to create multiple widgets at once, relying on naming conventions. It also accepts html_path, css_path, and js_path as arguments but in this case they do not refer to the file paths but instead to directory paths. This class will first go to the html directory and get all the file names and try to match them to css and js files of the same name in their respective folders. It will then loop through the list of html files and create an instance of the Widget class by passing in the html, css, and js file. The final result is an array of widgets (instances of Widget). The Widgets class also responds to ```save```, ```report```, and ```compile``` and loops over the array of widgets and calls the appropriate method on the widget instance.
36
+
37
+ ## Usage
38
+
39
+ #### The simplest way to get started with this gem is the following:
40
+
41
+ 1. Place the html, css, and js files needed for the widget all in the same folder and navigate there in the console.
42
+
43
+ 2. Load irb and require widget_builder
44
+ ```console
45
+ $ irb
46
+ > require 'widget_builder'
47
+ ```
48
+
49
+ 3. Compile the widget directly through irb.
50
+ ```ruby
51
+ WidgetBuilder::Widgets.new.compile
52
+ ```
53
+ Note: When no paths are passed as attributes to the Widgets class, it defaults them to the current directory.
54
+
55
+ This will create a new javascript file which is the new widget file, named according to the widget_name. The widget_name gets extracted by the class of the first div in the html or it can be passed in through the options hash.
56
+
57
+ This command will also generate a report in the console, also including an html snippet that the end user can copy and place on their pages to display the widget.
58
+
59
+ A sample snippet is shown below:
60
+ ```html
61
+ <a class="chemiphi_MMC" href="http://www.name-reaction.com"></a>
62
+ <script type="text/javascript">
63
+ var element = document.createElement('script');
64
+ element.type = 'text/javascript';
65
+ element.src = 'http://api.chemiphi.com/public_widgets/chemiphi_MMC.js';
66
+ document.getElementsByTagName('head')[0].appendChild(element);
67
+ </script>
68
+ ```
69
+
70
+ ## Usage with Rails
71
+ #### Building a widget by specifying the paths to the html, css, and js in a Rails app.
72
+
73
+ A simple way to build a widget in rails is to do it by creating a custom Task.
74
+
75
+ Let's create a new Ruby file "/lib/tasks/widget_compiler.rake" with the following code:
76
+
77
+ ```ruby
78
+ desc "Creates a single uglified widget JavaScript file containing the custom HTML, CSS, and JS"
79
+ task :create_widget do
80
+ html_path = File.join(Rails.root, 'app', 'views', 'widgets', 'my_widget.html')
81
+ css_path = File.join(Rails.root, 'app', 'assets', 'stylesheets', 'widgets', 'my_widget.css')
82
+ js_path = File.join(Rails.root, 'app', 'assets', 'javascripts', 'widgets', 'my_widget.js')
83
+
84
+ widget = WidgetBuilder::Widget.new(html_path, css_path, js_path)
85
+
86
+ export_path = File.join(Rails.root, 'public', 'widgets')
87
+ widget.compile(export_path)
88
+ end
89
+ ```
90
+ In the above code we have specified that the final widget js should be placed in a public/widgets folder so before we run this task we need to first create the widgets folder.
91
+
92
+ We can then build the widget by running the following command from the console:
93
+ ```console
94
+ $ rake create_widget
95
+ ```
96
+ This will create the widget.js in the public/widgets folder, ready to be accessed by users and also displays in the console the HTML snippet required to display this widget.
97
+
98
+ ## Options
99
+
100
+ #### The WidgetBuilder also accepts an options hash as a fourth argument.
101
+
102
+ Available options include:
103
+ - **compress** - *defaults to true* - specifies whether the compiled javascript file should be minified.
104
+ - **href** - *defaults to #* - specifies the url that the snippet anchor tag should link to. This has to be passed in as an option if the *validateReference* function is called from the js file.
105
+ - **source_path** - needed to point to the src of the compiled widget.js in the snippet. In the above example this could be *www.my_domain.com/widgets*.
106
+
107
+ **Example:**
108
+ ```ruby
109
+ options = { compress: false, href: 'www.my_domain.com', source_path: 'www.my_domain.com/widgets' }
110
+ widget = WidgetBuilder::Widget.new(html_path, css_path, js_path, options)
111
+ widget.compile(export_path)
112
+ ```
113
+
114
+ This would create a non-minified widget javascript and final HTML snippet that looks like this:
115
+ ```html
116
+ <a class="my_widget" href="http://www.my_domain.com"></a>
117
+ <script type="text/javascript">
118
+ var element = document.createElement('script');
119
+ element.type = 'text/javascript';
120
+ element.src = 'http://www.my_domain.com/widgets/my_widget.js';
121
+ document.getElementsByTagName('head')[0].appendChild(element);
122
+ </script>
123
+ ```
124
+ ## JavaScript Utilities
125
+ #### The widget's functionality is determined in the custom javascript file that you develop.
126
+ ##### This javascript get wrapped in the gem's ```widget_loader``` js code that extends it with additional functionality.
127
+
128
+ - ```var widget ``` becomes available to your custom javascript file and it stores the whole widget object. Outputting it to the console shows that it includes the widget ```id```, ```aTag```, ```dataset```, ```app```, and the ```validateRefence``` function.
129
+ - ```var w ``` is also available to the custom javascript and it holds the whole widget as a jQuery object. This can come in handy when trying to find elements within a particular widget and can be done using ```w.find('.my_element') ``` instead of searching it on the global scope as in ```$(.my_element) ```. This can be useful when it is desirable to have multiple widgets running on the same page without conflicting with each other.
130
+
131
+ ## Future Work
132
+ - As of now the only file formats that are supported are html, css, js as well as scss, and sass. In the next release I would like to extend support for haml and coffeeScript.
133
+ - Current integration with Rails is quite raw and does not take advantage of the capabilities of Rails. In the future I want to create another gem, likely wiget_builder-rails, that is designed specifically for working in Rails.
134
+
135
+ ## Contributing
136
+
137
+ 1. Fork it
138
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
139
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
140
+ 4. Push to the branch (`git push origin my-new-feature`)
141
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ Rake.application.options.trace = false
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
@@ -0,0 +1,79 @@
1
+ // START...
2
+ if (window.jQuery != undefined) { // If the user already has jQuery loaded on their site just start loading the widget
3
+ loadWidget();
4
+ } else { // Load jQuery
5
+ element = document.createElement('script');
6
+ element.setAttribute('type', 'text/javascript');
7
+ element.setAttribute('src', 'https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js'); // jQuery from Google
8
+ document.getElementsByTagName('head')[0].appendChild(element); // add jQuery to the head
9
+ element.onload = loadWidget; // once jQuery has loaded, start loading the chemiphi widget
10
+ }
11
+
12
+ // Loads the widget on top of <a> tags with a class of 'widget_name'
13
+ function loadWidget() {
14
+ jQuery(function($) {
15
+ // Note: The 'widget_name' below will be automatically replaced with the propper class from the ruby widget_builder script
16
+ $('a.widget_name').each(function(index, aTag) { // Creates a widget for every <a> tag with a class of widget_name
17
+ new CustomWidget(aTag);
18
+ });
19
+ });
20
+ }
21
+
22
+ // Custom Widget class that include the js code from the included js_path
23
+ function CustomWidget(aTag) {
24
+ var widget = new Widget(aTag); // Create an instance of the widget object
25
+ var w = widget.app; // 'w' is just a shortcut for the whole widget.app jQuery object
26
+ JAVASCRIPT_PLACEHOLDER // The rest of the javascript is then included
27
+ }
28
+
29
+ // The main Widget class.
30
+ function Widget(aTag) {
31
+ this.id = aTag.className + '_' + Math.round(Math.random()*10000); // generate a random number as the id of the widget
32
+ this.aTag = aTag;
33
+ this.dataset = $(aTag).data();
34
+ this.app = $('<div>HTML&CSS_PLACEHOLDER</div>').attr('id', this.id);
35
+ $(aTag).replaceWith(this.app); // Replace the <a> tag placeholder with the widget HTML
36
+
37
+ // Destroys the widget if the referring link has been altered. This functions needs to be called to take effect
38
+ this.validateReference = function validateReference() {
39
+ var a = $(aTag);
40
+ if (a.attr('href') != 'HREF_PLACEHOLDER' || a.attr('rel') == 'nofollow') {
41
+ this.app.remove();
42
+ delete this;
43
+ // Displays a console error alerting of the situation
44
+ console.error('The Widget widget_name was not loaded due to an invalid <a> tag reference.\nA valid tag would be: VALID_ATAG_PLACEHOLDER')
45
+ }
46
+ }
47
+ }
48
+
49
+ // Utility function that sets the CSS of elements to defaults if they are not already set
50
+ function resetCSS(element, andChildren) {
51
+ // if andChildren is true, reset the styles of the specified jQuery object and all its children
52
+ var elements = andChildren ? element.find('*').andSelf() : element;
53
+ elements.each( function() {
54
+ var defaultStyles = {
55
+ 'margin-top': '0px',
56
+ 'margin-bottom': '0px',
57
+ 'margin-left': '0px',
58
+ 'margin-right': '0px',
59
+ 'padding-top': '0px',
60
+ 'padding-bottom': '0px',
61
+ 'padding-left': '0px',
62
+ 'padding-right': '0px',
63
+ 'font-size': 'normal',
64
+ 'font-style': 'normal',
65
+ 'font-variant': 'normal',
66
+ 'font-weight': 'normal',
67
+ 'line-height': 'normal',
68
+ 'vertical-align': 'baseline',
69
+ 'color': 'black',
70
+ 'background-color': 'transparent'
71
+ }; // Need to reset borders, fonts etc.
72
+ for (var key in defaultStyles) {
73
+ if (!this.style[key])
74
+ this.style[key] = defaultStyles[key];
75
+ }
76
+ });
77
+ return element // return the jQuery object back for possible chaining
78
+ }
79
+
@@ -0,0 +1,4 @@
1
+ module WidgetBuilder
2
+ ROOT_PATH = File.join(File.absolute_path(File.dirname __FILE__), '..', '..')
3
+ WIDGET_LOADER_PATH = File.join(ROOT_PATH, 'app', 'assets', 'javascripts', 'widget_loader.js')
4
+ end
@@ -0,0 +1,3 @@
1
+ module WidgetBuilder
2
+ VERSION = "0.1.0.alpha"
3
+ end
@@ -0,0 +1,212 @@
1
+ require 'widget_builder/constants'
2
+ require 'awesome_print'
3
+ require 'yui/compressor'
4
+ require 'premailer'
5
+ require 'sass'
6
+ require 'find'
7
+
8
+ module WidgetBuilder
9
+
10
+ # Creates a single Widget by passing in the path to the html, css, and js files.
11
+ class Widget
12
+ def initialize(html_path, css_path, js_path, options = {})
13
+ @html_path, @css_path, @js_path = html_path, css_path, js_path
14
+
15
+ defaults = { compress: true }
16
+ defaults.merge(options).each do |k, v|
17
+ instance_variable_set("@#{k}",v)
18
+ end
19
+
20
+ @html = html
21
+ @widget_name ||= widget_name # the widget name is either passed in as an option or extrapolated from the html
22
+ @href = href
23
+
24
+ @css = css
25
+ @js = js
26
+ end
27
+
28
+ def html
29
+ File.read @html_path
30
+ end
31
+
32
+ # Get the widget name from the class of the first div tag in the html
33
+ def widget_name
34
+ @html.match(/<div\s+?class=(['"])(\w+)(?:\s+\w*)*\1/i)[2]
35
+ end
36
+
37
+ def css
38
+ css = File.read @css_path # Reads the css or scss file
39
+ css_folder = File.dirname @css_path # Infers the css foler
40
+
41
+ # Scans the file for any @import rules and includes their content
42
+ css.scan(/(^\s*@import\s+(?:url[\( ])?(['"])([\w\.]+)\2.*;)/).each do |m|
43
+ Find.find(css_folder) do |path|
44
+ css.gsub!(m[0], File.read(path)) if path.match(m[2])
45
+ end
46
+ end
47
+
48
+ # Determines the suffics of the file
49
+ suffix = @css_path.split('.').last
50
+ if suffix == 'css' # Just return the css if it is a plain css file
51
+ css
52
+ elsif suffix =~ /^scss|sass$/ # handle Sass files with the Sass Engine
53
+ engine = Sass::Engine.new(css, syntax: suffix.to_sym)
54
+ engine.render # converts scss or sass to plain css
55
+ else
56
+ raise 'Invalid css format'
57
+ end
58
+ end
59
+
60
+ def html_with_css
61
+ premailer = Premailer.new(@html, { with_html_string: true, remove_comments: true, css_string: @css })
62
+ html_with_css = premailer.to_inline_css # places all the css inline with the html code
63
+ html_with_css = WidgetBuilder.remove_excess_premailer_content(html_with_css) # cleans up excess styles
64
+ if @compress == true
65
+ WidgetBuilder.html_uglifier(html_with_css) # removes html comments and unnecessary spaces
66
+ else
67
+ html_with_css.gsub("\n", " \\\n") # returns the html as is but adds trailing backslashes after each line to allow the multiline string in JavaScript
68
+ end
69
+ end
70
+
71
+ # Properly formats the href for the widget a tag or returns '#' if not provided
72
+ def href
73
+ if href = @href
74
+ href.gsub!(/^http:\/\//, '') # removes leading http:// if present since it gets added in the next step
75
+ "http://#{href}"
76
+ else
77
+ '#'
78
+ end
79
+ end
80
+
81
+ # Generates the final js file with all included html & css
82
+ def js
83
+ js = File.read WidgetBuilder::WIDGET_LOADER_PATH # reads the widget_loader js
84
+ js.gsub!(/widget_name/, @widget_name) # adds the widget name to the js file
85
+ js.gsub!(/JAVASCRIPT_PLACEHOLDER/, File.read(@js_path)) # adds the custom js to the widget_loader js
86
+ js.gsub!(/HTML&CSS_PLACEHOLDER/, html_with_css) # includes the html & css
87
+ js.gsub!(/HREF_PLACEHOLDER/, @href) # adds the href to the js validateReference function
88
+ js.gsub!(/VALID_ATAG_PLACEHOLDER/, %Q{<a class="#{@widget_name}" href="#{@href}"></a>})
89
+ if @compress == true
90
+ YUI::JavaScriptCompressor.new(munge: true).compress(js) # uglifies the combined javascript
91
+ else
92
+ js # Otherwise returns the raw non-minified javascript
93
+ end
94
+ end
95
+
96
+ # Saves the final js file to the specified path
97
+ def save(path = File.dirname(@js_path))
98
+ new_js_path = File.join(path, @widget_name + '.js')
99
+ File.open(new_js_path, 'w') do |f|
100
+ f.write @js
101
+ end
102
+ end
103
+
104
+ def show_snippet
105
+ # Properly format or generate the javascript widget src path
106
+ if source_path = @source_path
107
+ source_path.gsub!(/^http:\/\//, '') # removes leading http:// if present since it gets added later
108
+ source_path.gsub!(/\/$/, '') # removes trailing slash if present since it gets added later
109
+ else
110
+ source_path = 'SOURCE_PATH_PLACEHOLDER'
111
+ ap "NOTE: Make sure to replace the #{source_path} in the code snippet below.", color: {string: :redish}
112
+ end
113
+
114
+ ap "------------ Copy the following HTML snippet to display the widget. -------------", color: {string: :cyanish}
115
+ puts %Q{<a class="#{@widget_name}" href="#{@href}"></a>
116
+ <script type="text/javascript">
117
+ var element = document.createElement('script');
118
+ element.type = 'text/javascript';
119
+ element.src = 'http://#{source_path}/#{@widget_name}.js';
120
+ document.getElementsByTagName('head')[0].appendChild(element);
121
+ </script>}
122
+ ap "---------------------------------------------------------------------------------", color: {string: :cyanish}
123
+ end
124
+
125
+ # Outputs a nice report on the console
126
+ def report
127
+ puts
128
+ ap "Widget name: #{@widget_name}", color: {string: :redish}
129
+ ap "HTML Template: #{@html_path.split('/').last}", color: {string: :greenish}
130
+ ap "Javascript reference: #{@js_path.split('/').last}", color: {string: :greenish}
131
+ ap "Stylesheet reference: #{@css_path.split('/').last}", color: {string: :greenish}
132
+ ap "HTML with CSS:"
133
+ puts html_with_css
134
+ ap "Final Compilation of the JS File (includes html, css, and js):", color: {string: :greenish}
135
+ puts @js
136
+ show_snippet
137
+ end
138
+
139
+ def compile(path = File.dirname(@js_path))
140
+ save(path)
141
+ report
142
+ end
143
+ end
144
+
145
+ # Crates an array of Widgets by passing in the paths to the html, css, and js directories
146
+ class Widgets
147
+ def initialize(html_path = '.', css_path = '.', js_path = '.', options = {})
148
+ @html_path, @css_path, @js_path, @options = html_path, css_path, js_path, options
149
+ @widgets = widgets
150
+ end
151
+
152
+ def widgets
153
+ widgets = []
154
+ Dir.foreach(@html_path) do |file| # read all the files in the 'Widget html' directory
155
+ if (file.match(/\.html$/)) # only consider html files for now
156
+ html_path = File.join(@html_path, file)
157
+
158
+ # HTML, CSS, and JS files should have the same name but different extensions
159
+ filename = file.gsub('.html', '')
160
+
161
+ css_path = ''
162
+ Find.find(@css_path) do |path|
163
+ css_path = path if path.split('/').last.match(/^#{filename}.*?\.(?:css|scss|sass)$/)
164
+ end
165
+
166
+ js_path = ''
167
+ Find.find(@js_path) do |path|
168
+ js_path = path if path.split('/').last.match(/^#{filename}\.js$/) # NOTE: Needs to add CoffeeScript support
169
+ end
170
+ widgets << WidgetBuilder::Widget.new(html_path, css_path, js_path, @options)
171
+ end
172
+ end
173
+ widgets
174
+ end
175
+
176
+ def save(path = @js_path)
177
+ widgets.each { |widget| widget.save(path) }
178
+ end
179
+
180
+ def report
181
+ widgets.each { |widget| widget.report }
182
+ end
183
+
184
+ def compile(path = File.dirname(@js_path))
185
+ widgets.each { |widget| widget.compile(path) }
186
+ end
187
+ end
188
+
189
+ # Utility methods
190
+ private
191
+
192
+ # removes styles that were added by default with the pre-mailer gem
193
+ def self.remove_excess_premailer_content(html)
194
+ html = html.gsub(/^.*?<body.*?>(.*?)<\/body>.*$/m,'\1') # removes created html and body tags
195
+ html = html.gsub(/\s*font-size:\s*normal\s*;\s*/, '')
196
+ html = html.gsub(/\s*font-style:\s*normal\s*;\s*/, '')
197
+ html = html.gsub(/\s*font-variant:\s*normal\s*;\s*/, '')
198
+ html = html.gsub(/\s*line-height:\s*normal\s*;\s*/, '')
199
+ html = html.gsub(/\s*font-weight:\s*normal\s*;\s*/, '')
200
+ end
201
+
202
+ # removes html comments and unnecessary spaces
203
+ def self.html_uglifier(html)
204
+ html = html.gsub(/<!--.*?-->/m, '') # remove html comments
205
+ html = html.gsub(/[\n\r\t]/m, '') # remove new lines, line returns, and tabs
206
+ html = html.gsub(/>\s+?</m, '><') # remove excess whitespace between tags
207
+ html = html.gsub(/\s+?/m, ' ') # remove excess whitespace between elements
208
+ html = html.gsub(/<\s+?/m, '<') # remove excess whitespace after <
209
+ html = html.gsub(/\s+?>/m, '>') # remove excess whitespace before >
210
+ end
211
+ end
212
+
@@ -0,0 +1 @@
1
+ require 'widget_builder'
@@ -0,0 +1,4 @@
1
+ require 'spec_helper'
2
+
3
+ describe WidgetBuilder do
4
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'widget_builder/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "widget_builder"
8
+ spec.version = WidgetBuilder::VERSION
9
+ spec.authors = ["Endri Gjiri"]
10
+ spec.email = ["egjiri@gmail.com"]
11
+ spec.description = %q{A widget builder tool}
12
+ spec.summary = %q{WidgetBuilder}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
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_development_dependency "bundler", "~> 1.3"
22
+ spec.add_development_dependency "rake"
23
+ spec.add_development_dependency "rspec"
24
+ spec.add_dependency "awesome_print"
25
+ spec.add_dependency "sass"
26
+ spec.add_dependency "yui-compressor"
27
+ spec.add_dependency "premailer"
28
+ end
metadata ADDED
@@ -0,0 +1,158 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: widget_builder
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0.alpha
5
+ platform: ruby
6
+ authors:
7
+ - Endri Gjiri
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2013-05-24 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.3'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.3'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
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
+ - !ruby/object:Gem::Dependency
56
+ name: awesome_print
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: sass
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - '>='
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :runtime
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - '>='
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: yui-compressor
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - '>='
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ type: :runtime
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - '>='
95
+ - !ruby/object:Gem::Version
96
+ version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: premailer
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :runtime
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - '>='
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
111
+ description: A widget builder tool
112
+ email:
113
+ - egjiri@gmail.com
114
+ executables: []
115
+ extensions: []
116
+ extra_rdoc_files: []
117
+ files:
118
+ - .gitignore
119
+ - .rspec
120
+ - CHANGELOG.md
121
+ - Gemfile
122
+ - LICENSE.txt
123
+ - README.md
124
+ - Rakefile
125
+ - app/assets/javascripts/widget_loader.js
126
+ - lib/widget_builder.rb
127
+ - lib/widget_builder/constants.rb
128
+ - lib/widget_builder/version.rb
129
+ - spec/spec_helper.rb
130
+ - spec/widget_builder_spec.rb
131
+ - widget_builder.gemspec
132
+ homepage: ''
133
+ licenses:
134
+ - MIT
135
+ metadata: {}
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - '>='
143
+ - !ruby/object:Gem::Version
144
+ version: '0'
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - '>'
148
+ - !ruby/object:Gem::Version
149
+ version: 1.3.1
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.0.3
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: WidgetBuilder
156
+ test_files:
157
+ - spec/spec_helper.rb
158
+ - spec/widget_builder_spec.rb