Files
Twyco 1cf7524a7b
CI/CD / preconditions (pull_request) Successful in 1s
Native JavaScript checks / Native launcher and release tests (pull_request) Successful in 1m13s
macOS checks / Native Rust tests and unsigned build (pull_request) Successful in 1m44s
CI/CD / test_and_check_app (pull_request) Successful in 7m4s
CI/CD / Publish immutable image (pull_request) Skipped
fix(KAN-71): use interactive WebKit navigation gestures
2026-09-29 08:02:10 +02:00

75 lines
4.2 KiB
Objective-C

#import <AppKit/AppKit.h>
#import <WebKit/WebKit.h>
#import "../src-tauri/src/navigation.m"
static void check(BOOL condition, NSString *message) {
if (!condition) {
fprintf(stderr, "FAIL: %s\n", message.UTF8String);
exit(1);
}
}
static void waitUntil(BOOL (^condition)(void), NSString *message) {
NSDate *deadline = [NSDate dateWithTimeIntervalSinceNow:10];
while (!condition() && deadline.timeIntervalSinceNow > 0) {
[NSRunLoop.currentRunLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.01]];
}
check(condition(), message);
}
@interface WorkspacePages : NSObject <WKURLSchemeHandler, WKNavigationDelegate>
@property(nonatomic) NSUInteger finished;
@end
@implementation WorkspacePages
- (void)webView:(WKWebView *)webView startURLSchemeTask:(id<WKURLSchemeTask>)task {
NSData *body = [[NSString stringWithFormat:@"<html><body>%@<input value='draft'></body></html>", task.request.URL.path]
dataUsingEncoding:NSUTF8StringEncoding];
NSURLResponse *response = [[NSURLResponse alloc] initWithURL:task.request.URL MIMEType:@"text/html"
expectedContentLength:body.length textEncodingName:@"utf-8"];
[task didReceiveResponse:response];
[task didReceiveData:body];
[task didFinish];
}
- (void)webView:(WKWebView *)webView stopURLSchemeTask:(id<WKURLSchemeTask>)task {}
- (void)webView:(WKWebView *)webView didFinishNavigation:(WKNavigation *)navigation {
self.finished++;
}
@end
int main(void) {
@autoreleasepool {
[NSApplication sharedApplication];
WorkspacePages *pages = [WorkspacePages new];
WKWebViewConfiguration *configuration = [WKWebViewConfiguration new];
configuration.websiteDataStore = WKWebsiteDataStore.nonPersistentDataStore;
[configuration setURLSchemeHandler:pages forURLScheme:@"kanban-test"];
WKWebView *webview = [[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration];
webview.navigationDelegate = pages;
check(!webview.allowsBackForwardNavigationGestures, @"WebKit defaults to disabled gestures");
install_workspace_navigation((__bridge void *)webview);
install_workspace_navigation((__bridge void *)webview);
check(webview.allowsBackForwardNavigationGestures, @"The workspace must enable WebKit's interactive gestures");
check(webview.configuration.userContentController.userScripts.count == 0, @"Enabling gestures must not inject a history adapter");
check([webview goBack] == nil && [webview goForward] == nil, @"Empty history must not navigate");
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"kanban-test://workspace/first"]]];
waitUntil(^BOOL { return pages.finished == 1; }, @"First page must load");
check(!webview.canGoBack && !webview.canGoForward, @"The first page must have no navigation target");
[webview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"kanban-test://workspace/second"]]];
waitUntil(^BOOL { return pages.finished == 2; }, @"Second page must load");
check(webview.canGoBack && !webview.canGoForward, @"Native history must retain the first page");
check([webview goBack] != nil, @"Native back navigation must start");
waitUntil(^BOOL { return pages.finished == 3; }, @"Native back navigation must complete");
check([webview.URL.path isEqualToString:@"/first"] && !webview.canGoBack && webview.canGoForward,
@"Back must restore the first page and retain forward history");
check([webview goBack] == nil, @"Back at the first page must leave it in place");
check([webview goForward] != nil, @"Native forward navigation must start");
waitUntil(^BOOL { return pages.finished == 4; }, @"Native forward navigation must complete");
check([webview.URL.path isEqualToString:@"/second"] && webview.canGoBack && !webview.canGoForward,
@"Forward must restore the second page");
check(webview.allowsBackForwardNavigationGestures, @"Native gestures must remain enabled across page navigation");
puts("PASS: WebKit interactive gesture configuration, full-page back/forward and empty history");
}
}