Module: WWW_App::CSS

Included in:
WWW_App
Defined in:
lib/www_app/CSS.rb

Constant Summary collapse

COMMA =
", ".freeze
AT_RULES =
[ 'font-face', 'media' ]
PSEUDO =
%w[
 active checked default dir() disabled
 empty enabled
 first first-child first-of-type fullscreen focus
 hover
 indeterminate in-range invalid
 lang() last-child last-of-type left link
 not() nth-child() nth-last-child() nth-last-of-type() nth-of-type()
 only-child only-of-type optional out-of-range
 read-only read-write required right root
 scope
 target
 valid visited
].select { |name| name[/\A[a-z0-9\-]+\Z/] }.map { |name| name.gsub('-', '_').to_sym }
PROPERTIES =

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

%w[
  background                 bottom                     font_variant_position      quotes
  background_attachment      box_decoration_break       font_weight                resize
  background_clip            box_shadow                 height                     right
  background_color           box_sizing                 hyphens                    tab_size
  background_image           clear                      icon                       table_layout
  background_origin          clip                       image_orientation          text_align
  background_position        clip_path                  image_rendering            text_align_last
  background_repeat          color                      image_resolution           text_combine_horizontal
  background_size            column_count               ime_mode                   text_decoration
  border                     column_fill                justify_content            text_decoration_color
  border_bottom              column_gap                 left                       text_decoration_line
  border_bottom_color        column_rule                letter_spacing             text_decoration_style
  border_bottom_left_radius  column_rule_color          line_height                text_indent
  border_bottom_right_radius column_rule_style          list_style                 text_orientation
  border_bottom_style        column_rule_width          list_style_image           text_overflow
  border_bottom_width        column_span                list_style_position        text_rendering
  border_collapse            column_width               list_style_type            text_shadow
  border_color               columns                    margin                     text_size_adjust
  border_image               counter_increment          margin_bottom              text_transform
  border_image_outset        counter_reset              margin_left                text_underline_position
  border_image_repeat        cursor                     margin_right               top
  border_image_slice         direction                  margin_top                 touch_action
  border_image_source        display                    marks                      transform
  border_image_width         empty_cells                mask                       transform_origin
  border_left                filter                     mask_type                  transform_style
  border_left_color          float                      max_height                 transition
  border_left_style          font                       max_width                  transition_delay
  border_left_width          font_family                min_height                 transition_duration
  border_radius              font_feature_settings      min_width                  transition_property
  border_right               font_kerning               opacity                    transition_timing_function
  border_right_color         font_language_override     order                      unicode_bidi
  border_right_style         font_size                  orphans                    unicode_range
  border_right_width         font_size_adjust           overflow                   vertical_align
  border_spacing             font_stretch               overflow_wrap              visibility
  border_style               font_style                 overflow_x                 white_space
  border_top                 font_synthesis             overflow_y                 widows
  border_top_color           font_variant               padding                    width
  border_top_left_radius     font_variant_alternates    padding_bottom             word_break
  border_top_right_radius    font_variant_caps          padding_left               word_spacing
  border_top_style           font_variant_east_asian    padding_right              word_wrap
  border_top_width           font_variant_ligatures     padding_top                z_index
  border_width               font_variant_numeric       position
].map(&:to_sym)

Instance Method Summary collapse

Instance Method Details

#/(*args) ⇒ Object

Example:

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

link.href('/file')./


122
123
124
125
126
127
128
129
130
131
132
133
# 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

#__Object

Ex:

style {
  div.^(:bad).__.div {
  }


100
101
102
103
104
105
106
107
108
109
110
# 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) ⇒ Object

Example:

css_selector
css_selector tag
css_selector :full || :tag || :ancestor
css_selector tag, :full || :tag || :ancestor


142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
# 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