Class: Goat::Component
Instance Attribute Summary collapse
-
#handlers ⇒ Object
readonly
Returns the value of attribute handlers.
-
#id ⇒ Object
readonly
Returns the value of attribute id.
-
#initargs ⇒ Object
readonly
Returns the value of attribute initargs.
-
#page ⇒ Object
readonly
Returns the value of attribute page.
-
#params ⇒ Object
readonly
Returns the value of attribute params.
-
#parent ⇒ Object
Returns the value of attribute parent.
Class Method Summary collapse
- .__css ⇒ Object
- .__script ⇒ Object
- .clientside(js) ⇒ Object
- .css(css) ⇒ Object
- .from_skel(skel) ⇒ Object
- .get_rpc(name, opts = {}, &blk) ⇒ Object
- .live_enabled ⇒ Object
- .live_enabled? ⇒ Boolean
- .live_rpc(name, opts = {}, &blk) ⇒ Object
- .rerender(skel) ⇒ Object
- .rerender_and_update(spec) ⇒ Object
- .rerender_and_update_inner(to_process) ⇒ Object
- .rpc(name, opts = {}, &blk) ⇒ Object
- .scope_css(css, prefix, dot_or_hash) ⇒ Object
- .scoped_css ⇒ Object
- .script(script) ⇒ Object
- .wired? ⇒ Boolean
Instance Method Summary collapse
- #__css ⇒ Object
- #__script ⇒ Object
- #_dom ⇒ Object
- #clientside_args ⇒ Object
- #clientside_instance ⇒ Object
- #component(body) ⇒ Object
- #component_name_hierarchy(cls = self.class) ⇒ Object
- #css(css) ⇒ Object
- #deserialize(state) ⇒ Object
- #dom_as_expanded ⇒ Object
- #dom_html(dom) ⇒ Object
- #erb(*args, &blk) ⇒ Object
- #expanded_dom ⇒ Object
-
#initialize ⇒ Component
constructor
A new instance of Component.
- #inject_prefixes(dom) ⇒ Object
- #live_enabled? ⇒ Boolean
- #live_for(spec) ⇒ Object
- #live_spec ⇒ Object
- #load_skel(skel) ⇒ Object
- #model_changed(item, notif) ⇒ Object
- #partial_erb(*args, &blk) ⇒ Object
- #pgid=(id) ⇒ Object
- #register_callback(callback) ⇒ Object
- #rerender ⇒ Object
- #rerender_fully(cs) ⇒ Object
- #rerender_partially(diff) ⇒ Object
- #scoped_css ⇒ Object
- #script(script) ⇒ Object
- #serialize ⇒ Object
- #skel ⇒ Object
- #update ⇒ Object
- #wire_script ⇒ Object
Methods included from HTMLHelpers
Constructor Details
Instance Attribute Details
#handlers ⇒ Object (readonly)
Returns the value of attribute handlers.
1122 1123 1124 |
# File 'lib/goat.rb', line 1122 def handlers @handlers end |
#id ⇒ Object (readonly)
Returns the value of attribute id.
1122 1123 1124 |
# File 'lib/goat.rb', line 1122 def id @id end |
#initargs ⇒ Object (readonly)
Returns the value of attribute initargs.
1122 1123 1124 |
# File 'lib/goat.rb', line 1122 def initargs @initargs end |
#page ⇒ Object (readonly)
Returns the value of attribute page.
1122 1123 1124 |
# File 'lib/goat.rb', line 1122 def page @page end |
#params ⇒ Object (readonly)
Returns the value of attribute params.
1122 1123 1124 |
# File 'lib/goat.rb', line 1122 def params @params end |
#parent ⇒ Object
Returns the value of attribute parent.
1123 1124 1125 |
# File 'lib/goat.rb', line 1123 def parent @parent end |
Class Method Details
.__css ⇒ Object
1288 |
# File 'lib/goat.rb', line 1288 def self.__css; @css; end |
.__script ⇒ Object
1279 |
# File 'lib/goat.rb', line 1279 def self.__script; @script; end |
.clientside(js) ⇒ Object
1291 1292 1293 1294 |
# File 'lib/goat.rb', line 1291 def self.clientside(js) script(js) @wired = true end |
.css(css) ⇒ Object
1286 |
# File 'lib/goat.rb', line 1286 def self.css(css); @css = css; end |
.from_skel(skel) ⇒ Object
1202 1203 1204 1205 1206 |
# File 'lib/goat.rb', line 1202 def self.from_skel(skel) inst = Goat.new_without_initialize(self) inst.load_skel(skel) inst end |
.get_rpc(name, opts = {}, &blk) ⇒ Object
1317 1318 1319 |
# File 'lib/goat.rb', line 1317 def self.get_rpc(name, opts={}, &blk) rpc(name, opts.merge(:is_get => true), &blk) end |
.live_enabled ⇒ Object
1127 |
# File 'lib/goat.rb', line 1127 def self.live_enabled; @live_enabled = true; end |
.live_enabled? ⇒ Boolean
1128 |
# File 'lib/goat.rb', line 1128 def self.live_enabled?; @live_enabled; end |
.live_rpc(name, opts = {}, &blk) ⇒ Object
1313 1314 1315 |
# File 'lib/goat.rb', line 1313 def self.live_rpc(name, opts={}, &blk) rpc(name, opts.merge(:live => true), &blk) end |
.rerender(skel) ⇒ Object
1147 1148 1149 1150 1151 1152 1153 1154 |
# File 'lib/goat.rb', line 1147 def self.rerender(skel) Profile.in(:create_component) c = Kernel.fetch_class(skel.cls).from_skel(skel) c.deserialize(skel.live_state) Profile.out(:create_component) c.rerender end |
.rerender_and_update(spec) ⇒ Object
1141 1142 1143 1144 1145 |
# File 'lib/goat.rb', line 1141 def self.rerender_and_update(spec) cls = self.name to_process = StateSrvClient.live_components(cls, spec) rerender_and_update_inner(to_process) end |
.rerender_and_update_inner(to_process) ⇒ Object
1131 1132 1133 1134 1135 1136 1137 1138 1139 |
# File 'lib/goat.rb', line 1131 def self.rerender_and_update_inner(to_process) # send updates as we calculate them; don't wait to compute everything unless to_process.empty? rerender(to_process.shift) unless to_process.empty? EM.next_tick { rerender_and_update_inner(to_process) } end end end |
.rpc(name, opts = {}, &blk) ⇒ Object
1306 1307 1308 1309 1310 1311 |
# File 'lib/goat.rb', line 1306 def self.rpc(name, opts={}, &blk) Goat.rpc_handlers[self.name.to_s] ||= {} Goat.rpc_handlers[self.name.to_s][name.to_s] = opts App.send(:define_method, "rpc_#{name}", blk) end |
.scope_css(css, prefix, dot_or_hash) ⇒ Object
1363 1364 1365 1366 1367 1368 1369 1370 1371 1372 1373 1374 |
# File 'lib/goat.rb', line 1363 def self.scope_css(css, prefix, dot_or_hash) # #%foo, .%bar, etc rep = css.gsub(/(.)%(\w+)([\ \t\{])/) do |str| p = $1 m = $2 ws = $3 "#{p}#{prefix}_#{m}#{ws}" end rep.gsub(/(^|\W)%([\W\{])/) do |str| "#{$1}#{dot_or_hash}#{prefix}#{$2}" end end |
.scoped_css ⇒ Object
1376 1377 1378 |
# File 'lib/goat.rb', line 1376 def self.scoped_css scope_css(self.__css, self.name, '.') end |
.script(script) ⇒ Object
1277 |
# File 'lib/goat.rb', line 1277 def self.script(script); @script = AutoBind.process(script); end |
.wired? ⇒ Boolean
1296 |
# File 'lib/goat.rb', line 1296 def self.wired?; @wired; end |
Instance Method Details
#__css ⇒ Object
1289 |
# File 'lib/goat.rb', line 1289 def __css; @css; end |
#__script ⇒ Object
1280 |
# File 'lib/goat.rb', line 1280 def __script; @script; end |
#_dom ⇒ Object
1347 1348 1349 1350 1351 1352 1353 |
# File 'lib/goat.rb', line 1347 def _dom if Dynamic.variable?(:in_a_dom) && !Dynamic.variable(:parent) raise "You must set the parent of a component before inserting it into the DOM tree. Try calling #parent=." end Dynamic.let(:parent => self, :in_a_dom => true) { self.dom } end |
#clientside_args ⇒ Object
1298 |
# File 'lib/goat.rb', line 1298 def clientside_args; []; end |
#clientside_instance ⇒ Object
1300 1301 1302 1303 1304 |
# File 'lib/goat.rb', line 1300 def clientside_instance args = [id, @parent ? @parent.id : nil, clientside_args] argjson = args.to_json[1..-2] # strip the braces "(new #{self.class.name}('#{self.class.name}', #{argjson}))" end |
#component(body) ⇒ Object
1333 1334 1335 1336 1337 1338 1339 1340 1341 |
# File 'lib/goat.rb', line 1333 def component(body) attrs = {:id => id, :class => component_name_hierarchy.join(' ')} if body.kind_of?(Array) && body.first == :tbody [:tbody, attrs, body[1..-1]] else [:div, attrs, body] end end |
#component_name_hierarchy(cls = self.class) ⇒ Object
1321 1322 1323 1324 1325 1326 1327 |
# File 'lib/goat.rb', line 1321 def component_name_hierarchy(cls=self.class) if cls == Component [] else component_name_hierarchy(cls.superclass) + [cls.name] end end |
#css(css) ⇒ Object
1287 |
# File 'lib/goat.rb', line 1287 def css(css); @css = css; end |
#deserialize(state) ⇒ Object
1260 1261 |
# File 'lib/goat.rb', line 1260 def deserialize(state) end |
#dom_as_expanded ⇒ Object
1355 1356 1357 |
# File 'lib/goat.rb', line 1355 def @expanded_dom end |
#dom_html(dom) ⇒ Object
1359 1360 1361 |
# File 'lib/goat.rb', line 1359 def dom_html(dom) DOMTools::HTMLBuilder.new(dom).html end |
#erb(*args, &blk) ⇒ Object
1267 1268 1269 |
# File 'lib/goat.rb', line 1267 def erb(*args, &blk) ERBRunner.new(nil, nil, @params).erb(*args, &blk) end |
#expanded_dom ⇒ Object
1343 1344 1345 |
# File 'lib/goat.rb', line 1343 def @expanded_dom ||= DOMTools.(inject_prefixes(self._dom)) end |
#inject_prefixes(dom) ⇒ Object
1329 1330 1331 |
# File 'lib/goat.rb', line 1329 def inject_prefixes(dom) DOMTools.inject_prefixes(self.id, dom) end |
#live_enabled? ⇒ Boolean
1129 |
# File 'lib/goat.rb', line 1129 def live_enabled?; self.class.live_enabled?; end |
#live_for(spec) ⇒ Object
1252 1253 1254 |
# File 'lib/goat.rb', line 1252 def live_for(spec) @live_spec = spec end |
#live_spec ⇒ Object
1263 1264 1265 |
# File 'lib/goat.rb', line 1263 def live_spec @live_spec ? @live_spec : raise("No live_spec specified") end |
#load_skel(skel) ⇒ Object
1208 1209 1210 1211 1212 1213 |
# File 'lib/goat.rb', line 1208 def load_skel(skel) @id = skel.id @pgid = skel.pgid @old_dom = skel.dom @live_spec = skel.live_spec end |
#model_changed(item, notif) ⇒ Object
1384 1385 1386 |
# File 'lib/goat.rb', line 1384 def model_changed(item, notif) render end |
#partial_erb(*args, &blk) ⇒ Object
1271 1272 1273 |
# File 'lib/goat.rb', line 1271 def partial_erb(*args, &blk) ERBRunner.new(nil, nil, @params).partial_erb(*args, &blk) end |
#pgid=(id) ⇒ Object
1189 |
# File 'lib/goat.rb', line 1189 def pgid=(id); @pgid = id; end |
#register_callback(callback) ⇒ Object
1388 1389 1390 1391 1392 1393 1394 1395 1396 |
# File 'lib/goat.rb', line 1388 def register_callback(callback) # if @callbacks.values.include?(callback) # @callbacks.to_a.detect{|k, v| k if v == callback} # else key = String.random @callbacks[key] = callback key # end end |
#rerender ⇒ Object
1160 1161 1162 1163 1164 1165 1166 1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 |
# File 'lib/goat.rb', line 1160 def rerender Profile.in(:rerender) helper = ExpansionHelper.new Profile.in(:expansion) Dynamic.let(:expander => helper) do @expanded_dom = self. end Profile.out(:expansion) Profile.in(:diff) diff = DOMDiff.diff(@old_dom, @expanded_dom, @id) Profile.out(:diff) if diff.size == 0 # pass $stderr.puts "No changes" elsif diff.size < 0 # TODO constant rerender_partially(diff) else rerender_fully(helper.components) end rescue JustRerenderError # partial updater gave up rerender_fully(helper.components) ensure Profile.out(:rerender) end |
#rerender_fully(cs) ⇒ Object
1224 1225 1226 1227 1228 1229 1230 1231 1232 1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 |
# File 'lib/goat.rb', line 1224 def rerender_fully(cs) Profile.in(:distillation) distiller = DOMDistiller.new(@expanded_dom, cs + [self]) js = distiller.script css = distiller.style Profile.out(:distillation) Profile.in(:update_send) UpdateDispatcher.component_updated( @pgid, ComponentUpdate.new( self.skel, [{'type' => 'rep', 'html' => dom_html(@expanded_dom), 'js' => js, 'css' => css, 'parent' => @id, 'position' => nil}])) Profile.out(:update_send) end |
#rerender_partially(diff) ⇒ Object
1215 1216 1217 1218 1219 1220 1221 1222 |
# File 'lib/goat.rb', line 1215 def rerender_partially(diff) $stderr.puts "should do #{diff.inspect} in #{self.class.name}/#{@id}" StateSrvClient.component_updated( self.class.name, @id, @expanded_dom ) end |
#scoped_css ⇒ Object
1380 1381 1382 |
# File 'lib/goat.rb', line 1380 def scoped_css self.class.scope_css(self.__css, @id, '#') end |
#script(script) ⇒ Object
1278 |
# File 'lib/goat.rb', line 1278 def script(script); @script = AutoBind.process(script); end |
#serialize ⇒ Object
1256 1257 1258 |
# File 'lib/goat.rb', line 1256 def serialize {} end |
#skel ⇒ Object
1191 1192 1193 1194 1195 1196 1197 1198 1199 1200 |
# File 'lib/goat.rb', line 1191 def skel ComponentSkeleton.new( 'pgid' => @pgid, 'class' => self.class.name, 'id' => @id, 'live_spec' => live_spec, 'live_state' => serialize, 'dom' => @expanded_dom ) end |
#update ⇒ Object
1156 1157 1158 |
# File 'lib/goat.rb', line 1156 def update rerender end |
#wire_script ⇒ Object
1282 1283 1284 |
# File 'lib/goat.rb', line 1282 def wire_script "Goat.wireComponent('#{id}', #{clientside_instance})" end |