module Loofah # # Mixes +scrub!+ into Document, DocumentFragment, Node and NodeSet. # # Traverse the document or fragment, invoking the +scrubber+ on # each node. # # +scrubber+ must either be one of the symbols representing the # built-in scrubbers (see Scrubbers), or a Scrubber instance. # # span2div = Loofah::Scrubber.new do |node| # node.name = "div" if node.name == "span" # end # Loofah.fragment("foo

bar

").scrub!(span2div).to_s # # => "
foo

bar

" # # or # # unsafe_html = "ohai!
div is safe
" # Loofah.fragment(unsafe_html).scrub!(:strip).to_s # # => "ohai!
div is safe
" # # Note that this method is called implicitly from # Loofah.scrub_fragment and Loofah.scrub_document. # # Please see Scrubber for more information on implementation and traversal, and # README.rdoc for more example usage. # module ScrubBehavior # see Loofah::ScrubBehavior module Node def scrub!(scrubber) # # yes. this should be three separate methods. but nokogiri # decorates (or not) based on whether the module name has # already been included. and since documents get decorated # just like their constituent nodes, we need to jam all the # logic into a single module. # scrubber = ScrubBehavior.resolve_scrubber(scrubber) case self when Nokogiri::XML::Document scrubber.traverse(root) if root when Nokogiri::XML::DocumentFragment children.each { |node| node.scrub!(scrubber) } # TODO: children.scrub! once Nokogiri 1.4.2 is out else scrubber.traverse(self) end self end end # see Loofah::ScrubBehavior module NodeSet def scrub!(scrubber) each { |node| node.scrub!(scrubber) } self end end def ScrubBehavior.resolve_scrubber(scrubber) # :nodoc: scrubber = Scrubbers::MAP[scrubber].new if Scrubbers::MAP[scrubber] unless scrubber.is_a?(Loofah::Scrubber) raise Loofah::ScrubberNotFound, "not a Scrubber or a scrubber name: #{scrubber.inspect}" end scrubber end end module DocumentDecorator # :nodoc: def initialize(*args, &block) super self.decorators(Nokogiri::XML::Node) << ScrubBehavior::Node self.decorators(Nokogiri::XML::NodeSet) << ScrubBehavior::NodeSet end end end