emcee 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (102) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/Rakefile +32 -0
  4. data/lib/emcee.rb +7 -0
  5. data/lib/emcee/compressors/html_compressor.rb +49 -0
  6. data/lib/emcee/helpers/action_view.rb +34 -0
  7. data/lib/emcee/helpers/sprockets_compressing.rb +32 -0
  8. data/lib/emcee/helpers/sprockets_view.rb +29 -0
  9. data/lib/emcee/processors/html_processor.rb +155 -0
  10. data/lib/emcee/railtie.rb +15 -0
  11. data/lib/emcee/version.rb +3 -0
  12. data/lib/generators/emcee/install/install_generator.rb +23 -0
  13. data/lib/generators/emcee/install/templates/application.html +9 -0
  14. data/lib/tasks/emcee_tasks.rake +4 -0
  15. data/test/compressors_test.rb +41 -0
  16. data/test/controllers_test.rb +16 -0
  17. data/test/dummy/README.rdoc +28 -0
  18. data/test/dummy/Rakefile +6 -0
  19. data/test/dummy/app/assets/elements/application.html +12 -0
  20. data/test/dummy/app/assets/elements/test/test2.html +2 -0
  21. data/test/dummy/app/assets/elements/test/test3.html +1 -0
  22. data/test/dummy/app/assets/elements/test1.html +1 -0
  23. data/test/dummy/app/assets/javascripts/application.js +13 -0
  24. data/test/dummy/app/assets/stylesheets/application.css +13 -0
  25. data/test/dummy/app/controllers/application_controller.rb +5 -0
  26. data/test/dummy/app/controllers/dummy_controller.rb +4 -0
  27. data/test/dummy/app/helpers/application_helper.rb +2 -0
  28. data/test/dummy/app/views/dummy/index.html.erb +1 -0
  29. data/test/dummy/app/views/layouts/application.html.erb +15 -0
  30. data/test/dummy/bin/bundle +3 -0
  31. data/test/dummy/bin/rails +4 -0
  32. data/test/dummy/bin/rake +4 -0
  33. data/test/dummy/config.ru +4 -0
  34. data/test/dummy/config/application.rb +23 -0
  35. data/test/dummy/config/boot.rb +5 -0
  36. data/test/dummy/config/database.yml +25 -0
  37. data/test/dummy/config/environment.rb +5 -0
  38. data/test/dummy/config/environments/development.rb +29 -0
  39. data/test/dummy/config/environments/production.rb +80 -0
  40. data/test/dummy/config/environments/test.rb +36 -0
  41. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  42. data/test/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  43. data/test/dummy/config/initializers/inflections.rb +16 -0
  44. data/test/dummy/config/initializers/mime_types.rb +5 -0
  45. data/test/dummy/config/initializers/secret_token.rb +12 -0
  46. data/test/dummy/config/initializers/session_store.rb +3 -0
  47. data/test/dummy/config/initializers/wrap_parameters.rb +14 -0
  48. data/test/dummy/config/locales/en.yml +23 -0
  49. data/test/dummy/config/routes.rb +3 -0
  50. data/test/dummy/db/development.sqlite3 +0 -0
  51. data/test/dummy/db/test.sqlite3 +0 -0
  52. data/test/dummy/log/development.log +12 -0
  53. data/test/dummy/log/test.log +2433 -0
  54. data/test/dummy/public/404.html +58 -0
  55. data/test/dummy/public/422.html +58 -0
  56. data/test/dummy/public/500.html +57 -0
  57. data/test/dummy/public/favicon.ico +0 -0
  58. data/test/dummy/tmp/cache/assets/development/sprockets/01abb54333b8d67888355b2f855692e8 +0 -0
  59. data/test/dummy/tmp/cache/assets/development/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  60. data/test/dummy/tmp/cache/assets/development/sprockets/1e24025f59396708b3bb44543bed32fc +0 -0
  61. data/test/dummy/tmp/cache/assets/development/sprockets/219d0afb67879a67bae32b4fe4c708ac +0 -0
  62. data/test/dummy/tmp/cache/assets/development/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  63. data/test/dummy/tmp/cache/assets/development/sprockets/32cae461a9446107294c8a0230f5080c +0 -0
  64. data/test/dummy/tmp/cache/assets/development/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  65. data/test/dummy/tmp/cache/assets/development/sprockets/4fd1effec4d6579ba9d4f03ed156a15b +0 -0
  66. data/test/dummy/tmp/cache/assets/development/sprockets/63ab3ecb77a01edbed6db1aca4d690fc +0 -0
  67. data/test/dummy/tmp/cache/assets/development/sprockets/6c9d8a21af4539e19a3462e79ac4d70c +0 -0
  68. data/test/dummy/tmp/cache/assets/development/sprockets/a69c3d00e22ad6c0d6ece35c9fd5f316 +0 -0
  69. data/test/dummy/tmp/cache/assets/development/sprockets/af6ba4ae23c6790e0f474b01ceee8dd9 +0 -0
  70. data/test/dummy/tmp/cache/assets/development/sprockets/c04739a2061e8e023568aabaa0e801d2 +0 -0
  71. data/test/dummy/tmp/cache/assets/development/sprockets/cf517b62bd978b748afe38d5beb317de +0 -0
  72. data/test/dummy/tmp/cache/assets/development/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  73. data/test/dummy/tmp/cache/assets/development/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  74. data/test/dummy/tmp/cache/assets/development/sprockets/df6cfcc50da209231a7d9e140e5bafdc +0 -0
  75. data/test/dummy/tmp/cache/assets/development/sprockets/e0949aa3dcdcab5f8b45d30e26f6ddd2 +0 -0
  76. data/test/dummy/tmp/cache/assets/development/sprockets/e1d520d14db311ab6347be6426dac6f5 +0 -0
  77. data/test/dummy/tmp/cache/assets/development/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  78. data/test/dummy/tmp/cache/assets/development/sprockets/ffd4adb86602a60c7fcedd5d472166d3 +0 -0
  79. data/test/dummy/tmp/cache/assets/test/sprockets/070957bfe375a537750196a12d9e6d1a +0 -0
  80. data/test/dummy/tmp/cache/assets/test/sprockets/13fe41fee1fe35b49d145bcc06610705 +0 -0
  81. data/test/dummy/tmp/cache/assets/test/sprockets/1e24025f59396708b3bb44543bed32fc +0 -0
  82. data/test/dummy/tmp/cache/assets/test/sprockets/219d0afb67879a67bae32b4fe4c708ac +0 -0
  83. data/test/dummy/tmp/cache/assets/test/sprockets/2f5173deea6c795b8fdde723bb4b63af +0 -0
  84. data/test/dummy/tmp/cache/assets/test/sprockets/32cae461a9446107294c8a0230f5080c +0 -0
  85. data/test/dummy/tmp/cache/assets/test/sprockets/357970feca3ac29060c1e3861e2c0953 +0 -0
  86. data/test/dummy/tmp/cache/assets/test/sprockets/4fd1effec4d6579ba9d4f03ed156a15b +0 -0
  87. data/test/dummy/tmp/cache/assets/test/sprockets/6c9d8a21af4539e19a3462e79ac4d70c +0 -0
  88. data/test/dummy/tmp/cache/assets/test/sprockets/a69c3d00e22ad6c0d6ece35c9fd5f316 +0 -0
  89. data/test/dummy/tmp/cache/assets/test/sprockets/af6ba4ae23c6790e0f474b01ceee8dd9 +0 -0
  90. data/test/dummy/tmp/cache/assets/test/sprockets/cf517b62bd978b748afe38d5beb317de +0 -0
  91. data/test/dummy/tmp/cache/assets/test/sprockets/cffd775d018f68ce5dba1ee0d951a994 +0 -0
  92. data/test/dummy/tmp/cache/assets/test/sprockets/d771ace226fc8215a3572e0aa35bb0d6 +0 -0
  93. data/test/dummy/tmp/cache/assets/test/sprockets/df6cfcc50da209231a7d9e140e5bafdc +0 -0
  94. data/test/dummy/tmp/cache/assets/test/sprockets/e0949aa3dcdcab5f8b45d30e26f6ddd2 +0 -0
  95. data/test/dummy/tmp/cache/assets/test/sprockets/f7cbd26ba1d28d48de824f0e94586655 +0 -0
  96. data/test/dummy/tmp/cache/assets/test/sprockets/fb7c86cdcce596d8b3c14ce236bf73c5 +0 -0
  97. data/test/dummy/tmp/cache/assets/test/sprockets/ffd4adb86602a60c7fcedd5d472166d3 +0 -0
  98. data/test/dummy/vendor/assets/elements/test4.html +1 -0
  99. data/test/emcee_test.rb +7 -0
  100. data/test/helpers_test.rb +7 -0
  101. data/test/test_helper.rb +15 -0
  102. metadata +259 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fb57be0dd8aa54269cad7513113aecae19cc050b
4
+ data.tar.gz: 5b088d3adeadf5be4fddbc4896d212be3a14aa05
5
+ SHA512:
6
+ metadata.gz: 9b749f99a257f213979bc70167e002e0d818bea8c8760b396a03cd937f2c08f7eda2a54b2a67f7753954331953b218ac75f7e67f53c8a2a1f3e22eef6fa35eb8
7
+ data.tar.gz: 8400a030e328ecd2ef69a3dfef0cd13a6a983f07f3c2f2866547ee5477c92492838d11eeba4ecfa91245a9eabaa727a3ece76ad0155a10906e48c81a479482b3
@@ -0,0 +1,20 @@
1
+ Copyright 2014 Andrew Huth
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,32 @@
1
+ begin
2
+ require 'bundler/setup'
3
+ rescue LoadError
4
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
5
+ end
6
+
7
+ require 'rdoc/task'
8
+
9
+ RDoc::Task.new(:rdoc) do |rdoc|
10
+ rdoc.rdoc_dir = 'rdoc'
11
+ rdoc.title = 'Emcee'
12
+ rdoc.options << '--line-numbers'
13
+ rdoc.rdoc_files.include('README.rdoc')
14
+ rdoc.rdoc_files.include('lib/**/*.rb')
15
+ end
16
+
17
+
18
+
19
+
20
+ Bundler::GemHelper.install_tasks
21
+
22
+ require 'rake/testtask'
23
+
24
+ Rake::TestTask.new(:test) do |t|
25
+ t.libs << 'lib'
26
+ t.libs << 'test'
27
+ t.pattern = 'test/**/*_test.rb'
28
+ t.verbose = false
29
+ end
30
+
31
+
32
+ task default: :test
@@ -0,0 +1,7 @@
1
+ require "emcee/version"
2
+
3
+ require "emcee/helpers/action_view"
4
+ require "emcee/helpers/sprockets_view"
5
+ require "emcee/helpers/sprockets_compressing"
6
+
7
+ require "emcee/railtie"
@@ -0,0 +1,49 @@
1
+ module Emcee
2
+ module Compressors
3
+ # HtmlCompressor is our basic implementation of an html minifier. For
4
+ # sprockets to use it, it must have a compress method that only accepts a
5
+ # string and returns the compressed output.
6
+ #
7
+ # Our implementation only strips out html and javascript comments, and
8
+ # removes blank lines.
9
+ #
10
+ class HtmlCompressor
11
+ # Match html comments.
12
+ #
13
+ # <!--
14
+ # Comments
15
+ # -->
16
+ #
17
+ HTML_COMMENTS = /\<!\s*--(?:.*?)(?:--\s*\>)/m
18
+
19
+ # Match multi-line javascript/css comments.
20
+ #
21
+ # /*
22
+ # Comments
23
+ # */
24
+ #
25
+ JS_MULTI_COMMENTS = /\/\*(?:.*?)\*\//m
26
+
27
+ # Match single-line javascript comments.
28
+ #
29
+ # // Comments
30
+ #
31
+ # This does not have the /m modifier, because we only want it to match a
32
+ # single line at a time.
33
+ #
34
+ JS_COMMENTS = /\/\/.*$/
35
+
36
+ # Match blank lines.
37
+ BLANK_LINES = /^[\s]*$\n/
38
+
39
+ # Remove comments and blank lines from our html.
40
+ def compress(string)
41
+ ops = [HTML_COMMENTS, JS_MULTI_COMMENTS, JS_COMMENTS, BLANK_LINES]
42
+
43
+ ops.reduce(string) do |output, op|
44
+ output.gsub(op, "")
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,34 @@
1
+ module ActionView
2
+ module Helpers
3
+ module AssetUrlHelper
4
+ ASSET_EXTENSIONS.merge!({ html: '.html' })
5
+ ASSET_PUBLIC_DIRECTORIES.merge!({ html: '/elements' })
6
+
7
+ # Convenience method for html based on javascript_path.
8
+ def html_path(source, options = {})
9
+ path_to_asset(source, { type: :html }.merge!(options))
10
+ end
11
+ alias_method :path_to_html, :html_path
12
+ end
13
+
14
+ module AssetTagHelper
15
+ # Custom view helper used to create an html import. Will search the asset
16
+ # directories for the sources.
17
+ #
18
+ # html_import_tag("navigation")
19
+ #
20
+ def html_import_tag(*sources)
21
+ options = sources.extract_options!.stringify_keys
22
+ path_options = options.extract!('protocol').symbolize_keys
23
+
24
+ sources.uniq.map { |source|
25
+ tag_options = {
26
+ "rel" => "import",
27
+ "href" => path_to_html(source, path_options)
28
+ }.merge!(options)
29
+ tag(:link, tag_options)
30
+ }.join("\n").html_safe
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,32 @@
1
+ module Sprockets
2
+ module Compressing
3
+ def html_compressor
4
+ @html_compressor if defined? @html_compressor
5
+ end
6
+
7
+ # Assign a compressor to run on 'text/html' assets.
8
+ #
9
+ # The compressor object must respond to 'compress'.
10
+ def html_compressor=(compressor)
11
+ unregister_bundle_processor 'text/html', html_compressor if html_compressor
12
+ @html_compressor = nil
13
+ return unless compressor
14
+
15
+ if compressor.is_a?(Symbol)
16
+ compressor = compressors['text/html'][compressor] || raise(Error, "unknown compressor: #{compressor}")
17
+ end
18
+
19
+ if compressor.respond_to?(:compress)
20
+ klass = Class.new(Processor) do
21
+ @name = "html_compressor"
22
+ @processor = proc { |context, data| compressor.compress(data) }
23
+ end
24
+ @html_compressor = :html_compressor
25
+ else
26
+ @html_compressor = klass = compressor
27
+ end
28
+
29
+ register_bundle_processor "text/html", klass
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,29 @@
1
+ module Sprockets
2
+ module Rails
3
+ module Helper
4
+ # Custom view helper used to create an html import. This same method is
5
+ # already defined in ActionView. We pull out the sources here, before
6
+ # calling back to ActionView's.
7
+ #
8
+ # Based on Sprocket's javascript_include_tag.
9
+ def html_import_tag(*sources)
10
+ options = sources.extract_options!.stringify_keys
11
+ if options["debug"] != false && request_debug_assets?
12
+ sources.map { |source|
13
+ #check_errors_for(source)
14
+ if asset = lookup_asset_for_path(source, type: :html)
15
+ asset.to_a.map do |a|
16
+ super(path_to_html(a.logical_path, debug: true), options)
17
+ end
18
+ else
19
+ super(source, options)
20
+ end
21
+ }.flatten.uniq.join("\n").html_safe
22
+ else
23
+ sources.push(options)
24
+ super(*sources)
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,155 @@
1
+ module Emcee
2
+ module Processors
3
+ # HtmlProcessor processes html files by doing 4 things:
4
+ #
5
+ # 1. Stripping out asset pipeline directives and processing the associated
6
+ # files.
7
+ # 2. Stripping out html imports and processing those files.
8
+ # 3. Stripping out external stylesheet includes, and inlining those sheets
9
+ # where they were called.
10
+ # 4. Stripping out external script tags, and inlining those scripts where
11
+ # they were called.
12
+ #
13
+ # It inherits from Sprocket::DirectiveProcessor, which does most of the
14
+ # work for us.
15
+ #
16
+ class HtmlProcessor < Sprockets::DirectiveProcessor
17
+ # Matches the entire header/directive block. This is everything from the
18
+ # top of the file, enclosed in html comments.
19
+ #
20
+ # ---
21
+ #
22
+ # \A matches the beginning of the string
23
+ # (?m:\s*) matches whitespace, including \n
24
+ # (<!--(?m:.*?)-->) matches html comments and their content
25
+ #
26
+ HEADER_PATTERN = /\A((?m:\s*)(<!--(?m:.*?)-->))+/
27
+
28
+ # Matches the an asset pipeline directive.
29
+ #
30
+ # *= require_tree .
31
+ #
32
+ # ---
33
+ #
34
+ # ^ matches the beginning of the line
35
+ # \W* matches any non-word character, zero or more times
36
+ # = matches =, obviously
37
+ # \s* matches any whitespace character, zero or more times
38
+ # (\w+.*?) matches a group of characters, starting with a letter or number
39
+ # $ matches the end of the line
40
+ #
41
+ DIRECTIVE_PATTERN = /^\W*=\s*(\w+.*?)$/
42
+
43
+ # Match an html import tag.
44
+ #
45
+ # <link rel="import" href="example.html">
46
+ #
47
+ IMPORT_PATTERN = /^<link .*rel=["']import["'].*>$/
48
+
49
+ # Match a stylesheet link tag.
50
+ #
51
+ # <link rel="stylesheet" href="example.css">
52
+ #
53
+ STYLESHEET_PATTERN = /^ +<link .*rel=["']stylesheet["'].*>$/
54
+
55
+ # Match a script tag.
56
+ #
57
+ # <script src="assets/example.js"></script>
58
+ #
59
+ SCRIPT_PATTERN = /^ *<script .*src=["'].+\.js["']><\/script>$/
60
+
61
+ # Match the path from the href attribute of an html import or stylesheet
62
+ # include tag. Captures the actual path.
63
+ #
64
+ # href="/assets/example.css"
65
+ #
66
+ HREF_PATH_PATTERN = /href=["'](?<path>[\w\.\/-]+)["']/
67
+
68
+ # Match the source path from a script tag. Captures the actual path.
69
+ #
70
+ # src="/assets/example.js"
71
+ #
72
+ SRC_PATH_PATTERN = /src=["'](?<path>[\w\.\/-]+)["']/
73
+
74
+ # Render takes the actual text of the file and does our processing to it.
75
+ # This is based on the standard render method on Sprockets's
76
+ # DirectiveProcessor.
77
+ #
78
+ def render(context, locals)
79
+ @context = context
80
+ @pathname = context.pathname
81
+ @directory = File.dirname(@pathname)
82
+
83
+ @header = data[HEADER_PATTERN, 0] || ""
84
+ @body = $' || data
85
+ # Ensure body ends in a new line
86
+ @body += "\n" if @body != "" && @body !~ /\n\Z/m
87
+
88
+ @included_pathnames = []
89
+
90
+ @result = ""
91
+ @result.force_encoding(body.encoding)
92
+
93
+ @has_written_body = false
94
+
95
+ process_directives
96
+ process_imports
97
+ process_stylesheets
98
+ process_scripts
99
+ process_source
100
+
101
+ @result
102
+ end
103
+
104
+ protected
105
+ # Scan the body for html imports. If any are found, tell sprockets to
106
+ # require their files like we would for a directive.
107
+ def process_imports
108
+ body.scan(IMPORT_PATTERN) do |import_tag|
109
+ if path = import_tag[HREF_PATH_PATTERN, :path]
110
+ absolute_path = File.absolute_path(path, @directory)
111
+ context.require_asset(absolute_path)
112
+ end
113
+ end
114
+
115
+ @body.gsub!(IMPORT_PATTERN, "")
116
+ end
117
+
118
+ # Scan the body for external stylesheet references. If any are found,
119
+ # inline the files in place of the references.
120
+ def process_stylesheets
121
+ to_inline = []
122
+
123
+ body.scan(STYLESHEET_PATTERN) do |stylesheet_tag|
124
+ if path = stylesheet_tag[HREF_PATH_PATTERN, :path]
125
+ absolute_path = File.absolute_path(path, @directory)
126
+ stylesheet_contents = File.read(absolute_path)
127
+ to_inline << [stylesheet_tag, "<style>\n" + stylesheet_contents + "</style>\n"]
128
+ end
129
+ end
130
+
131
+ to_inline.each do |(tag, contents)|
132
+ @body.gsub!(tag, contents)
133
+ end
134
+ end
135
+
136
+ # Scan the body for external script references. If any are found, inline
137
+ # the files in place of the references.
138
+ def process_scripts
139
+ to_inline = []
140
+
141
+ body.scan(SCRIPT_PATTERN) do |script_tag|
142
+ if path = script_tag[SRC_PATH_PATTERN, :path]
143
+ absolute_path = File.absolute_path(path, @directory)
144
+ script_contents = File.read(absolute_path)
145
+ to_inline << [script_tag, "<script>\n" + script_contents + "</script>\n"]
146
+ end
147
+ end
148
+
149
+ to_inline.each do |(tag, contents)|
150
+ @body.gsub!(tag, contents)
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
@@ -0,0 +1,15 @@
1
+ require "emcee/processors/html_processor"
2
+ require "emcee/compressors/html_compressor"
3
+
4
+ module Emcee
5
+ class Railtie < Rails::Railtie
6
+ initializer :add_html_processor do |app|
7
+ app.assets.register_mime_type "text/html", ".html"
8
+ app.assets.register_preprocessor "text/html", Processors::HtmlProcessor
9
+ end
10
+
11
+ initializer :add_html_compressor do |app|
12
+ app.assets.html_compressor = Compressors::HtmlCompressor.new
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,3 @@
1
+ module Emcee
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ module Emcee
2
+ module Generators
3
+ class InstallGenerator < Rails::Generators::Base
4
+ source_root File.expand_path("../templates", __FILE__)
5
+
6
+ desc "Adds an html import tag into your layout, adds a manifest to assets/elements/application.html, and adds a vendor/assets/elements directory"
7
+
8
+ def copy_application_manifest
9
+ empty_directory "app/assets/elements"
10
+ copy_file "application.html", "app/assets/elements/application.html"
11
+ end
12
+
13
+ def create_vendor_directory
14
+ empty_directory "vendor/assets/elements"
15
+ create_file "vendor/assets/elements/.keep"
16
+ end
17
+
18
+ def add_html_import_to_layout
19
+ insert_into_file "app/views/layouts/application.html.erb", "<%= html_import_tag \"application\" %>\n\t\t", before: "<%= csrf_meta_tags %>"
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ <!--
2
+ * This is a manifest file that'll be compiled into application.html, which will include all the files
3
+ * listed below and their dependencies.
4
+ *
5
+ * Any html files within this directory, lib/assets/elements, or vendor/assets/elements
6
+ * can be referenced here using a relative path.
7
+ *
8
+ *= require_tree .
9
+ -->
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :emcee do
3
+ # # Task goes here
4
+ # end
@@ -0,0 +1,41 @@
1
+ require 'test_Helper'
2
+
3
+ class CompressorsTest < ActiveSupport::TestCase
4
+ setup do
5
+ @compressor = Emcee::Compressors::HtmlCompressor.new
6
+ end
7
+
8
+ test "compressor should remove html comments" do
9
+ content = "<!--\nHere\nAre\nSome Comments\n-->\n<span>test</span>\n"
10
+ assert_equal "<span>test</span>\n", @compressor.compress(content)
11
+ end
12
+
13
+ test "compressor should remove multi-line javascript comments" do
14
+ content = "<script>\n/*\nHere\nAre\nA Bunch\nOf Comments\n*/\n</script>\n"
15
+ assert_equal "<script>\n</script>\n", @compressor.compress(content)
16
+ end
17
+
18
+ test "compressor should remove single-line javascript comments" do
19
+ content = "<script>\n// Here\n// Are Yet\n// Some More\n// Of The\n// Comments\n</script>\n"
20
+ assert_equal "<script>\n</script>\n", @compressor.compress(content)
21
+ end
22
+
23
+ test "compressor should remove css comments" do
24
+ content = %q{
25
+ <style>
26
+ h1 {
27
+ /*
28
+ Make it pink
29
+ */
30
+ color: pink;
31
+ }
32
+ </style>
33
+ }
34
+ assert_equal "<style>\n h1 {\n color: pink;\n }\n</style>\n", @compressor.compress(content)
35
+ end
36
+
37
+ test "compressor should remove blank lines" do
38
+ content = "<p>test</p>\n\n\n\n\n\n<p>oh yeah</p>"
39
+ assert_equal "<p>test</p>\n<p>oh yeah</p>", @compressor.compress(content)
40
+ end
41
+ end