Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Appkit+Qt+LibWeb+LibWebView: Dock inspector in browser window #1438

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions Base/res/ladybird/inspector.css
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,9 @@ body {
}

.global-controls {
display: flex;
align-items: center;
gap: 8px;
margin: 0 8px 0 8px;
}

Expand All @@ -170,6 +173,17 @@ body {
background-color: var(--tab-button-background);
}

#close-inspector-button {
background-image: url("resource://icons/16x16/close-tab.png");
background-position: center;
background-repeat: no-repeat;
background-color: var(--tab-controls);
}

#close-inspector-button:hover {
background-color: var(--tab-button-background);
}

.tab-content {
height: calc(100% - 40px);

Expand Down
2 changes: 2 additions & 0 deletions Base/res/ladybird/inspector.html
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

<div class="global-controls">
<button id="export-inspector-button" title="Export the Inspector to an HTML file" onclick="inspector.exportInspector()"></button>

@CLOSE_INSPECTOR_BUTTON@
</div>
</div>

Expand Down
20 changes: 20 additions & 0 deletions Base/res/ladybird/inspector.js
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,26 @@ inspector.exportInspector = () => {
inspector.exportInspectorHTML(html);
};

inspector.close = () => {
inspector.closeInspector();
};

inspector.setCloseInspectorButtonVisibility = isVisible => {
const closeInspectorButton = document.getElementById("close-inspector-button");

if (!closeInspectorButton) {
console.error("Could not find close-inspector-button button");
return;
}

let display = "none";
if (isVisible) {
display = "block";
}

closeInspectorButton.style.display = display;
};

inspector.reset = () => {
let domTree = document.getElementById("dom-tree");
domTree.innerHTML = "";
Expand Down
3 changes: 3 additions & 0 deletions Ladybird/AppKit/Application/ApplicationDelegate.mm
Original file line number Diff line number Diff line change
Expand Up @@ -606,6 +606,9 @@ - (NSMenuItem*)createInspectMenu
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Inspector"
action:@selector(openInspector:)
keyEquivalent:@"I"]];
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Inspector Pane"
action:@selector(openInspectorPane:)
keyEquivalent:@""]];
[submenu addItem:[[NSMenuItem alloc] initWithTitle:@"Open Task Manager"
action:@selector(openTaskManager:)
keyEquivalent:@"M"]];
Expand Down
1 change: 1 addition & 0 deletions Ladybird/AppKit/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ add_library(ladybird_impl STATIC
UI/Event.mm
UI/Inspector.mm
UI/InspectorController.mm
UI/InspectorWindow.mm
UI/LadybirdWebView.mm
UI/LadybirdWebViewBridge.cpp
UI/Palette.mm
Expand Down
8 changes: 6 additions & 2 deletions Ladybird/AppKit/UI/Inspector.h
Original file line number Diff line number Diff line change
Expand Up @@ -11,15 +11,19 @@
@class LadybirdWebView;
@class Tab;

@interface Inspector : NSWindow
@interface Inspector : NSScrollView
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved

- (instancetype)init:(Tab*)tab;
- (instancetype)init:(Tab*)tab
isWindowed:(BOOL)is_windowed;

- (void)inspect;
- (void)reset;

- (void)selectHoveredElement;

- (void)setIsWindowed:(BOOL)is_windowed;
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved

@property (nonatomic, strong) NSScrollView* inspector_scroll_view;
@property (nonatomic, strong) LadybirdWebView* web_view;

@end
62 changes: 31 additions & 31 deletions Ladybird/AppKit/UI/Inspector.mm
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@
# error "This project requires ARC"
#endif

static constexpr CGFloat const WINDOW_WIDTH = 875;
static constexpr CGFloat const WINDOW_HEIGHT = 825;

static constexpr NSInteger CONTEXT_MENU_EDIT_NODE_TAG = 1;
static constexpr NSInteger CONTEXT_MENU_REMOVE_ATTRIBUTE_TAG = 2;
static constexpr NSInteger CONTEXT_MENU_COPY_ATTRIBUTE_VALUE_TAG = 3;
Expand Down Expand Up @@ -50,26 +47,23 @@ @implementation Inspector
@synthesize cookie_context_menu = _cookie_context_menu;

- (instancetype)init:(Tab*)tab
isWindowed:(BOOL)is_windowed
{
auto tab_rect = [tab frame];
auto position_x = tab_rect.origin.x + (tab_rect.size.width - WINDOW_WIDTH) / 2;
auto position_y = tab_rect.origin.y + (tab_rect.size.height - WINDOW_HEIGHT) / 2;

auto window_rect = NSMakeRect(position_x, position_y, WINDOW_WIDTH, WINDOW_HEIGHT);
auto style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;

self = [super initWithContentRect:window_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO];
self = [super init];

if (self) {
self.tab = tab;

self.web_view = [[LadybirdWebView alloc] init:nil];
[self.web_view setPostsBoundsChangedNotifications:YES];

m_inspector_client = make<WebView::InspectorClient>([[tab web_view] view], [[self web_view] view]);
[self setHasVerticalScroller:YES];
[self setHasHorizontalScroller:YES];
[self setLineScroll:24];
[self setContentView:self.web_view];
[self setDocumentView:[[NSView alloc] init]];

m_inspector_client = make<WebView::InspectorClient>([[tab web_view] view], [[self web_view] view], is_windowed);
__weak Inspector* weak_self = self;

m_inspector_client->on_requested_dom_node_text_context_menu = [weak_self](auto position) {
Expand Down Expand Up @@ -139,28 +133,19 @@ - (instancetype)init:(Tab*)tab
[NSMenu popUpContextMenu:strong_self.cookie_context_menu withEvent:event forView:strong_self.web_view];
};

auto* scroll_view = [[NSScrollView alloc] init];
[scroll_view setHasVerticalScroller:YES];
[scroll_view setHasHorizontalScroller:YES];
[scroll_view setLineScroll:24];

[scroll_view setContentView:self.web_view];
[scroll_view setDocumentView:[[NSView alloc] init]];
m_inspector_client->on_requested_close = [weak_self]() {
Inspector* strong_self = weak_self;
if (strong_self == nil) {
return;
}

[self setContentView:scroll_view];
[self setTitle:@"Inspector"];
[self setIsVisible:YES];
[strong_self removeFromSuperview];
};
}

return self;
}

- (void)dealloc
{
auto& web_view = [[self.tab web_view] view];
web_view.clear_inspected_dom_node();
}

#pragma mark - Public methods

- (void)inspect
Expand All @@ -178,6 +163,11 @@ - (void)selectHoveredElement
m_inspector_client->select_hovered_node();
}

- (void)setIsWindowed:(BOOL)is_visible
{
m_inspector_client->set_is_windowed(is_visible);
}

#pragma mark - Private methods

- (void)editDOMNode:(id)sender
Expand Down Expand Up @@ -387,4 +377,14 @@ - (NSMenu*)cookie_context_menu
return _cookie_context_menu;
}

#pragma mark - NSView

- (void)viewWillMoveToWindow:(NSWindow*)newWindow
{
// newWindow being nil indicates the inspector view has been removed from its parent
if (newWindow == nil) {
[self.tab onInspectorClosed];
}
}

@end
1 change: 1 addition & 0 deletions Ladybird/AppKit/UI/InspectorController.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#pragma once

#import <Cocoa/Cocoa.h>
#import <UI/Inspector.h>

@class Tab;

Expand Down
24 changes: 18 additions & 6 deletions Ladybird/AppKit/UI/InspectorController.mm
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
* SPDX-License-Identifier: BSD-2-Clause
*/

#import <UI/Inspector.h>
#import <UI/InspectorController.h>
#import <UI/InspectorWindow.h>
#import <UI/LadybirdWebView.h>
#import <UI/Tab.h>

Expand All @@ -32,20 +32,32 @@ - (instancetype)init:(Tab*)tab

#pragma mark - Private methods

- (Inspector*)inspector
- (InspectorWindow*)inspectorWindow
{
return (Inspector*)[self window];
return (InspectorWindow*)[self window];
}

#pragma mark - NSWindowController

- (IBAction)showWindow:(id)sender
{
self.window = [[Inspector alloc] init:self.tab];
self.window = [[InspectorWindow alloc] init:self.tab];
[self.window setDelegate:self];
[self.window makeKeyAndOrderFront:sender];
}

- (void)close
{
// Temporarily remove the window delegate to prevent `windowWillClose`
// from being called. This avoids deallocating the inspector when
// we just want to move it to the main window and close the
// inspector's window
auto delegate = self.window.delegate;
[self.window setDelegate:nil];
[self.window close];
[self.window setDelegate:delegate];
}

#pragma mark - NSWindowDelegate
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved

- (void)windowWillClose:(NSNotification*)notification
Expand All @@ -56,13 +68,13 @@ - (void)windowWillClose:(NSNotification*)notification
- (void)windowDidResize:(NSNotification*)notification
{
if (![[self window] inLiveResize]) {
[[[self inspector] web_view] handleResize];
[[[self tab] web_view] handleResize];
}
}

- (void)windowDidChangeBackingProperties:(NSNotification*)notification
{
[[[self inspector] web_view] handleDevicePixelRatioChange];
[[[self tab] web_view] handleDevicePixelRatioChange];
}

@end
20 changes: 20 additions & 0 deletions Ladybird/AppKit/UI/InspectorWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* Copyright (c) 2023, Tim Flynn <[email protected]>
* Copyright (c) 2024, Neil Viloria <[email protected]>
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#pragma once

#import <Cocoa/Cocoa.h>
#import <UI/Inspector.h>

@class LadybirdWebView;
@class Tab;

@interface InspectorWindow : NSWindow

- (instancetype)init:(Tab*)tab;

@end
58 changes: 58 additions & 0 deletions Ladybird/AppKit/UI/InspectorWindow.mm
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
/*
* Copyright (c) 2023, Tim Flynn <[email protected]>
* Copyright (c) 2024, Neil Viloria <[email protected]>
neil-ptr marked this conversation as resolved.
Show resolved Hide resolved
*
* SPDX-License-Identifier: BSD-2-Clause
*/

#include <LibWebView/InspectorClient.h>

#import <UI/InspectorWindow.h>
#import <UI/LadybirdWebView.h>
#import <UI/Tab.h>

#if !__has_feature(objc_arc)
# error "This project requires ARC"
#endif

static constexpr CGFloat const WINDOW_WIDTH = 875;
static constexpr CGFloat const WINDOW_HEIGHT = 825;

@interface InspectorWindow ()
{
OwnPtr<WebView::InspectorClient> m_inspector_client;
}

@property (nonatomic, strong) Tab* tab;

@end

@implementation InspectorWindow

@synthesize tab = _tab;

- (instancetype)init:(Tab*)tab
{
auto tab_rect = [tab frame];
auto position_x = tab_rect.origin.x + (tab_rect.size.width - WINDOW_WIDTH) / 2;
auto position_y = tab_rect.origin.y + (tab_rect.size.height - WINDOW_HEIGHT) / 2;

auto window_rect = NSMakeRect(position_x, position_y, WINDOW_WIDTH, WINDOW_HEIGHT);
auto style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable;

self = [super initWithContentRect:window_rect
styleMask:style_mask
backing:NSBackingStoreBuffered
defer:NO];

if (self) {
self.tab = tab;

[self setContentView:tab.inspector];
[self setTitle:@"Inspector"];
[self setIsVisible:YES];
}
return self;
}

@end
4 changes: 4 additions & 0 deletions Ladybird/AppKit/UI/Tab.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@

#import <Cocoa/Cocoa.h>

@class Inspector;

@class LadybirdWebView;

@interface Tab : NSWindow
Expand All @@ -25,4 +27,6 @@

@property (nonatomic, strong) LadybirdWebView* web_view;

@property (nonatomic, strong) Inspector* inspector;

@end
Loading
Loading