tab_applescript.mm revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2010 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "chrome/browser/ui/cocoa/applescript/tab_applescript.h" 6 7#include "base/file_path.h" 8#include "base/logging.h" 9#import "base/scoped_nsobject.h" 10#include "base/sys_string_conversions.h" 11#include "base/utf_string_conversions.h" 12#include "chrome/browser/download/save_package.h" 13#include "chrome/browser/sessions/session_id.h" 14#include "chrome/browser/ui/cocoa/applescript/error_applescript.h" 15#include "chrome/common/url_constants.h" 16#include "content/browser/renderer_host/render_view_host.h" 17#include "content/browser/tab_contents/navigation_controller.h" 18#include "content/browser/tab_contents/navigation_entry.h" 19#include "content/browser/tab_contents/tab_contents.h" 20#include "googleurl/src/gurl.h" 21 22@interface TabAppleScript() 23@property (nonatomic, copy) NSString* tempURL; 24@end 25 26@implementation TabAppleScript 27 28@synthesize tempURL = tempURL_; 29 30- (id)init { 31 if ((self = [super init])) { 32 SessionID session; 33 SessionID::id_type futureSessionIDOfTab = session.id() + 1; 34 // Holds the SessionID that the new tab is going to get. 35 scoped_nsobject<NSNumber> numID( 36 [[NSNumber alloc] 37 initWithInt:futureSessionIDOfTab]); 38 [self setUniqueID:numID]; 39 [self setTempURL:@""]; 40 } 41 return self; 42} 43 44- (void)dealloc { 45 [tempURL_ release]; 46 [super dealloc]; 47} 48 49- (id)initWithTabContent:(TabContents*)aTabContent { 50 if (!aTabContent) { 51 [self release]; 52 return nil; 53 } 54 55 if ((self = [super init])) { 56 // It is safe to be weak, if a tab goes away (eg user closing a tab) 57 // the applescript runtime calls tabs in AppleScriptWindow and this 58 // particular tab is never returned. 59 tabContents_ = aTabContent; 60 scoped_nsobject<NSNumber> numID( 61 [[NSNumber alloc] 62 initWithInt:tabContents_->controller().session_id().id()]); 63 [self setUniqueID:numID]; 64 } 65 return self; 66} 67 68- (void)setTabContent:(TabContents*)aTabContent { 69 DCHECK(aTabContent); 70 // It is safe to be weak, if a tab goes away (eg user closing a tab) 71 // the applescript runtime calls tabs in AppleScriptWindow and this 72 // particular tab is never returned. 73 tabContents_ = aTabContent; 74 scoped_nsobject<NSNumber> numID( 75 [[NSNumber alloc] 76 initWithInt:tabContents_->controller().session_id().id()]); 77 [self setUniqueID:numID]; 78 79 [self setURL:[self tempURL]]; 80} 81 82- (NSString*)URL { 83 if (!tabContents_) { 84 return nil; 85 } 86 87 NavigationEntry* entry = tabContents_->controller().GetActiveEntry(); 88 if (!entry) { 89 return nil; 90 } 91 const GURL& url = entry->virtual_url(); 92 return base::SysUTF8ToNSString(url.spec()); 93} 94 95- (void)setURL:(NSString*)aURL { 96 // If a scripter sets a URL before the node is added save it at a temporary 97 // location. 98 if (!tabContents_) { 99 [self setTempURL:aURL]; 100 return; 101 } 102 103 GURL url(base::SysNSStringToUTF8(aURL)); 104 // check for valid url. 105 if (!url.is_empty() && !url.is_valid()) { 106 AppleScript::SetError(AppleScript::errInvalidURL); 107 return; 108 } 109 110 NavigationEntry* entry = tabContents_->controller().GetActiveEntry(); 111 if (!entry) 112 return; 113 114 const GURL& previousURL = entry->virtual_url(); 115 tabContents_->OpenURL(url, 116 previousURL, 117 CURRENT_TAB, 118 PageTransition::TYPED); 119} 120 121- (NSString*)title { 122 NavigationEntry* entry = tabContents_->controller().GetActiveEntry(); 123 if (!entry) 124 return nil; 125 126 std::wstring title; 127 if (entry != NULL) { 128 title = UTF16ToWideHack(entry->title()); 129 } 130 131 return base::SysWideToNSString(title); 132} 133 134- (NSNumber*)loading { 135 BOOL loadingValue = tabContents_->is_loading() ? YES : NO; 136 return [NSNumber numberWithBool:loadingValue]; 137} 138 139- (void)handlesUndoScriptCommand:(NSScriptCommand*)command { 140 RenderViewHost* view = tabContents_->render_view_host(); 141 if (!view) { 142 NOTREACHED(); 143 return; 144 } 145 146 view->Undo(); 147} 148 149- (void)handlesRedoScriptCommand:(NSScriptCommand*)command { 150 RenderViewHost* view = tabContents_->render_view_host(); 151 if (!view) { 152 NOTREACHED(); 153 return; 154 } 155 156 view->Redo(); 157} 158 159- (void)handlesCutScriptCommand:(NSScriptCommand*)command { 160 RenderViewHost* view = tabContents_->render_view_host(); 161 if (!view) { 162 NOTREACHED(); 163 return; 164 } 165 166 view->Cut(); 167} 168 169- (void)handlesCopyScriptCommand:(NSScriptCommand*)command { 170 RenderViewHost* view = tabContents_->render_view_host(); 171 if (!view) { 172 NOTREACHED(); 173 return; 174 } 175 176 view->Copy(); 177} 178 179- (void)handlesPasteScriptCommand:(NSScriptCommand*)command { 180 RenderViewHost* view = tabContents_->render_view_host(); 181 if (!view) { 182 NOTREACHED(); 183 return; 184 } 185 186 view->Paste(); 187} 188 189- (void)handlesSelectAllScriptCommand:(NSScriptCommand*)command { 190 RenderViewHost* view = tabContents_->render_view_host(); 191 if (!view) { 192 NOTREACHED(); 193 return; 194 } 195 196 view->SelectAll(); 197} 198 199- (void)handlesGoBackScriptCommand:(NSScriptCommand*)command { 200 NavigationController& navigationController = tabContents_->controller(); 201 if (navigationController.CanGoBack()) 202 navigationController.GoBack(); 203} 204 205- (void)handlesGoForwardScriptCommand:(NSScriptCommand*)command { 206 NavigationController& navigationController = tabContents_->controller(); 207 if (navigationController.CanGoForward()) 208 navigationController.GoForward(); 209} 210 211- (void)handlesReloadScriptCommand:(NSScriptCommand*)command { 212 NavigationController& navigationController = tabContents_->controller(); 213 const bool checkForRepost = true; 214 navigationController.Reload(checkForRepost); 215} 216 217- (void)handlesStopScriptCommand:(NSScriptCommand*)command { 218 RenderViewHost* view = tabContents_->render_view_host(); 219 if (!view) { 220 // We tolerate Stop being called even before a view has been created. 221 // So just log a warning instead of a NOTREACHED(). 222 DLOG(WARNING) << "Stop: no view for handle "; 223 return; 224 } 225 226 view->Stop(); 227} 228 229- (void)handlesPrintScriptCommand:(NSScriptCommand*)command { 230 bool initiateStatus = tabContents_->PrintNow(); 231 if (initiateStatus == false) { 232 AppleScript::SetError(AppleScript::errInitiatePrinting); 233 } 234} 235 236- (void)handlesSaveScriptCommand:(NSScriptCommand*)command { 237 NSDictionary* dictionary = [command evaluatedArguments]; 238 239 NSURL* fileURL = [dictionary objectForKey:@"File"]; 240 // Scripter has not specifed the location at which to save, so we prompt for 241 // it. 242 if (!fileURL) { 243 tabContents_->OnSavePage(); 244 return; 245 } 246 247 FilePath mainFile(base::SysNSStringToUTF8([fileURL path])); 248 // We create a directory path at the folder within which the file exists. 249 // Eg. if main_file = '/Users/Foo/Documents/Google.html' 250 // then directory_path = '/Users/Foo/Documents/Google_files/'. 251 FilePath directoryPath = mainFile.RemoveExtension(); 252 directoryPath = directoryPath.InsertBeforeExtension(std::string("_files/")); 253 254 NSString* saveType = [dictionary objectForKey:@"FileType"]; 255 256 SavePackage::SavePackageType savePackageType = 257 SavePackage::SAVE_AS_COMPLETE_HTML; 258 if (saveType) { 259 if ([saveType isEqualToString:@"only html"]) { 260 savePackageType = SavePackage::SAVE_AS_ONLY_HTML; 261 } else if ([saveType isEqualToString:@"complete html"]) { 262 savePackageType = SavePackage::SAVE_AS_COMPLETE_HTML; 263 } else { 264 AppleScript::SetError(AppleScript::errInvalidSaveType); 265 return; 266 } 267 } 268 269 tabContents_->SavePage(mainFile, directoryPath, savePackageType); 270} 271 272 273- (void)handlesViewSourceScriptCommand:(NSScriptCommand*)command { 274 NavigationEntry* entry = tabContents_->controller().GetLastCommittedEntry(); 275 if (entry) { 276 tabContents_->OpenURL(GURL(chrome::kViewSourceScheme + std::string(":") + 277 entry->url().spec()), GURL(), NEW_FOREGROUND_TAB, PageTransition::LINK); 278 } 279} 280 281- (id)handlesExecuteJavascriptScriptCommand:(NSScriptCommand*)command { 282 RenderViewHost* view = tabContents_->render_view_host(); 283 if (!view) { 284 NOTREACHED(); 285 return nil; 286 } 287 288 string16 script = base::SysNSStringToUTF16( 289 [[command evaluatedArguments] objectForKey:@"javascript"]); 290 view->ExecuteJavascriptInWebFrame(string16(), script); 291 292 // TODO(Shreyas): Figure out a way to get the response back. 293 return nil; 294} 295 296@end 297