lib/jekyll/assets/plugins/alternates.rb
# Frozen-string-literal: true
# Copyright: 2012 - 2020 - ISC License
# Author: Jordon Bedwell
# Encoding: utf-8
if Jekyll::Assets::Utils.activate("crass")
module Jekyll
module Assets
module Plugins
NODER = %r!/\*\! @alternate \*/!.freeze
RTEST = %r!#{Regexp.union(%w(-ms- -webkit- -moz- -o-).freeze)}!.freeze
NODE1 = { node: :whitespace, pos: 28, raw: ' ' }.freeze
NODE2 = {
raw: '/*! @alternate */',
pos: 0, # It's ignored. @see Crass::Parser.stringify
value: '! @alternate ',
node: :comment
}.freeze
NODE3 = {
value: '@alternate ',
raw: '/* @alternate */',
node: :comment,
pos: 0
}.freeze
class Alternates
def call(input)
comp = input[:environment].asset_config[:compression]
data = Crass.parse(input[:data] || "", preserve_comments: true)
data.each do |v|
next unless v[:node] == :style_rule
v[:children] = v[:children].each_with_object([]) do |c, a|
if alternate?(c)
a << (comp ? NODE2 : NODE3)
a << NODE1
end
a << c
end
end
{
data: Crass::Parser.stringify(data, {
preserve_comments: true,
}),
}
end
private
def alternate?(c)
c[:node] == :property && (
c[:name] =~ RTEST || c[:value] =~ RTEST
)
end
end
# --
# When compression is enabled we need to make sure to
# run an extra step, because when compression is being
# ran, we have to guard with /*! so we've to strip.
# --
Hook.register :asset, :after_compression do |_, o, t|
next o unless t == "text/css"
o.gsub(NODER,
" #{NODE3[:raw]} "
)
end
# --
Hook.register :env, :after_init, priority: 2 do
register_bundle_processor "text/css",
Alternates.new
end
end
end
end
end