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.

265 lines
7.8KB

  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. private:
  119. WebView* webView;
  120. DownloadClickDetector* clickListener;
  121. };
  122. //==============================================================================
  123. WebBrowserComponent::WebBrowserComponent()
  124. : browser (0),
  125. blankPageShown (false)
  126. {
  127. setOpaque (true);
  128. addAndMakeVisible (browser = new WebBrowserComponentInternal (this));
  129. }
  130. WebBrowserComponent::~WebBrowserComponent()
  131. {
  132. deleteAndZero (browser);
  133. }
  134. //==============================================================================
  135. void WebBrowserComponent::goToURL (const String& url,
  136. const StringArray* headers,
  137. const MemoryBlock* postData)
  138. {
  139. lastURL = url;
  140. lastHeaders.clear();
  141. if (headers != 0)
  142. lastHeaders = *headers;
  143. lastPostData.setSize (0);
  144. if (postData != 0)
  145. lastPostData = *postData;
  146. blankPageShown = false;
  147. browser->goToURL (url, headers, postData);
  148. }
  149. void WebBrowserComponent::stop()
  150. {
  151. browser->stop();
  152. }
  153. void WebBrowserComponent::goBack()
  154. {
  155. lastURL = String::empty;
  156. blankPageShown = false;
  157. browser->goBack();
  158. }
  159. void WebBrowserComponent::goForward()
  160. {
  161. lastURL = String::empty;
  162. browser->goForward();
  163. }
  164. //==============================================================================
  165. void WebBrowserComponent::paint (Graphics& g)
  166. {
  167. }
  168. void WebBrowserComponent::checkWindowAssociation()
  169. {
  170. // when the component becomes invisible, some stuff like flash
  171. // carries on playing audio, so we need to force it onto a blank
  172. // page to avoid this, (and send it back when it's made visible again).
  173. if (isShowing())
  174. {
  175. if (blankPageShown)
  176. goBack();
  177. }
  178. else
  179. {
  180. if (! blankPageShown)
  181. {
  182. blankPageShown = true;
  183. browser->goToURL ("about:blank", 0, 0);
  184. }
  185. }
  186. }
  187. void WebBrowserComponent::reloadLastURL()
  188. {
  189. if (lastURL.isNotEmpty())
  190. {
  191. goToURL (lastURL, &lastHeaders, &lastPostData);
  192. lastURL = String::empty;
  193. }
  194. }
  195. void WebBrowserComponent::parentHierarchyChanged()
  196. {
  197. checkWindowAssociation();
  198. }
  199. void WebBrowserComponent::resized()
  200. {
  201. browser->setSize (getWidth(), getHeight());
  202. }
  203. void WebBrowserComponent::visibilityChanged()
  204. {
  205. checkWindowAssociation();
  206. }
  207. bool WebBrowserComponent::pageAboutToLoad (const String& url)
  208. {
  209. return true;
  210. }
  211. #endif