This repository is private.
All pages are served over SSL and all pushing and pulling is done over SSH.
No one may fork, clone, or view it unless they are added as a member.
Every repository with this icon (
) is private.
Every repository with this icon (
This repository is public.
Anyone may fork, clone, or view it.
Every repository with this icon (
) is public.
Every repository with this icon (
| 89a10b9d » | hcatlin | 2006-10-14 | 1 | module Haml | |
| 2 | # This class is used only internally. It holds the buffer of XHTML that | ||||
| 3 | # is eventually output by Haml::Engine's to_html method. It's called | ||||
| 4 | # from within the precompiled code, and helps reduce the amount of | ||||
| 5 | # processing done within instance_eval'd code. | ||||
| 6 | class Buffer | ||||
| 7 | include Haml::Helpers | ||||
| 00ef3f99 » | nex3 | 2006-11-03 | 8 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 9 | # The string that holds the compiled XHTML. This is aliased as | |
| 10 | # _erbout for compatibility with ERB-specific code. | ||||
| 11 | attr_accessor :buffer | ||||
| 00ef3f99 » | nex3 | 2006-11-03 | 12 | ||
| b814ea29 » | nex3 | 2007-11-21 | 13 | # The options hash passed in from Haml::Engine. | |
| 14 | attr_accessor :options | ||||
| 15 | |||||
| 6c0473e3 » | nex3 | 2008-04-24 | 16 | # The Buffer for the enclosing Haml document. | |
| 17 | # This is set for partials and similar sorts of nested templates. | ||||
| 18 | # It's nil at the top level (see #toplevel?). | ||||
| 19 | attr_accessor :upper | ||||
| 20 | |||||
| f48294c4 » | nex3 | 2008-04-24 | 21 | # See #active? | |
| 22 | attr_writer :active | ||||
| 23 | |||||
| ae3c44f5 » | nex3 | 2008-02-29 | 24 | # True if the format is XHTML | |
| 25 | def xhtml? | ||||
| 26 | not html? | ||||
| 27 | end | ||||
| 28 | |||||
| 29 | # True if the format is any flavor of HTML | ||||
| 30 | def html? | ||||
| 31 | html4? or html5? | ||||
| 32 | end | ||||
| 33 | |||||
| 34 | # True if the format is HTML4 | ||||
| 35 | def html4? | ||||
| 36 | @options[:format] == :html4 | ||||
| 37 | end | ||||
| 38 | |||||
| 39 | # True if the format is HTML5 | ||||
| 40 | def html5? | ||||
| 41 | @options[:format] == :html5 | ||||
| 42 | end | ||||
| 43 | |||||
| 6c0473e3 » | nex3 | 2008-04-24 | 44 | # True if this buffer is a top-level template, | |
| 45 | # as opposed to a nested partial. | ||||
| 46 | def toplevel? | ||||
| 47 | upper.nil? | ||||
| 48 | end | ||||
| 49 | |||||
| f48294c4 » | nex3 | 2008-04-24 | 50 | # True if this buffer is currently being used to render a Haml template. | |
| 51 | # However, this returns false if a subtemplate is being rendered, | ||||
| 52 | # even if it's a subtemplate of this buffer's template. | ||||
| 53 | def active? | ||||
| 54 | @active | ||||
| 55 | end | ||||
| 56 | |||||
| aeade6a6 » | nex3 | 2007-03-15 | 57 | # Gets the current tabulation of the document. | |
| 58 | def tabulation | ||||
| 59 | @real_tabs + @tabulation | ||||
| 60 | end | ||||
| 61 | |||||
| 62 | # Sets the current tabulation of the document. | ||||
| 63 | def tabulation=(val) | ||||
| 64 | val = val - @real_tabs | ||||
| 65 | @tabulation = val > -1 ? val : 0 | ||||
| 66 | end | ||||
| 938101b7 » | nex3 | 2006-11-08 | 67 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 68 | # Creates a new buffer. | |
| 6c0473e3 » | nex3 | 2008-04-24 | 69 | def initialize(upper = nil, options = {}) | |
| f48294c4 » | nex3 | 2008-04-24 | 70 | @active = true | |
| 6c0473e3 » | nex3 | 2008-04-24 | 71 | @upper = upper | |
| 0c23fc9f » | nex3 | 2007-07-14 | 72 | @options = { | |
| f7f11e20 » | wincent | 2008-02-13 | 73 | :attr_wrapper => "'", | |
| ae3c44f5 » | nex3 | 2008-02-29 | 74 | :ugly => false, | |
| 75 | :format => :xhtml | ||||
| 0c23fc9f » | nex3 | 2007-07-14 | 76 | }.merge options | |
| 89a10b9d » | hcatlin | 2006-10-14 | 77 | @buffer = "" | |
| 938101b7 » | nex3 | 2006-11-08 | 78 | @tabulation = 0 | |
| aeade6a6 » | nex3 | 2007-03-15 | 79 | ||
| 80 | # The number of tabs that Engine thinks we should have | ||||
| 81 | # @real_tabs + @tabulation is the number of tabs actually output | ||||
| 82 | @real_tabs = 0 | ||||
| 89a10b9d » | hcatlin | 2006-10-14 | 83 | end | |
| 00ef3f99 » | nex3 | 2006-11-03 | 84 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 85 | # Renders +text+ with the proper tabulation. This also deals with | |
| 86 | # making a possible one-line tag one line or not. | ||||
| 5834545b » | nex3 | 2008-05-10 | 87 | def push_text(text, dont_tab_up = false, tab_change = 0) | |
| 40da6139 » | nex3 | 2008-02-13 | 88 | if @tabulation > 0 && !@options[:ugly] | |
| 5834545b » | nex3 | 2008-05-10 | 89 | # Have to push every line in by the extra user set tabulation. | |
| 90 | # Don't push lines with just whitespace, though, | ||||
| 91 | # because that screws up precompiled indentation. | ||||
| 92 | text.gsub!(/^(?!\s+$)/m, tabs) | ||||
| 93 | text.sub!(tabs, '') if dont_tab_up | ||||
| 89a10b9d » | hcatlin | 2006-10-14 | 94 | end | |
| 84fdde13 » | nex3 | 2008-04-07 | 95 | ||
| 40da6139 » | nex3 | 2008-02-13 | 96 | @buffer << text | |
| ab1dffda » | tom | 2007-07-12 | 97 | @real_tabs += tab_change | |
| 5834545b » | nex3 | 2008-05-10 | 98 | @dont_tab_up_next_line = false | |
| 89a10b9d » | hcatlin | 2006-10-14 | 99 | end | |
| 00ef3f99 » | nex3 | 2006-11-03 | 100 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 101 | # Properly formats the output of a script that was run in the | |
| 102 | # instance_eval. | ||||
| 204ba031 » | nex3 | 2008-05-10 | 103 | def push_script(result, preserve_script, in_tag = false, preserve_tag = false, | |
| 104 | escape_html = false, nuke_inner_whitespace = false) | ||||
| 5eafacd6 » | tom | 2007-07-13 | 105 | tabulation = @real_tabs | |
| a7c9aa9d » | nex3 | 2008-03-02 | 106 | ||
| 53508642 » | nex3 | 2008-08-03 | 107 | result = result.to_s.rstrip | |
| 7b5ae8db » | nex3 | 2009-01-08 | 108 | result = result.lstrip if nuke_inner_whitespace | |
| 53508642 » | nex3 | 2008-08-03 | 109 | result = html_escape(result) if escape_html | |
| 110 | |||||
| a7c9aa9d » | nex3 | 2008-03-02 | 111 | if preserve_tag | |
| 112 | result = Haml::Helpers.preserve(result) | ||||
| 113 | elsif preserve_script | ||||
| 535c40c4 » | nex3 | 2008-05-13 | 114 | result = Haml::Helpers.find_and_preserve(result, options[:preserve]) | |
| 89a10b9d » | hcatlin | 2006-10-14 | 115 | end | |
| 84fdde13 » | nex3 | 2008-04-07 | 116 | ||
| e5dedfa6 » | nex3 | 2008-05-09 | 117 | has_newline = result.include?("\n") | |
| 7c13afde » | nex3 | 2008-06-11 | 118 | if in_tag && !nuke_inner_whitespace && (@options[:ugly] || !has_newline || preserve_tag) | |
| 5834545b » | nex3 | 2008-05-10 | 119 | @buffer << result | |
| 120 | @real_tabs -= 1 | ||||
| 121 | return | ||||
| 122 | end | ||||
| 123 | |||||
| 204ba031 » | nex3 | 2008-05-10 | 124 | @buffer << "\n" if in_tag && !nuke_inner_whitespace | |
| 5834545b » | nex3 | 2008-05-10 | 125 | ||
| 126 | # Precompiled tabulation may be wrong | ||||
| 127 | if @tabulation > 0 && !in_tag | ||||
| 128 | result = tabs + result | ||||
| 129 | end | ||||
| 130 | |||||
| 131 | if has_newline && !@options[:ugly] | ||||
| 132 | result = result.gsub "\n", "\n" + tabs(tabulation) | ||||
| 133 | |||||
| 134 | # Add tabulation if it wasn't precompiled | ||||
| 204ba031 » | nex3 | 2008-05-10 | 135 | result = tabs(tabulation) + result if in_tag && !nuke_inner_whitespace | |
| 5834545b » | nex3 | 2008-05-10 | 136 | end | |
| 204ba031 » | nex3 | 2008-05-10 | 137 | @buffer << "#{result}" | |
| 138 | @buffer << "\n" unless nuke_inner_whitespace | ||||
| 5834545b » | nex3 | 2008-05-10 | 139 | ||
| 204ba031 » | nex3 | 2008-05-10 | 140 | if in_tag && !nuke_inner_whitespace | |
| 5834545b » | nex3 | 2008-05-10 | 141 | # We never get here if @options[:ugly] is true | |
| 142 | @buffer << tabs(tabulation-1) | ||||
| 9db4d2f3 » | nex3 | 2007-08-16 | 143 | @real_tabs -= 1 | |
| 89a10b9d » | hcatlin | 2006-10-14 | 144 | end | |
| 145 | nil | ||||
| 146 | end | ||||
| 00ef3f99 » | nex3 | 2006-11-03 | 147 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 148 | # Takes the various information about the opening tag for an | |
| 149 | # element, formats it, and adds it to the buffer. | ||||
| 5834545b » | nex3 | 2008-05-10 | 150 | def open_tag(name, self_closing, try_one_line, preserve_tag, escape_html, class_id, | |
| 151 | nuke_outer_whitespace, nuke_inner_whitespace, obj_ref, content, *attributes_hashes) | ||||
| 5eafacd6 » | tom | 2007-07-13 | 152 | tabulation = @real_tabs | |
| 84fdde13 » | nex3 | 2008-04-07 | 153 | ||
| 2f59543e » | nex3 | 2007-05-30 | 154 | attributes = class_id | |
| 34500a10 » | nex3 | 2008-10-02 | 155 | attributes_hashes.each do |old| | |
| 156 | self.class.merge_attrs(attributes, old.inject({}) {|h, (key, val)| h[key.to_s] = val; h}) | ||||
| 0141a596 » | nex3 | 2007-06-06 | 157 | end | |
| 158 | self.class.merge_attrs(attributes, parse_object_ref(obj_ref)) if obj_ref | ||||
| 00ef3f99 » | nex3 | 2006-11-03 | 159 | ||
| 49155711 » | cv | 2008-10-06 | 160 | if self_closing && xhtml? | |
| 5834545b » | nex3 | 2008-05-10 | 161 | str = " />" + (nuke_outer_whitespace ? "" : "\n") | |
| 89a10b9d » | hcatlin | 2006-10-14 | 162 | else | |
| 178cabab » | nex3 | 2008-10-06 | 163 | str = ">" + ((if self_closing && html? | |
| 164 | nuke_outer_whitespace | ||||
| 165 | else | ||||
| 166 | try_one_line || preserve_tag || nuke_inner_whitespace | ||||
| 167 | end) ? "" : "\n") | ||||
| 89a10b9d » | hcatlin | 2006-10-14 | 168 | end | |
| 40da6139 » | nex3 | 2008-02-13 | 169 | ||
| 402977cc » | indirect | 2008-03-18 | 170 | attributes = Precompiler.build_attributes(html?, @options[:attr_wrapper], attributes) | |
| 5834545b » | nex3 | 2008-05-10 | 171 | @buffer << "#{nuke_outer_whitespace || @options[:ugly] ? '' : tabs(tabulation)}<#{name}#{attributes}#{str}" | |
| 40da6139 » | nex3 | 2008-02-13 | 172 | ||
| ab1dffda » | tom | 2007-07-12 | 173 | if content | |
| 5834545b » | nex3 | 2008-05-10 | 174 | @buffer << "#{content}</#{name}>" << (nuke_outer_whitespace ? "" : "\n") | |
| 204ba031 » | nex3 | 2008-05-10 | 175 | return | |
| ab1dffda » | tom | 2007-07-12 | 176 | end | |
| 204ba031 » | nex3 | 2008-05-10 | 177 | ||
| 178 | @real_tabs += 1 unless self_closing || nuke_inner_whitespace | ||||
| 89a10b9d » | hcatlin | 2006-10-14 | 179 | end | |
| 00ef3f99 » | nex3 | 2006-11-03 | 180 | ||
| 0141a596 » | nex3 | 2007-06-06 | 181 | def self.merge_attrs(to, from) | |
| 182 | if to['id'] && from['id'] | ||||
| 183 | to['id'] << '_' << from.delete('id') | ||||
| a76b25d1 » | nex3 | 2008-01-10 | 184 | elsif to['id'] || from['id'] | |
| 185 | from['id'] ||= to['id'] | ||||
| 0141a596 » | nex3 | 2007-06-06 | 186 | end | |
| 187 | |||||
| 188 | if to['class'] && from['class'] | ||||
| 189 | # Make sure we don't duplicate class names | ||||
| 190 | from['class'] = (from['class'].split(' ') | to['class'].split(' ')).join(' ') | ||||
| a76b25d1 » | nex3 | 2008-01-10 | 191 | elsif to['class'] || from['class'] | |
| 192 | from['class'] ||= to['class'] | ||||
| 0141a596 » | nex3 | 2007-06-06 | 193 | end | |
| 194 | |||||
| 195 | to.merge!(from) | ||||
| 196 | end | ||||
| 197 | |||||
| a241cd4e » | nex3 | 2008-04-24 | 198 | private | |
| 199 | |||||
| aeade6a6 » | nex3 | 2007-03-15 | 200 | # Some of these methods are exposed as public class methods | |
| 201 | # so they can be re-used in helpers. | ||||
| 202 | |||||
| 8509286a » | nex3 | 2007-05-08 | 203 | @@tab_cache = {} | |
| 89a10b9d » | hcatlin | 2006-10-14 | 204 | # Gets <tt>count</tt> tabs. Mostly for internal use. | |
| e5dedfa6 » | nex3 | 2008-05-09 | 205 | def tabs(count = 0) | |
| 6f610190 » | nex3 | 2008-06-06 | 206 | tabs = [count + @tabulation, 0].max | |
| 8509286a » | nex3 | 2007-05-08 | 207 | @@tab_cache[tabs] ||= ' ' * tabs | |
| 89a10b9d » | hcatlin | 2006-10-14 | 208 | end | |
| 00ef3f99 » | nex3 | 2006-11-03 | 209 | ||
| 89a10b9d » | hcatlin | 2006-10-14 | 210 | # Takes an array of objects and uses the class and id of the first | |
| 211 | # one to create an attributes hash. | ||||
| 15332d55 » | stefanoc | 2008-04-09 | 212 | # The second object, if present, is used as a prefix, | |
| 213 | # just like you can do with dom_id() and dom_class() in Rails | ||||
| 0141a596 » | nex3 | 2007-06-06 | 214 | def parse_object_ref(ref) | |
| 15332d55 » | stefanoc | 2008-04-09 | 215 | prefix = ref[1] | |
| 89a10b9d » | hcatlin | 2006-10-14 | 216 | ref = ref[0] | |
| 4158db05 » | hcatlin | 2006-11-05 | 217 | # Let's make sure the value isn't nil. If it is, return the default Hash. | |
| 218 | return {} if ref.nil? | ||||
| 18c7df96 » | nex3 | 2007-03-30 | 219 | class_name = underscore(ref.class) | |
| d30629a9 » | nex3 | 2007-04-16 | 220 | id = "#{class_name}_#{ref.id || 'new'}" | |
| 15332d55 » | stefanoc | 2008-04-09 | 221 | if prefix | |
| 222 | class_name = "#{ prefix }_#{ class_name}" | ||||
| 223 | id = "#{ prefix }_#{ id }" | ||||
| 224 | end | ||||
| a234dafb » | nex3 | 2007-02-03 | 225 | ||
| d7030e9c » | nex3 | 2007-06-02 | 226 | {'id' => id, 'class' => class_name} | |
| 89a10b9d » | hcatlin | 2006-10-14 | 227 | end | |
| 00ef3f99 » | nex3 | 2006-11-03 | 228 | ||
| 18c7df96 » | nex3 | 2007-03-30 | 229 | # Changes a word from camel case to underscores. | |
| 230 | # Based on the method of the same name in Rails' Inflector, | ||||
| 231 | # but copied here so it'll run properly without Rails. | ||||
| 232 | def underscore(camel_cased_word) | ||||
| 233 | camel_cased_word.to_s.gsub(/::/, '_'). | ||||
| 234 | gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2'). | ||||
| 235 | gsub(/([a-z\d])([A-Z])/,'\1_\2'). | ||||
| 236 | tr("-", "_"). | ||||
| 237 | downcase | ||||
| 238 | end | ||||
| 89a10b9d » | hcatlin | 2006-10-14 | 239 | end | |
| 240 | end | ||||








