Skip to content

Commit

Permalink
Remove selective rendering (#838)
Browse files Browse the repository at this point in the history
Thought I’d open this up so we can look at what exactly it would involve
to remove selective rendering.

Closes #836
  • Loading branch information
joeldrapper authored Feb 3, 2025
1 parent 170fb27 commit 19a9271
Show file tree
Hide file tree
Showing 5 changed files with 15 additions and 200 deletions.
33 changes: 2 additions & 31 deletions lib/phlex/context.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,53 +6,24 @@ def initialize(user_context: {}, view_context: nil)
@buffer = +""
@capturing = false
@user_context = user_context
@fragments = nil
@in_target_fragment = false
@halt_signal = nil
@view_context = view_context
end

attr_accessor :buffer, :capturing, :user_context, :in_target_fragment
attr_accessor :buffer, :capturing, :user_context

attr_reader :fragments, :view_context

def target_fragments(fragments)
@fragments = fragments.to_h { |it| [it, true].freeze }
end

def around_render
return yield if !@fragments || @halt_signal

catch do |signal|
@halt_signal = signal
yield
end
end

def begin_target(id)
@in_target_fragment = id
end

def end_target
@fragments.delete(@in_target_fragment)
@in_target_fragment = false
throw @halt_signal if @fragments.length == 0
end
attr_reader :view_context

def capturing_into(new_buffer)
original_buffer = @buffer
original_capturing = @capturing
original_fragments = @fragments

begin
@buffer = new_buffer
@capturing = true
@fragments = nil
yield
ensure
@buffer = original_buffer
@capturing = original_capturing
@fragments = original_fragments
end

new_buffer
Expand Down
1 change: 0 additions & 1 deletion lib/phlex/html.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ class Phlex::HTML < Phlex::SGML
# Output an HTML doctype.
def doctype
context = @_context
return if context.fragments && !context.in_target_fragment

context.buffer << "<!doctype html>"
nil
Expand Down
39 changes: 13 additions & 26 deletions lib/phlex/sgml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -56,44 +56,38 @@ def to_proc
proc { |c| c.render(self) }
end

def call(buffer = +"", context: {}, view_context: nil, parent: nil, fragments: nil, &block)
def call(buffer = +"", context: {}, view_context: nil, parent: nil, &block)
@_buffer = buffer
@_context = phlex_context = parent&.__context__ || Phlex::Context.new(user_context: context, view_context:)
@_parent = parent

raise Phlex::DoubleRenderError.new("You can't render a #{self.class.name} more than once.") if @_rendered
@_rendered = true

if fragments
phlex_context.target_fragments(fragments)
end

block ||= @_content_block

return "" unless render?

Thread.current[:__phlex_component__] = [self, Fiber.current.object_id].freeze

phlex_context.around_render do
before_template(&block)
before_template(&block)

around_template do
if block
view_template do |*args|
if args.length > 0
__yield_content_with_args__(*args, &block)
else
__yield_content__(&block)
end
around_template do
if block
view_template do |*args|
if args.length > 0
__yield_content_with_args__(*args, &block)
else
__yield_content__(&block)
end
else
view_template
end
else
view_template
end

after_template(&block)
end

after_template(&block)

unless parent
buffer << phlex_context.buffer
end
Expand All @@ -119,7 +113,6 @@ def plain(content)
# Output a single space character. If a block is given, a space will be output before and after the block.
def whitespace(&)
context = @_context
return if context.fragments && !context.in_target_fragment

buffer = context.buffer

Expand All @@ -138,7 +131,6 @@ def whitespace(&)
# [MDN Docs](https://developer.mozilla.org/en-US/docs/Web/HTML/Comments)
def comment(&)
context = @_context
return if context.fragments && !context.in_target_fragment

buffer = context.buffer

Expand All @@ -154,7 +146,6 @@ def raw(content)
case content
when Phlex::SGML::SafeObject
context = @_context
return if context.fragments && !context.in_target_fragment

context.buffer << content.to_s
when nil, "" # do nothing
Expand Down Expand Up @@ -234,7 +225,6 @@ def render(renderable = nil, &)
# ```
def cache(*cache_key, **options, &content)
context = @_context
return if context.fragments && !context.in_target_fragment

location = caller_locations(1, 1)[0]

Expand Down Expand Up @@ -263,7 +253,6 @@ def cache(*cache_key, **options, &content)
# If you need to pass multiple cache keys, you should pass an array.
def low_level_cache(cache_key, **options, &content)
context = @_context
return if context.fragments && !context.in_target_fragment

context.buffer << cache_store.fetch(cache_key, **options) { capture(&content) }
end
Expand Down Expand Up @@ -351,7 +340,6 @@ def __yield_content_with_args__(*a)

def __implicit_output__(content)
context = @_context
return true if context.fragments && !context.in_target_fragment

case content
when Phlex::SGML::SafeObject
Expand All @@ -376,7 +364,6 @@ def __implicit_output__(content)
# same as __implicit_output__ but escapes even `safe` objects
def __text__(content)
context = @_context
return true if context.fragments && !context.in_target_fragment

case content
when String
Expand Down
38 changes: 0 additions & 38 deletions lib/phlex/sgml/elements.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,8 @@ def register_element(method_name, tag: method_name.name.tr("_", "-"))
def #{method_name}(**attributes)
context = @_context
buffer = context.buffer
fragment = context.fragments
target_found = false
block_given = block_given?
if fragment
return if fragment.length == 0 # we found all our fragments already
id = attributes[:id]
if !context.in_target_fragment
if fragment[id]
context.begin_target(id)
target_found = true
else
yield(self) if block_given
return nil
end
end
end
if attributes.length > 0 # with attributes
if block_given # with content block
buffer << "<#{tag}" << (Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
Expand Down Expand Up @@ -90,8 +72,6 @@ def #{method_name}(**attributes)
#{'flush' if tag == 'head'}
context.end_target if target_found
nil
end
RUBY
Expand All @@ -108,31 +88,13 @@ def __register_void_element__(method_name, tag: method_name.name.tr("_", "-"))
def #{method_name}(**attributes)
context = @_context
buffer = context.buffer
fragment = context.fragments
if fragment
return if fragment.length == 0 # we found all our fragments already
id = attributes[:id]
if !context.in_target_fragment
if fragment[id]
context.begin_target(id)
target_found = true
else
return nil
end
end
end
if attributes.length > 0 # with attributes
buffer << "<#{tag}" << (::Phlex::ATTRIBUTE_CACHE[attributes] ||= __attributes__(attributes)) << ">"
else # without attributes
buffer << "<#{tag}>"
end
context.end_target if target_found
nil
end
Expand Down
104 changes: 0 additions & 104 deletions quickdraw/sgml/selective_rendering.test.rb

This file was deleted.

0 comments on commit 19a9271

Please sign in to comment.