darkroom 0.0.2 → 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.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +141 -21
- data/VERSION +1 -1
- data/lib/darkroom/asset.rb +239 -97
- data/lib/darkroom/darkroom.rb +54 -13
- data/lib/darkroom/delegates/css.rb +39 -0
- data/lib/darkroom/delegates/html.rb +53 -0
- data/lib/darkroom/delegates/htx.rb +21 -0
- data/lib/darkroom/delegates/javascript.rb +16 -0
- data/lib/darkroom/errors/asset_error.rb +33 -0
- data/lib/darkroom/errors/asset_not_found_error.rb +10 -21
- data/lib/darkroom/errors/circular_reference_error.rb +21 -0
- data/lib/darkroom/errors/duplicate_asset_error.rb +4 -4
- data/lib/darkroom/errors/invalid_path_error.rb +28 -0
- data/lib/darkroom/errors/missing_library_error.rb +3 -3
- data/lib/darkroom/errors/unrecognized_extension_error.rb +21 -0
- data/lib/darkroom/version.rb +1 -1
- data/lib/darkroom.rb +21 -28
- metadata +15 -6
- data/lib/darkroom/errors/spec_not_defined_error.rb +0 -28
@@ -0,0 +1,53 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('../asset')
|
4
|
+
|
5
|
+
class Darkroom
|
6
|
+
class Asset
|
7
|
+
HTMLDelegate = Delegate.new(
|
8
|
+
content_type: 'text/html',
|
9
|
+
reference_regex: %r{
|
10
|
+
<(?<tag>a|area|audio|base|embed|iframe|img|input|link|script|source|track|video)\s+[^>]*
|
11
|
+
(?<attr>href|src)=#{REFERENCE_PATH.source}[^>]*>
|
12
|
+
}x.freeze,
|
13
|
+
|
14
|
+
validate_reference: ->(asset, match, format) do
|
15
|
+
return unless format == 'displace'
|
16
|
+
|
17
|
+
if match[:tag] == 'link'
|
18
|
+
'Asset type must be text/css' unless asset.content_type == 'text/css'
|
19
|
+
elsif match[:tag] == 'script'
|
20
|
+
'Asset type must be text/javascript' unless asset.content_type == 'text/javascript'
|
21
|
+
elsif match[:tag] == 'img'
|
22
|
+
'Asset type must be image/svg+xml' unless asset.content_type == 'image/svg+xml'
|
23
|
+
else
|
24
|
+
"Cannot displace <#{match[:tag]}> tags"
|
25
|
+
end
|
26
|
+
end,
|
27
|
+
|
28
|
+
reference_content: ->(asset, match, format) do
|
29
|
+
case format
|
30
|
+
when 'displace'
|
31
|
+
if match[:tag] == 'link' && asset.content_type == 'text/css'
|
32
|
+
"<style>#{asset.content}</style>"
|
33
|
+
elsif match[:tag] == 'script' && asset.content_type == 'text/javascript'
|
34
|
+
offset = match.begin(0)
|
35
|
+
|
36
|
+
"#{match[0][0..(match.begin(:attr) - 2 - offset)]}"\
|
37
|
+
"#{match[0][(match.end(:quoted) + match[:quote].size - offset)..(match.end(0) - offset)]}"\
|
38
|
+
"#{asset.content}"
|
39
|
+
elsif match[:tag] == 'img' && asset.content_type == 'image/svg+xml'
|
40
|
+
asset.content
|
41
|
+
end
|
42
|
+
when 'utf8'
|
43
|
+
quote = match[:quote] == '' ? Asset::DEFAULT_QUOTE : match[:quote]
|
44
|
+
|
45
|
+
content = asset.content.gsub('#', '%23')
|
46
|
+
content.gsub!(quote, quote == "'" ? '"' : "'")
|
47
|
+
|
48
|
+
content
|
49
|
+
end
|
50
|
+
end,
|
51
|
+
)
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('../asset')
|
4
|
+
require_relative('html')
|
5
|
+
require_relative('javascript')
|
6
|
+
|
7
|
+
class Darkroom
|
8
|
+
class Asset
|
9
|
+
HTXDelegate = Delegate.new(
|
10
|
+
content_type: JavaScriptDelegate.content_type,
|
11
|
+
import_regex: HTMLDelegate.import_regex,
|
12
|
+
reference_regex: HTMLDelegate.reference_regex,
|
13
|
+
validate_reference: HTMLDelegate.validate_reference,
|
14
|
+
reference_content: HTMLDelegate.reference_content,
|
15
|
+
compile_lib: 'htx',
|
16
|
+
compile: ->(path, content) { HTX.compile(path, content) },
|
17
|
+
minify_lib: JavaScriptDelegate.minify_lib,
|
18
|
+
minify: JavaScriptDelegate.minify,
|
19
|
+
)
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('../asset')
|
4
|
+
|
5
|
+
class Darkroom
|
6
|
+
class Asset
|
7
|
+
JavaScriptDelegate = Delegate.new(
|
8
|
+
content_type: 'text/javascript',
|
9
|
+
import_regex: /^ *import +#{QUOTED_PATH.source} *;? *(\n|$)/.freeze,
|
10
|
+
minify_lib: 'uglifier',
|
11
|
+
minify: ->(content) do
|
12
|
+
Uglifier.compile(content, harmony: true)
|
13
|
+
end,
|
14
|
+
)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Darkroom
|
4
|
+
##
|
5
|
+
# General error class used for errors encountered while processing an asset.
|
6
|
+
#
|
7
|
+
class AssetError < StandardError
|
8
|
+
attr_reader(:detail, :source_path, :source_line_num)
|
9
|
+
|
10
|
+
##
|
11
|
+
# Creates a new instance.
|
12
|
+
#
|
13
|
+
# * +message+ - Description of the error.
|
14
|
+
# * +detail+ - Additional detail about the error.
|
15
|
+
# * +source_path+ - Path of the asset that contains the error (optional).
|
16
|
+
# * +source_line_num+ - Line number in the asset where the error is located (optional).
|
17
|
+
#
|
18
|
+
def initialize(message, detail, source_path = nil, source_line_num = nil)
|
19
|
+
super(message)
|
20
|
+
|
21
|
+
@detail = detail
|
22
|
+
@source_path = source_path
|
23
|
+
@source_line_num = source_line_num
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Returns a string representation of the error.
|
28
|
+
#
|
29
|
+
def to_s
|
30
|
+
"#{"#{@source_path}:#{@source_line_num || '?'}: " if @source_path}#{super}: #{@detail}"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -1,33 +1,22 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require_relative('asset_error')
|
4
|
+
|
3
5
|
class Darkroom
|
4
6
|
##
|
5
|
-
# Error class used when an asset requested explicitly or specified as a dependency of another
|
6
|
-
#
|
7
|
+
# Error class used when an asset requested explicitly or specified as a dependency of another doesn't
|
8
|
+
# exist.
|
7
9
|
#
|
8
|
-
class AssetNotFoundError <
|
9
|
-
attr_reader(:path, :referenced_from, :referenced_from_line)
|
10
|
-
|
10
|
+
class AssetNotFoundError < AssetError
|
11
11
|
##
|
12
12
|
# Creates a new instance.
|
13
13
|
#
|
14
|
-
# * +path+ -
|
15
|
-
# * +
|
16
|
-
# * +
|
17
|
-
#
|
18
|
-
def initialize(path, referenced_from = nil, referenced_from_line = nil)
|
19
|
-
@path = path
|
20
|
-
@referenced_from = referenced_from
|
21
|
-
@referenced_from_line = referenced_from_line
|
22
|
-
end
|
23
|
-
|
24
|
-
##
|
25
|
-
# Returns a string representation of the error.
|
14
|
+
# * +path+ - Path of asset that doesn't exist.
|
15
|
+
# * +source_path+ - Path of the asset that contains the error (optional).
|
16
|
+
# * +source_line_num+ - Line number in the asset where the error is located (optional).
|
26
17
|
#
|
27
|
-
def
|
28
|
-
|
29
|
-
" (referenced from #{@referenced_from}:#{@referenced_from_line || '?'})" if @referenced_from
|
30
|
-
}: #{@path}"
|
18
|
+
def initialize(path, source_path = nil, source_line_num = nil)
|
19
|
+
super('Asset not found', path, source_path, source_line_num)
|
31
20
|
end
|
32
21
|
end
|
33
22
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('asset_error')
|
4
|
+
|
5
|
+
class Darkroom
|
6
|
+
##
|
7
|
+
# Error class used when an asset reference results in a circular reference chain.
|
8
|
+
#
|
9
|
+
class CircularReferenceError < AssetError
|
10
|
+
##
|
11
|
+
# Creates a new instance.
|
12
|
+
#
|
13
|
+
# * +snippet+ - Snippet showing the reference.
|
14
|
+
# * +source_path+ - Path of the asset that contains the error.
|
15
|
+
# * +source_line_num+ - Line number in the asset where the error is located.
|
16
|
+
#
|
17
|
+
def initialize(snippet, source_path, source_line_num)
|
18
|
+
super('Reference would result in a circular reference chain', snippet, source_path, source_line_num)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
class Darkroom
|
4
4
|
##
|
5
|
-
# Error class used when an asset exists
|
5
|
+
# Error class used when an asset exists under multiple load paths.
|
6
6
|
#
|
7
7
|
class DuplicateAssetError < StandardError
|
8
8
|
attr_reader(:path, :first_load_path, :second_load_path)
|
@@ -10,9 +10,9 @@ class Darkroom
|
|
10
10
|
##
|
11
11
|
# Creates a new instance.
|
12
12
|
#
|
13
|
-
# * +path+ -
|
14
|
-
# * +first_load_path+ -
|
15
|
-
# * +second_load_path+ -
|
13
|
+
# * +path+ - Path of the asset that exists under multiple load paths.
|
14
|
+
# * +first_load_path+ - Load path where the asset was first found.
|
15
|
+
# * +second_load_path+ - Load path where the asset was subsequently found.
|
16
16
|
#
|
17
17
|
def initialize(path, first_load_path, second_load_path)
|
18
18
|
@path = path
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class Darkroom
|
4
|
+
##
|
5
|
+
# Error class used when an asset's path contains one or more invalid characters.
|
6
|
+
#
|
7
|
+
class InvalidPathError < StandardError
|
8
|
+
attr_reader(:path, :index)
|
9
|
+
|
10
|
+
##
|
11
|
+
# Creates a new instance.
|
12
|
+
#
|
13
|
+
# * +path+ - Path of the asset with the invalid character(s).
|
14
|
+
# * +index+ - Position of the first bad character in the path.
|
15
|
+
#
|
16
|
+
def initialize(path, index)
|
17
|
+
@path = path
|
18
|
+
@index = index
|
19
|
+
end
|
20
|
+
|
21
|
+
##
|
22
|
+
# Returns a string representation of the error.
|
23
|
+
#
|
24
|
+
def to_s
|
25
|
+
"Asset path contains one or more invalid characters (#{DISALLOWED_PATH_CHARS}): #{@path}"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -10,9 +10,9 @@ class Darkroom
|
|
10
10
|
##
|
11
11
|
# Creates a new instance.
|
12
12
|
#
|
13
|
-
# * +library+ -
|
14
|
-
# * +need+ -
|
15
|
-
# * +extension+ -
|
13
|
+
# * +library+ - Name of the library that's missing.
|
14
|
+
# * +need+ - Reason the library is needed ('compile' or 'minify').
|
15
|
+
# * +extension+ - Extension of the type of asset that needs the library.
|
16
16
|
#
|
17
17
|
def initialize(library, need, extension)
|
18
18
|
@library = library
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative('asset_error')
|
4
|
+
|
5
|
+
class Darkroom
|
6
|
+
##
|
7
|
+
# Error class used when a reference is made to a file with an unrecognized extension.
|
8
|
+
#
|
9
|
+
class UnrecognizedExtensionError < AssetError
|
10
|
+
##
|
11
|
+
# Creates a new instance.
|
12
|
+
#
|
13
|
+
# * +file+ - File with the unrecognized extension.
|
14
|
+
# * +source_path+ - Path of the asset that contains the error (optional).
|
15
|
+
# * +source_line_num+ - Line number in the asset where the error is located (optional).
|
16
|
+
#
|
17
|
+
def initialize(file, source_path = nil, source_line_num = nil)
|
18
|
+
super('File extension not recognized', file, source_path, source_line_num)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/darkroom/version.rb
CHANGED
data/lib/darkroom.rb
CHANGED
@@ -4,36 +4,29 @@ require('darkroom/asset')
|
|
4
4
|
require('darkroom/darkroom')
|
5
5
|
require('darkroom/version')
|
6
6
|
|
7
|
+
require('darkroom/delegates/css')
|
8
|
+
require('darkroom/delegates/html')
|
9
|
+
require('darkroom/delegates/htx')
|
10
|
+
require('darkroom/delegates/javascript')
|
11
|
+
|
12
|
+
require('darkroom/errors/asset_error')
|
7
13
|
require('darkroom/errors/asset_not_found_error')
|
14
|
+
require('darkroom/errors/circular_reference_error')
|
8
15
|
require('darkroom/errors/duplicate_asset_error')
|
16
|
+
require('darkroom/errors/invalid_path_error')
|
9
17
|
require('darkroom/errors/missing_library_error')
|
10
18
|
require('darkroom/errors/processing_error')
|
11
|
-
require('darkroom/errors/
|
12
|
-
|
13
|
-
Darkroom::Asset.add_spec('.css', 'text/css',
|
14
|
-
dependency_regex: /^ *@import +(?<quote>['"]) *(?<path>.*) *\g<quote> *; *$/,
|
15
|
-
minify: -> (content) { CSSminify.compress(content) },
|
16
|
-
minify_lib: 'cssminify',
|
17
|
-
)
|
18
|
-
|
19
|
-
Darkroom::Asset.add_spec('.js', 'application/javascript',
|
20
|
-
dependency_regex: /^ *import +(?<quote>['"])(?<path>.*)\g<quote> *;? *$/,
|
21
|
-
minify: -> (content) { Uglifier.compile(content, harmony: true) },
|
22
|
-
minify_lib: 'uglifier',
|
23
|
-
)
|
24
|
-
|
25
|
-
Darkroom::Asset.add_spec('.htx', 'application/javascript',
|
26
|
-
compile: -> (path, content) { HTX.compile(path, content) },
|
27
|
-
compile_lib: 'htx',
|
28
|
-
minify: Darkroom::Asset.spec('.js').minify,
|
29
|
-
minify_lib: Darkroom::Asset.spec('.js').minify_lib,
|
30
|
-
)
|
19
|
+
require('darkroom/errors/unrecognized_extension_error')
|
31
20
|
|
32
|
-
Darkroom
|
33
|
-
Darkroom
|
34
|
-
Darkroom
|
35
|
-
Darkroom
|
36
|
-
Darkroom
|
37
|
-
Darkroom
|
38
|
-
Darkroom
|
39
|
-
Darkroom
|
21
|
+
Darkroom.register('.css', Darkroom::Asset::CSSDelegate)
|
22
|
+
Darkroom.register('.htm', '.html', Darkroom::Asset::HTMLDelegate)
|
23
|
+
Darkroom.register('.htx', Darkroom::Asset::HTXDelegate)
|
24
|
+
Darkroom.register('.ico', 'image/x-icon')
|
25
|
+
Darkroom.register('.jpg', '.jpeg', 'image/jpeg')
|
26
|
+
Darkroom.register('.js', Darkroom::Asset::JavaScriptDelegate)
|
27
|
+
Darkroom.register('.json', 'application/json')
|
28
|
+
Darkroom.register('.png', 'image/png')
|
29
|
+
Darkroom.register('.svg', 'image/svg+xml')
|
30
|
+
Darkroom.register('.txt', 'text/plain')
|
31
|
+
Darkroom.register('.woff', 'font/woff')
|
32
|
+
Darkroom.register('.woff2', 'font/woff2')
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: darkroom
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Pickens
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-03-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -44,8 +44,10 @@ dependencies:
|
|
44
44
|
- - "<"
|
45
45
|
- !ruby/object:Gem::Version
|
46
46
|
version: 6.0.0
|
47
|
-
description: Darkroom provides
|
48
|
-
|
47
|
+
description: Darkroom provides web asset compilation, bundling, and minification without
|
48
|
+
any external tools, manifest files, or special comment syntax. CSS and JavaScript
|
49
|
+
bundles are automatically generated based on import statements native to each language.
|
50
|
+
Darkroom is also extensible, allowing support to be added for arbitrary file types.
|
49
51
|
email:
|
50
52
|
executables: []
|
51
53
|
extensions: []
|
@@ -57,11 +59,18 @@ files:
|
|
57
59
|
- lib/darkroom.rb
|
58
60
|
- lib/darkroom/asset.rb
|
59
61
|
- lib/darkroom/darkroom.rb
|
62
|
+
- lib/darkroom/delegates/css.rb
|
63
|
+
- lib/darkroom/delegates/html.rb
|
64
|
+
- lib/darkroom/delegates/htx.rb
|
65
|
+
- lib/darkroom/delegates/javascript.rb
|
66
|
+
- lib/darkroom/errors/asset_error.rb
|
60
67
|
- lib/darkroom/errors/asset_not_found_error.rb
|
68
|
+
- lib/darkroom/errors/circular_reference_error.rb
|
61
69
|
- lib/darkroom/errors/duplicate_asset_error.rb
|
70
|
+
- lib/darkroom/errors/invalid_path_error.rb
|
62
71
|
- lib/darkroom/errors/missing_library_error.rb
|
63
72
|
- lib/darkroom/errors/processing_error.rb
|
64
|
-
- lib/darkroom/errors/
|
73
|
+
- lib/darkroom/errors/unrecognized_extension_error.rb
|
65
74
|
- lib/darkroom/version.rb
|
66
75
|
homepage: https://github.com/npickens/darkroom
|
67
76
|
licenses:
|
@@ -85,7 +94,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
94
|
- !ruby/object:Gem::Version
|
86
95
|
version: '0'
|
87
96
|
requirements: []
|
88
|
-
rubygems_version: 3.2.
|
97
|
+
rubygems_version: 3.2.32
|
89
98
|
signing_key:
|
90
99
|
specification_version: 4
|
91
100
|
summary: A fast, lightweight, and straightforward web asset management library.
|
@@ -1,28 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
class Darkroom
|
4
|
-
##
|
5
|
-
# Error class used when a spec is not defined for a particular file extension.
|
6
|
-
#
|
7
|
-
class SpecNotDefinedError < StandardError
|
8
|
-
attr_reader(:extension, :file)
|
9
|
-
|
10
|
-
##
|
11
|
-
# Creates a new instance.
|
12
|
-
#
|
13
|
-
# * +extension+ - Extension for which there is no spec defined.
|
14
|
-
# * +file+ - File path of the asset whose loading was attempted.
|
15
|
-
#
|
16
|
-
def initialize(extension, file = nil)
|
17
|
-
@extension = extension
|
18
|
-
@file = file
|
19
|
-
end
|
20
|
-
|
21
|
-
##
|
22
|
-
# Returns a string representation of the error.
|
23
|
-
#
|
24
|
-
def to_s
|
25
|
-
"Spec not defined for #{@extension} files#{" (#{@file})" if @file}"
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|