mirror of
https://github.com/RGBCube/serenity
synced 2025-07-25 15:47:44 +00:00
Ladybird: Add context menu items to the AppKit chrome to inspect nodes
This commit is contained in:
parent
bd1e35c726
commit
ece9908070
4 changed files with 85 additions and 0 deletions
|
@ -16,6 +16,7 @@
|
|||
- (instancetype)init:(Tab*)tab;
|
||||
|
||||
- (void)inspect;
|
||||
- (void)inspectHoveredElement;
|
||||
- (void)reset;
|
||||
|
||||
@end
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
|
||||
#include <AK/DeprecatedString.h>
|
||||
#include <AK/HashMap.h>
|
||||
#include <AK/Optional.h>
|
||||
#include <AK/Traits.h>
|
||||
#include <LibWeb/CSS/Selector.h>
|
||||
#include <LibWebView/ViewImplementation.h>
|
||||
|
@ -43,7 +44,10 @@ struct Selection {
|
|||
|
||||
@interface Inspector () <NSOutlineViewDataSource, NSOutlineViewDelegate, NSTableViewDataSource>
|
||||
{
|
||||
BOOL m_dom_tree_loaded;
|
||||
|
||||
Selection m_selection;
|
||||
Optional<i32> m_pending_selection;
|
||||
|
||||
HashMap<NSDictionary*, NSDictionary*> m_dom_node_to_parent_map;
|
||||
HashMap<i32, NSDictionary*> m_node_id_to_dom_node_map;
|
||||
|
@ -118,6 +122,11 @@ struct Selection {
|
|||
[strong_self.dom_tree_outline_view sizeToFit];
|
||||
|
||||
[strong_self prepareDOMNodeMaps:strong_self.dom_tree parentNode:nil];
|
||||
strong_self->m_dom_tree_loaded = YES;
|
||||
|
||||
if (strong_self->m_pending_selection.has_value()) {
|
||||
[strong_self inspectDOMNodeID:strong_self->m_pending_selection.release_value()];
|
||||
}
|
||||
} else {
|
||||
strong_self.dom_tree = @{};
|
||||
}
|
||||
|
@ -149,9 +158,25 @@ struct Selection {
|
|||
web_view.inspect_dom_tree();
|
||||
}
|
||||
|
||||
- (void)inspectHoveredElement
|
||||
{
|
||||
auto& web_view = [[self.tab web_view] view];
|
||||
auto node_id = web_view.get_hovered_node_id();
|
||||
|
||||
if (!m_dom_tree_loaded) {
|
||||
m_pending_selection = node_id;
|
||||
return;
|
||||
}
|
||||
|
||||
[self inspectDOMNodeID:node_id];
|
||||
}
|
||||
|
||||
- (void)reset
|
||||
{
|
||||
m_dom_tree_loaded = NO;
|
||||
|
||||
m_selection = {};
|
||||
m_pending_selection = {};
|
||||
|
||||
m_dom_node_to_parent_map = {};
|
||||
m_node_id_to_dom_node_map = {};
|
||||
|
@ -261,6 +286,34 @@ struct Selection {
|
|||
}
|
||||
}
|
||||
|
||||
- (void)inspectDOMNodeID:(i32)node_id
|
||||
{
|
||||
auto dom_node = m_node_id_to_dom_node_map.get(node_id);
|
||||
if (!dom_node.has_value()) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self expandDOMNode:*dom_node];
|
||||
|
||||
if (auto row = [self.dom_tree_outline_view rowForItem:*dom_node]; row != -1) {
|
||||
auto index = [NSIndexSet indexSetWithIndex:row];
|
||||
[self.dom_tree_outline_view selectRowIndexes:index byExtendingSelection:NO];
|
||||
}
|
||||
|
||||
[self setSelection: { node_id }];
|
||||
}
|
||||
|
||||
- (void)expandDOMNode:(NSDictionary*)dom_node
|
||||
{
|
||||
// We can't expand an item unless its parent is also already expanded, so walk up the tree to
|
||||
// expand all ancestors.
|
||||
if (auto parent_node = m_dom_node_to_parent_map.get(dom_node); parent_node.has_value()) {
|
||||
[self expandDOMNode:*parent_node];
|
||||
}
|
||||
|
||||
[self.dom_tree_outline_view expandItem:dom_node];
|
||||
}
|
||||
|
||||
- (void)setSelection:(Selection)selection
|
||||
{
|
||||
if (selection == m_selection)
|
||||
|
|
|
@ -722,6 +722,9 @@ static void copy_text_to_clipboard(StringView text)
|
|||
[_page_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"View Source"
|
||||
action:@selector(viewSource:)
|
||||
keyEquivalent:@""]];
|
||||
[_page_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Inspect Element"
|
||||
action:@selector(inspectElement:)
|
||||
keyEquivalent:@""]];
|
||||
}
|
||||
|
||||
return _page_context_menu;
|
||||
|
@ -743,6 +746,11 @@ static void copy_text_to_clipboard(StringView text)
|
|||
[_link_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Copy URL"
|
||||
action:@selector(copyLink:)
|
||||
keyEquivalent:@""]];
|
||||
[_link_context_menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
[_link_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Inspect Element"
|
||||
action:@selector(inspectElement:)
|
||||
keyEquivalent:@""]];
|
||||
}
|
||||
|
||||
return _link_context_menu;
|
||||
|
@ -767,6 +775,11 @@ static void copy_text_to_clipboard(StringView text)
|
|||
[_image_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Copy Image URL"
|
||||
action:@selector(copyLink:)
|
||||
keyEquivalent:@""]];
|
||||
[_image_context_menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
[_image_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Inspect Element"
|
||||
action:@selector(inspectElement:)
|
||||
keyEquivalent:@""]];
|
||||
}
|
||||
|
||||
return _image_context_menu;
|
||||
|
@ -814,6 +827,11 @@ static void copy_text_to_clipboard(StringView text)
|
|||
[_audio_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Copy Audio URL"
|
||||
action:@selector(copyLink:)
|
||||
keyEquivalent:@""]];
|
||||
[_audio_context_menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
[_audio_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Inspect Element"
|
||||
action:@selector(inspectElement:)
|
||||
keyEquivalent:@""]];
|
||||
}
|
||||
|
||||
return _audio_context_menu;
|
||||
|
@ -861,6 +879,11 @@ static void copy_text_to_clipboard(StringView text)
|
|||
[_video_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Copy Video URL"
|
||||
action:@selector(copyLink:)
|
||||
keyEquivalent:@""]];
|
||||
[_video_context_menu addItem:[NSMenuItem separatorItem]];
|
||||
|
||||
[_video_context_menu addItem:[[NSMenuItem alloc] initWithTitle:@"Inspect Element"
|
||||
action:@selector(inspectElement:)
|
||||
keyEquivalent:@""]];
|
||||
}
|
||||
|
||||
return _video_context_menu;
|
||||
|
|
|
@ -149,6 +149,14 @@ static constexpr CGFloat const WINDOW_HEIGHT = 800;
|
|||
self.inspector_controller = nil;
|
||||
}
|
||||
|
||||
- (void)inspectElement:(id)sender
|
||||
{
|
||||
[self openInspector:sender];
|
||||
|
||||
auto* inspector = (Inspector*)[self.inspector_controller window];
|
||||
[inspector inspectHoveredElement];
|
||||
}
|
||||
|
||||
#pragma mark - Private methods
|
||||
|
||||
- (TabController*)tabController
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue