inkcite 1.15.0 → 1.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Rakefile +1 -1
- data/inkcite.gemspec +0 -3
- data/lib/inkcite.rb +0 -1
- data/lib/inkcite/cli/base.rb +12 -8
- data/lib/inkcite/cli/preview.rb +0 -10
- data/lib/inkcite/cli/server.rb +9 -1
- data/lib/inkcite/email.rb +5 -10
- data/lib/inkcite/facade/animation.rb +4 -1
- data/lib/inkcite/image_minifier.rb +96 -0
- data/lib/inkcite/mailer.rb +2 -2
- data/lib/inkcite/minifier.rb +1 -1
- data/lib/inkcite/renderer.rb +10 -0
- data/lib/inkcite/renderer/base.rb +47 -2
- data/lib/inkcite/renderer/button.rb +15 -5
- data/lib/inkcite/renderer/container_base.rb +15 -1
- data/lib/inkcite/renderer/image.rb +1 -1
- data/lib/inkcite/renderer/image_base.rb +8 -0
- data/lib/inkcite/renderer/list.rb +104 -0
- data/lib/inkcite/renderer/mobile_image.rb +3 -0
- data/lib/inkcite/renderer/responsive.rb +2 -0
- data/lib/inkcite/renderer/slant.rb +207 -0
- data/lib/inkcite/renderer/snow.rb +15 -1
- data/lib/inkcite/renderer/special_effect.rb +7 -0
- data/lib/inkcite/renderer/sup.rb +18 -4
- data/lib/inkcite/renderer/table.rb +9 -1
- data/lib/inkcite/renderer/table_base.rb +20 -2
- data/lib/inkcite/renderer/td.rb +7 -2
- data/lib/inkcite/renderer/video_preview.rb +1 -1
- data/lib/inkcite/uploader.rb +40 -27
- data/lib/inkcite/version.rb +1 -1
- data/lib/inkcite/view.rb +133 -13
- data/lib/inkcite/view/context.rb +6 -1
- data/lib/inkcite/view/developer_scripts.rb +56 -0
- data/test/renderer/background_spec.rb +4 -4
- data/test/renderer/button_spec.rb +14 -8
- data/test/renderer/div_spec.rb +26 -3
- data/test/renderer/image_spec.rb +9 -4
- data/test/renderer/list_spec.rb +36 -0
- data/test/renderer/mobile_image_spec.rb +5 -0
- data/test/renderer/slant_spec.rb +47 -0
- data/test/renderer/span_spec.rb +12 -1
- data/test/renderer/table_spec.rb +1 -1
- data/test/renderer/td_spec.rb +24 -8
- data/test/renderer/trademark_spec.rb +6 -6
- metadata +11 -50
- data/lib/inkcite/image/base.rb +0 -38
- data/lib/inkcite/image/guetzli_minifier.rb +0 -62
- data/lib/inkcite/image/image_minifier.rb +0 -143
- data/lib/inkcite/image/image_optim_minifier.rb +0 -90
- data/lib/inkcite/image/mozjpeg_minifier.rb +0 -92
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4288c340956699599f226510e4d407f05f9800b9
|
4
|
+
data.tar.gz: ec0def8a09ffa81f5e6acaa620d058f3b7c94d85
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b20720b8716b6ed506383d4e8df220202e00afaf8cc1f48e02d5975952f4c42375cda55b1d4fcd8832d730248f9defd6aca904f47fbdeb17389a228c15cd308
|
7
|
+
data.tar.gz: f11d762ebaab6d41e45b6affe121ce9165701a695329fa3220cc817e36c6a40298ad5c6d36114ea11f84684de6bce33e10d2d91c244bde304982f01742994439
|
data/Rakefile
CHANGED
data/inkcite.gemspec
CHANGED
@@ -31,13 +31,10 @@ Gem::Specification.new do |spec|
|
|
31
31
|
spec.add_dependency 'guard'
|
32
32
|
spec.add_dependency 'guard-livereload'
|
33
33
|
spec.add_dependency 'htmlbeautifier'
|
34
|
-
spec.add_dependency 'image_optim'
|
35
|
-
spec.add_dependency 'image_optim_pack'
|
36
34
|
spec.add_dependency 'listen'
|
37
35
|
spec.add_dependency 'litmus'
|
38
36
|
spec.add_dependency 'mail'
|
39
37
|
spec.add_dependency 'mailgun-ruby'
|
40
|
-
spec.add_dependency 'mozjpeg'
|
41
38
|
spec.add_dependency 'net-sftp'
|
42
39
|
spec.add_dependency 'rack'
|
43
40
|
spec.add_dependency 'rack-livereload'
|
data/lib/inkcite.rb
CHANGED
data/lib/inkcite/cli/base.rb
CHANGED
@@ -41,28 +41,29 @@ module Inkcite
|
|
41
41
|
Cli::Init.invoke(name, options)
|
42
42
|
end
|
43
43
|
|
44
|
-
desc '
|
44
|
+
desc 'imageoptim', 'Minify the images in the project using ImageOptim'
|
45
45
|
option :force,
|
46
46
|
:aliases => '-f',
|
47
|
-
:desc => 'Force re-optimize every image, not just
|
47
|
+
:desc => 'Force re-optimize every image, not just ones that were updated since the last minification',
|
48
48
|
:type => :boolean
|
49
49
|
option :image,
|
50
50
|
:aliases => '-i',
|
51
51
|
:desc => 'Optimize a specific image',
|
52
52
|
:type => :string
|
53
|
-
def
|
53
|
+
def imageoptim
|
54
54
|
|
55
55
|
if options[:image]
|
56
|
-
|
56
|
+
ImageMinifier.minify(email, options[:image], true)
|
57
57
|
|
58
58
|
else
|
59
|
-
|
59
|
+
ImageMinifier.minify_all(email, options[:force])
|
60
60
|
|
61
61
|
original_size = Util.dir_size(email.image_dir)
|
62
62
|
compressed_size = Util.dir_size(email.optimized_image_dir)
|
63
|
-
compressed_percent =
|
63
|
+
compressed_percent = ImageMinifier.compressed_percent(original_size, compressed_size)
|
64
|
+
image_count = Dir.glob(File.join(email.optimized_image_dir, '*.*')).count
|
64
65
|
|
65
|
-
puts "Compressed from #{Util.pretty_file_size(original_size)} to #{Util.pretty_file_size(compressed_size)} (#{compressed_percent}%)"
|
66
|
+
puts "Compressed #{image_count} images from #{Util.pretty_file_size(original_size)} to #{Util.pretty_file_size(compressed_size)} (#{compressed_percent}%)"
|
66
67
|
end
|
67
68
|
|
68
69
|
end
|
@@ -145,8 +146,11 @@ module Inkcite
|
|
145
146
|
:aliases => '-f',
|
146
147
|
:desc => "Forces files to be uploaded regardless of whether or not they've changed",
|
147
148
|
:type => :boolean
|
149
|
+
option :'images',
|
150
|
+
:aliases => '-i',
|
151
|
+
:desc => 'Uploads images only (not the email HTML)'
|
148
152
|
def upload
|
149
|
-
|
153
|
+
email.upload options
|
150
154
|
end
|
151
155
|
|
152
156
|
private
|
data/lib/inkcite/cli/preview.rb
CHANGED
@@ -27,16 +27,6 @@ module Inkcite
|
|
27
27
|
else
|
28
28
|
preview_opt[:tag] = "#{list.to_s.titleize} Test"
|
29
29
|
preview_opt[:bcc] = true
|
30
|
-
# abort <<-USAGE.strip_heredoc
|
31
|
-
#
|
32
|
-
# Oops! Inkcite doesn't recognize that distribution list. It needs
|
33
|
-
# to be one of 'client', 'internal' or 'developer':
|
34
|
-
#
|
35
|
-
# inkcite preview internal
|
36
|
-
#
|
37
|
-
# USAGE
|
38
|
-
#
|
39
|
-
# return
|
40
30
|
end
|
41
31
|
|
42
32
|
Mailer.send_to_list email, list, opt.merge(preview_opt)
|
data/lib/inkcite/cli/server.rb
CHANGED
@@ -5,6 +5,8 @@ require 'rack'
|
|
5
5
|
require 'rack-livereload'
|
6
6
|
require 'webrick'
|
7
7
|
|
8
|
+
require 'inkcite/view/developer_scripts'
|
9
|
+
|
8
10
|
module Inkcite
|
9
11
|
module Cli
|
10
12
|
class Server
|
@@ -108,7 +110,7 @@ module Inkcite
|
|
108
110
|
# Minify the image if the source version in images/ is newer
|
109
111
|
# or if the configuration file controlling optimization has
|
110
112
|
# been updated since the last time the image was requested.
|
111
|
-
|
113
|
+
ImageMinifier.minify(@email, File.basename(path), false) if can_serve(path)
|
112
114
|
|
113
115
|
# Let the super method handle the actual serving of the image.
|
114
116
|
res = super
|
@@ -158,6 +160,12 @@ module Inkcite
|
|
158
160
|
|
159
161
|
view = @email.view(environment, format, version)
|
160
162
|
|
163
|
+
# Check to see if images have been disabled in this rendering.
|
164
|
+
view.images_off = true if params.key?('images-off')
|
165
|
+
|
166
|
+
# Install the developer toolkit into the view.
|
167
|
+
Inkcite::View::DeveloperScripts.install!(view)
|
168
|
+
|
161
169
|
html = view.render!
|
162
170
|
|
163
171
|
# If minification is disabled, then beautify the output to make it easier
|
data/lib/inkcite/email.rb
CHANGED
@@ -61,12 +61,12 @@ module Inkcite
|
|
61
61
|
# Optimizes this email's images if optimize-images is enabled
|
62
62
|
# in the email configuration.
|
63
63
|
def optimize_images
|
64
|
-
|
64
|
+
ImageMinifier.minify_all(self, false) if optimize_images?
|
65
65
|
end
|
66
66
|
|
67
67
|
# Optimizes all of the images in this email.
|
68
68
|
def optimize_images!
|
69
|
-
|
69
|
+
ImageMinifier.minify_all(self, true)
|
70
70
|
end
|
71
71
|
|
72
72
|
def optimize_images?
|
@@ -76,7 +76,7 @@ module Inkcite
|
|
76
76
|
# Returns the directory that optimized, compressed images
|
77
77
|
# have been saved to.
|
78
78
|
def optimized_image_dir
|
79
|
-
File.join(path, optimize_images??
|
79
|
+
File.join(path, optimize_images?? ImageMinifier::IMAGE_CACHE : IMAGES)
|
80
80
|
end
|
81
81
|
|
82
82
|
def project_file file
|
@@ -90,14 +90,9 @@ module Inkcite
|
|
90
90
|
value
|
91
91
|
end
|
92
92
|
|
93
|
-
def upload
|
93
|
+
def upload opts={}
|
94
94
|
require_relative 'uploader'
|
95
|
-
Uploader.upload(self)
|
96
|
-
end
|
97
|
-
|
98
|
-
def upload!
|
99
|
-
require_relative 'uploader'
|
100
|
-
Uploader.upload!(self)
|
95
|
+
Uploader.upload(self, opts)
|
101
96
|
end
|
102
97
|
|
103
98
|
def versions
|
@@ -105,7 +105,10 @@ module Inkcite
|
|
105
105
|
@timing_function
|
106
106
|
]
|
107
107
|
|
108
|
-
|
108
|
+
# Negative delays start the animation mid-sequence whereas positive
|
109
|
+
# values cause the animation to delay start.
|
110
|
+
# https://css-tricks.com/starting-css-animations-mid-way/
|
111
|
+
css << seconds(@delay) if @delay != 0
|
109
112
|
|
110
113
|
css << @iteration_count
|
111
114
|
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module Inkcite
|
2
|
+
class ImageMinifier
|
3
|
+
|
4
|
+
# Directory of optimized images
|
5
|
+
IMAGE_CACHE = 'images-optim'
|
6
|
+
|
7
|
+
# Path to ImageOption app on OS X
|
8
|
+
IMAGE_OPTIM_PATH = "/Applications/ImageOptim.app/Contents/MacOS/ImageOptim"
|
9
|
+
|
10
|
+
# Extension to put on files tha have been optimized already in the images/
|
11
|
+
# source folder
|
12
|
+
OPTIMIZED_EXTENSION = '.optimized'
|
13
|
+
|
14
|
+
def self.minify email, img_name, force=false
|
15
|
+
|
16
|
+
# Original, unoptimized source image
|
17
|
+
source_img = File.join(email.image_dir, img_name)
|
18
|
+
|
19
|
+
# Cached, optimized path for this image.
|
20
|
+
cache_path = email.project_file(IMAGE_CACHE)
|
21
|
+
cached_img = File.join(cache_path, File.basename(img_name))
|
22
|
+
|
23
|
+
unless force
|
24
|
+
|
25
|
+
# Get the last-modified date of the actual image. If the source
|
26
|
+
# image is newer than the cached version, we'll need to run it
|
27
|
+
# through optimization again, too.
|
28
|
+
cache_last_modified = Util.last_modified(cached_img)
|
29
|
+
source_last_modified = Util.last_modified(source_img)
|
30
|
+
|
31
|
+
# Nothing to do unless the image in the cache is older than the
|
32
|
+
# source or the config file.
|
33
|
+
return unless source_last_modified > cache_last_modified
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# Make sure the image cache directory exists
|
38
|
+
FileUtils.mkpath(cache_path)
|
39
|
+
|
40
|
+
# Copy the original image to the cache where it can be processed.
|
41
|
+
FileUtils.copy(source_img, cached_img)
|
42
|
+
|
43
|
+
# Can only optimize the image if ImageOptim app is installed.
|
44
|
+
# @TODO Need to do the right thing on Windows.
|
45
|
+
if File.file?(IMAGE_OPTIM_PATH)
|
46
|
+
|
47
|
+
original_size = File.size(source_img)
|
48
|
+
|
49
|
+
# Check to see if there is a .optimized marker file indicating that a file
|
50
|
+
# shouldn't be further optimized.
|
51
|
+
if File.exists?("#{source_img}#{OPTIMIZED_EXTENSION}")
|
52
|
+
msg = "Copying #{img_name} #{Util.pretty_file_size(original_size)}"
|
53
|
+
|
54
|
+
compressed_size = original_size
|
55
|
+
|
56
|
+
else
|
57
|
+
msg = "Compressing #{img_name} #{Util.pretty_file_size(original_size)}"
|
58
|
+
|
59
|
+
Util.exec("#{IMAGE_OPTIM_PATH} #{cached_img}")
|
60
|
+
|
61
|
+
compressed_size = File.size(cached_img)
|
62
|
+
msg << " → #{Util.pretty_file_size(compressed_size)}"
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
# Get the final compressed size of the image so we can print the
|
67
|
+
# resulting compression ratio.
|
68
|
+
msg << " (#{self.compressed_percent(original_size, compressed_size)}%)"
|
69
|
+
|
70
|
+
Util.log msg
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
# Minifies all of the images in the provided email's project directory.
|
77
|
+
def self.minify_all email, force=false
|
78
|
+
|
79
|
+
images_path = File.join(email.image_dir, '*.*')
|
80
|
+
|
81
|
+
# Iterate through all of the images in the project and optimize them
|
82
|
+
# if necessary.
|
83
|
+
Dir.glob(images_path).each do |img|
|
84
|
+
next if img.to_s.end_with?(OPTIMIZED_EXTENSION)
|
85
|
+
self.minify(email, File.basename(img), force)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.compressed_percent original_size, compressed_size
|
91
|
+
((1.0 - (compressed_size / original_size.to_f)) * 100).round(1)
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
data/lib/inkcite/mailer.rb
CHANGED
@@ -196,10 +196,10 @@ module Inkcite
|
|
196
196
|
clients = recipient_yml[:clients] || recipient_yml[:client]
|
197
197
|
recipients[:to] = first_preview || clients
|
198
198
|
recipients[:cc] = recipient_yml[:internal]
|
199
|
-
when :internal
|
200
|
-
recipients[:to] = recipient_yml[:internal]
|
201
199
|
when :developer
|
202
200
|
recipients[:to] = from
|
201
|
+
else # internal or any custom list
|
202
|
+
recipients[:to] = recipient_yml[list]
|
203
203
|
end
|
204
204
|
|
205
205
|
end
|
data/lib/inkcite/minifier.rb
CHANGED
data/lib/inkcite/renderer.rb
CHANGED
@@ -17,6 +17,7 @@ require_relative 'renderer/in_browser'
|
|
17
17
|
require_relative 'renderer/increment'
|
18
18
|
require_relative 'renderer/like'
|
19
19
|
require_relative 'renderer/link'
|
20
|
+
require_relative 'renderer/list'
|
20
21
|
require_relative 'renderer/litmus_analytics'
|
21
22
|
require_relative 'renderer/lorem'
|
22
23
|
require_relative 'renderer/mobile_image'
|
@@ -27,6 +28,7 @@ require_relative 'renderer/partial'
|
|
27
28
|
require_relative 'renderer/preheader'
|
28
29
|
require_relative 'renderer/property'
|
29
30
|
require_relative 'renderer/redacted'
|
31
|
+
require_relative 'renderer/slant'
|
30
32
|
require_relative 'renderer/snow'
|
31
33
|
require_relative 'renderer/social'
|
32
34
|
require_relative 'renderer/span'
|
@@ -71,6 +73,10 @@ module Inkcite
|
|
71
73
|
# Remove unicode line break characters
|
72
74
|
value.gsub!(/\u2028/, '')
|
73
75
|
|
76
|
+
# Nuclear option to remove invisible unicode characters injected
|
77
|
+
# when pasting text from MS Word or Google Docs.
|
78
|
+
value.gsub!(/[^\P{C}\n]+/u, '')
|
79
|
+
|
74
80
|
value
|
75
81
|
end
|
76
82
|
|
@@ -194,6 +200,7 @@ module Inkcite
|
|
194
200
|
:'in-browser' => InBrowser.new,
|
195
201
|
:include => Partial.new,
|
196
202
|
:instagram => Social::Instagram.new,
|
203
|
+
:li => List.new,
|
197
204
|
:like => Like.new,
|
198
205
|
:litmus => LitmusAnalytics.new,
|
199
206
|
:lorem => Lorem.new,
|
@@ -201,10 +208,12 @@ module Inkcite
|
|
201
208
|
:'mobile-only' => MobileOnly.new,
|
202
209
|
:'mobile-style' => MobileStyle.new,
|
203
210
|
:'mobile-toggle-on' => MobileToggleOn.new,
|
211
|
+
:ol => List.new,
|
204
212
|
:pintrest => Social::Pintrest.new,
|
205
213
|
:preheader => Preheader.new,
|
206
214
|
:r => Trademark.new('®'),
|
207
215
|
:redacted => Redacted.new,
|
216
|
+
:slant => Slant.new,
|
208
217
|
:snow => Snow.new,
|
209
218
|
:span => Span.new,
|
210
219
|
:sparkle => Sparkle.new,
|
@@ -215,6 +224,7 @@ module Inkcite
|
|
215
224
|
:'topic' => Topic.new,
|
216
225
|
:'topic-list' => TopicList.new,
|
217
226
|
:twitter => Social::Twitter.new,
|
227
|
+
:ul => List.new,
|
218
228
|
:'video-preview' => VideoPreview.new
|
219
229
|
}
|
220
230
|
|
@@ -5,6 +5,8 @@ module Inkcite
|
|
5
5
|
# Constants for style and property names with dashes in them.
|
6
6
|
BACKGROUND_COLOR = :'background-color'
|
7
7
|
BACKGROUND_GRADIENT = :'background-gradient'
|
8
|
+
BACKGROUND_GRADIENT_POSITION = :'background-gradient-position'
|
9
|
+
BACKGROUND_GRADIENT_SHAPE = :'background-gradient-shape'
|
8
10
|
BACKGROUND_IMAGE = :'background-image'
|
9
11
|
BACKGROUND_REPEAT = :'background-repeat'
|
10
12
|
BACKGROUND_POSITION = :'background-position'
|
@@ -16,7 +18,9 @@ module Inkcite
|
|
16
18
|
BORDER_RADIUS = :'border-radius'
|
17
19
|
BORDER_RIGHT = :'border-right'
|
18
20
|
BORDER_SPACING = :'border-spacing'
|
21
|
+
BORDER_STYLE = :'border-style'
|
19
22
|
BORDER_TOP = :'border-top'
|
23
|
+
BORDER_WIDTH = :'border-width'
|
20
24
|
BOX_SHADOW = :'box-shadow'
|
21
25
|
FONT_FAMILY = :'font-family'
|
22
26
|
FONT_SIZE = :'font-size'
|
@@ -31,10 +35,13 @@ module Inkcite
|
|
31
35
|
MARGIN_TOP = :'margin-top'
|
32
36
|
MAX_HEIGHT = :'max-height'
|
33
37
|
MAX_WIDTH = :'max-width'
|
38
|
+
MSO_HIDE = :'mso-hide'
|
39
|
+
MSO_PADDING_ALT = :'mso-padding-alt'
|
34
40
|
PADDING_X = :'padding-x'
|
35
41
|
PADDING_Y = :'padding-y'
|
36
42
|
TEXT_ALIGN = :'text-align'
|
37
43
|
TEXT_DECORATION = :'text-decoration'
|
44
|
+
TEXT_JUSTIFY = :'text-justify'
|
38
45
|
TEXT_SHADOW = :'text-shadow'
|
39
46
|
TEXT_SHADOW_BLUR = :'shadow-blur'
|
40
47
|
TEXT_SHADOW_OFFSET = :'shadow-offset'
|
@@ -62,6 +69,14 @@ module Inkcite
|
|
62
69
|
# Zero-width non-breaking character
|
63
70
|
ZERO_WIDTH_NON_BREAKING_SPACE = ''
|
64
71
|
|
72
|
+
# Constant for justified text alignment.
|
73
|
+
JUSTIFY = 'justify'
|
74
|
+
|
75
|
+
# For gradients
|
76
|
+
LINEAR = 'linear'
|
77
|
+
CIRCLE = 'circle'
|
78
|
+
RADIAL = 'radial'
|
79
|
+
|
65
80
|
def render tag, opt, ctx
|
66
81
|
raise "Not implemented: #{tag} #{opts}"
|
67
82
|
end
|
@@ -151,7 +166,26 @@ module Inkcite
|
|
151
166
|
center_color = bgcolor ? bgcolor : bggradient
|
152
167
|
outer_color = bgcolor ? bggradient : Util.darken(bggradient)
|
153
168
|
|
154
|
-
|
169
|
+
# The default position of the gradient when not specified
|
170
|
+
# by the designer.
|
171
|
+
default_position = 'center'
|
172
|
+
|
173
|
+
shape = opt[BACKGROUND_GRADIENT_SHAPE] || LINEAR
|
174
|
+
if shape == LINEAR
|
175
|
+
type = LINEAR
|
176
|
+
shape = 'to '
|
177
|
+
|
178
|
+
# Linear gradients default to the bottom.
|
179
|
+
default_position = 'bottom'
|
180
|
+
|
181
|
+
else
|
182
|
+
type = RADIAL
|
183
|
+
shape = "#{shape} at "
|
184
|
+
end
|
185
|
+
|
186
|
+
position = detect(opt[BACKGROUND_GRADIENT_POSITION], default_position)
|
187
|
+
|
188
|
+
bggradient = %Q(#{type}-gradient(#{shape}#{position}, #{center_color}, #{outer_color}))
|
155
189
|
end
|
156
190
|
|
157
191
|
element.style[BACKGROUND_IMAGE] = bggradient
|
@@ -238,7 +272,18 @@ module Inkcite
|
|
238
272
|
def mix_text_align element, opt, ctx
|
239
273
|
|
240
274
|
align = detect(opt[:align] || opt[TEXT_ALIGN])
|
241
|
-
|
275
|
+
return if none?(align)
|
276
|
+
|
277
|
+
element.style[TEXT_ALIGN] = align
|
278
|
+
|
279
|
+
mix_text_justify(element, opt, ctx) if align == JUSTIFY
|
280
|
+
|
281
|
+
end
|
282
|
+
|
283
|
+
def mix_text_justify element, opt, ctx
|
284
|
+
|
285
|
+
text_justify = opt[TEXT_JUSTIFY]
|
286
|
+
element.style[TEXT_JUSTIFY] = text_justify unless none?(text_justify)
|
242
287
|
|
243
288
|
end
|
244
289
|
|