mirror of
https://github.com/haml/haml.git
synced 2022-11-09 12:33:31 -05:00
[Sass] Add some callback infrastructure.
This commit is contained in:
parent
6248ca3721
commit
4987a5cb0d
4 changed files with 142 additions and 0 deletions
50
lib/sass/callbacks.rb
Normal file
50
lib/sass/callbacks.rb
Normal file
|
@ -0,0 +1,50 @@
|
|||
# A lightweight infrastructure for defining and running callbacks.
|
||||
# Callbacks are defined using \{#define\_callback\} at the class level,
|
||||
# and called using `run_#{name}` at the instance level.
|
||||
#
|
||||
# Clients can add callbacks by calling the generated `on_#{name}` method,
|
||||
# and passing in a block that's run when the callback is activated.
|
||||
#
|
||||
# @example Define a callback
|
||||
# class Munger
|
||||
# extend Sass::Callbacks
|
||||
# define_callback :string_munged
|
||||
#
|
||||
# def munge(str)
|
||||
# res = str.gsub(/[a-z]/, '\1\1')
|
||||
# run_string_munged str, res
|
||||
# res
|
||||
# end
|
||||
# end
|
||||
#
|
||||
# @example Use a callback
|
||||
# m = Munger.new
|
||||
# m.on_string_munged {|str, res| puts "#{str} was munged into #{res}!"}
|
||||
# m.munge "bar" #=> bar was munged into bbaarr!
|
||||
module Sass::Callbacks
|
||||
protected
|
||||
|
||||
# Define a callback with the given name.
|
||||
# This will define an `on_#{name}` method
|
||||
# that registers a block,
|
||||
# and a `run_#{name}` method that runs that block
|
||||
# (optionall with some arguments).
|
||||
#
|
||||
# @param name [Symbol] The name of the callback
|
||||
# @return [void]
|
||||
def define_callback(name)
|
||||
class_eval <<RUBY
|
||||
def on_#{name}(&block)
|
||||
@_sass_callbacks ||= {}
|
||||
(@_sass_callbacks[#{name.inspect}] ||= []) << block
|
||||
end
|
||||
|
||||
def run_#{name}(*args)
|
||||
return unless @_sass_callbacks
|
||||
return unless @_sass_callbacks[#{name.inspect}]
|
||||
@_sass_callbacks[#{name.inspect}].each {|c| c[*args]}
|
||||
end
|
||||
private :run_#{name}
|
||||
RUBY
|
||||
end
|
||||
end
|
|
@ -1,6 +1,7 @@
|
|||
require 'fileutils'
|
||||
|
||||
require 'sass'
|
||||
require 'sass/callbacks'
|
||||
|
||||
module Sass
|
||||
# This module handles the compilation of Sass files.
|
||||
|
@ -14,6 +15,7 @@ module Sass
|
|||
# Other frameworks must enable it explicitly; see {Sass::Plugin::Rack}.
|
||||
module Plugin
|
||||
include Haml::Util
|
||||
include Sass::Callbacks
|
||||
extend self
|
||||
|
||||
@options = {
|
||||
|
|
61
test/sass/callbacks_test.rb
Executable file
61
test/sass/callbacks_test.rb
Executable file
|
@ -0,0 +1,61 @@
|
|||
#!/usr/bin/env ruby
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'sass/callbacks'
|
||||
|
||||
class CallerBack
|
||||
extend Sass::Callbacks
|
||||
define_callback :foo
|
||||
define_callback :bar
|
||||
|
||||
def do_foo
|
||||
run_foo
|
||||
end
|
||||
|
||||
def do_bar
|
||||
run_bar 12
|
||||
end
|
||||
end
|
||||
|
||||
module ClassLevelCallerBack
|
||||
extend Sass::Callbacks
|
||||
define_callback :foo
|
||||
extend self
|
||||
|
||||
def do_foo
|
||||
run_foo
|
||||
end
|
||||
end
|
||||
|
||||
class SassCallbacksTest < Test::Unit::TestCase
|
||||
def test_simple_callback
|
||||
cb = CallerBack.new
|
||||
there = false
|
||||
cb.on_foo {there = true}
|
||||
cb.do_foo
|
||||
assert there, "Expected callback to be called."
|
||||
end
|
||||
|
||||
def test_multiple_callbacks
|
||||
cb = CallerBack.new
|
||||
str = ""
|
||||
cb.on_foo {str += "first"}
|
||||
cb.on_foo {str += " second"}
|
||||
cb.do_foo
|
||||
assert_equal "first second", str
|
||||
end
|
||||
|
||||
def test_callback_with_arg
|
||||
cb = CallerBack.new
|
||||
val = nil
|
||||
cb.on_bar {|a| val = a}
|
||||
cb.do_bar
|
||||
assert_equal 12, val
|
||||
end
|
||||
|
||||
def test_class_level_callback
|
||||
there = false
|
||||
ClassLevelCallerBack.on_foo {there = true}
|
||||
ClassLevelCallerBack.do_foo
|
||||
assert there, "Expected callback to be called."
|
||||
end
|
||||
end
|
29
yard/callbacks.rb
Normal file
29
yard/callbacks.rb
Normal file
|
@ -0,0 +1,29 @@
|
|||
class CallbacksHandler < YARD::Handlers::Ruby::Legacy::Base
|
||||
handles /\Adefine_callback(\s|\()/
|
||||
|
||||
def process
|
||||
callback_name = tokval(statement.tokens[2])
|
||||
attr_index = statement.comments.each_with_index {|c, i| break i if c[0] == ?@}
|
||||
if attr_index.is_a?(Fixnum)
|
||||
docstring = statement.comments[0...attr_index]
|
||||
attrs = statement.comments[attr_index..-1]
|
||||
else
|
||||
docstring = statement.comments
|
||||
attrs = []
|
||||
end
|
||||
|
||||
yieldparams = ""
|
||||
attrs.reject! do |a|
|
||||
next unless a =~ /^@yield *(\[.*?\])/
|
||||
yieldparams = $1
|
||||
true
|
||||
end
|
||||
|
||||
o = register(MethodObject.new(namespace, "on_#{callback_name}", scope))
|
||||
o.docstring = docstring + [
|
||||
"@return [void]",
|
||||
"@yield #{yieldparams} When the callback is run"
|
||||
] + attrs
|
||||
o.signature = true
|
||||
end
|
||||
end
|
Loading…
Add table
Reference in a new issue