WebFrame.cpp 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784
  1. /*
  2. * Copyright (C) 2010 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. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
  14. * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  15. * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
  17. * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  18. * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  19. * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  20. * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
  21. * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  22. * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
  23. * THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "WebFrame.h"
  27. #include "DownloadManager.h"
  28. #include "InjectedBundleHitTestResult.h"
  29. #include "InjectedBundleNodeHandle.h"
  30. #include "InjectedBundleRangeHandle.h"
  31. #include "InjectedBundleScriptWorld.h"
  32. #include "PluginView.h"
  33. #include "WKAPICast.h"
  34. #include "WKBundleAPICast.h"
  35. #include "WebChromeClient.h"
  36. #include "WebPage.h"
  37. #include "WebPageProxyMessages.h"
  38. #include "WebProcess.h"
  39. #include <JavaScriptCore/APICast.h>
  40. #include <JavaScriptCore/JSContextRef.h>
  41. #include <JavaScriptCore/JSLock.h>
  42. #include <JavaScriptCore/JSValueRef.h>
  43. #include <WebCore/ArchiveResource.h>
  44. #include <WebCore/Chrome.h>
  45. #include <WebCore/DocumentLoader.h>
  46. #include <WebCore/EventHandler.h>
  47. #include <WebCore/Frame.h>
  48. #include <WebCore/FrameView.h>
  49. #include <WebCore/HTMLFrameOwnerElement.h>
  50. #include <WebCore/HTMLNames.h>
  51. #include <WebCore/JSCSSStyleDeclaration.h>
  52. #include <WebCore/JSElement.h>
  53. #include <WebCore/JSRange.h>
  54. #include <WebCore/NetworkingContext.h>
  55. #include <WebCore/NodeTraversal.h>
  56. #include <WebCore/Page.h>
  57. #include <WebCore/PluginDocument.h>
  58. #include <WebCore/RenderTreeAsText.h>
  59. #include <WebCore/ResourceBuffer.h>
  60. #include <WebCore/ResourceLoader.h>
  61. #include <WebCore/ScriptController.h>
  62. #include <WebCore/SecurityOrigin.h>
  63. #include <WebCore/TextIterator.h>
  64. #include <WebCore/TextResourceDecoder.h>
  65. #include <wtf/text/StringBuilder.h>
  66. #if PLATFORM(MAC)
  67. #include <WebCore/LegacyWebArchive.h>
  68. #endif
  69. #if ENABLE(NETWORK_PROCESS)
  70. #include "NetworkConnectionToWebProcessMessages.h"
  71. #include "NetworkProcessConnection.h"
  72. #include "WebCoreArgumentCoders.h"
  73. #endif
  74. #ifndef NDEBUG
  75. #include <wtf/RefCountedLeakCounter.h>
  76. #endif
  77. using namespace JSC;
  78. using namespace WebCore;
  79. namespace WebKit {
  80. DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, webFrameCounter, ("WebFrame"));
  81. static uint64_t generateFrameID()
  82. {
  83. static uint64_t uniqueFrameID = 1;
  84. return uniqueFrameID++;
  85. }
  86. static uint64_t generateListenerID()
  87. {
  88. static uint64_t uniqueListenerID = 1;
  89. return uniqueListenerID++;
  90. }
  91. PassRefPtr<WebFrame> WebFrame::createMainFrame(WebPage* page)
  92. {
  93. RefPtr<WebFrame> frame = create();
  94. page->send(Messages::WebPageProxy::DidCreateMainFrame(frame->frameID()));
  95. frame->init(page, String(), 0);
  96. return frame.release();
  97. }
  98. PassRefPtr<WebFrame> WebFrame::createSubframe(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
  99. {
  100. RefPtr<WebFrame> frame = create();
  101. page->send(Messages::WebPageProxy::DidCreateSubframe(frame->frameID()));
  102. frame->init(page, frameName, ownerElement);
  103. return frame.release();
  104. }
  105. PassRefPtr<WebFrame> WebFrame::create()
  106. {
  107. RefPtr<WebFrame> frame = adoptRef(new WebFrame);
  108. // Add explict ref() that will be balanced in WebFrameLoaderClient::frameLoaderDestroyed().
  109. frame->ref();
  110. return frame.release();
  111. }
  112. WebFrame::WebFrame()
  113. : m_coreFrame(0)
  114. , m_policyListenerID(0)
  115. , m_policyFunction(0)
  116. , m_policyDownloadID(0)
  117. , m_frameLoaderClient(this)
  118. , m_loadListener(0)
  119. , m_frameID(generateFrameID())
  120. {
  121. WebProcess::shared().addWebFrame(m_frameID, this);
  122. #ifndef NDEBUG
  123. webFrameCounter.increment();
  124. #endif
  125. }
  126. WebFrame::~WebFrame()
  127. {
  128. ASSERT(!m_coreFrame);
  129. #ifndef NDEBUG
  130. webFrameCounter.decrement();
  131. #endif
  132. }
  133. void WebFrame::init(WebPage* page, const String& frameName, HTMLFrameOwnerElement* ownerElement)
  134. {
  135. RefPtr<Frame> frame = Frame::create(page->corePage(), ownerElement, &m_frameLoaderClient);
  136. m_coreFrame = frame.get();
  137. frame->tree()->setName(frameName);
  138. if (ownerElement) {
  139. ASSERT(ownerElement->document()->frame());
  140. ownerElement->document()->frame()->tree()->appendChild(frame);
  141. }
  142. frame->init();
  143. }
  144. WebPage* WebFrame::page() const
  145. {
  146. if (!m_coreFrame)
  147. return 0;
  148. if (Page* page = m_coreFrame->page())
  149. return WebPage::fromCorePage(page);
  150. return 0;
  151. }
  152. void WebFrame::invalidate()
  153. {
  154. WebProcess::shared().removeWebFrame(m_frameID);
  155. m_coreFrame = 0;
  156. }
  157. uint64_t WebFrame::setUpPolicyListener(WebCore::FramePolicyFunction policyFunction)
  158. {
  159. // FIXME: <rdar://5634381> We need to support multiple active policy listeners.
  160. invalidatePolicyListener();
  161. m_policyListenerID = generateListenerID();
  162. m_policyFunction = policyFunction;
  163. return m_policyListenerID;
  164. }
  165. void WebFrame::invalidatePolicyListener()
  166. {
  167. if (!m_policyListenerID)
  168. return;
  169. m_policyDownloadID = 0;
  170. m_policyListenerID = 0;
  171. m_policyFunction = 0;
  172. }
  173. void WebFrame::didReceivePolicyDecision(uint64_t listenerID, PolicyAction action, uint64_t downloadID)
  174. {
  175. if (!m_coreFrame)
  176. return;
  177. if (!m_policyListenerID)
  178. return;
  179. if (listenerID != m_policyListenerID)
  180. return;
  181. ASSERT(m_policyFunction);
  182. FramePolicyFunction function = m_policyFunction;
  183. invalidatePolicyListener();
  184. m_policyDownloadID = downloadID;
  185. (m_coreFrame->loader()->policyChecker()->*function)(action);
  186. }
  187. void WebFrame::startDownload(const WebCore::ResourceRequest& request)
  188. {
  189. ASSERT(m_policyDownloadID);
  190. uint64_t policyDownloadID = m_policyDownloadID;
  191. m_policyDownloadID = 0;
  192. #if ENABLE(NETWORK_PROCESS)
  193. if (WebProcess::shared().usesNetworkProcess()) {
  194. bool privateBrowsingEnabled = m_coreFrame->loader()->networkingContext()->storageSession().isPrivateBrowsingSession();
  195. WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::StartDownload(privateBrowsingEnabled, policyDownloadID, request), 0);
  196. return;
  197. }
  198. #endif
  199. WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
  200. }
  201. void WebFrame::convertMainResourceLoadToDownload(DocumentLoader* documentLoader, const ResourceRequest& request, const ResourceResponse& response)
  202. {
  203. ASSERT(m_policyDownloadID);
  204. uint64_t policyDownloadID = m_policyDownloadID;
  205. m_policyDownloadID = 0;
  206. ResourceLoader* mainResourceLoader = documentLoader->mainResourceLoader();
  207. #if ENABLE(NETWORK_PROCESS)
  208. if (WebProcess::shared().usesNetworkProcess()) {
  209. // Use 0 to indicate that there is no main resource loader.
  210. // This can happen if the main resource is in the WebCore memory cache.
  211. uint64_t mainResourceLoadIdentifier;
  212. if (mainResourceLoader)
  213. mainResourceLoadIdentifier = mainResourceLoader->identifier();
  214. else
  215. mainResourceLoadIdentifier = 0;
  216. WebProcess::shared().networkConnection()->connection()->send(Messages::NetworkConnectionToWebProcess::ConvertMainResourceLoadToDownload(mainResourceLoadIdentifier, policyDownloadID, request, response), 0);
  217. return;
  218. }
  219. #endif
  220. if (!mainResourceLoader) {
  221. // The main resource has already been loaded. Start a new download instead.
  222. WebProcess::shared().downloadManager().startDownload(policyDownloadID, request);
  223. return;
  224. }
  225. WebProcess::shared().downloadManager().convertHandleToDownload(policyDownloadID, documentLoader->mainResourceLoader()->handle(), request, response);
  226. }
  227. String WebFrame::source() const
  228. {
  229. if (!m_coreFrame)
  230. return String();
  231. Document* document = m_coreFrame->document();
  232. if (!document)
  233. return String();
  234. TextResourceDecoder* decoder = document->decoder();
  235. if (!decoder)
  236. return String();
  237. DocumentLoader* documentLoader = m_coreFrame->loader()->activeDocumentLoader();
  238. if (!documentLoader)
  239. return String();
  240. RefPtr<ResourceBuffer> mainResourceData = documentLoader->mainResourceData();
  241. if (!mainResourceData)
  242. return String();
  243. return decoder->encoding().decode(mainResourceData->data(), mainResourceData->size());
  244. }
  245. String WebFrame::contentsAsString() const
  246. {
  247. if (!m_coreFrame)
  248. return String();
  249. if (isFrameSet()) {
  250. StringBuilder builder;
  251. for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
  252. if (!builder.isEmpty())
  253. builder.append(' ');
  254. WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(child->loader()->client());
  255. WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
  256. ASSERT(webFrame);
  257. builder.append(webFrame->contentsAsString());
  258. }
  259. // FIXME: It may make sense to use toStringPreserveCapacity() here.
  260. return builder.toString();
  261. }
  262. Document* document = m_coreFrame->document();
  263. if (!document)
  264. return String();
  265. RefPtr<Element> documentElement = document->documentElement();
  266. if (!documentElement)
  267. return String();
  268. RefPtr<Range> range = document->createRange();
  269. ExceptionCode ec = 0;
  270. range->selectNode(documentElement.get(), ec);
  271. if (ec)
  272. return String();
  273. return plainText(range.get());
  274. }
  275. String WebFrame::selectionAsString() const
  276. {
  277. if (!m_coreFrame)
  278. return String();
  279. return m_coreFrame->displayStringModifiedByEncoding(m_coreFrame->editor().selectedText());
  280. }
  281. IntSize WebFrame::size() const
  282. {
  283. if (!m_coreFrame)
  284. return IntSize();
  285. FrameView* frameView = m_coreFrame->view();
  286. if (!frameView)
  287. return IntSize();
  288. return frameView->contentsSize();
  289. }
  290. bool WebFrame::isFrameSet() const
  291. {
  292. if (!m_coreFrame)
  293. return false;
  294. Document* document = m_coreFrame->document();
  295. if (!document)
  296. return false;
  297. return document->isFrameSet();
  298. }
  299. bool WebFrame::isMainFrame() const
  300. {
  301. if (WebPage* p = page())
  302. return p->mainWebFrame() == this;
  303. return false;
  304. }
  305. String WebFrame::name() const
  306. {
  307. if (!m_coreFrame)
  308. return String();
  309. return m_coreFrame->tree()->uniqueName();
  310. }
  311. String WebFrame::url() const
  312. {
  313. if (!m_coreFrame)
  314. return String();
  315. DocumentLoader* documentLoader = m_coreFrame->loader()->documentLoader();
  316. if (!documentLoader)
  317. return String();
  318. return documentLoader->url().string();
  319. }
  320. String WebFrame::innerText() const
  321. {
  322. if (!m_coreFrame)
  323. return String();
  324. if (!m_coreFrame->document()->documentElement())
  325. return String();
  326. return m_coreFrame->document()->documentElement()->innerText();
  327. }
  328. WebFrame* WebFrame::parentFrame() const
  329. {
  330. if (!m_coreFrame || !m_coreFrame->ownerElement() || !m_coreFrame->ownerElement()->document())
  331. return 0;
  332. WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(m_coreFrame->ownerElement()->document()->frame()->loader()->client());
  333. return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
  334. }
  335. PassRefPtr<ImmutableArray> WebFrame::childFrames()
  336. {
  337. if (!m_coreFrame)
  338. return ImmutableArray::create();
  339. size_t size = m_coreFrame->tree()->childCount();
  340. if (!size)
  341. return ImmutableArray::create();
  342. Vector<RefPtr<APIObject>> vector;
  343. vector.reserveInitialCapacity(size);
  344. for (Frame* child = m_coreFrame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
  345. WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(child->loader()->client());
  346. WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
  347. ASSERT(webFrame);
  348. vector.uncheckedAppend(webFrame);
  349. }
  350. return ImmutableArray::adopt(vector);
  351. }
  352. String WebFrame::layerTreeAsText() const
  353. {
  354. if (!m_coreFrame)
  355. return "";
  356. return m_coreFrame->layerTreeAsText(0);
  357. }
  358. unsigned WebFrame::pendingUnloadCount() const
  359. {
  360. if (!m_coreFrame)
  361. return 0;
  362. return m_coreFrame->document()->domWindow()->pendingUnloadEventListeners();
  363. }
  364. bool WebFrame::allowsFollowingLink(const WebCore::KURL& url) const
  365. {
  366. if (!m_coreFrame)
  367. return true;
  368. return m_coreFrame->document()->securityOrigin()->canDisplay(url);
  369. }
  370. JSGlobalContextRef WebFrame::jsContext()
  371. {
  372. return toGlobalRef(m_coreFrame->script()->globalObject(mainThreadNormalWorld())->globalExec());
  373. }
  374. JSGlobalContextRef WebFrame::jsContextForWorld(InjectedBundleScriptWorld* world)
  375. {
  376. return toGlobalRef(m_coreFrame->script()->globalObject(world->coreWorld())->globalExec());
  377. }
  378. bool WebFrame::handlesPageScaleGesture() const
  379. {
  380. if (!m_coreFrame->document()->isPluginDocument())
  381. return 0;
  382. PluginDocument* pluginDocument = static_cast<PluginDocument*>(m_coreFrame->document());
  383. PluginView* pluginView = static_cast<PluginView*>(pluginDocument->pluginWidget());
  384. return pluginView && pluginView->handlesPageScaleFactor();
  385. }
  386. IntRect WebFrame::contentBounds() const
  387. {
  388. if (!m_coreFrame)
  389. return IntRect();
  390. FrameView* view = m_coreFrame->view();
  391. if (!view)
  392. return IntRect();
  393. return IntRect(0, 0, view->contentsWidth(), view->contentsHeight());
  394. }
  395. IntRect WebFrame::visibleContentBounds() const
  396. {
  397. if (!m_coreFrame)
  398. return IntRect();
  399. FrameView* view = m_coreFrame->view();
  400. if (!view)
  401. return IntRect();
  402. IntRect contentRect = view->visibleContentRect(ScrollableArea::IncludeScrollbars);
  403. return IntRect(0, 0, contentRect.width(), contentRect.height());
  404. }
  405. IntRect WebFrame::visibleContentBoundsExcludingScrollbars() const
  406. {
  407. if (!m_coreFrame)
  408. return IntRect();
  409. FrameView* view = m_coreFrame->view();
  410. if (!view)
  411. return IntRect();
  412. IntRect contentRect = view->visibleContentRect();
  413. return IntRect(0, 0, contentRect.width(), contentRect.height());
  414. }
  415. IntSize WebFrame::scrollOffset() const
  416. {
  417. if (!m_coreFrame)
  418. return IntSize();
  419. FrameView* view = m_coreFrame->view();
  420. if (!view)
  421. return IntSize();
  422. return view->scrollOffset();
  423. }
  424. bool WebFrame::hasHorizontalScrollbar() const
  425. {
  426. if (!m_coreFrame)
  427. return false;
  428. FrameView* view = m_coreFrame->view();
  429. if (!view)
  430. return false;
  431. return view->horizontalScrollbar();
  432. }
  433. bool WebFrame::hasVerticalScrollbar() const
  434. {
  435. if (!m_coreFrame)
  436. return false;
  437. FrameView* view = m_coreFrame->view();
  438. if (!view)
  439. return false;
  440. return view->verticalScrollbar();
  441. }
  442. PassRefPtr<InjectedBundleHitTestResult> WebFrame::hitTest(const IntPoint point) const
  443. {
  444. if (!m_coreFrame)
  445. return 0;
  446. return InjectedBundleHitTestResult::create(m_coreFrame->eventHandler()->hitTestResultAtPoint(point, HitTestRequest::ReadOnly | HitTestRequest::Active | HitTestRequest::IgnoreClipping | HitTestRequest::DisallowShadowContent));
  447. }
  448. bool WebFrame::getDocumentBackgroundColor(double* red, double* green, double* blue, double* alpha)
  449. {
  450. if (!m_coreFrame)
  451. return false;
  452. FrameView* view = m_coreFrame->view();
  453. if (!view)
  454. return false;
  455. Color bgColor = view->documentBackgroundColor();
  456. if (!bgColor.isValid())
  457. return false;
  458. bgColor.getRGBA(*red, *green, *blue, *alpha);
  459. return true;
  460. }
  461. bool WebFrame::containsAnyFormElements() const
  462. {
  463. if (!m_coreFrame)
  464. return false;
  465. Document* document = m_coreFrame->document();
  466. if (!document)
  467. return false;
  468. for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
  469. if (!node->isElementNode())
  470. continue;
  471. if (toElement(node)->hasTagName(HTMLNames::formTag))
  472. return true;
  473. }
  474. return false;
  475. }
  476. bool WebFrame::containsAnyFormControls() const
  477. {
  478. if (!m_coreFrame)
  479. return false;
  480. Document* document = m_coreFrame->document();
  481. if (!document)
  482. return false;
  483. for (Node* node = document->documentElement(); node; node = NodeTraversal::next(node)) {
  484. if (!node->isElementNode())
  485. continue;
  486. if (toElement(node)->hasTagName(HTMLNames::inputTag) || toElement(node)->hasTagName(HTMLNames::selectTag) || toElement(node)->hasTagName(HTMLNames::textareaTag))
  487. return true;
  488. }
  489. return false;
  490. }
  491. void WebFrame::stopLoading()
  492. {
  493. if (!m_coreFrame)
  494. return;
  495. m_coreFrame->loader()->stopForUserCancel();
  496. }
  497. WebFrame* WebFrame::frameForContext(JSContextRef context)
  498. {
  499. JSObjectRef globalObjectRef = JSContextGetGlobalObject(context);
  500. JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
  501. if (strcmp(globalObjectObj->classInfo()->className, "JSDOMWindowShell") != 0)
  502. return 0;
  503. Frame* coreFrame = static_cast<JSDOMWindowShell*>(globalObjectObj)->window()->impl()->frame();
  504. WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(coreFrame->loader()->client());
  505. return webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
  506. }
  507. JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleNodeHandle* nodeHandle, InjectedBundleScriptWorld* world)
  508. {
  509. if (!m_coreFrame)
  510. return 0;
  511. JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
  512. ExecState* exec = globalObject->globalExec();
  513. JSLockHolder lock(exec);
  514. return toRef(exec, toJS(exec, globalObject, nodeHandle->coreNode()));
  515. }
  516. JSValueRef WebFrame::jsWrapperForWorld(InjectedBundleRangeHandle* rangeHandle, InjectedBundleScriptWorld* world)
  517. {
  518. if (!m_coreFrame)
  519. return 0;
  520. JSDOMWindow* globalObject = m_coreFrame->script()->globalObject(world->coreWorld());
  521. ExecState* exec = globalObject->globalExec();
  522. JSLockHolder lock(exec);
  523. return toRef(exec, toJS(exec, globalObject, rangeHandle->coreRange()));
  524. }
  525. String WebFrame::counterValue(JSObjectRef element)
  526. {
  527. if (!toJS(element)->inherits(&JSElement::s_info))
  528. return String();
  529. return counterValueForElement(static_cast<JSElement*>(toJS(element))->impl());
  530. }
  531. String WebFrame::provisionalURL() const
  532. {
  533. if (!m_coreFrame)
  534. return String();
  535. return m_coreFrame->loader()->provisionalDocumentLoader()->url().string();
  536. }
  537. String WebFrame::suggestedFilenameForResourceWithURL(const KURL& url) const
  538. {
  539. if (!m_coreFrame)
  540. return String();
  541. DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
  542. if (!loader)
  543. return String();
  544. // First, try the main resource.
  545. if (loader->url() == url)
  546. return loader->response().suggestedFilename();
  547. // Next, try subresources.
  548. RefPtr<ArchiveResource> resource = loader->subresource(url);
  549. if (resource)
  550. return resource->response().suggestedFilename();
  551. return page()->cachedSuggestedFilenameForURL(url);
  552. }
  553. String WebFrame::mimeTypeForResourceWithURL(const KURL& url) const
  554. {
  555. if (!m_coreFrame)
  556. return String();
  557. DocumentLoader* loader = m_coreFrame->loader()->documentLoader();
  558. if (!loader)
  559. return String();
  560. // First, try the main resource.
  561. if (loader->url() == url)
  562. return loader->response().mimeType();
  563. // Next, try subresources.
  564. RefPtr<ArchiveResource> resource = loader->subresource(url);
  565. if (resource)
  566. return resource->mimeType();
  567. return page()->cachedResponseMIMETypeForURL(url);
  568. }
  569. void WebFrame::setTextDirection(const String& direction)
  570. {
  571. if (!m_coreFrame)
  572. return;
  573. if (direction == "auto")
  574. m_coreFrame->editor().setBaseWritingDirection(NaturalWritingDirection);
  575. else if (direction == "ltr")
  576. m_coreFrame->editor().setBaseWritingDirection(LeftToRightWritingDirection);
  577. else if (direction == "rtl")
  578. m_coreFrame->editor().setBaseWritingDirection(RightToLeftWritingDirection);
  579. }
  580. #if PLATFORM(MAC)
  581. class WebFrameFilter : public FrameFilter {
  582. public:
  583. WebFrameFilter(WebFrame*, WebFrame::FrameFilterFunction, void* context);
  584. private:
  585. virtual bool shouldIncludeSubframe(Frame*) const OVERRIDE;
  586. WebFrame* m_topLevelWebFrame;
  587. WebFrame::FrameFilterFunction m_callback;
  588. void* m_context;
  589. };
  590. WebFrameFilter::WebFrameFilter(WebFrame* topLevelWebFrame, WebFrame::FrameFilterFunction callback, void* context)
  591. : m_topLevelWebFrame(topLevelWebFrame)
  592. , m_callback(callback)
  593. , m_context(context)
  594. {
  595. }
  596. bool WebFrameFilter::shouldIncludeSubframe(Frame* frame) const
  597. {
  598. if (!m_callback)
  599. return true;
  600. WebFrameLoaderClient* webFrameLoaderClient = toWebFrameLoaderClient(frame->loader()->client());
  601. WebFrame* webFrame = webFrameLoaderClient ? webFrameLoaderClient->webFrame() : 0;
  602. ASSERT(webFrame);
  603. return m_callback(toAPI(m_topLevelWebFrame), toAPI(webFrame), m_context);
  604. }
  605. RetainPtr<CFDataRef> WebFrame::webArchiveData(FrameFilterFunction callback, void* context)
  606. {
  607. WebFrameFilter filter(this, callback, context);
  608. if (RefPtr<LegacyWebArchive> archive = LegacyWebArchive::create(coreFrame()->document(), &filter))
  609. return archive->rawDataRepresentation();
  610. return 0;
  611. }
  612. #endif
  613. } // namespace WebKit