-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
6 changed files
with
1,107 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
Setup | ||
----- | ||
Get/Build Chromium (Content project is all you need) | ||
Set target SDK to 10.6 | ||
|
||
|
||
Changes to build brackets shell | ||
------------------------------- | ||
- copy brackets_shell_mac.mm from node-shell/content_shell to chromium/src/content/shell | ||
- copy node directory from node-shell into chromium/src/content/shell | ||
- copy NodeWrapper.m/.h from node-shell into chromium/src/content/shell | ||
- make sure the correct line is un-commented in NodeWrapper.m processCommand | ||
- copy server directory from node-shell into chromium/src/content/shell | ||
|
||
- Update content_shell.gypi with the following changes: (or use content_shell.gypi from node-shell) | ||
- Replace "shell_mac.mm" with "brackets_shell_mac.mm" | ||
- Add the following to 'mac_bundle_resources', after 'shell/mac/ap-Info.plist': | ||
'shell/server/appProxy.js', # Brackets | ||
'shell/server/clientProxy.js', # Brackets | ||
'shell/server/config.js', # Brackets | ||
'shell/server/server.js', # Brackets | ||
|
||
- Add the following after the "Make sure there isn't any Objective-C in the shell" build step: | ||
{ # Brackets begin | ||
# Copy node | ||
'postbuild_name': 'Copy node', | ||
'action': [ | ||
'cp', | ||
'shell/node/node', | ||
'$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/node-executable', | ||
], | ||
}, | ||
{ | ||
# Copy node modules | ||
'postbuild_name': 'Copy node modules', | ||
'action': [ | ||
'cp', | ||
'-r', | ||
'shell/node/node_modules', | ||
'$BUILT_PRODUCTS_DIR/$UNLOCALIZED_RESOURCES_FOLDER_PATH/', | ||
], | ||
} # Brackets end | ||
|
||
- Add 'shell/NodeWrapper.m' to content_shell.gypi (under brackets_shell_mac.mm) | ||
|
||
- Add to shell_browser_main_parts_mac.mm (or use from node-shell) | ||
#include "content/shell/NodeWrapper.h | ||
|
||
in PreMainMessageLoopStart: | ||
NodeWrapper *node = [[NodeWrapper alloc] init]; | ||
[node start]; | ||
|
||
- Add to shell_application_mac.h (before @end) (or use from node-shell) | ||
- (void)goToURL:(NSString*)url; | ||
|
||
- Add to shell_application_mac.mm (before @end) (or use from node-shell) | ||
|
||
- (void)goToURL:(NSString *)url { | ||
NSWindow* aWindow = [self mainWindow]; | ||
|
||
// Early in startup, mainWindow is nil. In that case, grab the first | ||
// window from the 'windows' array | ||
NSArray* someWindows = [self windows]; | ||
|
||
if (!aWindow && someWindows) { | ||
aWindow = [someWindows objectAtIndex:0]; | ||
} | ||
|
||
if (aWindow) { | ||
[[aWindow delegate] performSelector: @selector(goToURL:) withObject:url]; | ||
} | ||
} | ||
|
||
|
||
|
||
|
||
Building | ||
-------- | ||
|
||
All commands to be run from ~/chromium/src | ||
|
||
From XCode | ||
---------- | ||
# update projects | ||
gclient runhooks | ||
|
||
# open project in xcode and build | ||
|
||
From Command Line | ||
----------------- | ||
|
||
# update projects | ||
GYP_GENERATORS=ninja GYP_DEFINES=mac_sdk=10.6 ./build/gyp_chromium | ||
|
||
# build | ||
ninja -C out/Debug content_shell | ||
(use out/Release for release build) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,279 @@ | ||
// Copyright (c) 2012 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "content/shell/shell.h" | ||
|
||
#include <algorithm> | ||
|
||
#include "base/logging.h" | ||
#import "base/mac/cocoa_protocols.h" | ||
#import "base/memory/scoped_nsobject.h" | ||
#include "base/string_piece.h" | ||
#include "base/sys_string_conversions.h" | ||
#include "content/public/browser/native_web_keyboard_event.h" | ||
#include "content/public/browser/web_contents.h" | ||
#include "content/public/browser/web_contents_view.h" | ||
#include "content/shell/resource.h" | ||
#include "googleurl/src/gurl.h" | ||
#import "ui/base/cocoa/underlay_opengl_hosting_window.h" | ||
#include "NodeWrapper.h" | ||
|
||
#define SHOW_BROWSER_UI | ||
|
||
// Receives notification that the window is closing so that it can start the | ||
// tear-down process. Is responsible for deleting itself when done. | ||
@interface ContentShellWindowDelegate : NSObject<NSWindowDelegate> { | ||
@private | ||
content::Shell* shell_; | ||
} | ||
- (id)initWithShell:(content::Shell*)shell; | ||
- (void)goToURL:(NSString*)url; | ||
@end | ||
|
||
@implementation ContentShellWindowDelegate | ||
|
||
- (id)initWithShell:(content::Shell*)shell { | ||
if ((self = [super init])) { | ||
shell_ = shell; | ||
} | ||
return self; | ||
} | ||
|
||
// Called when the window is about to close. Perform the self-destruction | ||
// sequence by getting rid of the shell and removing it and the window from | ||
// the various global lists. Instead of doing it here, however, we fire off | ||
// a delayed call to |-cleanup:| to allow everything to get off the stack | ||
// before we go deleting objects. By returning YES, we allow the window to be | ||
// removed from the screen. | ||
- (BOOL)windowShouldClose:(id)window { | ||
[window autorelease]; | ||
|
||
// Clean ourselves up and do the work after clearing the stack of anything | ||
// that might have the shell on it. | ||
[self performSelectorOnMainThread:@selector(cleanup:) | ||
withObject:window | ||
waitUntilDone:NO]; | ||
|
||
return YES; | ||
} | ||
|
||
// Does the work of removing the window from our various bookkeeping lists | ||
// and gets rid of the shell. | ||
- (void)cleanup:(id)window { | ||
delete shell_; | ||
|
||
[self release]; | ||
} | ||
|
||
- (void)performAction:(id)sender { | ||
shell_->ActionPerformed([sender tag]); | ||
} | ||
|
||
- (void)takeURLStringValueFrom:(id)sender { | ||
shell_->URLEntered(base::SysNSStringToUTF8([sender stringValue])); | ||
} | ||
|
||
- (void)goToURL:(NSString*)url { | ||
shell_->URLEntered(base::SysNSStringToUTF8(url)); | ||
} | ||
|
||
@end | ||
|
||
namespace { | ||
|
||
NSString* kWindowTitle = @"Brackets"; | ||
|
||
// Layout constants (in view coordinates) | ||
const CGFloat kButtonWidth = 72; | ||
const CGFloat kURLBarHeight = 24; | ||
|
||
// The minimum size of the window's content (in view coordinates) | ||
const CGFloat kMinimumWindowWidth = 400; | ||
const CGFloat kMinimumWindowHeight = 300; | ||
|
||
#ifdef SHOW_BROWSER_UI | ||
void MakeShellButton(NSRect* rect, | ||
NSString* title, | ||
NSView* parent, | ||
int control, | ||
NSView* target) { | ||
scoped_nsobject<NSButton> button([[NSButton alloc] initWithFrame:*rect]); | ||
[button setTitle:title]; | ||
[button setBezelStyle:NSSmallSquareBezelStyle]; | ||
[button setAutoresizingMask:(NSViewMaxXMargin | NSViewMinYMargin)]; | ||
[button setTarget:target]; | ||
[button setAction:@selector(performAction:)]; | ||
[button setTag:control]; | ||
[parent addSubview:button]; | ||
rect->origin.x += kButtonWidth; | ||
} | ||
#endif // SHOW_BROWSER_UI | ||
|
||
} // namespace | ||
|
||
namespace content { | ||
|
||
void Shell::PlatformInitialize() { | ||
} | ||
|
||
base::StringPiece Shell::PlatformResourceProvider(int key) { | ||
return base::StringPiece(); | ||
} | ||
|
||
void Shell::PlatformCleanUp() { | ||
} | ||
|
||
void Shell::PlatformEnableUIControl(UIControl control, bool is_enabled) { | ||
#ifdef SHOW_BROWSER_UI | ||
int id; | ||
switch (control) { | ||
case BACK_BUTTON: | ||
id = IDC_NAV_BACK; | ||
break; | ||
case FORWARD_BUTTON: | ||
id = IDC_NAV_FORWARD; | ||
break; | ||
case STOP_BUTTON: | ||
id = IDC_NAV_STOP; | ||
break; | ||
default: | ||
NOTREACHED() << "Unknown UI control"; | ||
return; | ||
} | ||
[[[window_ contentView] viewWithTag:id] setEnabled:is_enabled]; | ||
#endif // SHOW_BROWSER_UI | ||
} | ||
|
||
void Shell::PlatformSetAddressBarURL(const GURL& url) { | ||
#ifdef SHOW_BROWSER_UI | ||
NSString* url_string = base::SysUTF8ToNSString(url.spec()); | ||
[url_edit_view_ setStringValue:url_string]; | ||
#endif // SHOW_BROWSER_UI | ||
} | ||
|
||
void Shell::PlatformSetIsLoading(bool loading) { | ||
} | ||
|
||
void Shell::PlatformCreateWindow(int width, int height) { | ||
NSRect initial_window_bounds = NSMakeRect(0, 0, width, height); | ||
window_ = [[UnderlayOpenGLHostingWindow alloc] | ||
initWithContentRect:initial_window_bounds | ||
styleMask:(NSTitledWindowMask | | ||
NSClosableWindowMask | | ||
NSMiniaturizableWindowMask | | ||
NSResizableWindowMask ) | ||
backing:NSBackingStoreBuffered | ||
defer:NO]; | ||
[window_ setTitle:kWindowTitle]; | ||
NSView* content = [window_ contentView]; | ||
|
||
// If the window is allowed to get too small, it will wreck the view bindings. | ||
NSSize min_size = NSMakeSize(kMinimumWindowWidth, kMinimumWindowHeight); | ||
min_size = [content convertSize:min_size toView:nil]; | ||
// Note that this takes window coordinates. | ||
[window_ setContentMinSize:min_size]; | ||
|
||
// Rely on the window delegate to clean us up rather than immediately | ||
// releasing when the window gets closed. We use the delegate to do | ||
// everything from the autorelease pool so the shell isn't on the stack | ||
// during cleanup (ie, a window close from javascript). | ||
[window_ setReleasedWhenClosed:NO]; | ||
|
||
// Create a window delegate to watch for when it's asked to go away. It will | ||
// clean itself up so we don't need to hold a reference. | ||
ContentShellWindowDelegate* delegate = | ||
[[ContentShellWindowDelegate alloc] initWithShell:this]; | ||
[window_ setDelegate:delegate]; | ||
|
||
#ifdef SHOW_BROWSER_UI | ||
NSRect button_frame = | ||
NSMakeRect(0, NSMaxY(initial_window_bounds) - kURLBarHeight, | ||
kButtonWidth, kURLBarHeight); | ||
|
||
MakeShellButton(&button_frame, @"Back", content, IDC_NAV_BACK, | ||
(NSView*)delegate); | ||
MakeShellButton(&button_frame, @"Forward", content, IDC_NAV_FORWARD, | ||
(NSView*)delegate); | ||
MakeShellButton(&button_frame, @"Reload", content, IDC_NAV_RELOAD, | ||
(NSView*)delegate); | ||
MakeShellButton(&button_frame, @"Stop", content, IDC_NAV_STOP, | ||
(NSView*)delegate); | ||
|
||
button_frame.size.width = | ||
NSWidth(initial_window_bounds) - NSMinX(button_frame); | ||
scoped_nsobject<NSTextField> url_edit_view( | ||
[[NSTextField alloc] initWithFrame:button_frame]); | ||
[content addSubview:url_edit_view]; | ||
[url_edit_view setAutoresizingMask:(NSViewWidthSizable | NSViewMinYMargin)]; | ||
[url_edit_view setTarget:delegate]; | ||
[url_edit_view setAction:@selector(takeURLStringValueFrom:)]; | ||
[[url_edit_view cell] setWraps:NO]; | ||
[[url_edit_view cell] setScrollable:YES]; | ||
url_edit_view_ = url_edit_view.get(); | ||
#endif // SHOW_BROWSER_UI | ||
// show the window | ||
[window_ makeKeyAndOrderFront:nil]; | ||
} | ||
|
||
void Shell::PlatformSetContents() { | ||
NSView* web_view = web_contents_->GetView()->GetNativeView(); | ||
NSView* content = [window_ contentView]; | ||
[content addSubview:web_view]; | ||
|
||
NSRect frame = [content bounds]; | ||
#ifdef SHOW_BROWSER_UI | ||
frame.size.height -= kURLBarHeight; | ||
#endif // SHOW_BROWSER_UI | ||
[web_view setFrame:frame]; | ||
[web_view setAutoresizingMask:(NSViewWidthSizable | NSViewHeightSizable)]; | ||
[web_view setNeedsDisplay:YES]; | ||
} | ||
|
||
void Shell::PlatformResizeSubViews() { | ||
// Not needed; subviews are bound. | ||
} | ||
|
||
void Shell::Close() { | ||
[window_ performClose:nil]; | ||
} | ||
|
||
void Shell::ActionPerformed(int control) { | ||
#ifdef SHOW_BROWSER_UI | ||
switch (control) { | ||
case IDC_NAV_BACK: | ||
GoBackOrForward(-1); | ||
break; | ||
case IDC_NAV_FORWARD: | ||
GoBackOrForward(1); | ||
break; | ||
case IDC_NAV_RELOAD: | ||
Reload(); | ||
break; | ||
case IDC_NAV_STOP: | ||
Stop(); | ||
break; | ||
} | ||
#endif | ||
} | ||
|
||
void Shell::URLEntered(std::string url_string) { | ||
if (!url_string.empty()) { | ||
GURL url(url_string); | ||
if (!url.has_scheme()) | ||
url = GURL("http://" + url_string); | ||
LoadURL(url); | ||
} | ||
} | ||
|
||
void Shell::HandleKeyboardEvent(const NativeWebKeyboardEvent& event) { | ||
if (event.skip_in_browser) | ||
return; | ||
|
||
// The event handling to get this strictly right is a tangle; cheat here a bit | ||
// by just letting the menus have a chance at it. | ||
if ([event.os_event type] == NSKeyDown) | ||
[[NSApp mainMenu] performKeyEquivalent:event.os_event]; | ||
} | ||
|
||
} // namespace content |
Oops, something went wrong.