Skip to content

Commit

Permalink
Sticky components experiment (#70)
Browse files Browse the repository at this point in the history
* Sticky components experiment

* Call will_mount before render

* Differed init + update + lifecycle 'hooks' (#71)

* Differred init + update + lifecycle 'hooks'

* make initialize call update by default

* Remove callbacks per Dr. Ian Malcolm

* Swap back to the render class method

This commit also adds a warning if you use .new instead of .render

* Make sure to always render when using instances

* Add sticky wrapper

* Switch to MemoizedComponent

* Fix spec by passing a real Renderable

* Remove test knowledge of BlackBoxNode::Renderable

* Remove a bunch of WIP experiments
  • Loading branch information
jgaskins authored May 30, 2017
1 parent 2cfef46 commit bb82bdf
Show file tree
Hide file tree
Showing 6 changed files with 93 additions and 7 deletions.
15 changes: 14 additions & 1 deletion opal/clearwater/black_box_node.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,15 @@ def render
Renderable.new(self)
end

def key
end

class Renderable
def initialize delegate
@delegate = delegate
if delegate.key
@key = delegate.key
end
end

def wrap node
Expand Down Expand Up @@ -52,7 +58,14 @@ def create_element
// node: a Bowser-wrapped version of the DOM node
Opal.defn(self, 'update', function(previous, node) {
var self = this;
#{@delegate.update(`previous.delegate`, wrap(`node`))};
if(self.delegate.$$class === previous.delegate.$$class) {
#{@delegate.update(`previous.delegate`, wrap(`node`))};
} else {
previous.destroy(#{wrap(`node`)});
var new_node = #{create_element};
#{@delegate.mount(`new_node`)};
return new_node.native;
}
});
// virtual-dom destroy hook
Expand Down
1 change: 0 additions & 1 deletion opal/clearwater/cached_render.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ def should_render? _
end

def key
`undefined`
end
end
end
2 changes: 1 addition & 1 deletion opal/clearwater/cached_render/wrapper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ class Wrapper

def initialize content
@content = content
@key = content.key
@key = content.key if content.key
end

# Hook into vdom diff/patch
Expand Down
75 changes: 75 additions & 0 deletions opal/clearwater/memoized_component.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
require 'clearwater/component'
require 'clearwater/black_box_node'

module Clearwater
class MemoizedComponent
include Clearwater::Component

def self.memoize *args, &block
Placeholder.new(self, args, block)
end

def self.[] key
memoize[key]
end

def update
end

def destroy
end

class Placeholder
include Clearwater::BlackBoxNode

attr_reader :klass, :key, :vdom

def initialize klass, args, block
@klass = klass
@args = args
@block = block
end

def memoize *args, &block
initialize @klass, args, block
self
end

def [] key
@key = key.to_s
self
end

def component
@component ||= @klass.new(*@args, &@block)
end

def node
@node ||= Clearwater::Component.sanitize_content(component)
end

def mount element
@vdom = VirtualDOM::Document.new(element)

# TODO: add a public interface to generate a pre-initialized VDOM::Doc
`#@vdom.tree = #{element.to_n}`
`#@vdom.node = #{node}`
`#@vdom.rendered = true`
end

def update previous
@vdom = previous.vdom
@component = previous.component

if component.should_update?(*@args, &@block)
component.update(*@args, &@block)
@vdom.render component.render
end
end

def unmount
component.destroy
end
end
end
end
2 changes: 1 addition & 1 deletion opal/clearwater/virtual_dom.rb
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ def self.sanitize_content content
end

class Document
def initialize(root=Bowser.document.create_element('div'))
def initialize(root=Bowser.document.create_element(:div))
@root = root
end

Expand Down
5 changes: 2 additions & 3 deletions spec-opal/clearwater/black_box_node_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ def mounted?
end
end.new
}
let(:renderable) { BlackBoxNode::Renderable.new(object) }
let(:renderable) { object.render }

it 'has the special type of "Widget"' do
r = renderable
Expand All @@ -55,8 +55,7 @@ def mounted?
end

it 'calls update when updated in the DOM' do
r = renderable
`r.update({})`
`#{renderable}.update(#{renderable.dup})`

expect(object.last_update).not_to be_nil
end
Expand Down

0 comments on commit bb82bdf

Please sign in to comment.