The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

269 lines
7.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. // (This file gets included by juce_mac_NativeCode.mm, rather than being
  19. // compiled on its own).
  20. #if JUCE_INCLUDED_FILE && JUCE_WEB_BROWSER
  21. //==============================================================================
  22. END_JUCE_NAMESPACE
  23. #define DownloadClickDetector MakeObjCClassName(DownloadClickDetector)
  24. @interface DownloadClickDetector : NSObject
  25. {
  26. JUCE_NAMESPACE::WebBrowserComponent* ownerComponent;
  27. }
  28. - (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent;
  29. - (void) webView: (WebView*) webView decidePolicyForNavigationAction: (NSDictionary*) actionInformation
  30. request: (NSURLRequest*) request
  31. frame: (WebFrame*) frame
  32. decisionListener: (id<WebPolicyDecisionListener>) listener;
  33. @end
  34. //==============================================================================
  35. @implementation DownloadClickDetector
  36. - (DownloadClickDetector*) initWithWebBrowserOwner: (JUCE_NAMESPACE::WebBrowserComponent*) ownerComponent_
  37. {
  38. [super init];
  39. ownerComponent = ownerComponent_;
  40. return self;
  41. }
  42. - (void) webView: (WebView*) sender decidePolicyForNavigationAction: (NSDictionary*) actionInformation
  43. request: (NSURLRequest*) request
  44. frame: (WebFrame*) frame
  45. decisionListener: (id <WebPolicyDecisionListener>) listener
  46. {
  47. NSURL* url = [actionInformation valueForKey: @"WebActionOriginalURLKey"];
  48. if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
  49. [listener use];
  50. else
  51. [listener ignore];
  52. }
  53. @end
  54. BEGIN_JUCE_NAMESPACE
  55. //==============================================================================
  56. class WebBrowserComponentInternal : public NSViewComponent
  57. {
  58. public:
  59. WebBrowserComponentInternal (WebBrowserComponent* owner)
  60. {
  61. webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
  62. frameName: @""
  63. groupName: @""];
  64. setView (webView);
  65. clickListener = [[DownloadClickDetector alloc] initWithWebBrowserOwner: owner];
  66. [webView setPolicyDelegate: clickListener];
  67. }
  68. ~WebBrowserComponentInternal()
  69. {
  70. [webView setPolicyDelegate: nil];
  71. [clickListener release];
  72. setView (0);
  73. }
  74. void goToURL (const String& url,
  75. const StringArray* headers,
  76. const MemoryBlock* postData)
  77. {
  78. NSMutableURLRequest* r
  79. = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)]
  80. cachePolicy: NSURLRequestUseProtocolCachePolicy
  81. timeoutInterval: 30.0];
  82. if (postData != 0 && postData->getSize() > 0)
  83. {
  84. [r setHTTPMethod: @"POST"];
  85. [r setHTTPBody: [NSData dataWithBytes: postData->getData()
  86. length: postData->getSize()]];
  87. }
  88. if (headers != 0)
  89. {
  90. for (int i = 0; i < headers->size(); ++i)
  91. {
  92. const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
  93. const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
  94. [r setValue: juceStringToNS (headerValue)
  95. forHTTPHeaderField: juceStringToNS (headerName)];
  96. }
  97. }
  98. stop();
  99. [[webView mainFrame] loadRequest: r];
  100. }
  101. void goBack()
  102. {
  103. [webView goBack];
  104. }
  105. void goForward()
  106. {
  107. [webView goForward];
  108. }
  109. void stop()
  110. {
  111. [webView stopLoading: nil];
  112. }
  113. void refresh()
  114. {
  115. [webView reload: nil];
  116. }
  117. private:
  118. WebView* webView;
  119. DownloadClickDetector* clickListener;
  120. };
  121. //==============================================================================
  122. WebBrowserComponent::WebBrowserComponent()
  123. : browser (0),
  124. blankPageShown (false)
  125. {
  126. setOpaque (true);
  127. addAndMakeVisible (browser = new WebBrowserComponentInternal (this));
  128. }
  129. WebBrowserComponent::~WebBrowserComponent()
  130. {
  131. deleteAndZero (browser);
  132. }
  133. //==============================================================================
  134. void WebBrowserComponent::goToURL (const String& url,
  135. const StringArray* headers,
  136. const MemoryBlock* postData)
  137. {
  138. lastURL = url;
  139. lastHeaders.clear();
  140. if (headers != 0)
  141. lastHeaders = *headers;
  142. lastPostData.setSize (0);
  143. if (postData != 0)
  144. lastPostData = *postData;
  145. blankPageShown = false;
  146. browser->goToURL (url, headers, postData);
  147. }
  148. void WebBrowserComponent::stop()
  149. {
  150. browser->stop();
  151. }
  152. void WebBrowserComponent::goBack()
  153. {
  154. lastURL = String::empty;
  155. blankPageShown = false;
  156. browser->goBack();
  157. }
  158. void WebBrowserComponent::goForward()
  159. {
  160. lastURL = String::empty;
  161. browser->goForward();
  162. }
  163. void WebBrowserComponent::refresh()
  164. {
  165. browser->refresh();
  166. }
  167. //==============================================================================
  168. void WebBrowserComponent::paint (Graphics& g)
  169. {
  170. }
  171. void WebBrowserComponent::checkWindowAssociation()
  172. {
  173. // when the component becomes invisible, some stuff like flash
  174. // carries on playing audio, so we need to force it onto a blank
  175. // page to avoid this, (and send it back when it's made visible again).
  176. if (isShowing())
  177. {
  178. if (blankPageShown)
  179. goBack();
  180. }
  181. else
  182. {
  183. if (! blankPageShown)
  184. {
  185. blankPageShown = true;
  186. browser->goToURL ("about:blank", 0, 0);
  187. }
  188. }
  189. }
  190. void WebBrowserComponent::reloadLastURL()
  191. {
  192. if (lastURL.isNotEmpty())
  193. {
  194. goToURL (lastURL, &lastHeaders, &lastPostData);
  195. lastURL = String::empty;
  196. }
  197. }
  198. void WebBrowserComponent::parentHierarchyChanged()
  199. {
  200. checkWindowAssociation();
  201. }
  202. void WebBrowserComponent::resized()
  203. {
  204. browser->setSize (getWidth(), getHeight());
  205. }
  206. void WebBrowserComponent::visibilityChanged()
  207. {
  208. checkWindowAssociation();
  209. }
  210. bool WebBrowserComponent::pageAboutToLoad (const String& url)
  211. {
  212. return true;
  213. }
  214. #endif