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