From 180e9cfb9929eeadb58aa9c6732abea5c1274c5c Mon Sep 17 00:00:00 2001 From: Julian Rubisch Date: Wed, 13 Jul 2022 11:44:20 +0200 Subject: [PATCH 1/3] chore: Extract StimulusReflex::Fragment class --- lib/stimulus_reflex.rb | 3 +-- .../broadcasters/page_broadcaster.rb | 9 ++++---- .../broadcasters/selector_broadcaster.rb | 4 ++-- lib/stimulus_reflex/fragment.rb | 22 +++++++++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) create mode 100644 lib/stimulus_reflex/fragment.rb diff --git a/lib/stimulus_reflex.rb b/lib/stimulus_reflex.rb index 6b39bc93..d94014cf 100644 --- a/lib/stimulus_reflex.rb +++ b/lib/stimulus_reflex.rb @@ -1,5 +1,3 @@ -# frozen_string_literal: true - require "uri" require "open-uri" require "rack" @@ -15,6 +13,7 @@ require "stimulus_reflex/concern_enhancer" require "stimulus_reflex/configuration" require "stimulus_reflex/callbacks" +require "stimulus_reflex/fragment" require "stimulus_reflex/request_parameters" require "stimulus_reflex/reflex" require "stimulus_reflex/reflex_data" diff --git a/lib/stimulus_reflex/broadcasters/page_broadcaster.rb b/lib/stimulus_reflex/broadcasters/page_broadcaster.rb index ab182aaf..80227e5d 100644 --- a/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +++ b/lib/stimulus_reflex/broadcasters/page_broadcaster.rb @@ -4,15 +4,14 @@ module StimulusReflex class PageBroadcaster < Broadcaster def broadcast(selectors, data) reflex.controller.process reflex.params[:action] - page_html = reflex.controller.response.body + fragment = StimulusReflex::Fragment.new(reflex.controller.response.body) - return unless page_html.present? + return if fragment.empty? - document = Nokogiri::HTML.parse(page_html) - selectors = selectors.select { |s| document.css(s).present? } + selectors = selectors.select { |s| fragment.match(s).present? } selectors.each do |selector| operations << [selector, :morph] - html = document.css(selector).inner_html(save_with: Broadcaster::DEFAULT_HTML_WITHOUT_FORMAT) + html = fragment.match(selector).inner_html(save_with: Broadcaster::DEFAULT_HTML_WITHOUT_FORMAT) cable_ready.morph( selector: selector, html: html, diff --git a/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb b/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb index 3fd1769f..72188df4 100644 --- a/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +++ b/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb @@ -7,8 +7,8 @@ def broadcast(_, data = {}) selectors, html = morph updates = create_update_collection(selectors, html) updates.each do |update| - fragment = Nokogiri::HTML.fragment(update.html.to_s) - match = fragment.at_css(update.selector) + fragment = StimulusReflex::Fragment.new(update.html) + match = fragment.match(update.selector) if match.present? operations << [update.selector, :morph] cable_ready.morph( diff --git a/lib/stimulus_reflex/fragment.rb b/lib/stimulus_reflex/fragment.rb new file mode 100644 index 00000000..7881e9c9 --- /dev/null +++ b/lib/stimulus_reflex/fragment.rb @@ -0,0 +1,22 @@ +# frozen_string_literal: true + +module StimulusReflex + class Fragment + delegate :to_html, to: :"@fragment" + + def initialize(html) + @fragment = Nokogiri::HTML.fragment(html.to_s) + @matches = { + "body" => @fragment + } + end + + def empty? + @fragment.content.empty? + end + + def match(selector) + @matches[selector] ||= @fragment.at_css(selector) + end + end +end From e5330255ccd16999f660a9c304aaece3e42bd0c0 Mon Sep 17 00:00:00 2001 From: Julian Rubisch Date: Wed, 13 Jul 2022 11:48:09 +0200 Subject: [PATCH 2/3] chore: Extract separate Match struct --- lib/stimulus_reflex/broadcasters/page_broadcaster.rb | 2 +- .../broadcasters/selector_broadcaster.rb | 2 +- lib/stimulus_reflex/fragment.rb | 12 ++++++++++-- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/lib/stimulus_reflex/broadcasters/page_broadcaster.rb b/lib/stimulus_reflex/broadcasters/page_broadcaster.rb index 80227e5d..ad81e311 100644 --- a/lib/stimulus_reflex/broadcasters/page_broadcaster.rb +++ b/lib/stimulus_reflex/broadcasters/page_broadcaster.rb @@ -11,7 +11,7 @@ def broadcast(selectors, data) selectors = selectors.select { |s| fragment.match(s).present? } selectors.each do |selector| operations << [selector, :morph] - html = fragment.match(selector).inner_html(save_with: Broadcaster::DEFAULT_HTML_WITHOUT_FORMAT) + html = fragment.match(selector).to_html cable_ready.morph( selector: selector, html: html, diff --git a/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb b/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb index 72188df4..91cd172b 100644 --- a/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb +++ b/lib/stimulus_reflex/broadcasters/selector_broadcaster.rb @@ -13,7 +13,7 @@ def broadcast(_, data = {}) operations << [update.selector, :morph] cable_ready.morph( selector: update.selector, - html: match.inner_html(save_with: Broadcaster::DEFAULT_HTML_WITHOUT_FORMAT), + html: match.to_html, payload: payload, children_only: true, permanent_attribute_name: permanent_attribute_name, diff --git a/lib/stimulus_reflex/fragment.rb b/lib/stimulus_reflex/fragment.rb index 7881e9c9..8e873e95 100644 --- a/lib/stimulus_reflex/fragment.rb +++ b/lib/stimulus_reflex/fragment.rb @@ -7,7 +7,7 @@ class Fragment def initialize(html) @fragment = Nokogiri::HTML.fragment(html.to_s) @matches = { - "body" => @fragment + "body" => Match.new(@fragment) } end @@ -16,7 +16,15 @@ def empty? end def match(selector) - @matches[selector] ||= @fragment.at_css(selector) + @matches[selector] ||= Match.new(@fragment.at_css(selector)) + end + + Match = Struct.new(:element) do + delegate :present?, to: :element + + def to_html + element&.inner_html(save_with: Broadcaster::DEFAULT_HTML_WITHOUT_FORMAT) + end end end end From 3db17f2fa61301f92f8ad897244bc3222afa2bde Mon Sep 17 00:00:00 2001 From: Julian Rubisch Date: Wed, 13 Jul 2022 11:49:21 +0200 Subject: [PATCH 3/3] lint: Standardize --- lib/stimulus_reflex/fragment.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/stimulus_reflex/fragment.rb b/lib/stimulus_reflex/fragment.rb index 8e873e95..bf4c606e 100644 --- a/lib/stimulus_reflex/fragment.rb +++ b/lib/stimulus_reflex/fragment.rb @@ -2,7 +2,7 @@ module StimulusReflex class Fragment - delegate :to_html, to: :"@fragment" + delegate :to_html, to: :@fragment def initialize(html) @fragment = Nokogiri::HTML.fragment(html.to_s)