lib/nitro/mixin/javascript.rb in nitro-0.23.0 vs lib/nitro/mixin/javascript.rb in nitro-0.24.0

- old
+ new

@@ -26,15 +26,19 @@ # :section: behaviour.js def behaviour(id, js) @_behaviours ||= [] @_behaviours << [id, js] + return nil end # :section: prototype.js def live_request(id, options = {}) + __append_script_file__ 'js/behaviour.js' + __append_script_file__ 'js/prototype.js' + if href = options.delete(:href) behaviour "##{id}", %{ el.onclick = function() { new Ajax.Request('#{href}', #{hash_to_js(options)}); return false; @@ -46,52 +50,172 @@ new Ajax.Request(el.href, #{hash_to_js(options)}); return false; } } end + return nil end alias_method :live, :live_request alias_method :async, :live_request # :section: script.aculo.us dragdrop.js # Make the element dragable. def draggable(id, options = {}) - @_javascript ||= '' - @_javascript << "\nnew Draggable('#{id}', #{hash_to_js(options)});" + __append_script_file__ 'js/behaviour.js' + __append_script_file__ 'js/prototype.js' + __append_script_file__ 'js/effects.js' + __append_script_file__ 'js/dragdrop.js' + + __append_script__ "\nnew Draggable('#{id}', #{hash_to_js(options)});" + return nil end # :section: script.aculo.us controls.js # Add autocomplete functionality to a text field. def auto_complete(id, options = {}) update = options[:update] || "#{id}_auto_complete" url = options[:url] || "#{id}_auto_complete" - @_javascript ||= '' - @_javascript << "\nnew Ajax.Autocompleter('#{id}', '#{update}', '#{url}');" + + __append_script_file__ 'js/behaviour.js' + __append_script_file__ 'js/prototype.js' + __append_script_file__ 'js/effects.js' + __append_script_file__ 'js/controls.js' + __append_script__ "\nnew Ajax.Autocompleter('#{id}', '#{update}', '#{url}');" + # Turn off the browser's autocomplete functionality to avoid # interference. behaviour "##{id}", %{ el.autocomplete = 'off'; } + return nil end + # :section: styling. + + # Style border. + + def style_border + end + + # Round element corners using the nifty corners technique. + + def round_corners(id, options = {}) + o = { + :bg => '#fff', + :fg => '#ccc', + }.update(options) + + __append_script_file__ 'js/prototype.js' + __append_script_file__ 'js/round.js' + + __append_script__ %{ + Box.round('#{id}', '#{o[:fg]}', '#{o[:bg]}'); + } + + __append_css__ %{ + .rtop,.rbottom{display:block} + .rtop *,.rbottom *{display:block;height: 1px;overflow: hidden} + .r1{margin: 0 5px} + .r2{margin: 0 3px} + .r3{margin: 0 2px} + .r4{margin: 0 1px;height: 2px} + } + + return nil + end + + # Generalized border decoration. + + def decorate_borders(options = {}) + o = { + :bg => '#fff', + :fg => '#ccc', + :klass => 'w' + }.update(options) + + klass = o[:klass] + + __append_script_file__ 'js/prototype.js' + __append_script_file__ 'js/styler.js' + + __append_script__ %{ + decorateBorders('#{klass}'); + } + + __append_css__ %{ + .#{klass}t { + background: #{o[:bg]}; + background-image: url(m/#{klass}t.gif); + background-repeat: repeat-x; + background-position: top; + } + .#{klass}r { + background-image: url(m/#{klass}r.gif); + background-repeat: repeat-y; + background-position: right; + } + .#{klass}b { + background-image: url(m/#{klass}b.gif); + background-repeat: repeat-x; + background-position: bottom; + } + .#{klass}l { + background-image: url(m/#{klass}l.gif); + background-repeat: repeat-y; + background-position: left; + } + .#{klass}tl { + background-image: url(m/#{klass}tl.gif); + background-repeat: no-repeat; + background-position: top left; + } + .#{klass}tr { + background-image: url(m/#{klass}tr.gif); + background-repeat: no-repeat; + background-position: top right; + } + .#{klass}bl { + background-image: url(m/#{klass}bl.gif); + background-repeat: no-repeat; + background-position: bottom left; + } + .#{klass}br { + background-image: url(m/#{klass}br.gif); + background-repeat: no-repeat; + background-position: bottom right; + } + .#{klass}c { + padding: 25px; + } + } + + return nil + end + # :section: general javascript helpers. # Include external javascript file. - def include_script(files = DEFAULT_JAVASCRIPT_FILES) + def include_script(*files) + return if @_script_files.nil? and files.empty? + code = '' + + for file in files + code << %|<script src="#{file}" type="text/javascript">//</script>\n| + end if files + + for file in @_script_files + code << %|<script src="#{file}" type="text/javascript">//</script>\n| + end if @_script_files - for file in [files].flatten - code << %|<script src="#{file}" type="text/javascript">//</script>| - end - return code end # Escape carrier returns and single and double quotes for JavaScript segments. @@ -103,16 +227,24 @@ def hash_to_js(options) '{' + options.map {|k, v| "#{k}:#{v}"}.join(', ') + '}' end + # Emits the aggregated css. + + def emit_css + return unless @_css + %{<style>#{@_css.join("\n")}</style>} + end + alias_method :helper_css, :emit_css + # Emits the aggregated helper javascript. #-- # FIXME: refactor this! #++ - def helper_script + def emit_script code = %|<script type="text/javascript">\n| unless @_behaviours.empty? code << %|var _behaviours = {\n| compo = [] for id, js in @_behaviours @@ -123,14 +255,41 @@ } Behaviour.register(_behaviours); | end code << %| - #@_javascript + #{@_script.join("\n")} + | if @_script + code << %| </script> | end + alias_method :helper_script, :emit_script + + # ... + def js_distance_of_time_in_words(time) + time = time.utc.strftime("%a, %d %b %Y %H:%M:%S GMT") + %|<span class="human_time" title="#{time}">#{time}</span>| + end + + # :section: internal helpers. + + def __append_script_file__(file) + @_script_files ||= [] + @_script_files << file unless @_script_files.include?(file) + end + + def __append_script__(script) + @_script ||= [] + @_script << script unless @_script.include?(script) + end + + def __append_css__(css) + @_css ||= [] + @_css << css unless @_css.include?(css) + end + end end # * George Moschovitis <gm@navel.gr>