WebBaseNetscapePluginView.mm 29 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945
  1. /*
  2. * Copyright (C) 2005, 2006, 2007, 2008 Apple Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. *
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  14. * its contributors may be used to endorse or promote products derived
  15. * from this software without specific prior written permission.
  16. *
  17. * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  18. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  19. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  20. * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  21. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  22. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  23. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  24. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27. */
  28. #if ENABLE(NETSCAPE_PLUGIN_API)
  29. #import "WebBaseNetscapePluginView.h"
  30. #import "WebFrameInternal.h"
  31. #import "WebKitLogging.h"
  32. #import "WebKitNSStringExtras.h"
  33. #import "WebKitSystemInterface.h"
  34. #import "WebPluginContainerCheck.h"
  35. #import "WebNetscapeContainerCheckContextInfo.h"
  36. #import "WebNSURLExtras.h"
  37. #import "WebNSURLRequestExtras.h"
  38. #import "WebView.h"
  39. #import "WebViewInternal.h"
  40. #import <WebCore/AuthenticationCF.h>
  41. #import <WebCore/AuthenticationMac.h>
  42. #import <WebCore/BitmapImage.h>
  43. #import <WebCore/Credential.h>
  44. #import <WebCore/CredentialStorage.h>
  45. #import <WebCore/Document.h>
  46. #import <WebCore/Element.h>
  47. #import <WebCore/Frame.h>
  48. #import <WebCore/FrameLoader.h>
  49. #import <WebCore/HTMLPlugInElement.h>
  50. #import <WebCore/Page.h>
  51. #import <WebCore/ProtectionSpace.h>
  52. #import <WebCore/RenderView.h>
  53. #import <WebCore/RenderWidget.h>
  54. #import <WebCore/RunLoop.h>
  55. #import <WebCore/SecurityOrigin.h>
  56. #import <WebCore/WebCoreObjCExtras.h>
  57. #import <WebKit/DOMPrivate.h>
  58. #import <runtime/InitializeThreading.h>
  59. #import <wtf/Assertions.h>
  60. #import <wtf/MainThread.h>
  61. #import <wtf/text/CString.h>
  62. #define LoginWindowDidSwitchFromUserNotification @"WebLoginWindowDidSwitchFromUserNotification"
  63. #define LoginWindowDidSwitchToUserNotification @"WebLoginWindowDidSwitchToUserNotification"
  64. static const NSTimeInterval ClearSubstituteImageDelay = 0.5;
  65. using namespace WebCore;
  66. @implementation WebBaseNetscapePluginView
  67. + (void)initialize
  68. {
  69. JSC::initializeThreading();
  70. WTF::initializeMainThreadToProcessMainThread();
  71. WebCore::RunLoop::initializeMainRunLoop();
  72. WebCoreObjCFinalizeOnMainThread(self);
  73. WKSendUserChangeNotifications();
  74. }
  75. - (id)initWithFrame:(NSRect)frame
  76. pluginPackage:(WebNetscapePluginPackage *)pluginPackage
  77. URL:(NSURL *)URL
  78. baseURL:(NSURL *)baseURL
  79. MIMEType:(NSString *)MIME
  80. attributeKeys:(NSArray *)keys
  81. attributeValues:(NSArray *)values
  82. loadManually:(BOOL)loadManually
  83. element:(PassRefPtr<WebCore::HTMLPlugInElement>)element
  84. {
  85. self = [super initWithFrame:frame];
  86. if (!self)
  87. return nil;
  88. _pluginPackage = pluginPackage;
  89. _element = element;
  90. _sourceURL = adoptNS([URL copy]);
  91. _baseURL = adoptNS([baseURL copy]);
  92. _MIMEType = adoptNS([MIME copy]);
  93. // Enable "kiosk mode" when instantiating the QT plug-in inside of Dashboard. See <rdar://problem/6878105>
  94. if ([[[NSBundle mainBundle] bundleIdentifier] isEqualToString:@"com.apple.dashboard.client"] &&
  95. [_pluginPackage.get() bundleIdentifier] == "com.apple.QuickTime Plugin.plugin") {
  96. RetainPtr<NSMutableArray> mutableKeys = adoptNS([keys mutableCopy]);
  97. RetainPtr<NSMutableArray> mutableValues = adoptNS([values mutableCopy]);
  98. [mutableKeys.get() addObject:@"kioskmode"];
  99. [mutableValues.get() addObject:@"true"];
  100. [self setAttributeKeys:mutableKeys.get() andValues:mutableValues.get()];
  101. } else
  102. [self setAttributeKeys:keys andValues:values];
  103. if (loadManually)
  104. _mode = NP_FULL;
  105. else
  106. _mode = NP_EMBED;
  107. _loadManually = loadManually;
  108. return self;
  109. }
  110. - (void)dealloc
  111. {
  112. ASSERT(!_isStarted);
  113. [super dealloc];
  114. }
  115. - (void)finalize
  116. {
  117. ASSERT_MAIN_THREAD();
  118. ASSERT(!_isStarted);
  119. [super finalize];
  120. }
  121. - (WebNetscapePluginPackage *)pluginPackage
  122. {
  123. return _pluginPackage.get();
  124. }
  125. - (BOOL)isFlipped
  126. {
  127. return YES;
  128. }
  129. - (NSURL *)URLWithCString:(const char *)URLCString
  130. {
  131. if (!URLCString)
  132. return nil;
  133. CFStringRef string = CFStringCreateWithCString(kCFAllocatorDefault, URLCString, kCFStringEncodingISOLatin1);
  134. ASSERT(string); // All strings should be representable in ISO Latin 1
  135. NSString *URLString = [(NSString *)string _web_stringByStrippingReturnCharacters];
  136. NSURL *URL = [NSURL _web_URLWithDataAsString:URLString relativeToURL:_baseURL.get()];
  137. CFRelease(string);
  138. if (!URL)
  139. return nil;
  140. return URL;
  141. }
  142. - (NSMutableURLRequest *)requestWithURLCString:(const char *)URLCString
  143. {
  144. NSURL *URL = [self URLWithCString:URLCString];
  145. if (!URL)
  146. return nil;
  147. NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:URL];
  148. Frame* frame = core([self webFrame]);
  149. if (!frame)
  150. return nil;
  151. [request _web_setHTTPReferrer:frame->loader()->outgoingReferrer()];
  152. return request;
  153. }
  154. // Methods that subclasses must override
  155. - (void)setAttributeKeys:(NSArray *)keys andValues:(NSArray *)values
  156. {
  157. // This needs to be overridden by subclasses.
  158. }
  159. - (void)handleMouseMoved:(NSEvent *)event
  160. {
  161. // This needs to be overriden by subclasses.
  162. }
  163. - (void)handleMouseEntered:(NSEvent *)event
  164. {
  165. // This needs to be overridden by subclasses.
  166. }
  167. - (void)handleMouseExited:(NSEvent *)event
  168. {
  169. // This needs to be overridden by subclasses.
  170. }
  171. - (void)focusChanged
  172. {
  173. // This needs to be overridden by subclasses.
  174. }
  175. - (void)windowFocusChanged:(BOOL)hasFocus
  176. {
  177. // This needs to be overridden by subclasses.
  178. }
  179. - (BOOL)createPlugin
  180. {
  181. // This needs to be overridden by subclasses.
  182. return NO;
  183. }
  184. - (void)loadStream
  185. {
  186. // This needs to be overridden by subclasses.
  187. }
  188. - (BOOL)shouldStop
  189. {
  190. // This needs to be overridden by subclasses.
  191. return YES;
  192. }
  193. - (void)destroyPlugin
  194. {
  195. // This needs to be overridden by subclasses.
  196. }
  197. - (void)updateAndSetWindow
  198. {
  199. // This needs to be overridden by subclasses.
  200. }
  201. - (void)sendModifierEventWithKeyCode:(int)keyCode character:(char)character
  202. {
  203. // This needs to be overridden by subclasses.
  204. }
  205. - (void)privateBrowsingModeDidChange
  206. {
  207. }
  208. - (void)removeTrackingRect
  209. {
  210. if (_trackingTag) {
  211. [self removeTrackingRect:_trackingTag];
  212. _trackingTag = 0;
  213. // Do the following after setting trackingTag to 0 so we don't re-enter.
  214. // Balance the retain in resetTrackingRect. Use autorelease in case we hold
  215. // the last reference to the window during tear-down, to avoid crashing AppKit.
  216. [[self window] autorelease];
  217. }
  218. }
  219. - (void)resetTrackingRect
  220. {
  221. [self removeTrackingRect];
  222. if (_isStarted) {
  223. // Retain the window so that removeTrackingRect can work after the window is closed.
  224. [[self window] retain];
  225. _trackingTag = [self addTrackingRect:[self bounds] owner:self userData:nil assumeInside:NO];
  226. }
  227. }
  228. - (void)stopTimers
  229. {
  230. _shouldFireTimers = NO;
  231. }
  232. - (void)startTimers
  233. {
  234. _shouldFireTimers = YES;
  235. }
  236. - (void)restartTimers
  237. {
  238. [self stopTimers];
  239. if (!_isStarted || [[self window] isMiniaturized])
  240. return;
  241. [self startTimers];
  242. }
  243. - (NSRect)_windowClipRect
  244. {
  245. RenderObject* renderer = _element->renderer();
  246. if (!renderer || !renderer->view())
  247. return NSZeroRect;
  248. return toRenderWidget(renderer)->windowClipRect();
  249. }
  250. - (NSRect)visibleRect
  251. {
  252. // WebCore may impose an additional clip (via CSS overflow or clip properties). Fetch
  253. // that clip now.
  254. return NSIntersectionRect([self convertRect:[self _windowClipRect] fromView:nil], [super visibleRect]);
  255. }
  256. - (void)visibleRectDidChange
  257. {
  258. [self renewGState];
  259. }
  260. - (BOOL)acceptsFirstResponder
  261. {
  262. return YES;
  263. }
  264. - (void)sendActivateEvent:(BOOL)activate
  265. {
  266. if (!_isStarted)
  267. return;
  268. [self windowFocusChanged:activate];
  269. }
  270. - (void)setHasFocus:(BOOL)flag
  271. {
  272. if (!_isStarted)
  273. return;
  274. if (_hasFocus == flag)
  275. return;
  276. _hasFocus = flag;
  277. [self focusChanged];
  278. }
  279. - (void)addWindowObservers
  280. {
  281. ASSERT([self window]);
  282. NSWindow *theWindow = [self window];
  283. NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
  284. [notificationCenter addObserver:self selector:@selector(windowWillClose:)
  285. name:NSWindowWillCloseNotification object:theWindow];
  286. [notificationCenter addObserver:self selector:@selector(windowBecameKey:)
  287. name:NSWindowDidBecomeKeyNotification object:theWindow];
  288. [notificationCenter addObserver:self selector:@selector(windowResignedKey:)
  289. name:NSWindowDidResignKeyNotification object:theWindow];
  290. [notificationCenter addObserver:self selector:@selector(windowDidMiniaturize:)
  291. name:NSWindowDidMiniaturizeNotification object:theWindow];
  292. [notificationCenter addObserver:self selector:@selector(windowDidDeminiaturize:)
  293. name:NSWindowDidDeminiaturizeNotification object:theWindow];
  294. [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchFromUser:)
  295. name:LoginWindowDidSwitchFromUserNotification object:nil];
  296. [notificationCenter addObserver:self selector:@selector(loginWindowDidSwitchToUser:)
  297. name:LoginWindowDidSwitchToUserNotification object:nil];
  298. }
  299. - (void)removeWindowObservers
  300. {
  301. NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
  302. [notificationCenter removeObserver:self name:NSWindowWillCloseNotification object:nil];
  303. [notificationCenter removeObserver:self name:NSWindowDidBecomeKeyNotification object:nil];
  304. [notificationCenter removeObserver:self name:NSWindowDidResignKeyNotification object:nil];
  305. [notificationCenter removeObserver:self name:NSWindowDidMiniaturizeNotification object:nil];
  306. [notificationCenter removeObserver:self name:NSWindowDidDeminiaturizeNotification object:nil];
  307. [notificationCenter removeObserver:self name:LoginWindowDidSwitchFromUserNotification object:nil];
  308. [notificationCenter removeObserver:self name:LoginWindowDidSwitchToUserNotification object:nil];
  309. }
  310. - (void)start
  311. {
  312. ASSERT([self currentWindow]);
  313. if (_isStarted)
  314. return;
  315. if (_triedAndFailedToCreatePlugin)
  316. return;
  317. ASSERT([self webView]);
  318. if (![[[self webView] preferences] arePlugInsEnabled])
  319. return;
  320. Frame* frame = core([self webFrame]);
  321. if (!frame)
  322. return;
  323. Page* page = frame->page();
  324. if (!page)
  325. return;
  326. bool wasDeferring = page->defersLoading();
  327. if (!wasDeferring)
  328. page->setDefersLoading(true);
  329. BOOL result = [self createPlugin];
  330. if (!wasDeferring)
  331. page->setDefersLoading(false);
  332. if (!result) {
  333. _triedAndFailedToCreatePlugin = YES;
  334. return;
  335. }
  336. _isStarted = YES;
  337. [[self webView] addPluginInstanceView:self];
  338. if ([self currentWindow])
  339. [self updateAndSetWindow];
  340. if ([self window]) {
  341. [self addWindowObservers];
  342. if ([[self window] isKeyWindow]) {
  343. [self sendActivateEvent:YES];
  344. }
  345. [self restartTimers];
  346. }
  347. [self resetTrackingRect];
  348. [self loadStream];
  349. }
  350. - (void)stop
  351. {
  352. if (![self shouldStop])
  353. return;
  354. [self removeTrackingRect];
  355. if (!_isStarted)
  356. return;
  357. _isStarted = NO;
  358. [[self webView] removePluginInstanceView:self];
  359. // Stop the timers
  360. [self stopTimers];
  361. // Stop notifications and callbacks.
  362. [self removeWindowObservers];
  363. [self destroyPlugin];
  364. }
  365. - (BOOL)shouldClipOutPlugin
  366. {
  367. NSWindow *window = [self window];
  368. return !window || [window isMiniaturized] || [NSApp isHidden] || ![self isDescendantOf:[[self window] contentView]] || [self isHiddenOrHasHiddenAncestor];
  369. }
  370. - (BOOL)inFlatteningPaint
  371. {
  372. RenderObject* renderer = _element->renderer();
  373. if (renderer && renderer->view()) {
  374. if (FrameView* frameView = renderer->view()->frameView())
  375. return frameView->paintBehavior() & PaintBehaviorFlattenCompositingLayers;
  376. }
  377. return NO;
  378. }
  379. - (BOOL)supportsSnapshotting
  380. {
  381. return [_pluginPackage.get() supportsSnapshotting];
  382. }
  383. - (void)cacheSnapshot
  384. {
  385. NSSize boundsSize = [self bounds].size;
  386. if (!boundsSize.height || !boundsSize.width)
  387. return;
  388. NSImage *snapshot = [[NSImage alloc] initWithSize:boundsSize];
  389. _snapshotting = YES;
  390. [snapshot lockFocus];
  391. [self drawRect:[self bounds]];
  392. [snapshot unlockFocus];
  393. _snapshotting = NO;
  394. _cachedSnapshot = adoptNS(snapshot);
  395. }
  396. - (void)clearCachedSnapshot
  397. {
  398. _cachedSnapshot.clear();
  399. }
  400. - (void)viewWillMoveToWindow:(NSWindow *)newWindow
  401. {
  402. // We must remove the tracking rect before we move to the new window.
  403. // Once we move to the new window, it will be too late.
  404. [self removeTrackingRect];
  405. [self removeWindowObservers];
  406. // Workaround for: <rdar://problem/3822871> resignFirstResponder is not sent to first responder view when it is removed from the window
  407. [self setHasFocus:NO];
  408. if (!newWindow) {
  409. if ([[self webView] hostWindow]) {
  410. // View will be moved out of the actual window but it still has a host window.
  411. [self stopTimers];
  412. } else {
  413. // View will have no associated windows.
  414. [self stop];
  415. // Stop observing WebPreferencesChangedInternalNotification -- we only need to observe this when installed in the view hierarchy.
  416. // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
  417. [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
  418. }
  419. }
  420. }
  421. - (void)viewWillMoveToSuperview:(NSView *)newSuperview
  422. {
  423. if (!newSuperview) {
  424. // Stop the plug-in when it is removed from its superview. It is not sufficient to do this in -viewWillMoveToWindow:nil, because
  425. // the WebView might still has a hostWindow at that point, which prevents the plug-in from being destroyed.
  426. // There is no need to start the plug-in when moving into a superview. -viewDidMoveToWindow takes care of that.
  427. [self stop];
  428. // Stop observing WebPreferencesChangedInternalNotification -- we only need to observe this when installed in the view hierarchy.
  429. // When not in the view hierarchy, -viewWillMoveToWindow: and -viewDidMoveToWindow will start/stop the plugin as needed.
  430. [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
  431. }
  432. }
  433. - (void)viewDidMoveToWindow
  434. {
  435. [self resetTrackingRect];
  436. if ([self window]) {
  437. // While in the view hierarchy, observe WebPreferencesChangedInternalNotification so that we can start/stop depending
  438. // on whether plugins are enabled.
  439. [[NSNotificationCenter defaultCenter] addObserver:self
  440. selector:@selector(preferencesHaveChanged:)
  441. name:WebPreferencesChangedInternalNotification
  442. object:nil];
  443. _isPrivateBrowsingEnabled = [[[self webView] preferences] privateBrowsingEnabled];
  444. // View moved to an actual window. Start it if not already started.
  445. [self start];
  446. // Starting the plug-in can result in it removing itself from the window so we need to ensure that we're still in
  447. // place before doing anything that requires a window.
  448. if ([self window]) {
  449. [self restartTimers];
  450. [self addWindowObservers];
  451. }
  452. } else if ([[self webView] hostWindow]) {
  453. // View moved out of an actual window, but still has a host window.
  454. // Call setWindow to explicitly "clip out" the plug-in from sight.
  455. // FIXME: It would be nice to do this where we call stopNullEvents in viewWillMoveToWindow.
  456. [self updateAndSetWindow];
  457. }
  458. }
  459. - (void)viewWillMoveToHostWindow:(NSWindow *)hostWindow
  460. {
  461. if (!hostWindow && ![self window]) {
  462. // View will have no associated windows.
  463. [self stop];
  464. // Remove WebPreferencesChangedInternalNotification observer -- we will observe once again when we move back into the window
  465. [[NSNotificationCenter defaultCenter] removeObserver:self name:WebPreferencesChangedInternalNotification object:nil];
  466. }
  467. }
  468. - (void)viewDidMoveToHostWindow
  469. {
  470. if ([[self webView] hostWindow]) {
  471. // View now has an associated window. Start it if not already started.
  472. [self start];
  473. }
  474. }
  475. // MARK: NOTIFICATIONS
  476. - (void)windowWillClose:(NSNotification *)notification
  477. {
  478. [self stop];
  479. }
  480. - (void)windowBecameKey:(NSNotification *)notification
  481. {
  482. [self sendActivateEvent:YES];
  483. [self invalidatePluginContentRect:[self bounds]];
  484. [self restartTimers];
  485. }
  486. - (void)windowResignedKey:(NSNotification *)notification
  487. {
  488. [self sendActivateEvent:NO];
  489. [self invalidatePluginContentRect:[self bounds]];
  490. [self restartTimers];
  491. }
  492. - (void)windowDidMiniaturize:(NSNotification *)notification
  493. {
  494. [self stopTimers];
  495. }
  496. - (void)windowDidDeminiaturize:(NSNotification *)notification
  497. {
  498. [self restartTimers];
  499. }
  500. - (void)loginWindowDidSwitchFromUser:(NSNotification *)notification
  501. {
  502. [self stopTimers];
  503. }
  504. -(void)loginWindowDidSwitchToUser:(NSNotification *)notification
  505. {
  506. [self restartTimers];
  507. }
  508. - (void)preferencesHaveChanged:(NSNotification *)notification
  509. {
  510. WebPreferences *preferences = [[self webView] preferences];
  511. if ([notification object] != preferences)
  512. return;
  513. BOOL arePlugInsEnabled = [preferences arePlugInsEnabled];
  514. if (_isStarted != arePlugInsEnabled) {
  515. if (arePlugInsEnabled) {
  516. if ([self currentWindow]) {
  517. [self start];
  518. }
  519. } else {
  520. [self stop];
  521. [self invalidatePluginContentRect:[self bounds]];
  522. }
  523. }
  524. BOOL isPrivateBrowsingEnabled = [preferences privateBrowsingEnabled];
  525. if (isPrivateBrowsingEnabled != _isPrivateBrowsingEnabled) {
  526. _isPrivateBrowsingEnabled = isPrivateBrowsingEnabled;
  527. [self privateBrowsingModeDidChange];
  528. }
  529. }
  530. - (void)renewGState
  531. {
  532. [super renewGState];
  533. // -renewGState is called whenever the view's geometry changes. It's a little hacky to override this method, but
  534. // much safer than walking up the view hierarchy and observing frame/bounds changed notifications, since you don't
  535. // have to track subsequent changes to the view hierarchy and add/remove notification observers.
  536. // NSOpenGLView uses the exact same technique to reshape its OpenGL surface.
  537. // All of the work this method does may safely be skipped if the view is not in a window. When the view
  538. // is moved back into a window, everything should be set up correctly.
  539. if (![self window])
  540. return;
  541. [self updateAndSetWindow];
  542. [self resetTrackingRect];
  543. // Check to see if the plugin view is completely obscured (scrolled out of view, for example).
  544. // For performance reasons, we send null events at a lower rate to plugins which are obscured.
  545. BOOL oldIsObscured = _isCompletelyObscured;
  546. _isCompletelyObscured = NSIsEmptyRect([self visibleRect]);
  547. if (_isCompletelyObscured != oldIsObscured)
  548. [self restartTimers];
  549. }
  550. - (BOOL)becomeFirstResponder
  551. {
  552. [self setHasFocus:YES];
  553. return YES;
  554. }
  555. - (BOOL)resignFirstResponder
  556. {
  557. [self setHasFocus:NO];
  558. return YES;
  559. }
  560. - (WebDataSource *)dataSource
  561. {
  562. return [[self webFrame] _dataSource];
  563. }
  564. - (WebFrame *)webFrame
  565. {
  566. return kit(_element->document()->frame());
  567. }
  568. - (WebView *)webView
  569. {
  570. return [[self webFrame] webView];
  571. }
  572. - (NSWindow *)currentWindow
  573. {
  574. return [self window] ? [self window] : [[self webView] hostWindow];
  575. }
  576. - (WebCore::HTMLPlugInElement*)element
  577. {
  578. return _element.get();
  579. }
  580. - (void)cut:(id)sender
  581. {
  582. [self sendModifierEventWithKeyCode:7 character:'x'];
  583. }
  584. - (void)copy:(id)sender
  585. {
  586. [self sendModifierEventWithKeyCode:8 character:'c'];
  587. }
  588. - (void)paste:(id)sender
  589. {
  590. [self sendModifierEventWithKeyCode:9 character:'v'];
  591. }
  592. - (void)selectAll:(id)sender
  593. {
  594. [self sendModifierEventWithKeyCode:0 character:'a'];
  595. }
  596. // AppKit doesn't call mouseDown or mouseUp on right-click. Simulate control-click
  597. // mouseDown and mouseUp so plug-ins get the right-click event as they do in Carbon (3125743).
  598. - (void)rightMouseDown:(NSEvent *)theEvent
  599. {
  600. [self mouseDown:theEvent];
  601. }
  602. - (void)rightMouseUp:(NSEvent *)theEvent
  603. {
  604. [self mouseUp:theEvent];
  605. }
  606. - (BOOL)convertFromX:(double)sourceX andY:(double)sourceY space:(NPCoordinateSpace)sourceSpace
  607. toX:(double *)destX andY:(double *)destY space:(NPCoordinateSpace)destSpace
  608. {
  609. // Nothing to do
  610. if (sourceSpace == destSpace) {
  611. if (destX)
  612. *destX = sourceX;
  613. if (destY)
  614. *destY = sourceY;
  615. return YES;
  616. }
  617. NSPoint sourcePoint = NSMakePoint(sourceX, sourceY);
  618. NSPoint sourcePointInScreenSpace;
  619. // First convert to screen space
  620. switch (sourceSpace) {
  621. case NPCoordinateSpacePlugin:
  622. sourcePointInScreenSpace = [self convertPoint:sourcePoint toView:nil];
  623. sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePointInScreenSpace];
  624. break;
  625. case NPCoordinateSpaceWindow:
  626. sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
  627. break;
  628. case NPCoordinateSpaceFlippedWindow:
  629. sourcePoint.y = [[self currentWindow] frame].size.height - sourcePoint.y;
  630. sourcePointInScreenSpace = [[self currentWindow] convertBaseToScreen:sourcePoint];
  631. break;
  632. case NPCoordinateSpaceScreen:
  633. sourcePointInScreenSpace = sourcePoint;
  634. break;
  635. case NPCoordinateSpaceFlippedScreen:
  636. sourcePoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - sourcePoint.y;
  637. sourcePointInScreenSpace = sourcePoint;
  638. break;
  639. default:
  640. return FALSE;
  641. }
  642. NSPoint destPoint;
  643. // Then convert back to the destination space
  644. switch (destSpace) {
  645. case NPCoordinateSpacePlugin:
  646. destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
  647. destPoint = [self convertPoint:destPoint fromView:nil];
  648. break;
  649. case NPCoordinateSpaceWindow:
  650. destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
  651. break;
  652. case NPCoordinateSpaceFlippedWindow:
  653. destPoint = [[self currentWindow] convertScreenToBase:sourcePointInScreenSpace];
  654. destPoint.y = [[self currentWindow] frame].size.height - destPoint.y;
  655. break;
  656. case NPCoordinateSpaceScreen:
  657. destPoint = sourcePointInScreenSpace;
  658. break;
  659. case NPCoordinateSpaceFlippedScreen:
  660. destPoint = sourcePointInScreenSpace;
  661. destPoint.y = [(NSScreen *)[[NSScreen screens] objectAtIndex:0] frame].size.height - destPoint.y;
  662. break;
  663. default:
  664. return FALSE;
  665. }
  666. if (destX)
  667. *destX = destPoint.x;
  668. if (destY)
  669. *destY = destPoint.y;
  670. return TRUE;
  671. }
  672. - (CString)resolvedURLStringForURL:(const char*)url target:(const char*)target
  673. {
  674. String relativeURLString = String::fromUTF8(url);
  675. if (relativeURLString.isNull())
  676. return CString();
  677. Frame* frame = core([self webFrame]);
  678. if (!frame)
  679. return CString();
  680. Frame* targetFrame = frame->tree()->find(String::fromUTF8(target));
  681. if (!targetFrame)
  682. return CString();
  683. if (!frame->document()->securityOrigin()->canAccess(targetFrame->document()->securityOrigin()))
  684. return CString();
  685. KURL absoluteURL = targetFrame->document()->completeURL(relativeURLString);
  686. return absoluteURL.string().utf8();
  687. }
  688. - (void)invalidatePluginContentRect:(NSRect)rect
  689. {
  690. if (RenderBoxModelObject *renderer = toRenderBoxModelObject(_element->renderer())) {
  691. IntRect contentRect(rect);
  692. contentRect.move(renderer->borderLeft() + renderer->paddingLeft(), renderer->borderTop() + renderer->paddingTop());
  693. renderer->repaintRectangle(contentRect);
  694. }
  695. }
  696. - (NSRect)actualVisibleRectInWindow
  697. {
  698. RenderObject* renderer = _element->renderer();
  699. if (!renderer || !renderer->view())
  700. return NSZeroRect;
  701. FrameView* frameView = renderer->view()->frameView();
  702. if (!frameView)
  703. return NSZeroRect;
  704. IntRect widgetRect = renderer->pixelSnappedAbsoluteClippedOverflowRect();
  705. widgetRect = frameView->contentsToWindow(widgetRect);
  706. return intersection(toRenderWidget(renderer)->windowClipRect(), widgetRect);
  707. }
  708. - (CALayer *)pluginLayer
  709. {
  710. // This needs to be overridden by subclasses.
  711. return nil;
  712. }
  713. - (BOOL)getFormValue:(NSString **)value
  714. {
  715. // This needs to be overridden by subclasses.
  716. return false;
  717. }
  718. @end
  719. namespace WebKit {
  720. bool getAuthenticationInfo(const char* protocolStr, const char* hostStr, int32_t port, const char* schemeStr, const char* realmStr,
  721. CString& username, CString& password)
  722. {
  723. if (strcasecmp(protocolStr, "http") != 0 &&
  724. strcasecmp(protocolStr, "https") != 0)
  725. return false;
  726. NSString *host = [NSString stringWithUTF8String:hostStr];
  727. if (!hostStr)
  728. return false;
  729. NSString *protocol = [NSString stringWithUTF8String:protocolStr];
  730. if (!protocol)
  731. return false;
  732. NSString *realm = [NSString stringWithUTF8String:realmStr];
  733. if (!realm)
  734. return NPERR_GENERIC_ERROR;
  735. NSString *authenticationMethod = NSURLAuthenticationMethodDefault;
  736. if (!strcasecmp(protocolStr, "http")) {
  737. if (!strcasecmp(schemeStr, "basic"))
  738. authenticationMethod = NSURLAuthenticationMethodHTTPBasic;
  739. else if (!strcasecmp(schemeStr, "digest"))
  740. authenticationMethod = NSURLAuthenticationMethodHTTPDigest;
  741. }
  742. RetainPtr<NSURLProtectionSpace> protectionSpace = adoptNS([[NSURLProtectionSpace alloc] initWithHost:host port:port protocol:protocol realm:realm authenticationMethod:authenticationMethod]);
  743. NSURLCredential *credential = mac(CredentialStorage::get(core(protectionSpace.get())));
  744. if (!credential)
  745. credential = [[NSURLCredentialStorage sharedCredentialStorage] defaultCredentialForProtectionSpace:protectionSpace.get()];
  746. if (!credential)
  747. return false;
  748. if (![credential hasPassword])
  749. return false;
  750. username = [[credential user] UTF8String];
  751. password = [[credential password] UTF8String];
  752. return true;
  753. }
  754. } // namespace WebKit
  755. #endif // ENABLE(NETSCAPE_PLUGIN_API)