PageRenderTime 51ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/src/qt/qtwebkit/Source/WebCore/page/Frame.cpp

https://gitlab.com/x33n/phantomjs
C++ | 1167 lines | 900 code | 176 blank | 91 comment | 228 complexity | d701ef2ee9d9ef4de49c2c628377f4bb MD5 | raw file
  1. /*
  2. * Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
  3. * 1999 Lars Knoll <knoll@kde.org>
  4. * 1999 Antti Koivisto <koivisto@kde.org>
  5. * 2000 Simon Hausmann <hausmann@kde.org>
  6. * 2000 Stefan Schimanski <1Stein@gmx.de>
  7. * 2001 George Staikos <staikos@kde.org>
  8. * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011 Apple Inc. All rights reserved.
  9. * Copyright (C) 2005 Alexey Proskuryakov <ap@nypop.com>
  10. * Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies)
  11. * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
  12. * Copyright (C) 2008 Google Inc.
  13. *
  14. * This library is free software; you can redistribute it and/or
  15. * modify it under the terms of the GNU Library General Public
  16. * License as published by the Free Software Foundation; either
  17. * version 2 of the License, or (at your option) any later version.
  18. *
  19. * This library is distributed in the hope that it will be useful,
  20. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  21. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  22. * Library General Public License for more details.
  23. *
  24. * You should have received a copy of the GNU Library General Public License
  25. * along with this library; see the file COPYING.LIB. If not, write to
  26. * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
  27. * Boston, MA 02110-1301, USA.
  28. */
  29. #include "config.h"
  30. #include "Frame.h"
  31. #include "AnimationController.h"
  32. #include "ApplyStyleCommand.h"
  33. #include "BackForwardController.h"
  34. #include "CSSComputedStyleDeclaration.h"
  35. #include "CSSPropertyNames.h"
  36. #include "CachedCSSStyleSheet.h"
  37. #include "CachedResourceLoader.h"
  38. #include "Chrome.h"
  39. #include "ChromeClient.h"
  40. #include "DOMWindow.h"
  41. #include "DocumentType.h"
  42. #include "Editor.h"
  43. #include "EditorClient.h"
  44. #include "Event.h"
  45. #include "EventHandler.h"
  46. #include "EventNames.h"
  47. #include "FloatQuad.h"
  48. #include "FocusController.h"
  49. #include "FrameDestructionObserver.h"
  50. #include "FrameLoader.h"
  51. #include "FrameLoaderClient.h"
  52. #include "FrameSelection.h"
  53. #include "FrameView.h"
  54. #include "GraphicsContext.h"
  55. #include "GraphicsLayer.h"
  56. #include "HTMLDocument.h"
  57. #include "HTMLFormControlElement.h"
  58. #include "HTMLFormElement.h"
  59. #include "HTMLFrameElementBase.h"
  60. #include "HTMLNames.h"
  61. #include "HTMLTableCellElement.h"
  62. #include "HitTestResult.h"
  63. #include "ImageBuffer.h"
  64. #include "InspectorInstrumentation.h"
  65. #include "JSDOMWindowShell.h"
  66. #include "Logging.h"
  67. #include "MathMLNames.h"
  68. #include "MediaFeatureNames.h"
  69. #include "Navigator.h"
  70. #include "NodeList.h"
  71. #include "NodeTraversal.h"
  72. #include "Page.h"
  73. #include "PageCache.h"
  74. #include "PageGroup.h"
  75. #include "RegularExpression.h"
  76. #include "RenderPart.h"
  77. #include "RenderTableCell.h"
  78. #include "RenderTextControl.h"
  79. #include "RenderTheme.h"
  80. #include "RenderView.h"
  81. #include "RuntimeEnabledFeatures.h"
  82. #include "SVGNames.h"
  83. #include "ScriptController.h"
  84. #include "ScriptSourceCode.h"
  85. #include "ScriptValue.h"
  86. #include "ScrollingCoordinator.h"
  87. #include "Settings.h"
  88. #include "StylePropertySet.h"
  89. #include "TextIterator.h"
  90. #include "TextResourceDecoder.h"
  91. #include "UserContentURLPattern.h"
  92. #include "UserTypingGestureIndicator.h"
  93. #include "VisibleUnits.h"
  94. #include "WebKitFontFamilyNames.h"
  95. #include "XLinkNames.h"
  96. #include "XMLNSNames.h"
  97. #include "XMLNames.h"
  98. #include "htmlediting.h"
  99. #include "markup.h"
  100. #include "npruntime_impl.h"
  101. #include "runtime_root.h"
  102. #include <wtf/PassOwnPtr.h>
  103. #include <wtf/RefCountedLeakCounter.h>
  104. #include <wtf/StdLibExtras.h>
  105. #if USE(ACCELERATED_COMPOSITING)
  106. #include "RenderLayerCompositor.h"
  107. #endif
  108. #if ENABLE(SVG)
  109. #include "SVGDocument.h"
  110. #include "SVGDocumentExtensions.h"
  111. #endif
  112. #if USE(TILED_BACKING_STORE)
  113. #include "TiledBackingStore.h"
  114. #endif
  115. using namespace std;
  116. namespace WebCore {
  117. using namespace HTMLNames;
  118. DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, frameCounter, ("Frame"));
  119. static inline Frame* parentFromOwnerElement(HTMLFrameOwnerElement* ownerElement)
  120. {
  121. if (!ownerElement)
  122. return 0;
  123. return ownerElement->document()->frame();
  124. }
  125. static inline float parentPageZoomFactor(Frame* frame)
  126. {
  127. Frame* parent = frame->tree()->parent();
  128. if (!parent)
  129. return 1;
  130. return parent->pageZoomFactor();
  131. }
  132. static inline float parentTextZoomFactor(Frame* frame)
  133. {
  134. Frame* parent = frame->tree()->parent();
  135. if (!parent)
  136. return 1;
  137. return parent->textZoomFactor();
  138. }
  139. inline Frame::Frame(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* frameLoaderClient)
  140. : m_page(page)
  141. , m_treeNode(this, parentFromOwnerElement(ownerElement))
  142. , m_loader(this, frameLoaderClient)
  143. , m_navigationScheduler(this)
  144. , m_ownerElement(ownerElement)
  145. , m_script(adoptPtr(new ScriptController(this)))
  146. , m_editor(adoptPtr(new Editor(this)))
  147. , m_selection(adoptPtr(new FrameSelection(this)))
  148. , m_eventHandler(adoptPtr(new EventHandler(this)))
  149. , m_animationController(adoptPtr(new AnimationController(this)))
  150. , m_pageZoomFactor(parentPageZoomFactor(this))
  151. , m_textZoomFactor(parentTextZoomFactor(this))
  152. #if ENABLE(ORIENTATION_EVENTS)
  153. , m_orientation(0)
  154. #endif
  155. , m_inViewSourceMode(false)
  156. , m_activeDOMObjectsAndAnimationsSuspendedCount(0)
  157. {
  158. ASSERT(page);
  159. AtomicString::init();
  160. HTMLNames::init();
  161. QualifiedName::init();
  162. MediaFeatureNames::init();
  163. SVGNames::init();
  164. XLinkNames::init();
  165. MathMLNames::init();
  166. XMLNSNames::init();
  167. XMLNames::init();
  168. WebKitFontFamilyNames::init();
  169. if (!ownerElement) {
  170. #if USE(TILED_BACKING_STORE)
  171. // Top level frame only for now.
  172. setTiledBackingStoreEnabled(page->settings()->tiledBackingStoreEnabled());
  173. #endif
  174. } else {
  175. page->incrementSubframeCount();
  176. ownerElement->setContentFrame(this);
  177. }
  178. #ifndef NDEBUG
  179. frameCounter.increment();
  180. #endif
  181. // Pause future ActiveDOMObjects if this frame is being created while the page is in a paused state.
  182. Frame* parent = parentFromOwnerElement(ownerElement);
  183. if (parent && parent->activeDOMObjectsAndAnimationsSuspended())
  184. suspendActiveDOMObjectsAndAnimations();
  185. }
  186. PassRefPtr<Frame> Frame::create(Page* page, HTMLFrameOwnerElement* ownerElement, FrameLoaderClient* client)
  187. {
  188. RefPtr<Frame> frame = adoptRef(new Frame(page, ownerElement, client));
  189. if (!ownerElement)
  190. page->setMainFrame(frame);
  191. return frame.release();
  192. }
  193. Frame::~Frame()
  194. {
  195. setView(0);
  196. loader()->cancelAndClear();
  197. // FIXME: We should not be doing all this work inside the destructor
  198. #ifndef NDEBUG
  199. frameCounter.decrement();
  200. #endif
  201. disconnectOwnerElement();
  202. HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
  203. for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
  204. (*it)->frameDestroyed();
  205. }
  206. bool Frame::inScope(TreeScope* scope) const
  207. {
  208. ASSERT(scope);
  209. Document* doc = document();
  210. if (!doc)
  211. return false;
  212. HTMLFrameOwnerElement* owner = doc->ownerElement();
  213. if (!owner)
  214. return false;
  215. return owner->treeScope() == scope;
  216. }
  217. void Frame::addDestructionObserver(FrameDestructionObserver* observer)
  218. {
  219. m_destructionObservers.add(observer);
  220. }
  221. void Frame::removeDestructionObserver(FrameDestructionObserver* observer)
  222. {
  223. m_destructionObservers.remove(observer);
  224. }
  225. void Frame::setView(PassRefPtr<FrameView> view)
  226. {
  227. // We the custom scroll bars as early as possible to prevent m_doc->detach()
  228. // from messing with the view such that its scroll bars won't be torn down.
  229. // FIXME: We should revisit this.
  230. if (m_view)
  231. m_view->prepareForDetach();
  232. // Prepare for destruction now, so any unload event handlers get run and the DOMWindow is
  233. // notified. If we wait until the view is destroyed, then things won't be hooked up enough for
  234. // these calls to work.
  235. if (!view && m_doc && m_doc->attached() && !m_doc->inPageCache()) {
  236. // FIXME: We don't call willRemove here. Why is that OK?
  237. m_doc->prepareForDestruction();
  238. }
  239. if (m_view)
  240. m_view->unscheduleRelayout();
  241. eventHandler()->clear();
  242. m_view = view;
  243. // Only one form submission is allowed per view of a part.
  244. // Since this part may be getting reused as a result of being
  245. // pulled from the back/forward cache, reset this flag.
  246. loader()->resetMultipleFormSubmissionProtection();
  247. #if USE(TILED_BACKING_STORE)
  248. if (m_view && tiledBackingStore())
  249. m_view->setPaintsEntireContents(true);
  250. #endif
  251. }
  252. void Frame::setDocument(PassRefPtr<Document> newDoc)
  253. {
  254. ASSERT(!newDoc || newDoc->frame() == this);
  255. if (m_doc && m_doc->attached() && !m_doc->inPageCache()) {
  256. // FIXME: We don't call willRemove here. Why is that OK?
  257. m_doc->detach();
  258. }
  259. m_doc = newDoc;
  260. ASSERT(!m_doc || m_doc->domWindow());
  261. ASSERT(!m_doc || m_doc->domWindow()->frame() == this);
  262. if (m_doc && !m_doc->attached())
  263. m_doc->attach();
  264. if (m_doc) {
  265. m_script->updateDocument();
  266. m_doc->updateViewportArguments();
  267. }
  268. if (m_page && m_page->mainFrame() == this) {
  269. notifyChromeClientWheelEventHandlerCountChanged();
  270. #if ENABLE(TOUCH_EVENTS)
  271. if (m_doc && m_doc->hasTouchEventHandlers())
  272. m_page->chrome().client()->needTouchEvents(true);
  273. #endif
  274. }
  275. // Suspend document if this frame was created in suspended state.
  276. if (m_doc && activeDOMObjectsAndAnimationsSuspended()) {
  277. m_doc->suspendScriptedAnimationControllerCallbacks();
  278. m_animationController->suspendAnimationsForDocument(m_doc.get());
  279. m_doc->suspendActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
  280. }
  281. }
  282. #if ENABLE(ORIENTATION_EVENTS)
  283. void Frame::sendOrientationChangeEvent(int orientation)
  284. {
  285. m_orientation = orientation;
  286. if (Document* doc = document())
  287. doc->dispatchWindowEvent(Event::create(eventNames().orientationchangeEvent, false, false));
  288. }
  289. #endif // ENABLE(ORIENTATION_EVENTS)
  290. Settings* Frame::settings() const
  291. {
  292. return m_page ? m_page->settings() : 0;
  293. }
  294. static PassOwnPtr<RegularExpression> createRegExpForLabels(const Vector<String>& labels)
  295. {
  296. // REVIEW- version of this call in FrameMac.mm caches based on the NSArray ptrs being
  297. // the same across calls. We can't do that.
  298. DEFINE_STATIC_LOCAL(RegularExpression, wordRegExp, ("\\w", TextCaseSensitive));
  299. String pattern("(");
  300. unsigned int numLabels = labels.size();
  301. unsigned int i;
  302. for (i = 0; i < numLabels; i++) {
  303. String label = labels[i];
  304. bool startsWithWordChar = false;
  305. bool endsWithWordChar = false;
  306. if (label.length()) {
  307. startsWithWordChar = wordRegExp.match(label.substring(0, 1)) >= 0;
  308. endsWithWordChar = wordRegExp.match(label.substring(label.length() - 1, 1)) >= 0;
  309. }
  310. if (i)
  311. pattern.append("|");
  312. // Search for word boundaries only if label starts/ends with "word characters".
  313. // If we always searched for word boundaries, this wouldn't work for languages
  314. // such as Japanese.
  315. if (startsWithWordChar)
  316. pattern.append("\\b");
  317. pattern.append(label);
  318. if (endsWithWordChar)
  319. pattern.append("\\b");
  320. }
  321. pattern.append(")");
  322. return adoptPtr(new RegularExpression(pattern, TextCaseInsensitive));
  323. }
  324. String Frame::searchForLabelsAboveCell(RegularExpression* regExp, HTMLTableCellElement* cell, size_t* resultDistanceFromStartOfCell)
  325. {
  326. HTMLTableCellElement* aboveCell = cell->cellAbove();
  327. if (aboveCell) {
  328. // search within the above cell we found for a match
  329. size_t lengthSearched = 0;
  330. for (Node* n = aboveCell->firstChild(); n; n = NodeTraversal::next(n, aboveCell)) {
  331. if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
  332. // For each text chunk, run the regexp
  333. String nodeString = n->nodeValue();
  334. int pos = regExp->searchRev(nodeString);
  335. if (pos >= 0) {
  336. if (resultDistanceFromStartOfCell)
  337. *resultDistanceFromStartOfCell = lengthSearched;
  338. return nodeString.substring(pos, regExp->matchedLength());
  339. }
  340. lengthSearched += nodeString.length();
  341. }
  342. }
  343. }
  344. // Any reason in practice to search all cells in that are above cell?
  345. if (resultDistanceFromStartOfCell)
  346. *resultDistanceFromStartOfCell = notFound;
  347. return String();
  348. }
  349. String Frame::searchForLabelsBeforeElement(const Vector<String>& labels, Element* element, size_t* resultDistance, bool* resultIsInCellAbove)
  350. {
  351. OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
  352. // We stop searching after we've seen this many chars
  353. const unsigned int charsSearchedThreshold = 500;
  354. // This is the absolute max we search. We allow a little more slop than
  355. // charsSearchedThreshold, to make it more likely that we'll search whole nodes.
  356. const unsigned int maxCharsSearched = 600;
  357. // If the starting element is within a table, the cell that contains it
  358. HTMLTableCellElement* startingTableCell = 0;
  359. bool searchedCellAbove = false;
  360. if (resultDistance)
  361. *resultDistance = notFound;
  362. if (resultIsInCellAbove)
  363. *resultIsInCellAbove = false;
  364. // walk backwards in the node tree, until another element, or form, or end of tree
  365. int unsigned lengthSearched = 0;
  366. Node* n;
  367. for (n = NodeTraversal::previous(element); n && lengthSearched < charsSearchedThreshold; n = NodeTraversal::previous(n)) {
  368. // We hit another form element or the start of the form - bail out
  369. if (isHTMLFormElement(n) || (n->isHTMLElement() && toElement(n)->isFormControlElement()))
  370. break;
  371. if (n->hasTagName(tdTag) && !startingTableCell) {
  372. startingTableCell = static_cast<HTMLTableCellElement*>(n);
  373. } else if (n->hasTagName(trTag) && startingTableCell) {
  374. String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
  375. if (!result.isEmpty()) {
  376. if (resultIsInCellAbove)
  377. *resultIsInCellAbove = true;
  378. return result;
  379. }
  380. searchedCellAbove = true;
  381. } else if (n->isTextNode() && n->renderer() && n->renderer()->style()->visibility() == VISIBLE) {
  382. // For each text chunk, run the regexp
  383. String nodeString = n->nodeValue();
  384. // add 100 for slop, to make it more likely that we'll search whole nodes
  385. if (lengthSearched + nodeString.length() > maxCharsSearched)
  386. nodeString = nodeString.right(charsSearchedThreshold - lengthSearched);
  387. int pos = regExp->searchRev(nodeString);
  388. if (pos >= 0) {
  389. if (resultDistance)
  390. *resultDistance = lengthSearched;
  391. return nodeString.substring(pos, regExp->matchedLength());
  392. }
  393. lengthSearched += nodeString.length();
  394. }
  395. }
  396. // If we started in a cell, but bailed because we found the start of the form or the
  397. // previous element, we still might need to search the row above us for a label.
  398. if (startingTableCell && !searchedCellAbove) {
  399. String result = searchForLabelsAboveCell(regExp.get(), startingTableCell, resultDistance);
  400. if (!result.isEmpty()) {
  401. if (resultIsInCellAbove)
  402. *resultIsInCellAbove = true;
  403. return result;
  404. }
  405. }
  406. return String();
  407. }
  408. static String matchLabelsAgainstString(const Vector<String>& labels, const String& stringToMatch)
  409. {
  410. if (stringToMatch.isEmpty())
  411. return String();
  412. String mutableStringToMatch = stringToMatch;
  413. // Make numbers and _'s in field names behave like word boundaries, e.g., "address2"
  414. replace(mutableStringToMatch, RegularExpression("\\d", TextCaseSensitive), " ");
  415. mutableStringToMatch.replace('_', ' ');
  416. OwnPtr<RegularExpression> regExp(createRegExpForLabels(labels));
  417. // Use the largest match we can find in the whole string
  418. int pos;
  419. int length;
  420. int bestPos = -1;
  421. int bestLength = -1;
  422. int start = 0;
  423. do {
  424. pos = regExp->match(mutableStringToMatch, start);
  425. if (pos != -1) {
  426. length = regExp->matchedLength();
  427. if (length >= bestLength) {
  428. bestPos = pos;
  429. bestLength = length;
  430. }
  431. start = pos + 1;
  432. }
  433. } while (pos != -1);
  434. if (bestPos != -1)
  435. return mutableStringToMatch.substring(bestPos, bestLength);
  436. return String();
  437. }
  438. String Frame::matchLabelsAgainstElement(const Vector<String>& labels, Element* element)
  439. {
  440. // Match against the name element, then against the id element if no match is found for the name element.
  441. // See 7538330 for one popular site that benefits from the id element check.
  442. // FIXME: This code is mirrored in FrameMac.mm. It would be nice to make the Mac code call the platform-agnostic
  443. // code, which would require converting the NSArray of NSStrings to a Vector of Strings somewhere along the way.
  444. String resultFromNameAttribute = matchLabelsAgainstString(labels, element->getNameAttribute());
  445. if (!resultFromNameAttribute.isEmpty())
  446. return resultFromNameAttribute;
  447. return matchLabelsAgainstString(labels, element->getAttribute(idAttr));
  448. }
  449. void Frame::setPrinting(bool printing, const FloatSize& pageSize, const FloatSize& originalPageSize, float maximumShrinkRatio, AdjustViewSizeOrNot shouldAdjustViewSize)
  450. {
  451. m_pageResets.clear();
  452. // In setting printing, we should not validate resources already cached for the document.
  453. // See https://bugs.webkit.org/show_bug.cgi?id=43704
  454. ResourceCacheValidationSuppressor validationSuppressor(m_doc->cachedResourceLoader());
  455. m_doc->setPrinting(printing);
  456. view()->adjustMediaTypeForPrinting(printing);
  457. m_doc->styleResolverChanged(RecalcStyleImmediately);
  458. if (shouldUsePrintingLayout()) {
  459. view()->forceLayoutForPagination(pageSize, originalPageSize, maximumShrinkRatio, shouldAdjustViewSize);
  460. } else {
  461. view()->forceLayout();
  462. if (shouldAdjustViewSize == AdjustViewSize)
  463. view()->adjustViewSize();
  464. }
  465. // Subframes of the one we're printing don't lay out to the page size.
  466. for (RefPtr<Frame> child = tree()->firstChild(); child; child = child->tree()->nextSibling())
  467. child->setPrinting(printing, FloatSize(), FloatSize(), 0, shouldAdjustViewSize);
  468. }
  469. bool Frame::shouldUsePrintingLayout() const
  470. {
  471. // Only top frame being printed should be fit to page size.
  472. // Subframes should be constrained by parents only.
  473. return m_doc->printing() && (!tree()->parent() || !tree()->parent()->m_doc->printing());
  474. }
  475. FloatSize Frame::resizePageRectsKeepingRatio(const FloatSize& originalSize, const FloatSize& expectedSize)
  476. {
  477. FloatSize resultSize;
  478. if (!contentRenderer())
  479. return FloatSize();
  480. if (contentRenderer()->style()->isHorizontalWritingMode()) {
  481. ASSERT(fabs(originalSize.width()) > numeric_limits<float>::epsilon());
  482. float ratio = originalSize.height() / originalSize.width();
  483. resultSize.setWidth(floorf(expectedSize.width()));
  484. resultSize.setHeight(floorf(resultSize.width() * ratio));
  485. } else {
  486. ASSERT(fabs(originalSize.height()) > numeric_limits<float>::epsilon());
  487. float ratio = originalSize.width() / originalSize.height();
  488. resultSize.setHeight(floorf(expectedSize.height()));
  489. resultSize.setWidth(floorf(resultSize.height() * ratio));
  490. }
  491. return resultSize;
  492. }
  493. void Frame::addResetPage(int page)
  494. {
  495. m_pageResets.append(page);
  496. }
  497. void Frame::getPagination(int page, int pages, int& logicalPage, int& logicalPages) const
  498. {
  499. logicalPage = page;
  500. logicalPages = pages;
  501. int last_j = 0;
  502. int j = 0;
  503. for(size_t i = 0; i < m_pageResets.size(); ++i) {
  504. j = m_pageResets.at(i);
  505. if (j >= page) {
  506. break;
  507. }
  508. last_j = j;
  509. }
  510. if (page > last_j) {
  511. logicalPage = page - last_j;
  512. }
  513. if (last_j) {
  514. if (j > last_j) {
  515. logicalPages = j - last_j;
  516. } else {
  517. logicalPages = pages - last_j;
  518. }
  519. } else if (j >= page && j < pages) {
  520. logicalPages = j;
  521. }
  522. }
  523. void Frame::injectUserScripts(UserScriptInjectionTime injectionTime)
  524. {
  525. if (!m_page)
  526. return;
  527. if (loader()->stateMachine()->creatingInitialEmptyDocument() && !settings()->shouldInjectUserScriptsInInitialEmptyDocument())
  528. return;
  529. // Walk the hashtable. Inject by world.
  530. const UserScriptMap* userScripts = m_page->group().userScripts();
  531. if (!userScripts)
  532. return;
  533. UserScriptMap::const_iterator end = userScripts->end();
  534. for (UserScriptMap::const_iterator it = userScripts->begin(); it != end; ++it)
  535. injectUserScriptsForWorld(it->key.get(), *it->value, injectionTime);
  536. }
  537. void Frame::injectUserScriptsForWorld(DOMWrapperWorld* world, const UserScriptVector& userScripts, UserScriptInjectionTime injectionTime)
  538. {
  539. if (userScripts.isEmpty())
  540. return;
  541. Document* doc = document();
  542. if (!doc)
  543. return;
  544. Vector<ScriptSourceCode> sourceCode;
  545. unsigned count = userScripts.size();
  546. for (unsigned i = 0; i < count; ++i) {
  547. UserScript* script = userScripts[i].get();
  548. if (script->injectedFrames() == InjectInTopFrameOnly && ownerElement())
  549. continue;
  550. if (script->injectionTime() == injectionTime && UserContentURLPattern::matchesPatterns(doc->url(), script->whitelist(), script->blacklist()))
  551. m_script->evaluateInWorld(ScriptSourceCode(script->source(), script->url()), world);
  552. }
  553. }
  554. RenderView* Frame::contentRenderer() const
  555. {
  556. return document() ? document()->renderView() : 0;
  557. }
  558. RenderPart* Frame::ownerRenderer() const
  559. {
  560. HTMLFrameOwnerElement* ownerElement = m_ownerElement;
  561. if (!ownerElement)
  562. return 0;
  563. RenderObject* object = ownerElement->renderer();
  564. if (!object)
  565. return 0;
  566. // FIXME: If <object> is ever fixed to disassociate itself from frames
  567. // that it has started but canceled, then this can turn into an ASSERT
  568. // since m_ownerElement would be 0 when the load is canceled.
  569. // https://bugs.webkit.org/show_bug.cgi?id=18585
  570. if (!object->isRenderPart())
  571. return 0;
  572. return toRenderPart(object);
  573. }
  574. Frame* Frame::frameForWidget(const Widget* widget)
  575. {
  576. ASSERT_ARG(widget, widget);
  577. if (RenderWidget* renderer = RenderWidget::find(widget))
  578. if (Node* node = renderer->node())
  579. return node->document()->frame();
  580. // Assume all widgets are either a FrameView or owned by a RenderWidget.
  581. // FIXME: That assumption is not right for scroll bars!
  582. ASSERT_WITH_SECURITY_IMPLICATION(widget->isFrameView());
  583. return toFrameView(widget)->frame();
  584. }
  585. void Frame::clearTimers(FrameView *view, Document *document)
  586. {
  587. if (view) {
  588. view->unscheduleRelayout();
  589. if (view->frame()) {
  590. view->frame()->animation()->suspendAnimationsForDocument(document);
  591. view->frame()->eventHandler()->stopAutoscrollTimer();
  592. }
  593. }
  594. }
  595. void Frame::clearTimers()
  596. {
  597. clearTimers(m_view.get(), document());
  598. }
  599. #if ENABLE(PAGE_VISIBILITY_API)
  600. void Frame::dispatchVisibilityStateChangeEvent()
  601. {
  602. if (m_doc)
  603. m_doc->dispatchVisibilityStateChangeEvent();
  604. Vector<RefPtr<Frame> > childFrames;
  605. for (Frame* child = tree()->firstChild(); child; child = child->tree()->nextSibling())
  606. childFrames.append(child);
  607. for (size_t i = 0; i < childFrames.size(); ++i)
  608. childFrames[i]->dispatchVisibilityStateChangeEvent();
  609. }
  610. #endif
  611. void Frame::willDetachPage()
  612. {
  613. if (Frame* parent = tree()->parent())
  614. parent->loader()->checkLoadComplete();
  615. HashSet<FrameDestructionObserver*>::iterator stop = m_destructionObservers.end();
  616. for (HashSet<FrameDestructionObserver*>::iterator it = m_destructionObservers.begin(); it != stop; ++it)
  617. (*it)->willDetachPage();
  618. // FIXME: It's unclear as to why this is called more than once, but it is,
  619. // so page() could be NULL.
  620. if (page() && page()->focusController()->focusedFrame() == this)
  621. page()->focusController()->setFocusedFrame(0);
  622. if (page() && page()->scrollingCoordinator() && m_view)
  623. page()->scrollingCoordinator()->willDestroyScrollableArea(m_view.get());
  624. script()->clearScriptObjects();
  625. script()->updatePlatformScriptObjects();
  626. }
  627. void Frame::disconnectOwnerElement()
  628. {
  629. if (m_ownerElement) {
  630. if (Document* doc = document())
  631. doc->topDocument()->clearAXObjectCache();
  632. m_ownerElement->clearContentFrame();
  633. if (m_page)
  634. m_page->decrementSubframeCount();
  635. }
  636. m_ownerElement = 0;
  637. }
  638. String Frame::documentTypeString() const
  639. {
  640. if (DocumentType* doctype = document()->doctype())
  641. return createMarkup(doctype);
  642. return String();
  643. }
  644. String Frame::displayStringModifiedByEncoding(const String& str) const
  645. {
  646. return document() ? document()->displayStringModifiedByEncoding(str) : str;
  647. }
  648. VisiblePosition Frame::visiblePositionForPoint(const IntPoint& framePoint)
  649. {
  650. HitTestResult result = eventHandler()->hitTestResultAtPoint(framePoint, HitTestRequest::ReadOnly | HitTestRequest::Active);
  651. Node* node = result.innerNonSharedNode();
  652. if (!node)
  653. return VisiblePosition();
  654. RenderObject* renderer = node->renderer();
  655. if (!renderer)
  656. return VisiblePosition();
  657. VisiblePosition visiblePos = renderer->positionForPoint(result.localPoint());
  658. if (visiblePos.isNull())
  659. visiblePos = firstPositionInOrBeforeNode(node);
  660. return visiblePos;
  661. }
  662. Document* Frame::documentAtPoint(const IntPoint& point)
  663. {
  664. if (!view())
  665. return 0;
  666. IntPoint pt = view()->windowToContents(point);
  667. HitTestResult result = HitTestResult(pt);
  668. if (contentRenderer())
  669. result = eventHandler()->hitTestResultAtPoint(pt);
  670. return result.innerNode() ? result.innerNode()->document() : 0;
  671. }
  672. PassRefPtr<Range> Frame::rangeForPoint(const IntPoint& framePoint)
  673. {
  674. VisiblePosition position = visiblePositionForPoint(framePoint);
  675. if (position.isNull())
  676. return 0;
  677. VisiblePosition previous = position.previous();
  678. if (previous.isNotNull()) {
  679. RefPtr<Range> previousCharacterRange = makeRange(previous, position);
  680. LayoutRect rect = editor().firstRectForRange(previousCharacterRange.get());
  681. if (rect.contains(framePoint))
  682. return previousCharacterRange.release();
  683. }
  684. VisiblePosition next = position.next();
  685. if (RefPtr<Range> nextCharacterRange = makeRange(position, next)) {
  686. LayoutRect rect = editor().firstRectForRange(nextCharacterRange.get());
  687. if (rect.contains(framePoint))
  688. return nextCharacterRange.release();
  689. }
  690. return 0;
  691. }
  692. void Frame::createView(const IntSize& viewportSize, const Color& backgroundColor, bool transparent,
  693. const IntSize& fixedLayoutSize, const IntRect& fixedVisibleContentRect ,
  694. bool useFixedLayout, ScrollbarMode horizontalScrollbarMode, bool horizontalLock,
  695. ScrollbarMode verticalScrollbarMode, bool verticalLock)
  696. {
  697. ASSERT(this);
  698. ASSERT(m_page);
  699. bool isMainFrame = this == m_page->mainFrame();
  700. if (isMainFrame && view())
  701. view()->setParentVisible(false);
  702. setView(0);
  703. RefPtr<FrameView> frameView;
  704. if (isMainFrame) {
  705. frameView = FrameView::create(this, viewportSize);
  706. frameView->setFixedLayoutSize(fixedLayoutSize);
  707. frameView->setFixedVisibleContentRect(fixedVisibleContentRect);
  708. frameView->setUseFixedLayout(useFixedLayout);
  709. } else
  710. frameView = FrameView::create(this);
  711. frameView->setScrollbarModes(horizontalScrollbarMode, verticalScrollbarMode, horizontalLock, verticalLock);
  712. setView(frameView);
  713. if (backgroundColor.isValid())
  714. frameView->updateBackgroundRecursively(backgroundColor, transparent);
  715. if (isMainFrame)
  716. frameView->setParentVisible(true);
  717. if (ownerRenderer())
  718. ownerRenderer()->setWidget(frameView);
  719. if (HTMLFrameOwnerElement* owner = ownerElement())
  720. view()->setCanHaveScrollbars(owner->scrollingMode() != ScrollbarAlwaysOff);
  721. }
  722. #if USE(TILED_BACKING_STORE)
  723. void Frame::setTiledBackingStoreEnabled(bool enabled)
  724. {
  725. if (!enabled) {
  726. m_tiledBackingStore.clear();
  727. return;
  728. }
  729. if (m_tiledBackingStore)
  730. return;
  731. m_tiledBackingStore = adoptPtr(new TiledBackingStore(this));
  732. m_tiledBackingStore->setCommitTileUpdatesOnIdleEventLoop(true);
  733. if (m_view)
  734. m_view->setPaintsEntireContents(true);
  735. }
  736. void Frame::tiledBackingStorePaintBegin()
  737. {
  738. if (!m_view)
  739. return;
  740. m_view->updateLayoutAndStyleIfNeededRecursive();
  741. m_view->flushDeferredRepaints();
  742. }
  743. void Frame::tiledBackingStorePaint(GraphicsContext* context, const IntRect& rect)
  744. {
  745. if (!m_view)
  746. return;
  747. m_view->paintContents(context, rect);
  748. }
  749. void Frame::tiledBackingStorePaintEnd(const Vector<IntRect>& paintedArea)
  750. {
  751. if (!m_page || !m_view)
  752. return;
  753. unsigned size = paintedArea.size();
  754. // Request repaint from the system
  755. for (unsigned n = 0; n < size; ++n)
  756. m_page->chrome().invalidateContentsAndRootView(m_view->contentsToRootView(paintedArea[n]), false);
  757. }
  758. IntRect Frame::tiledBackingStoreContentsRect()
  759. {
  760. if (!m_view)
  761. return IntRect();
  762. return IntRect(IntPoint(), m_view->contentsSize());
  763. }
  764. IntRect Frame::tiledBackingStoreVisibleRect()
  765. {
  766. if (!m_page)
  767. return IntRect();
  768. return m_page->chrome().client()->visibleRectForTiledBackingStore();
  769. }
  770. Color Frame::tiledBackingStoreBackgroundColor() const
  771. {
  772. if (!m_view)
  773. return Color();
  774. return m_view->baseBackgroundColor();
  775. }
  776. #endif
  777. String Frame::layerTreeAsText(LayerTreeFlags flags) const
  778. {
  779. #if USE(ACCELERATED_COMPOSITING)
  780. document()->updateLayout();
  781. if (!contentRenderer())
  782. return String();
  783. return contentRenderer()->compositor()->layerTreeAsText(flags);
  784. #else
  785. UNUSED_PARAM(flags);
  786. return String();
  787. #endif
  788. }
  789. String Frame::trackedRepaintRectsAsText() const
  790. {
  791. if (!m_view)
  792. return String();
  793. return m_view->trackedRepaintRectsAsText();
  794. }
  795. void Frame::setPageZoomFactor(float factor)
  796. {
  797. setPageAndTextZoomFactors(factor, m_textZoomFactor);
  798. }
  799. void Frame::setTextZoomFactor(float factor)
  800. {
  801. setPageAndTextZoomFactors(m_pageZoomFactor, factor);
  802. }
  803. void Frame::setPageAndTextZoomFactors(float pageZoomFactor, float textZoomFactor)
  804. {
  805. if (m_pageZoomFactor == pageZoomFactor && m_textZoomFactor == textZoomFactor)
  806. return;
  807. Page* page = this->page();
  808. if (!page)
  809. return;
  810. Document* document = this->document();
  811. if (!document)
  812. return;
  813. m_editor->dismissCorrectionPanelAsIgnored();
  814. #if ENABLE(SVG)
  815. // Respect SVGs zoomAndPan="disabled" property in standalone SVG documents.
  816. // FIXME: How to handle compound documents + zoomAndPan="disabled"? Needs SVG WG clarification.
  817. if (document->isSVGDocument()) {
  818. if (!toSVGDocument(document)->zoomAndPanEnabled())
  819. return;
  820. }
  821. #endif
  822. if (m_pageZoomFactor != pageZoomFactor) {
  823. if (FrameView* view = this->view()) {
  824. // Update the scroll position when doing a full page zoom, so the content stays in relatively the same position.
  825. LayoutPoint scrollPosition = view->scrollPosition();
  826. float percentDifference = (pageZoomFactor / m_pageZoomFactor);
  827. view->setScrollPosition(IntPoint(scrollPosition.x() * percentDifference, scrollPosition.y() * percentDifference));
  828. }
  829. }
  830. m_pageZoomFactor = pageZoomFactor;
  831. m_textZoomFactor = textZoomFactor;
  832. document->recalcStyle(Node::Force);
  833. for (RefPtr<Frame> child = tree()->firstChild(); child; child = child->tree()->nextSibling())
  834. child->setPageAndTextZoomFactors(m_pageZoomFactor, m_textZoomFactor);
  835. if (FrameView* view = this->view()) {
  836. if (document->renderer() && document->renderer()->needsLayout() && view->didFirstLayout())
  837. view->layout();
  838. }
  839. if (page->mainFrame() == this)
  840. pageCache()->markPagesForFullStyleRecalc(page);
  841. }
  842. float Frame::frameScaleFactor() const
  843. {
  844. Page* page = this->page();
  845. // Main frame is scaled with respect to he container but inner frames are not scaled with respect to the main frame.
  846. if (!page || page->mainFrame() != this || page->settings()->applyPageScaleFactorInCompositor())
  847. return 1;
  848. return page->pageScaleFactor();
  849. }
  850. void Frame::suspendActiveDOMObjectsAndAnimations()
  851. {
  852. bool wasSuspended = activeDOMObjectsAndAnimationsSuspended();
  853. m_activeDOMObjectsAndAnimationsSuspendedCount++;
  854. if (wasSuspended)
  855. return;
  856. if (document()) {
  857. document()->suspendScriptedAnimationControllerCallbacks();
  858. animation()->suspendAnimationsForDocument(document());
  859. document()->suspendActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
  860. }
  861. }
  862. void Frame::resumeActiveDOMObjectsAndAnimations()
  863. {
  864. ASSERT(activeDOMObjectsAndAnimationsSuspended());
  865. m_activeDOMObjectsAndAnimationsSuspendedCount--;
  866. if (activeDOMObjectsAndAnimationsSuspended())
  867. return;
  868. if (document()) {
  869. document()->resumeActiveDOMObjects(ActiveDOMObject::PageWillBeSuspended);
  870. animation()->resumeAnimationsForDocument(document());
  871. document()->resumeScriptedAnimationControllerCallbacks();
  872. }
  873. if (m_view)
  874. m_view->resumeAnimatingImages();
  875. }
  876. #if USE(ACCELERATED_COMPOSITING)
  877. void Frame::deviceOrPageScaleFactorChanged()
  878. {
  879. for (RefPtr<Frame> child = tree()->firstChild(); child; child = child->tree()->nextSibling())
  880. child->deviceOrPageScaleFactorChanged();
  881. RenderView* root = contentRenderer();
  882. if (root && root->compositor())
  883. root->compositor()->deviceOrPageScaleFactorChanged();
  884. }
  885. #endif
  886. void Frame::notifyChromeClientWheelEventHandlerCountChanged() const
  887. {
  888. // Ensure that this method is being called on the main frame of the page.
  889. ASSERT(m_page && m_page->mainFrame() == this);
  890. unsigned count = 0;
  891. for (const Frame* frame = this; frame; frame = frame->tree()->traverseNext()) {
  892. if (frame->document())
  893. count += frame->document()->wheelEventHandlerCount();
  894. }
  895. m_page->chrome().client()->numWheelEventHandlersChanged(count);
  896. }
  897. bool Frame::isURLAllowed(const KURL& url) const
  898. {
  899. // We allow one level of self-reference because some sites depend on that,
  900. // but we don't allow more than one.
  901. if (m_page->subframeCount() >= Page::maxNumberOfFrames)
  902. return false;
  903. bool foundSelfReference = false;
  904. for (const Frame* frame = this; frame; frame = frame->tree()->parent()) {
  905. if (equalIgnoringFragmentIdentifier(frame->document()->url(), url)) {
  906. if (foundSelfReference)
  907. return false;
  908. foundSelfReference = true;
  909. }
  910. }
  911. return true;
  912. }
  913. #if !PLATFORM(MAC) && !PLATFORM(WIN)
  914. struct ScopedFramePaintingState {
  915. ScopedFramePaintingState(Frame* frame, Node* node)
  916. : frame(frame)
  917. , node(node)
  918. , paintBehavior(frame->view()->paintBehavior())
  919. , backgroundColor(frame->view()->baseBackgroundColor())
  920. {
  921. ASSERT(!node || node->renderer());
  922. if (node)
  923. node->renderer()->updateDragState(true);
  924. }
  925. ~ScopedFramePaintingState()
  926. {
  927. if (node && node->renderer())
  928. node->renderer()->updateDragState(false);
  929. frame->view()->setPaintBehavior(paintBehavior);
  930. frame->view()->setBaseBackgroundColor(backgroundColor);
  931. frame->view()->setNodeToDraw(0);
  932. }
  933. Frame* frame;
  934. Node* node;
  935. PaintBehavior paintBehavior;
  936. Color backgroundColor;
  937. };
  938. DragImageRef Frame::nodeImage(Node* node)
  939. {
  940. if (!node->renderer())
  941. return 0;
  942. const ScopedFramePaintingState state(this, node);
  943. m_view->setPaintBehavior(state.paintBehavior | PaintBehaviorFlattenCompositingLayers);
  944. // When generating the drag image for an element, ignore the document background.
  945. m_view->setBaseBackgroundColor(Color::transparent);
  946. m_doc->updateLayout();
  947. m_view->setNodeToDraw(node); // Enable special sub-tree drawing mode.
  948. // Document::updateLayout may have blown away the original RenderObject.
  949. RenderObject* renderer = node->renderer();
  950. if (!renderer)
  951. return 0;
  952. LayoutRect topLevelRect;
  953. IntRect paintingRect = pixelSnappedIntRect(renderer->paintingRootRect(topLevelRect));
  954. float deviceScaleFactor = 1;
  955. if (m_page)
  956. deviceScaleFactor = m_page->deviceScaleFactor();
  957. paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
  958. paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
  959. OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB));
  960. if (!buffer)
  961. return 0;
  962. buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
  963. buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
  964. m_view->paintContents(buffer->context(), paintingRect);
  965. RefPtr<Image> image = buffer->copyImage();
  966. return createDragImageFromImage(image.get(), renderer->shouldRespectImageOrientation());
  967. }
  968. DragImageRef Frame::dragImageForSelection()
  969. {
  970. if (!selection()->isRange())
  971. return 0;
  972. const ScopedFramePaintingState state(this, 0);
  973. m_view->setPaintBehavior(PaintBehaviorSelectionOnly);
  974. m_doc->updateLayout();
  975. IntRect paintingRect = enclosingIntRect(selection()->bounds());
  976. float deviceScaleFactor = 1;
  977. if (m_page)
  978. deviceScaleFactor = m_page->deviceScaleFactor();
  979. paintingRect.setWidth(paintingRect.width() * deviceScaleFactor);
  980. paintingRect.setHeight(paintingRect.height() * deviceScaleFactor);
  981. OwnPtr<ImageBuffer> buffer(ImageBuffer::create(paintingRect.size(), deviceScaleFactor, ColorSpaceDeviceRGB));
  982. if (!buffer)
  983. return 0;
  984. buffer->context()->translate(-paintingRect.x(), -paintingRect.y());
  985. buffer->context()->clip(FloatRect(0, 0, paintingRect.maxX(), paintingRect.maxY()));
  986. m_view->paintContents(buffer->context(), paintingRect);
  987. RefPtr<Image> image = buffer->copyImage();
  988. return createDragImageFromImage(image.get());
  989. }
  990. #endif
  991. } // namespace WebCore