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.

275 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. if (ownerComponent->pageAboutToLoad (nsStringToJuce ([url absoluteString])))
  54. [listener use];
  55. else
  56. [listener ignore];
  57. }
  58. @end
  59. BEGIN_JUCE_NAMESPACE
  60. //==============================================================================
  61. class WebBrowserComponentInternal : public NSViewComponent
  62. {
  63. public:
  64. WebBrowserComponentInternal (WebBrowserComponent* owner)
  65. {
  66. webView = [[WebView alloc] initWithFrame: NSMakeRect (0, 0, 100.0f, 100.0f)
  67. frameName: @""
  68. groupName: @""];
  69. setView (webView);
  70. clickListener = [[DownloadClickDetector alloc] initWithWebBrowserOwner: owner];
  71. [webView setPolicyDelegate: clickListener];
  72. }
  73. ~WebBrowserComponentInternal()
  74. {
  75. [webView setPolicyDelegate: nil];
  76. [clickListener release];
  77. setView (0);
  78. }
  79. void goToURL (const String& url,
  80. const StringArray* headers,
  81. const MemoryBlock* postData)
  82. {
  83. NSMutableURLRequest* r
  84. = [NSMutableURLRequest requestWithURL: [NSURL URLWithString: juceStringToNS (url)]
  85. cachePolicy: NSURLRequestUseProtocolCachePolicy
  86. timeoutInterval: 30.0];
  87. if (postData != 0 && postData->getSize() > 0)
  88. {
  89. [r setHTTPMethod: @"POST"];
  90. [r setHTTPBody: [NSData dataWithBytes: postData->getData()
  91. length: postData->getSize()]];
  92. }
  93. if (headers != 0)
  94. {
  95. for (int i = 0; i < headers->size(); ++i)
  96. {
  97. const String headerName ((*headers)[i].upToFirstOccurrenceOf (T(":"), false, false).trim());
  98. const String headerValue ((*headers)[i].fromFirstOccurrenceOf (T(":"), false, false).trim());
  99. [r setValue: juceStringToNS (headerValue)
  100. forHTTPHeaderField: juceStringToNS (headerName)];
  101. }
  102. }
  103. stop();
  104. [[webView mainFrame] loadRequest: r];
  105. }
  106. void goBack()
  107. {
  108. [webView goBack];
  109. }
  110. void goForward()
  111. {
  112. [webView goForward];
  113. }
  114. void stop()
  115. {
  116. [webView stopLoading: nil];
  117. }
  118. void refresh()
  119. {
  120. [webView reload: nil];
  121. }
  122. private:
  123. WebView* webView;
  124. DownloadClickDetector* clickListener;
  125. };
  126. //==============================================================================
  127. WebBrowserComponent::WebBrowserComponent()
  128. : browser (0),
  129. blankPageShown (false)
  130. {
  131. setOpaque (true);
  132. addAndMakeVisible (browser = new WebBrowserComponentInternal (this));
  133. }
  134. WebBrowserComponent::~WebBrowserComponent()
  135. {
  136. deleteAndZero (browser);
  137. }
  138. //==============================================================================
  139. void WebBrowserComponent::goToURL (const String& url,
  140. const StringArray* headers,
  141. const MemoryBlock* postData)
  142. {
  143. lastURL = url;
  144. lastHeaders.clear();
  145. if (headers != 0)
  146. lastHeaders = *headers;
  147. lastPostData.setSize (0);
  148. if (postData != 0)
  149. lastPostData = *postData;
  150. blankPageShown = false;
  151. browser->goToURL (url, headers, postData);
  152. }
  153. void WebBrowserComponent::stop()
  154. {
  155. browser->stop();
  156. }
  157. void WebBrowserComponent::goBack()
  158. {
  159. lastURL = String::empty;
  160. blankPageShown = false;
  161. browser->goBack();
  162. }
  163. void WebBrowserComponent::goForward()
  164. {
  165. lastURL = String::empty;
  166. browser->goForward();
  167. }
  168. void WebBrowserComponent::refresh()
  169. {
  170. browser->refresh();
  171. }
  172. //==============================================================================
  173. void WebBrowserComponent::paint (Graphics& g)
  174. {
  175. }
  176. void WebBrowserComponent::checkWindowAssociation()
  177. {
  178. // when the component becomes invisible, some stuff like flash
  179. // carries on playing audio, so we need to force it onto a blank
  180. // page to avoid this, (and send it back when it's made visible again).
  181. if (isShowing())
  182. {
  183. if (blankPageShown)
  184. goBack();
  185. }
  186. else
  187. {
  188. if (! blankPageShown)
  189. {
  190. blankPageShown = true;
  191. browser->goToURL ("about:blank", 0, 0);
  192. }
  193. }
  194. }
  195. void WebBrowserComponent::reloadLastURL()
  196. {
  197. if (lastURL.isNotEmpty())
  198. {
  199. goToURL (lastURL, &lastHeaders, &lastPostData);
  200. lastURL = String::empty;
  201. }
  202. }
  203. void WebBrowserComponent::parentHierarchyChanged()
  204. {
  205. checkWindowAssociation();
  206. }
  207. void WebBrowserComponent::resized()
  208. {
  209. browser->setSize (getWidth(), getHeight());
  210. }
  211. void WebBrowserComponent::visibilityChanged()
  212. {
  213. checkWindowAssociation();
  214. }
  215. bool WebBrowserComponent::pageAboutToLoad (const String& url)
  216. {
  217. return true;
  218. }
  219. #endif