Include private method event listeners

This commit is contained in:
Isaiah Odhner 2023-05-29 15:50:13 -04:00
parent fb4ff044ea
commit 03020d767a

View File

@ -441,49 +441,51 @@ class NodeInfo(Container):
# although I'm not sure the module is meant to be public, it's sort of just a helper.) # although I'm not sure the module is meant to be public, it's sort of just a helper.)
name = camel_to_snake(message_class.__name__) name = camel_to_snake(message_class.__name__)
handler_name = f"on_{message_class.namespace}_{name}" if message_class.namespace else f"on_{name}" handler_name = f"on_{message_class.namespace}_{name}" if message_class.namespace else f"on_{name}"
handler_names = [handler_name, f"_{handler_name}"]
# Find any listeners for this event # Find any listeners for this event
# TODO: only look upwards if the event bubbles # TODO: only look upwards if the event bubbles
usages: list[Text] = [] usages: list[Text] = []
for ancestor in dom_node.ancestors_with_self: for ancestor in dom_node.ancestors_with_self:
if hasattr(ancestor, handler_name): for handler_name in handler_names:
# Record which class the handler is defined on if hasattr(ancestor, handler_name):
# Not sure which order would be needed here # Record which class the handler is defined on
# for cls in type(ancestor).__mro__: # Not sure which order would be needed here
# if hasattr(cls, handler_name): # for cls in type(ancestor).__mro__:
# ... # if hasattr(cls, handler_name):
# break # ...
# But there's a simpler way: method.__self__.__class__ # break
handler = getattr(ancestor, handler_name) # But there's a simpler way: method.__self__.__class__
defining_class = handler.__self__.__class__ handler = getattr(ancestor, handler_name)
try: defining_class = handler.__self__.__class__
line_number = inspect.getsourcelines(handler)[1] try:
file = inspect.getsourcefile(handler) line_number = inspect.getsourcelines(handler)[1]
if file is None: file = inspect.getsourcefile(handler)
def_location = Text.from_markup(f"[#808080](unknown location)[/#808080]") if file is None:
else: def_location = Text.from_markup(f"[#808080](unknown location)[/#808080]")
# def_location = f"{file}:{line_number}" else:
# def_location = f"[link=file://{file}]{file}:{line_number}[/link]" # def_location = f"{file}:{line_number}"
# def_location = f"{file}:{line_number} [link=file://{file}](open)[/link]" # def_location = f"[link=file://{file}]{file}:{line_number}[/link]"
# I'm including the line number here hoping that SOME editor will use it. # def_location = f"{file}:{line_number} [link=file://{file}](open)[/link]"
# TODO: button to execute a command to open the file in an editor # I'm including the line number here hoping that SOME editor will use it.
# (configurable? magical? or with a button for each known editor?) # TODO: button to execute a command to open the file in an editor
file_uri = pathlib.Path(file).as_uri() + "#" + str(line_number) # (configurable? magical? or with a button for each known editor?)
def_location = Text.from_markup(f"{escape(file)}:{line_number} [link={escape(file_uri)}](open file)[/link]") file_uri = pathlib.Path(file).as_uri() + "#" + str(line_number)
except OSError as e: def_location = Text.from_markup(f"{escape(file)}:{line_number} [link={escape(file_uri)}](open file)[/link]")
def_location = Text.from_markup(f"[#808080](error getting location: [red]{escape(repr(e))}[/red])[/#808080]") except OSError as e:
# TODO: link to the DOM node in the tree that has the listener def_location = Text.from_markup(f"[#808080](error getting location: [red]{escape(repr(e))}[/red])[/#808080]")
# Note: css_path_nodes is just like ancestors_with_self, but reversed; it's still DOM nodes # TODO: link to the DOM node in the tree that has the listener
descendant_arrow = Text.from_markup("[#808080] > [/#808080]") # Note: css_path_nodes is just like ancestors_with_self, but reversed; it's still DOM nodes
dom_path = descendant_arrow.join([css_path_node.css_identifier_styled for css_path_node in ancestor.css_path_nodes]) descendant_arrow = Text.from_markup("[#808080] > [/#808080]")
handler_qualname = f"{defining_class.__qualname__}.{handler_name}" dom_path = descendant_arrow.join([css_path_node.css_identifier_styled for css_path_node in ancestor.css_path_nodes])
usages.append(Text.assemble( handler_qualname = f"{defining_class.__qualname__}.{handler_name}"
"Listener on DOM node: ", usages.append(Text.assemble(
dom_path, "Listener on DOM node: ",
"\n\n", dom_path,
handler_qualname, "\n\n",
"\n", handler_qualname,
def_location, "\n",
)) def_location,
))
if usages: if usages:
usage_info = Text("\n\n").join(usages) usage_info = Text("\n\n").join(usages)
else: else: