module WWW_App::CSS

Constants

AT_RULES
COMMA
PROPERTIES

From: Sanitize::Config::RELAXED[:properties]

PSEUDO

From:

developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes

Public Instance Methods

/(*args) click to toggle source

Example:

style {
  a._link / a._hover {
    ...
  }
}

link.href('/file')./
# File lib/www_app/CSS.rb, line 122
def / *args
  fail "No block allowed here." if block_given?

  case args.size
  when 0
    close
  when 1
    self
  else
    fail ::ArgumentError, "Unknown args: #{args.inspect[0,50]}"
  end
end
__() click to toggle source

Ex:

style {
  div.^(:bad).__.div {
  }
# File lib/www_app/CSS.rb, line 100
def __
  fail "Can only be used inside :style tag" unless ancestor?(:style)

  if !@tag || (@tag[:tag_name] == :group || @tag[:tag_name] == :groups)
    fail "Can only be used after an HTML element is created: #{@tag[:tag_name].inspect}"
  end

  @tag[:__] = true
  go_up
  self
end
css_selector(*args) click to toggle source

Example:

css_selector
css_selector tag
css_selector :full || :tag || :ancestor
css_selector tag, :full || :tag || :ancestor
# File lib/www_app/CSS.rb, line 142
def css_selector *args
  tag  = @tag
  type = :full
  args.each { |a|
    case
    when a.is_a?(Symbol)
      type = a
    else
      tag = a
    end
  }

  metaphor = (de_ref(tag) || {}.freeze)

  final = case

          when type == :full && tag?(metaphor, :group)
            css = metaphor[:children].inject([]) { |memo, c|
              if !(tag?(c, :group)) && !c[:__parent]
                memo << css_selector(c, :full)
              end
              memo
            }

            if css
              css.join COMMA
            else
              nil
            end

          when tag?(metaphor, :style)
            p = metaphor[:parent]
            if p
              css_selector p, type
            end

          when type == :full && parent?(metaphor, :group)
            grand_parent = metaphor[:parent][:parent]
            grand_css    = grand_parent && css_selector(grand_parent, :full)
            use_grand    = !(metaphor[:__] && metaphor[:__children].detect { |e| tag?(e, :_) })

            if grand_css && use_grand
              grand_css.split(COMMA).map { |css|
                css << SPACE << css_selector(metaphor, :tag)
              }.join COMMA
            else
              css_selector metaphor, :tag
            end

          when type == :tag
            id = metaphor[:id]
            name = if id
                     '#' << Clean.html_id(id).to_s
                   else
                     metaphor[:tag_name].to_s
                   end

            if metaphor[:class]
              name << '.'.freeze
              name.<<(
                metaphor[:class].map { |name|
                  Clean.css_class_name(name.to_s)
                }.join('.'.freeze)
              )
            end

            if metaphor[:pseudo]
              name << ":#{metaphor[:pseudo]}"
            end

            if tag[:__]
              name << SPACE << tag[:__children].map { |c|
                css_selector(c, :tag)
              }.join(SPACE)
            end

            name = if name.empty?
                     nil
                   else
                     name
                   end

          when type == :ancestor
            if metaphor[:id]
              nil
            else
              selectors = []
              p         = metaphor[:parent]
              while p
                selectors.unshift(css_selector(p, :tag)) unless [:style, :group].freeze.include?(p[:tag_name])
                p = p[:id] ? nil : p[:parent]
              end # === while

              selectors.compact.join(SPACE)
            end

          else
            [css_selector(metaphor, :ancestor), css_selector(metaphor, :tag)].compact.join SPACE
          end

  return nil if !final || final.empty?
  final.gsub(' _!:'.freeze, ':'.freeze)
end