blob: 640adc52893733ec81d71849da277924ee7d1f9e [file] [log] [blame]
/*
* Copyright (C) 2015 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
* THE POSSIBILITY OF SUCH DAMAGE.
*/
#import "AppDelegate.h"
#import "CannedContent.h"
#import "EditingOperations.h"
#import "WK1WebDocumentController.h"
#import "WK2WebDocumentController.h"
#import <WebKit/WKBrowsingContextController.h>
static NSString * const UseWebKit2ByDefaultPreferenceKey = @"UseWebKit2ByDefault";
@implementation WebEditingAppDelegate {
Class _openingDocumentController;
}
- (id)init
{
self = [super init];
if (self)
_webDocuments = [[NSMutableSet alloc] init];
return self;
}
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[NSURLProtocol registerClass:[CannedContent class]];
[WKBrowsingContextController registerSchemeForCustomProtocol:@"canned"];
[self newEditor:self];
[self _updateNewWindowKeyEquivalents];
}
- (IBAction)newEditor:(id)sender
{
Class controllerClass;
if (sender == self)
controllerClass = self._defaultWebDocumentControllerClass;
else if (sender == _newWebKit2EditorItem)
controllerClass = [WK2WebDocumentController class];
else if (sender == _newWebKit1EditorItem)
controllerClass = [WK1WebDocumentController class];
WebDocumentController *controller = [[controllerClass alloc] init];
[[controller window] makeKeyAndOrderFront:sender];
[_webDocuments addObject:controller];
[controller loadHTMLString:[WebDocumentController defaultEditingSource]];
}
- (IBAction)showOperations:(id)sender
{
static BOOL initialized = NO;
if (!initialized) {
NSFont *font = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:NSControlSizeMini]];
NSDictionary *attributes = [NSDictionary dictionaryWithObject:font forKey:NSFontAttributeName];
NSArray *operations = editingOperations();
float maxWidth = 0;
for (NSString *operationName in operations)
maxWidth = MAX(maxWidth, [operationName sizeWithAttributes:attributes].width);
maxWidth += 24;
unsigned long columnHeight = (operations.count + 2) / 3;
NSView *superview = [_operationsPanel contentView];
[_operationsPanel setContentSize:NSMakeSize(3 * maxWidth, columnHeight * 16 + 1)];
float firstY = NSMaxY([superview frame]) - 1;
float y = firstY;
float x = 0;
for (NSString *operationName in operations) {
y -= 16;
if (y < 0) {
y = firstY - 16;
x += maxWidth;
}
NSButton *button = [[NSButton alloc] initWithFrame:NSMakeRect(x, y, maxWidth, 16)];
[button setBezelStyle:NSRoundedBezelStyle];
[button.cell setControlSize:NSControlSizeMini];
[button setFont:font];
[button setTitle:operationName];
[button setAction:NSSelectorFromString(operationName)];
[superview addSubview:button];
}
[_operationsPanel center];
[_operationsPanel setFloatingPanel:YES];
[_operationsPanel setBecomesKeyOnlyIfNeeded:YES];
initialized = YES;
}
[_operationsPanel orderFront:nil];
}
- (Class)_defaultWebDocumentControllerClass
{
return self.useWebKit2ByDefault ? [WK2WebDocumentController class] : [WK1WebDocumentController class];
}
- (BOOL)useWebKit2ByDefault
{
return [[NSUserDefaults standardUserDefaults] boolForKey:UseWebKit2ByDefaultPreferenceKey];
}
- (IBAction)toggleUseWebKit2ByDefault:(id)sender
{
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setBool:![defaults boolForKey:UseWebKit2ByDefaultPreferenceKey] forKey:UseWebKit2ByDefaultPreferenceKey];
[self _updateNewWindowKeyEquivalents];
}
- (BOOL)validateMenuItem:(NSMenuItem *)menuItem
{
SEL action = [menuItem action];
if (action == @selector(toggleUseWebKit2ByDefault:))
[menuItem setState:[self useWebKit2ByDefault] ? NSOnState : NSOffState];
return YES;
}
- (void)_openDocumentWithWebKit1:(id)sender
{
_openingDocumentController = [WK1WebDocumentController class];
}
- (void)_openDocumentWithWebKit2:(id)sender
{
_openingDocumentController = [WK2WebDocumentController class];
}
- (IBAction)openDocument:(id)sender
{
_openingDocumentController = self._defaultWebDocumentControllerClass;
NSButtonCell *radioButtonPrototype = [[NSButtonCell alloc] init];
radioButtonPrototype.buttonType = NSRadioButton;
NSMatrix *openPanelAccessoryView = [[NSMatrix alloc] initWithFrame:NSZeroRect mode:NSRadioModeMatrix prototype:radioButtonPrototype numberOfRows:2 numberOfColumns:1];
openPanelAccessoryView.autorecalculatesCellSize = YES;
openPanelAccessoryView.autosizesCells = YES;
NSArray *cells = openPanelAccessoryView.cells;
[[cells objectAtIndex:0] setTitle:@"Open with WebKit1"];
[[cells objectAtIndex:0] setAction:@selector(_openDocumentWithWebKit1:)];
[[cells objectAtIndex:0] setState:!self.useWebKit2ByDefault];
[[cells objectAtIndex:1] setTitle:@"Open with WebKit2"];
[[cells objectAtIndex:1] setAction:@selector(_openDocumentWithWebKit2:)];
[[cells objectAtIndex:1] setState:self.useWebKit2ByDefault];
[openPanelAccessoryView sizeToFit];
NSOpenPanel *panel = [NSOpenPanel openPanel];
[panel setAccessoryView:openPanelAccessoryView];
[panel beginWithCompletionHandler:^(NSInteger result) {
if (result != NSFileHandlingPanelOKButton)
return;
NSURL *URL = panel.URLs.lastObject;
[self application:[NSApplication sharedApplication] openFile:URL.path];
_openingDocumentController = nil;
}];
}
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
Class controllerClass = _openingDocumentController ? _openingDocumentController : self._defaultWebDocumentControllerClass;
WebDocumentController *controller = [[controllerClass alloc] init];
[controller.window makeKeyAndOrderFront:nil];
[_webDocuments addObject:controller];
[controller loadHTMLString:[NSString stringWithContentsOfFile:filename encoding:NSUTF8StringEncoding error:nil]];
return YES;
}
- (void)_updateNewWindowKeyEquivalents
{
if (self.useWebKit2ByDefault) {
[_newWebKit1EditorItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand | NSEventModifierFlagOption];
[_newWebKit2EditorItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
} else {
[_newWebKit1EditorItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand];
[_newWebKit2EditorItem setKeyEquivalentModifierMask:NSEventModifierFlagCommand | NSEventModifierFlagOption];
}
}
- (void)performTextFinderAction:(id)sender
{
id keyWindowDelegate = [NSApplication sharedApplication].keyWindow.delegate;
if (![keyWindowDelegate isKindOfClass:[WebDocumentController class]])
return;
[(WebDocumentController *)keyWindowDelegate performTextFinderAction:sender];
}
@end