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