| OLD | NEW |
| (Empty) |
| 1 /* | |
| 2 * Copyright (C) 2009 Google 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 are | |
| 6 * met: | |
| 7 * | |
| 8 * * Redistributions of source code must retain the above copyright | |
| 9 * notice, this list of conditions and the following disclaimer. | |
| 10 * * Redistributions in binary form must reproduce the above | |
| 11 * copyright notice, this list of conditions and the following disclaimer | |
| 12 * in the documentation and/or other materials provided with the | |
| 13 * distribution. | |
| 14 * * Neither the name of Google Inc. nor the names of its | |
| 15 * contributors may be used to endorse or promote products derived from | |
| 16 * this software without specific prior written permission. | |
| 17 * | |
| 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
| 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
| 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
| 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |
| 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |
| 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |
| 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
| 29 */ | |
| 30 | |
| 31 // How ownership works | |
| 32 // ------------------- | |
| 33 // | |
| 34 // Big oh represents a refcounted relationship: owner O--- ownee | |
| 35 // | |
| 36 // WebView (for the toplevel frame only) | |
| 37 // O | |
| 38 // | WebFrame | |
| 39 // | O | |
| 40 // | | | |
| 41 // Page O------- LocalFrame (m_mainFrame) O-------O FrameView | |
| 42 // || | |
| 43 // || | |
| 44 // FrameLoader | |
| 45 // | |
| 46 // FrameLoader and LocalFrame are formerly one object that was split apart becau
se | |
| 47 // it got too big. They basically have the same lifetime, hence the double line. | |
| 48 // | |
| 49 // From the perspective of the embedder, WebFrame is simply an object that it | |
| 50 // allocates by calling WebFrame::create() and must be freed by calling close(). | |
| 51 // Internally, WebFrame is actually refcounted and it holds a reference to its | |
| 52 // corresponding LocalFrame in WebCore. | |
| 53 // | |
| 54 // How frames are destroyed | |
| 55 // ------------------------ | |
| 56 // | |
| 57 // The main frame is never destroyed and is re-used. The FrameLoader is re-used | |
| 58 // and a reference to the main frame is kept by the Page. | |
| 59 // | |
| 60 // When frame content is replaced, all subframes are destroyed. This happens | |
| 61 // in FrameLoader::detachFromParent for each subframe in a pre-order depth-first | |
| 62 // traversal. Note that child node order may not match DOM node order! | |
| 63 // detachFromParent() calls FrameLoaderClient::detachedFromParent(), which calls | |
| 64 // WebFrame::frameDetached(). This triggers WebFrame to clear its reference to | |
| 65 // LocalFrame, and also notifies the embedder via WebFrameClient that the frame
is | |
| 66 // detached. Most embedders will invoke close() on the WebFrame at this point, | |
| 67 // triggering its deletion unless something else is still retaining a reference. | |
| 68 // | |
| 69 // Thie client is expected to be set whenever the WebLocalFrameImpl is attached
to | |
| 70 // the DOM. | |
| 71 | |
| 72 #include "sky/engine/web/WebLocalFrameImpl.h" | |
| 73 | |
| 74 #include <algorithm> | |
| 75 #include "base/strings/stringprintf.h" | |
| 76 #include "mojo/common/data_pipe_utils.h" | |
| 77 #include "mojo/public/cpp/system/data_pipe.h" | |
| 78 #include "sky/engine/bindings/exception_state.h" | |
| 79 #include "sky/engine/bindings/exception_state_placeholder.h" | |
| 80 #include "sky/engine/core/dom/Document.h" | |
| 81 #include "sky/engine/core/dom/Node.h" | |
| 82 #include "sky/engine/core/dom/NodeTraversal.h" | |
| 83 #include "sky/engine/core/dom/shadow/ShadowRoot.h" | |
| 84 #include "sky/engine/core/editing/Editor.h" | |
| 85 #include "sky/engine/core/editing/FrameSelection.h" | |
| 86 #include "sky/engine/core/editing/htmlediting.h" | |
| 87 #include "sky/engine/core/editing/InputMethodController.h" | |
| 88 #include "sky/engine/core/editing/PlainTextRange.h" | |
| 89 #include "sky/engine/core/editing/SpellChecker.h" | |
| 90 #include "sky/engine/core/editing/TextAffinity.h" | |
| 91 #include "sky/engine/core/editing/TextIterator.h" | |
| 92 #include "sky/engine/core/frame/FrameHost.h" | |
| 93 #include "sky/engine/core/frame/FrameView.h" | |
| 94 #include "sky/engine/core/frame/LocalDOMWindow.h" | |
| 95 #include "sky/engine/core/frame/Settings.h" | |
| 96 #include "sky/engine/core/html/HTMLAnchorElement.h" | |
| 97 #include "sky/engine/core/inspector/ConsoleMessage.h" | |
| 98 #include "sky/engine/core/loader/MojoLoader.h" | |
| 99 #include "sky/engine/core/page/EventHandler.h" | |
| 100 #include "sky/engine/core/page/FocusController.h" | |
| 101 #include "sky/engine/core/page/Page.h" | |
| 102 #include "sky/engine/core/rendering/HitTestResult.h" | |
| 103 #include "sky/engine/core/rendering/RenderBox.h" | |
| 104 #include "sky/engine/core/rendering/RenderLayer.h" | |
| 105 #include "sky/engine/core/rendering/RenderObject.h" | |
| 106 #include "sky/engine/core/rendering/RenderTreeAsText.h" | |
| 107 #include "sky/engine/core/rendering/RenderView.h" | |
| 108 #include "sky/engine/core/rendering/style/StyleInheritedData.h" | |
| 109 #include "sky/engine/platform/clipboard/ClipboardUtilities.h" | |
| 110 #include "sky/engine/platform/fonts/FontCache.h" | |
| 111 #include "sky/engine/platform/graphics/GraphicsContext.h" | |
| 112 #include "sky/engine/platform/graphics/skia/SkiaUtils.h" | |
| 113 #include "sky/engine/platform/heap/Handle.h" | |
| 114 #include "sky/engine/platform/network/ResourceRequest.h" | |
| 115 #include "sky/engine/platform/TraceEvent.h" | |
| 116 #include "sky/engine/platform/weborigin/KURL.h" | |
| 117 #include "sky/engine/platform/weborigin/SecurityPolicy.h" | |
| 118 #include "sky/engine/public/platform/Platform.h" | |
| 119 #include "sky/engine/public/platform/WebFloatPoint.h" | |
| 120 #include "sky/engine/public/platform/WebFloatRect.h" | |
| 121 #include "sky/engine/public/platform/WebLayer.h" | |
| 122 #include "sky/engine/public/platform/WebPoint.h" | |
| 123 #include "sky/engine/public/platform/WebRect.h" | |
| 124 #include "sky/engine/public/platform/WebSize.h" | |
| 125 #include "sky/engine/public/platform/WebURLError.h" | |
| 126 #include "sky/engine/public/platform/WebVector.h" | |
| 127 #include "sky/engine/public/web/WebConsoleMessage.h" | |
| 128 #include "sky/engine/public/web/WebDocument.h" | |
| 129 #include "sky/engine/public/web/WebElement.h" | |
| 130 #include "sky/engine/public/web/WebFrameClient.h" | |
| 131 #include "sky/engine/public/web/WebNode.h" | |
| 132 #include "sky/engine/public/web/WebRange.h" | |
| 133 #include "sky/engine/public/web/WebScriptSource.h" | |
| 134 #include "sky/engine/web/CompositionUnderlineVectorBuilder.h" | |
| 135 #include "sky/engine/web/WebViewImpl.h" | |
| 136 #include "sky/engine/wtf/CurrentTime.h" | |
| 137 #include "sky/engine/wtf/HashMap.h" | |
| 138 | |
| 139 namespace blink { | |
| 140 | |
| 141 static int frameCount = 0; | |
| 142 | |
| 143 // Key for a StatsCounter tracking how many WebFrames are active. | |
| 144 static const char webFrameActiveCount[] = "WebFrameActiveCount"; | |
| 145 | |
| 146 static void frameContentAsPlainText(size_t maxChars, LocalFrame* frame, StringBu
ilder& output) | |
| 147 { | |
| 148 Document* document = frame->document(); | |
| 149 if (!document) | |
| 150 return; | |
| 151 | |
| 152 if (!frame->view()) | |
| 153 return; | |
| 154 | |
| 155 // Select the document body. | |
| 156 RefPtr<Range> range(document->createRange()); | |
| 157 TrackExceptionState exceptionState; | |
| 158 range->selectNodeContents(document, exceptionState); | |
| 159 | |
| 160 if (!exceptionState.had_exception()) { | |
| 161 // The text iterator will walk nodes giving us text. This is similar to | |
| 162 // the plainText() function in core/editing/TextIterator.h, but we imple
ment the maximum | |
| 163 // size and also copy the results directly into a wstring, avoiding the | |
| 164 // string conversion. | |
| 165 for (TextIterator it(range.get()); !it.atEnd(); it.advance()) { | |
| 166 it.appendTextToStringBuilder(output, 0, maxChars - output.length()); | |
| 167 if (output.length() >= maxChars) | |
| 168 return; // Filled up the buffer. | |
| 169 } | |
| 170 } | |
| 171 } | |
| 172 | |
| 173 // WebFrame ------------------------------------------------------------------- | |
| 174 | |
| 175 int WebFrame::instanceCount() | |
| 176 { | |
| 177 return frameCount; | |
| 178 } | |
| 179 | |
| 180 bool WebLocalFrameImpl::isWebLocalFrame() const | |
| 181 { | |
| 182 return true; | |
| 183 } | |
| 184 | |
| 185 WebLocalFrame* WebLocalFrameImpl::toWebLocalFrame() | |
| 186 { | |
| 187 return this; | |
| 188 } | |
| 189 | |
| 190 void WebLocalFrameImpl::close() | |
| 191 { | |
| 192 m_client = 0; | |
| 193 | |
| 194 deref(); // Balances ref() acquired in WebFrame::create | |
| 195 } | |
| 196 | |
| 197 WebSize WebLocalFrameImpl::contentsSize() const | |
| 198 { | |
| 199 return frame()->view()->size(); | |
| 200 } | |
| 201 | |
| 202 bool WebLocalFrameImpl::hasVisibleContent() const | |
| 203 { | |
| 204 return frame()->view()->width() > 0 && frame()->view()->height() > 0; | |
| 205 } | |
| 206 | |
| 207 WebRect WebLocalFrameImpl::visibleContentRect() const | |
| 208 { | |
| 209 return frame()->view()->frameRect(); | |
| 210 } | |
| 211 | |
| 212 WebView* WebLocalFrameImpl::view() const | |
| 213 { | |
| 214 return viewImpl(); | |
| 215 } | |
| 216 | |
| 217 WebDocument WebLocalFrameImpl::document() const | |
| 218 { | |
| 219 if (!frame() || !frame()->document()) | |
| 220 return WebDocument(); | |
| 221 return WebDocument(frame()->document()); | |
| 222 } | |
| 223 | |
| 224 void WebLocalFrameImpl::executeScript(const WebScriptSource& source) | |
| 225 { | |
| 226 ASSERT(frame()); | |
| 227 // TODO(dart) | |
| 228 } | |
| 229 | |
| 230 void WebLocalFrameImpl::addMessageToConsole(const WebConsoleMessage& message) | |
| 231 { | |
| 232 ASSERT(frame()); | |
| 233 | |
| 234 MessageLevel webCoreMessageLevel; | |
| 235 switch (message.level) { | |
| 236 case WebConsoleMessage::LevelDebug: | |
| 237 webCoreMessageLevel = DebugMessageLevel; | |
| 238 break; | |
| 239 case WebConsoleMessage::LevelLog: | |
| 240 webCoreMessageLevel = LogMessageLevel; | |
| 241 break; | |
| 242 case WebConsoleMessage::LevelWarning: | |
| 243 webCoreMessageLevel = WarningMessageLevel; | |
| 244 break; | |
| 245 case WebConsoleMessage::LevelError: | |
| 246 webCoreMessageLevel = ErrorMessageLevel; | |
| 247 break; | |
| 248 default: | |
| 249 ASSERT_NOT_REACHED(); | |
| 250 return; | |
| 251 } | |
| 252 | |
| 253 frame()->document()->addConsoleMessage(ConsoleMessage::create(OtherMessageSo
urce, webCoreMessageLevel, message.text)); | |
| 254 } | |
| 255 | |
| 256 void WebLocalFrameImpl::collectGarbage() | |
| 257 { | |
| 258 // TODO(dart): Implement. | |
| 259 } | |
| 260 | |
| 261 void WebLocalFrameImpl::loadFromDataPipeWithURL(mojo::ScopedDataPipeConsumerHand
le responseStream, const WebURL& url) | |
| 262 { | |
| 263 frame()->mojoLoader().init(url); | |
| 264 frame()->mojoLoader().parse(responseStream.Pass()); | |
| 265 } | |
| 266 | |
| 267 void WebLocalFrameImpl::load(const WebURL& url) | |
| 268 { | |
| 269 frame()->mojoLoader().init(url); | |
| 270 m_fetcher = adoptPtr(new MojoFetcher(this, url)); | |
| 271 } | |
| 272 | |
| 273 void WebLocalFrameImpl::OnReceivedResponse(mojo::URLResponsePtr response) | |
| 274 { | |
| 275 m_fetcher.clear(); | |
| 276 if (response->body.is_valid()) { | |
| 277 frame()->mojoLoader().parse(response->body.Pass()); | |
| 278 return; | |
| 279 } | |
| 280 LOG(ERROR) << "Response for " << response->url | |
| 281 << " (status " << response->status_code << ") has no body."; | |
| 282 | |
| 283 // TODO(eseidel): This is a hack, but makes debugging way easier. | |
| 284 mojo::DataPipe pipe; | |
| 285 frame()->mojoLoader().parse(pipe.consumer_handle.Pass()); | |
| 286 std::string error_response = base::StringPrintf( | |
| 287 "<error><h style='display: paragraph'>Empty Body</h>" | |
| 288 "<l style='display: paragraph'>%d %s</l>" | |
| 289 "<m style='display: paragraph'>%s</m></t></error>", | |
| 290 response->status_code, response->status_line.get().c_str(), | |
| 291 response->error->description.get().c_str()); | |
| 292 | |
| 293 uint32_t length = error_response.length(); | |
| 294 MojoWriteData(pipe.producer_handle.get().value(), | |
| 295 error_response.data(), | |
| 296 &length, | |
| 297 MOJO_WRITE_DATA_FLAG_ALL_OR_NONE); | |
| 298 } | |
| 299 | |
| 300 void WebLocalFrameImpl::replaceSelection(const WebString& text) | |
| 301 { | |
| 302 bool selectReplacement = false; | |
| 303 bool smartReplace = true; | |
| 304 frame()->editor().replaceSelectionWithText(text, selectReplacement, smartRep
lace); | |
| 305 } | |
| 306 | |
| 307 void WebLocalFrameImpl::insertText(const WebString& text) | |
| 308 { | |
| 309 if (frame()->inputMethodController().hasComposition()) | |
| 310 frame()->inputMethodController().confirmComposition(text); | |
| 311 else | |
| 312 frame()->editor().insertText(text, 0); | |
| 313 } | |
| 314 | |
| 315 void WebLocalFrameImpl::setMarkedText(const WebString& text, unsigned location,
unsigned length) | |
| 316 { | |
| 317 Vector<CompositionUnderline> decorations; | |
| 318 frame()->inputMethodController().setComposition(text, decorations, location,
length); | |
| 319 } | |
| 320 | |
| 321 void WebLocalFrameImpl::unmarkText() | |
| 322 { | |
| 323 frame()->inputMethodController().cancelComposition(); | |
| 324 } | |
| 325 | |
| 326 bool WebLocalFrameImpl::hasMarkedText() const | |
| 327 { | |
| 328 return frame()->inputMethodController().hasComposition(); | |
| 329 } | |
| 330 | |
| 331 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebNode& nod
e) | |
| 332 { | |
| 333 ASSERT(frame()); | |
| 334 | |
| 335 if (name.length() <= 2) | |
| 336 return false; | |
| 337 | |
| 338 // Since we don't have NSControl, we will convert the format of command | |
| 339 // string and call the function on Editor directly. | |
| 340 String command = name; | |
| 341 | |
| 342 // Make sure the first letter is upper case. | |
| 343 command.replace(0, 1, command.substring(0, 1).upper()); | |
| 344 | |
| 345 // Remove the trailing ':' if existing. | |
| 346 if (command[command.length() - 1] == UChar(':')) | |
| 347 command = command.substring(0, command.length() - 1); | |
| 348 | |
| 349 return frame()->editor().executeCommand(command); | |
| 350 } | |
| 351 | |
| 352 bool WebLocalFrameImpl::executeCommand(const WebString& name, const WebString& v
alue, const WebNode& node) | |
| 353 { | |
| 354 ASSERT(frame()); | |
| 355 | |
| 356 return frame()->editor().executeCommand(name, value); | |
| 357 } | |
| 358 | |
| 359 bool WebLocalFrameImpl::isCommandEnabled(const WebString& name) const | |
| 360 { | |
| 361 ASSERT(frame()); | |
| 362 return frame()->editor().command(name).isEnabled(); | |
| 363 } | |
| 364 | |
| 365 void WebLocalFrameImpl::enableContinuousSpellChecking(bool enable) | |
| 366 { | |
| 367 if (enable == isContinuousSpellCheckingEnabled()) | |
| 368 return; | |
| 369 frame()->spellChecker().toggleContinuousSpellChecking(); | |
| 370 } | |
| 371 | |
| 372 bool WebLocalFrameImpl::isContinuousSpellCheckingEnabled() const | |
| 373 { | |
| 374 return frame()->spellChecker().isContinuousSpellCheckingEnabled(); | |
| 375 } | |
| 376 | |
| 377 void WebLocalFrameImpl::requestTextChecking(const WebElement& webElement) | |
| 378 { | |
| 379 if (webElement.isNull()) | |
| 380 return; | |
| 381 frame()->spellChecker().requestTextChecking(*webElement.constUnwrap<Element>
()); | |
| 382 } | |
| 383 | |
| 384 void WebLocalFrameImpl::replaceMisspelledRange(const WebString& text) | |
| 385 { | |
| 386 frame()->spellChecker().replaceMisspelledRange(text); | |
| 387 } | |
| 388 | |
| 389 void WebLocalFrameImpl::removeSpellingMarkers() | |
| 390 { | |
| 391 frame()->spellChecker().removeSpellingMarkers(); | |
| 392 } | |
| 393 | |
| 394 bool WebLocalFrameImpl::hasSelection() const | |
| 395 { | |
| 396 // frame()->selection()->isNone() never returns true. | |
| 397 return frame()->selection().start() != frame()->selection().end(); | |
| 398 } | |
| 399 | |
| 400 WebRange WebLocalFrameImpl::selectionRange() const | |
| 401 { | |
| 402 return frame()->selection().toNormalizedRange(); | |
| 403 } | |
| 404 | |
| 405 WebString WebLocalFrameImpl::selectionAsText() const | |
| 406 { | |
| 407 RefPtr<Range> range = frame()->selection().toNormalizedRange(); | |
| 408 if (!range) | |
| 409 return WebString(); | |
| 410 | |
| 411 String text = range->text(); | |
| 412 replaceNBSPWithSpace(text); | |
| 413 return text; | |
| 414 } | |
| 415 | |
| 416 void WebLocalFrameImpl::selectWordAroundPosition(LocalFrame* frame, VisiblePosit
ion position) | |
| 417 { | |
| 418 VisibleSelection selection(position); | |
| 419 selection.expandUsingGranularity(WordGranularity); | |
| 420 | |
| 421 TextGranularity granularity = selection.isRange() ? WordGranularity : Charac
terGranularity; | |
| 422 frame->selection().setSelection(selection, granularity); | |
| 423 } | |
| 424 | |
| 425 bool WebLocalFrameImpl::selectWordAroundCaret() | |
| 426 { | |
| 427 FrameSelection& selection = frame()->selection(); | |
| 428 if (selection.isNone() || selection.isRange()) | |
| 429 return false; | |
| 430 selectWordAroundPosition(frame(), selection.selection().visibleStart()); | |
| 431 return true; | |
| 432 } | |
| 433 | |
| 434 void WebLocalFrameImpl::selectRange(const WebPoint& base, const WebPoint& extent
) | |
| 435 { | |
| 436 moveRangeSelection(base, extent); | |
| 437 } | |
| 438 | |
| 439 void WebLocalFrameImpl::selectRange(const WebRange& webRange) | |
| 440 { | |
| 441 if (RefPtr<Range> range = static_cast<PassRefPtr<Range> >(webRange)) | |
| 442 frame()->selection().setSelectedRange(range.get(), VP_DEFAULT_AFFINITY,
FrameSelection::NonDirectional, NotUserTriggered); | |
| 443 } | |
| 444 | |
| 445 void WebLocalFrameImpl::moveRangeSelection(const WebPoint& base, const WebPoint&
extent) | |
| 446 { | |
| 447 VisiblePosition basePosition = visiblePositionForWindowPoint(base); | |
| 448 VisiblePosition extentPosition = visiblePositionForWindowPoint(extent); | |
| 449 VisibleSelection newSelection = VisibleSelection(basePosition, extentPositio
n); | |
| 450 frame()->selection().setSelection(newSelection, CharacterGranularity); | |
| 451 } | |
| 452 | |
| 453 void WebLocalFrameImpl::moveCaretSelection(const WebPoint& point) | |
| 454 { | |
| 455 Element* editable = frame()->selection().rootEditableElement(); | |
| 456 if (!editable) | |
| 457 return; | |
| 458 | |
| 459 VisiblePosition position = visiblePositionForWindowPoint(point); | |
| 460 frame()->selection().moveTo(position, UserTriggered); | |
| 461 } | |
| 462 | |
| 463 bool WebLocalFrameImpl::setEditableSelectionOffsets(int start, int end) | |
| 464 { | |
| 465 return frame()->inputMethodController().setEditableSelectionOffsets(PlainTex
tRange(start, end)); | |
| 466 } | |
| 467 | |
| 468 bool WebLocalFrameImpl::setCompositionFromExistingText(int compositionStart, int
compositionEnd, const WebVector<WebCompositionUnderline>& underlines) | |
| 469 { | |
| 470 if (!frame()->editor().canEdit()) | |
| 471 return false; | |
| 472 | |
| 473 InputMethodController& inputMethodController = frame()->inputMethodControlle
r(); | |
| 474 inputMethodController.cancelComposition(); | |
| 475 | |
| 476 if (compositionStart == compositionEnd) | |
| 477 return true; | |
| 478 | |
| 479 inputMethodController.setCompositionFromExistingText(CompositionUnderlineVec
torBuilder(underlines), compositionStart, compositionEnd); | |
| 480 | |
| 481 return true; | |
| 482 } | |
| 483 | |
| 484 void WebLocalFrameImpl::extendSelectionAndDelete(int before, int after) | |
| 485 { | |
| 486 frame()->inputMethodController().extendSelectionAndDelete(before, after); | |
| 487 } | |
| 488 | |
| 489 void WebLocalFrameImpl::setCaretVisible(bool visible) | |
| 490 { | |
| 491 frame()->selection().setCaretVisible(visible); | |
| 492 } | |
| 493 | |
| 494 VisiblePosition WebLocalFrameImpl::visiblePositionForWindowPoint(const WebPoint&
point) | |
| 495 { | |
| 496 HitTestRequest request = HitTestRequest::Move | HitTestRequest::ReadOnly | H
itTestRequest::Active | HitTestRequest::IgnoreClipping; | |
| 497 HitTestResult result(frame()->view()->windowToContents(roundedIntPoint(Float
Point(point)))); | |
| 498 frame()->document()->renderView()->hitTest(request, result.hitTestLocation()
, result); | |
| 499 | |
| 500 if (Node* node = result.targetNode()) | |
| 501 return frame()->selection().selection().visiblePositionRespectingEditing
Boundary(result.localPoint(), node); | |
| 502 return VisiblePosition(); | |
| 503 } | |
| 504 | |
| 505 WebString WebLocalFrameImpl::contentAsText(size_t maxChars) const | |
| 506 { | |
| 507 if (!frame()) | |
| 508 return WebString(); | |
| 509 StringBuilder text; | |
| 510 frameContentAsPlainText(maxChars, frame(), text); | |
| 511 return text.toString(); | |
| 512 } | |
| 513 | |
| 514 WebString WebLocalFrameImpl::renderTreeAsText(RenderAsTextControls toShow) const | |
| 515 { | |
| 516 RenderAsTextBehavior behavior = RenderAsTextBehaviorNormal; | |
| 517 | |
| 518 if (toShow & RenderAsTextDebug) | |
| 519 behavior |= RenderAsTextShowCompositedLayers | RenderAsTextShowAddresses
| RenderAsTextShowIDAndClass | RenderAsTextShowLayerNesting; | |
| 520 | |
| 521 return externalRepresentation(frame(), behavior); | |
| 522 } | |
| 523 | |
| 524 bool WebLocalFrameImpl::selectionStartHasSpellingMarkerFor(int from, int length)
const | |
| 525 { | |
| 526 if (!frame()) | |
| 527 return false; | |
| 528 return frame()->spellChecker().selectionStartHasSpellingMarkerFor(from, leng
th); | |
| 529 } | |
| 530 | |
| 531 // WebLocalFrameImpl public ----------------------------------------------------
----- | |
| 532 | |
| 533 WebLocalFrame* WebLocalFrame::create(WebFrameClient* client) | |
| 534 { | |
| 535 return WebLocalFrameImpl::create(client); | |
| 536 } | |
| 537 | |
| 538 WebLocalFrameImpl* WebLocalFrameImpl::create(WebFrameClient* client) | |
| 539 { | |
| 540 return adoptRef(new WebLocalFrameImpl(client)).leakRef(); | |
| 541 } | |
| 542 | |
| 543 WebLocalFrameImpl::WebLocalFrameImpl(WebFrameClient* client) | |
| 544 : m_frameLoaderClientImpl(this) | |
| 545 , m_client(client) | |
| 546 , m_inputEventsScaleFactorForEmulation(1) | |
| 547 { | |
| 548 Platform::current()->incrementStatsCounter(webFrameActiveCount); | |
| 549 frameCount++; | |
| 550 } | |
| 551 | |
| 552 WebLocalFrameImpl::~WebLocalFrameImpl() | |
| 553 { | |
| 554 Platform::current()->decrementStatsCounter(webFrameActiveCount); | |
| 555 frameCount--; | |
| 556 } | |
| 557 | |
| 558 void WebLocalFrameImpl::setCoreFrame(PassRefPtr<LocalFrame> frame) | |
| 559 { | |
| 560 m_frame = frame; | |
| 561 } | |
| 562 | |
| 563 PassRefPtr<LocalFrame> WebLocalFrameImpl::initializeCoreFrame(FrameHost* host) | |
| 564 { | |
| 565 RefPtr<LocalFrame> frame = LocalFrame::create(&m_frameLoaderClientImpl, host
); | |
| 566 setCoreFrame(frame); | |
| 567 return frame; | |
| 568 } | |
| 569 | |
| 570 void WebLocalFrameImpl::createFrameView() | |
| 571 { | |
| 572 TRACE_EVENT0("blink", "WebLocalFrameImpl::createFrameView"); | |
| 573 | |
| 574 ASSERT(frame()); // If frame() doesn't exist, we probably didn't init proper
ly. | |
| 575 | |
| 576 WebViewImpl* webView = viewImpl(); | |
| 577 frame()->createView(webView->size(), webView->baseBackgroundColor(), webView
->isTransparent()); | |
| 578 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffsetForE
mulation, m_inputEventsScaleFactorForEmulation); | |
| 579 } | |
| 580 | |
| 581 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame* frame) | |
| 582 { | |
| 583 if (!frame) | |
| 584 return 0; | |
| 585 return fromFrame(*frame); | |
| 586 } | |
| 587 | |
| 588 WebLocalFrameImpl* WebLocalFrameImpl::fromFrame(LocalFrame& frame) | |
| 589 { | |
| 590 FrameLoaderClient* client = frame.loaderClient(); | |
| 591 if (!client || !client->isFrameLoaderClientImpl()) | |
| 592 return 0; | |
| 593 return toFrameLoaderClientImpl(client)->webFrame(); | |
| 594 } | |
| 595 | |
| 596 WebViewImpl* WebLocalFrameImpl::viewImpl() const | |
| 597 { | |
| 598 if (!frame()) | |
| 599 return 0; | |
| 600 return WebViewImpl::fromPage(frame()->page()); | |
| 601 } | |
| 602 | |
| 603 void WebLocalFrameImpl::didFail(const ResourceError& error) | |
| 604 { | |
| 605 if (!client()) | |
| 606 return; | |
| 607 client()->didFailLoad(this, error); | |
| 608 } | |
| 609 | |
| 610 void WebLocalFrameImpl::setInputEventsTransformForEmulation(const IntSize& offse
t, float contentScaleFactor) | |
| 611 { | |
| 612 m_inputEventsOffsetForEmulation = offset; | |
| 613 m_inputEventsScaleFactorForEmulation = contentScaleFactor; | |
| 614 if (frame()->view()) | |
| 615 frame()->view()->setInputEventsTransformForEmulation(m_inputEventsOffset
ForEmulation, m_inputEventsScaleFactorForEmulation); | |
| 616 } | |
| 617 | |
| 618 } // namespace blink | |
| OLD | NEW |