linner 0.5.1 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG +3 -0
- data/README.md +2 -1
- data/docs/config.md +18 -0
- data/lib/linner.rb +31 -0
- data/lib/linner/environment.rb +4 -0
- data/lib/linner/sprite.rb +124 -0
- data/lib/linner/templates/app/images/logo.png +0 -0
- data/lib/linner/templates/app/styles/app.scss +1 -0
- data/lib/linner/templates/app/views/index.html +1 -1
- data/lib/linner/templates/config.yml +28 -16
- data/lib/linner/version.rb +1 -1
- data/spec/linner/sprites_spec.rb +23 -0
- metadata +8 -5
- data/lib/linner/templates/app/styles/app.sass +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f40ea1d47371f91db7d8a653f4b8e30b7e2748d4
|
4
|
+
data.tar.gz: 422e0dbbc14c7420296ae953b08a89ac2d1a88c4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c9cbf841d6560337ced7e9fcd4577464e49e5aaa77ad1ba06c8911bbfabcb9afd05dcda48d372a5047dddeeb46a04289d577739a5924f2e9712624775bfc3041
|
7
|
+
data.tar.gz: b3f075eb30fb16b459d0ad0ec702cf7a2d8fbbfcc8f3e71a04faa3e23b1534a229660a2558bfe1e43ab0d5e13da71f2112916827f81d5a03487008645c3ac0db
|
data/CHANGELOG
CHANGED
data/README.md
CHANGED
@@ -16,7 +16,8 @@ Linner is a full-featured HTML5 application assembler.
|
|
16
16
|
* Supports Modular Javascript, All your code will be wrapped by `cmd`.
|
17
17
|
* Supports `concat` code by `config file` not `directive processor`.
|
18
18
|
* Supports `copy` code from `src` to `dest`.
|
19
|
-
* Supports `precompile` Javascript Templates from `src` to `desc
|
19
|
+
* Supports `precompile` Javascript Templates from `src` to `desc`.
|
20
|
+
* Supports `sprite` PNG images from `src` to `desc`.
|
20
21
|
* Supports Real-time `concat` by `$ linner watch`.
|
21
22
|
* Supports `compress` by `$ linner build`.
|
22
23
|
* Supports `LiveReload` with [LiveReload Chrome Extention](https://chrome.google.com/webstore/detail/livereload/jnihajbhpnppcggbcgedagnkighmdlei).
|
data/docs/config.md
CHANGED
@@ -53,6 +53,8 @@ the default configuration defines four groups: `scripts`, `styles`, `images` and
|
|
53
53
|
|
54
54
|
`precompile` defines precompile strategy of javascript templates for Linner. The `Dir.glob` of `value` will be concat to `key`
|
55
55
|
|
56
|
+
`sprite` defines sprite strategy of images for Linner. The `Dir.glob` of `value` will be sprite to `key`
|
57
|
+
|
56
58
|
`order` defines the order of this group files, and It's very useful when you `concat` your files. for example:
|
57
59
|
|
58
60
|
```yaml
|
@@ -64,6 +66,22 @@ order:
|
|
64
66
|
|
65
67
|
In the above example, if a group contains 5 files, `vendor/jquery-1.10.2.js` will be the first, and `vendor/underscore.js` will be the last file.
|
66
68
|
|
69
|
+
## `sprites`
|
70
|
+
|
71
|
+
`sprites` defines application sprite stategy. `sprites` support pseudo class of css, if your file's basename end with `_active`, the generated css will be `.active`. if your file's basename end with `_hover`, the generated css will be `:hover`, eg: `arrow_hover.png` will be `.selector-arrow:hover { ... }`
|
72
|
+
|
73
|
+
Example:
|
74
|
+
|
75
|
+
```yaml
|
76
|
+
sprites:
|
77
|
+
# sprite image output path
|
78
|
+
path: "/images/"
|
79
|
+
# css selector
|
80
|
+
selector: ".icon-"
|
81
|
+
# css url background: url(/images/icon.png)
|
82
|
+
url: "http://s3.amazonaws.com/"
|
83
|
+
```
|
84
|
+
|
67
85
|
## `modules`
|
68
86
|
|
69
87
|
`modules` defines application module strategy, The default wrapper is `cmd`.
|
data/lib/linner.rb
CHANGED
@@ -5,6 +5,7 @@ require "linner/command"
|
|
5
5
|
require "linner/asset"
|
6
6
|
require "linner/cache"
|
7
7
|
require "linner/helper"
|
8
|
+
require "linner/sprite"
|
8
9
|
require "linner/bundler"
|
9
10
|
require "linner/reactor"
|
10
11
|
require "linner/wrapper"
|
@@ -68,6 +69,7 @@ module Linner
|
|
68
69
|
def perform(*asset)
|
69
70
|
env.groups.each do |config|
|
70
71
|
precompile(config) if config["precompile"]
|
72
|
+
sprite(config) if config["sprite"]
|
71
73
|
end
|
72
74
|
env.groups.each do |config|
|
73
75
|
copy(config) if config["copy"]
|
@@ -106,6 +108,14 @@ module Linner
|
|
106
108
|
end
|
107
109
|
end
|
108
110
|
|
111
|
+
def sprite(config)
|
112
|
+
config["sprite"].each do |dest, pattern|
|
113
|
+
matches = Dir.glob(pattern).sort_by(&:downcase)
|
114
|
+
next if matches.select { |p| cache.miss? p }.empty?
|
115
|
+
paint_sprite(dest, matches)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
109
119
|
def revision
|
110
120
|
dump_manifest
|
111
121
|
[env.revision].flatten.each do |rev|
|
@@ -115,6 +125,27 @@ module Linner
|
|
115
125
|
end
|
116
126
|
end
|
117
127
|
|
128
|
+
def paint_sprite(dest, images)
|
129
|
+
images = images.map do |path|
|
130
|
+
ImageProxy.new(path, ChunkyPNG::Image.from_file(path))
|
131
|
+
end
|
132
|
+
sprite = Sprite.new(images).pack!
|
133
|
+
map = ChunkyPNG::Image.new(sprite.root[:w], sprite.root[:h], ChunkyPNG::Color::TRANSPARENT)
|
134
|
+
|
135
|
+
sprite.images.each do |image|
|
136
|
+
map.compose!(image.image, image.left, image.top)
|
137
|
+
end
|
138
|
+
|
139
|
+
name = File.basename(dest).sub(/[^.]+\z/, "png")
|
140
|
+
path = File.join(env.public_folder, env.sprites["path"], File.basename(dest).sub(/[^.]+\z/, "png"))
|
141
|
+
FileUtils.mkdir_p File.dirname(path)
|
142
|
+
map.save path
|
143
|
+
|
144
|
+
asset = Asset.new(File.join env.public_folder, dest)
|
145
|
+
asset.content = sprite.generate_style(env.sprites, name)
|
146
|
+
asset.write
|
147
|
+
end
|
148
|
+
|
118
149
|
def write_template(dest, child_assets)
|
119
150
|
asset = Asset.new(File.join env.public_folder, dest)
|
120
151
|
content = child_assets.inject("") {|s, m| s << cache[m].content}
|
data/lib/linner/environment.rb
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
module Linner
|
2
|
+
ImageProxy = Struct.new(:path, :image, :top, :left) do
|
3
|
+
def width
|
4
|
+
image.width
|
5
|
+
end
|
6
|
+
|
7
|
+
def height
|
8
|
+
image.height
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
class Sprite
|
13
|
+
|
14
|
+
attr_accessor :root, :images
|
15
|
+
|
16
|
+
def initialize(images)
|
17
|
+
@images = images.sort do |a, b|
|
18
|
+
diff = [b.width, b.height].max <=> [a.width, a.height].max
|
19
|
+
diff = [b.width, b.height].min <=> [a.width, a.height].min if diff.zero?
|
20
|
+
diff = b.height <=> a.height if diff.zero?
|
21
|
+
diff = b.width <=> a.width if diff.zero?
|
22
|
+
diff
|
23
|
+
end
|
24
|
+
|
25
|
+
@root = { :x => 0, :y => 0, :w => @images.first.width, :h => @images.first.height}
|
26
|
+
end
|
27
|
+
|
28
|
+
def pack!
|
29
|
+
@images.each do |image|
|
30
|
+
if block = find_block(@root, image)
|
31
|
+
place_image(block, image)
|
32
|
+
split_block(block, image)
|
33
|
+
else
|
34
|
+
@root = expand_root(@root, image)
|
35
|
+
redo
|
36
|
+
end
|
37
|
+
end
|
38
|
+
self
|
39
|
+
end
|
40
|
+
|
41
|
+
def generate_style(config, name)
|
42
|
+
selector = config["selector"] || ".icon-"
|
43
|
+
@images.inject("") do |style, image|
|
44
|
+
logical_path = Asset.new(image.path).logical_path
|
45
|
+
selector_with_pseudo_class = logical_path.chomp(File.extname(logical_path))
|
46
|
+
.gsub("/", "-")
|
47
|
+
.gsub("_active", ".active")
|
48
|
+
.gsub("_hover", ":hover")
|
49
|
+
.gsub("_", "-")
|
50
|
+
style <<
|
51
|
+
"#{selector}#{selector_with_pseudo_class} {
|
52
|
+
width: #{image.width}px;
|
53
|
+
height: #{image.height}px;
|
54
|
+
background: url(#{File.join config['url'], name}) -#{image.left}px -#{image.top}px no-repeat;
|
55
|
+
}
|
56
|
+
"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
def find_block(root, image)
|
62
|
+
if root[:used]
|
63
|
+
find_block(root[:right], image) || find_block(root[:down], image)
|
64
|
+
elsif (image.width <= root[:w]) && (image.height <= root[:h])
|
65
|
+
root
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def place_image(block, image)
|
70
|
+
image.top = block[:y]
|
71
|
+
image.left = block[:x]
|
72
|
+
end
|
73
|
+
|
74
|
+
def split_block(block, image)
|
75
|
+
block[:used] = true
|
76
|
+
block[:down] = {:x => block[:x], :y => block[:y] + image.width, :w => block[:w], :h => block[:h] - image.height}
|
77
|
+
block[:right] = {:x => block[:x] + image.width, :y => block[:y], :w => block[:w] - image.width, :h => image.height}
|
78
|
+
end
|
79
|
+
|
80
|
+
def expand_root(root, image)
|
81
|
+
can_expand_down = (image.width <= root[:w])
|
82
|
+
can_expand_right = (image.height <= root[:h])
|
83
|
+
|
84
|
+
should_expand_down = can_expand_down && (root[:w] >= (root[:h] + image.height))
|
85
|
+
should_expand_right = can_expand_right && (root[:h] >= (root[:w] + image.width))
|
86
|
+
|
87
|
+
if should_expand_right
|
88
|
+
expand_right(root, image.width)
|
89
|
+
elsif should_expand_down
|
90
|
+
expand_down(root, image.height)
|
91
|
+
elsif can_expand_right
|
92
|
+
expand_right(root, image.width)
|
93
|
+
elsif can_expand_down
|
94
|
+
expand_down(root, image.height)
|
95
|
+
else
|
96
|
+
raise RuntimeError, "Crashed!"
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def expand_right(root, width)
|
101
|
+
Hash[
|
102
|
+
:used => true,
|
103
|
+
:x => 0,
|
104
|
+
:y => 0,
|
105
|
+
:w => root[:w] + width,
|
106
|
+
:h => root[:h],
|
107
|
+
:down => root,
|
108
|
+
:right => { :x => root[:w], :y => 0, :w => width, :h => root[:h] }
|
109
|
+
]
|
110
|
+
end
|
111
|
+
|
112
|
+
def expand_down(root, height)
|
113
|
+
Hash[
|
114
|
+
:used => true,
|
115
|
+
:x => 0,
|
116
|
+
:y => 0,
|
117
|
+
:w => root[:w],
|
118
|
+
:h => root[:h] + height,
|
119
|
+
:down => { :x => 0, :y => root[:h], :w => root[:w], :h => height },
|
120
|
+
:right => root
|
121
|
+
]
|
122
|
+
end
|
123
|
+
end # Sprite
|
124
|
+
end # Linner
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
@import "icons";
|
@@ -12,7 +12,7 @@
|
|
12
12
|
<!--[if lt IE 7]>
|
13
13
|
<p class="browsehappy">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</p>
|
14
14
|
<![endif]-->
|
15
|
-
|
15
|
+
<div class="icon-logo"></div>
|
16
16
|
<script src="/scripts/vendor.js"></script>
|
17
17
|
<script src="/scripts/app.js"></script>
|
18
18
|
<script src="/scripts/templates.js"></script>
|
@@ -2,38 +2,50 @@ paths:
|
|
2
2
|
public: "public"
|
3
3
|
groups:
|
4
4
|
scripts:
|
5
|
+
paths:
|
6
|
+
- app/scripts
|
5
7
|
concat:
|
6
8
|
"/scripts/app.js": "app/**/*.{js,coffee}"
|
7
9
|
"/scripts/vendor.js": "vendor/**/*.{js,coffee}"
|
8
10
|
order:
|
9
|
-
-
|
10
|
-
-
|
11
|
-
-
|
11
|
+
- vendor/jquery-1.10.2.js
|
12
|
+
- ...
|
13
|
+
- app/scripts/app.coffee
|
12
14
|
styles:
|
15
|
+
paths:
|
16
|
+
- app/styles
|
13
17
|
concat:
|
14
18
|
"/styles/app.css": "app/styles/**/[a-z]*.{css,scss,sass}"
|
15
19
|
images:
|
16
|
-
|
17
|
-
|
20
|
+
paths:
|
21
|
+
- app/images
|
22
|
+
sprite:
|
23
|
+
"../app/images/icons.scss": "app/images/**/*.png"
|
18
24
|
views:
|
25
|
+
paths:
|
26
|
+
- app/views
|
19
27
|
copy:
|
20
28
|
"/": "app/views/**/*.html"
|
21
29
|
templates:
|
22
30
|
paths:
|
23
|
-
-
|
31
|
+
- app/templates
|
24
32
|
precompile:
|
25
33
|
"/scripts/templates.js": "app/templates/**/*.hbs"
|
26
34
|
modules:
|
27
|
-
wrapper:
|
28
|
-
ignored:
|
29
|
-
definition:
|
30
|
-
|
35
|
+
wrapper: cmd
|
36
|
+
ignored: vendor/**/*
|
37
|
+
definition: /scripts/app.js
|
38
|
+
sprites:
|
39
|
+
url: /images/
|
40
|
+
path: /images/
|
41
|
+
selector: .icon-
|
42
|
+
revision: index.html
|
31
43
|
notification: true
|
32
44
|
bundles:
|
33
|
-
|
34
|
-
version:
|
35
|
-
url:
|
36
|
-
|
37
|
-
version:
|
38
|
-
url:
|
45
|
+
jquery.js:
|
46
|
+
version: 1.10.2
|
47
|
+
url: http://code.jquery.com/jquery-1.10.2.js
|
48
|
+
handlebars.js:
|
49
|
+
version: 1.0.0
|
50
|
+
url: https://raw.github.com/wycats/handlebars.js/1.0.0/dist/handlebars.runtime.js
|
39
51
|
|
data/lib/linner/version.rb
CHANGED
@@ -0,0 +1,23 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
|
3
|
+
describe Sprite do
|
4
|
+
before(:all) do
|
5
|
+
MockImage = Struct.new :width, :height, :top, :left
|
6
|
+
@sprites = Environment.new(root.join "config.yml").sprites
|
7
|
+
image0 = MockImage.new 2, 3
|
8
|
+
image1 = MockImage.new 5, 3
|
9
|
+
image2 = MockImage.new 6, 2
|
10
|
+
image3 = MockImage.new 2, 24
|
11
|
+
image4 = MockImage.new 1, 3
|
12
|
+
@images = [image0, image1, image2, image3, image4]
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should be an empty hash" do
|
16
|
+
@sprites.should eql(Hash.new)
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should be fit in blocks" do
|
20
|
+
sprites = Sprite.new(@images)
|
21
|
+
sprites.pack!
|
22
|
+
end
|
23
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: linner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.6.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Saito
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2013-
|
11
|
+
date: 2013-12-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: reel
|
@@ -263,10 +263,12 @@ files:
|
|
263
263
|
- lib/linner/helper.rb
|
264
264
|
- lib/linner/notifier.rb
|
265
265
|
- lib/linner/reactor.rb
|
266
|
+
- lib/linner/sprite.rb
|
266
267
|
- lib/linner/template.rb
|
267
268
|
- lib/linner/templates/app/images/.gitkeep
|
269
|
+
- lib/linner/templates/app/images/logo.png
|
268
270
|
- lib/linner/templates/app/scripts/app.coffee
|
269
|
-
- lib/linner/templates/app/styles/app.
|
271
|
+
- lib/linner/templates/app/styles/app.scss
|
270
272
|
- lib/linner/templates/app/templates/welcome.hbs
|
271
273
|
- lib/linner/templates/app/views/index.html
|
272
274
|
- lib/linner/templates/bin/server
|
@@ -283,6 +285,7 @@ files:
|
|
283
285
|
- spec/linner/bundler_spec.rb
|
284
286
|
- spec/linner/environment_spec.rb
|
285
287
|
- spec/linner/helper_spec.rb
|
288
|
+
- spec/linner/sprites_spec.rb
|
286
289
|
- spec/linner/template_spec.rb
|
287
290
|
- spec/linner/wrapper_spec.rb
|
288
291
|
- spec/spec_helper.rb
|
@@ -309,7 +312,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
309
312
|
version: '0'
|
310
313
|
requirements: []
|
311
314
|
rubyforge_project:
|
312
|
-
rubygems_version: 2.
|
315
|
+
rubygems_version: 2.0.14
|
313
316
|
signing_key:
|
314
317
|
specification_version: 4
|
315
318
|
summary: HTML5 Application Assembler
|
@@ -320,7 +323,7 @@ test_files:
|
|
320
323
|
- spec/linner/bundler_spec.rb
|
321
324
|
- spec/linner/environment_spec.rb
|
322
325
|
- spec/linner/helper_spec.rb
|
326
|
+
- spec/linner/sprites_spec.rb
|
323
327
|
- spec/linner/template_spec.rb
|
324
328
|
- spec/linner/wrapper_spec.rb
|
325
329
|
- spec/spec_helper.rb
|
326
|
-
has_rdoc:
|
File without changes
|