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 |