lib/react/component/resolution.rb in isomorfeus-react-16.13.6 vs lib/react/component/resolution.rb in isomorfeus-react-16.13.7

- old
+ new

@@ -1,112 +1,96 @@ module React module Component module Resolution def self.included(base) base.instance_exec do - alias _react_component_class_resolution_original_const_missing const_missing + unless method_defined?(:_react_component_class_resolution_original_const_missing) + alias _react_component_class_resolution_original_const_missing const_missing + end def const_missing(const_name) - # language=JS %x{ if (typeof Opal.global[const_name] !== "undefined" && (const_name[0] === const_name[0].toUpperCase())) { var new_const = #{React::NativeConstantWrapper.new(`Opal.global[const_name]`, const_name)}; + new_const.react_component = Opal.global[const_name]; #{Object.const_set(const_name, `new_const`)}; return new_const; } else { return #{_react_component_class_resolution_original_const_missing(const_name)}; } } end # this is required for autoloading support, as the component may not be loaded and so its method is not registered. # must load it first, done by const_get, and next time the method will be there. - unless method_defined?(:_react_component_class_resolution_original_method_missing) alias _react_component_class_resolution_original_method_missing method_missing end def method_missing(component_name, *args, &block) # check for ruby component and render it # otherwise pass on method missing - # language=JS %x{ - var modules = self.$to_s().split("::"); - var modules_length = modules.length; - var module; var constant; - var component; - for (var i = modules_length; i > 0; i--) { - try { - module = modules.slice(0, i).join('::'); - constant = self.$const_get(module).$const_get(component_name, false); - if (typeof constant.react_component !== 'undefined') { - component = constant.react_component; - break; - } - } catch(err) { component = null; } - } - if (!component) { - try { - constant = Opal.Object.$const_get(component_name); - if (typeof constant.react_component !== 'undefined') { - component = constant.react_component; - } - } catch(err) { component = null; } - } - if (component) { - return Opal.React.internal_prepare_args_and_render(component, args, block); - } else { - return #{_react_component_class_resolution_original_method_missing(component_name, *args, block)}; - } + if (typeof self.iso_react_const_cache === 'undefined') { self.iso_react_const_cache = {}; } + try { + if (typeof self.iso_react_const_cache[component_name] !== 'undefined') { + constant = self.iso_react_const_cache[component_name] + } else { + constant = self.$const_get(component_name); + self.iso_react_const_cache[component_name] = constant; + } + if (typeof constant.react_component !== 'undefined') { + return Opal.React.internal_prepare_args_and_render(constant.react_component, args, block); + } + } catch(err) { } + return #{_react_component_class_resolution_original_method_missing(component_name, *args, block)}; } end end end unless method_defined?(:_react_component_resolution_original_method_missing) alias _react_component_resolution_original_method_missing method_missing end def method_missing(component_name, *args, &block) - # html tags are defined as methods, so they will not end up here. - # first check for native component and render it, we want to be fast for native components - # second check for ruby component and render it, they are a bit slower anyway - # third pass on method missing - # language=JS + # Further on it must check for modules, because $const_get does not take + # the full nesting into account, as usually its called via $$ with the + # nesting provided by the compiler. %x{ - var component = null; - if (typeof Opal.global[component_name] !== "undefined" && (component_name[0] === component_name[0].toUpperCase())) { - component = Opal.global[component_name]; + var constant; + if (typeof self.iso_react_const_cache === 'undefined') { self.iso_react_const_cache = {}; } + + if (typeof self.iso_react_const_cache[component_name] !== 'undefined') { + constant = self.iso_react_const_cache[component_name] + } else if (typeof self.$$is_a_module !== 'undefined') { + try { + constant = self.$const_get(component_name); + self.iso_react_const_cache[component_name] = constant; + } catch(err) { } } else { - var modules = self.$to_s().split("::"); - var modules_length = modules.length; - var module; - var constant; - for (var i = modules_length; i > 0; i--) { - try { - module = modules.slice(0, i).join('::'); - constant = self.$class().$const_get(module).$const_get(component_name, false); - if (typeof constant.react_component !== 'undefined') { - component = constant.react_component; + let sc = self.$class(); + try { + constant = sc.$const_get(component_name); + self.iso_react_const_cache[component_name] = constant; + } catch(err) { + var module_names = sc.$to_s().split("::"); + var module_name; + for (var i = module_names.length - 1; i > 0; i--) { + module_name = module_names.slice(0, i).join('::'); + try { + constant = sc.$const_get(module_name).$const_get(component_name, false); + self.iso_react_const_cache[component_name] = constant; break; - } - } catch(err) { component = null; } + } catch(err) { } + } } - if (!component) { - try { - constant = Opal.Object.$const_get(component_name); - if (typeof constant.react_component !== 'undefined') { - component = constant.react_component; - } - } catch(err) { component = null; } - } } - if (component) { - return Opal.React.internal_prepare_args_and_render(component, args, block); - } else { - return #{_react_component_resolution_original_method_missing(component_name, *args, block)}; + if (constant && typeof constant.react_component !== 'undefined') { + return Opal.React.internal_prepare_args_and_render(constant.react_component, args, block); } + return #{_react_component_resolution_original_method_missing(component_name, *args, block)}; } end end end end