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.

277 lines
8.0KB

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