1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
17 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
20 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
21 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27 #include "config.h"
28 #include "Internals.h"
29
30 #include <v8.h>
31 #include "HTMLNames.h"
32 #include "InspectorFrontendClientLocal.h"
33 #include "InternalProfilers.h"
34 #include "InternalRuntimeFlags.h"
35 #include "InternalSettings.h"
36 #include "LayerRect.h"
37 #include "LayerRectList.h"
38 #include "MallocStatistics.h"
39 #include "MockPagePopupDriver.h"
40 #include "RuntimeEnabledFeatures.h"
41 #include "TypeConversions.h"
42 #include "bindings/v8/ExceptionState.h"
43 #include "bindings/v8/SerializedScriptValue.h"
44 #include "bindings/v8/V8ThrowException.h"
45 #include "core/animation/DocumentTimeline.h"
46 #include "core/css/StyleSheetContents.h"
47 #include "core/css/resolver/StyleResolver.h"
48 #include "core/css/resolver/StyleResolverStats.h"
49 #include "core/css/resolver/ViewportStyleResolver.h"
50 #include "core/dom/ClientRect.h"
51 #include "core/dom/ClientRectList.h"
52 #include "core/dom/DOMStringList.h"
53 #include "core/dom/Document.h"
54 #include "core/dom/DocumentMarker.h"
55 #include "core/dom/DocumentMarkerController.h"
56 #include "core/dom/Element.h"
57 #include "core/dom/ExceptionCode.h"
58 #include "core/dom/FullscreenElementStack.h"
59 #include "core/dom/PseudoElement.h"
60 #include "core/dom/Range.h"
61 #include "core/dom/StaticNodeList.h"
62 #include "core/dom/TreeScope.h"
63 #include "core/dom/ViewportDescription.h"
64 #include "core/dom/WheelController.h"
65 #include "core/dom/shadow/ComposedTreeWalker.h"
66 #include "core/dom/shadow/ElementShadow.h"
67 #include "core/dom/shadow/SelectRuleFeatureSet.h"
68 #include "core/dom/shadow/ShadowRoot.h"
69 #include "core/editing/Editor.h"
70 #include "core/editing/PlainTextRange.h"
71 #include "core/editing/SpellCheckRequester.h"
72 #include "core/editing/SpellChecker.h"
73 #include "core/editing/TextIterator.h"
74 #include "core/fetch/MemoryCache.h"
75 #include "core/fetch/ResourceFetcher.h"
76 #include "core/frame/DOMPoint.h"
77 #include "core/frame/Frame.h"
78 #include "core/history/HistoryItem.h"
79 #include "core/html/HTMLIFrameElement.h"
80 #include "core/html/HTMLInputElement.h"
81 #include "core/html/HTMLMediaElement.h"
82 #include "core/html/HTMLSelectElement.h"
83 #include "core/html/HTMLTextAreaElement.h"
84 #include "core/html/forms/FormController.h"
85 #include "core/html/shadow/HTMLContentElement.h"
86 #include "core/inspector/InspectorClient.h"
87 #include "core/inspector/InspectorConsoleAgent.h"
88 #include "core/inspector/InspectorController.h"
89 #include "core/inspector/InspectorCounters.h"
90 #include "core/inspector/InspectorFrontendChannel.h"
91 #include "core/inspector/InspectorInstrumentation.h"
92 #include "core/inspector/InspectorOverlay.h"
93 #include "core/inspector/InstrumentingAgents.h"
94 #include "core/loader/FrameLoader.h"
95 #include "core/page/Chrome.h"
96 #include "core/page/ChromeClient.h"
97 #include "core/frame/DOMWindow.h"
98 #include "core/page/EventHandler.h"
99 #include "core/frame/FrameView.h"
100 #include "core/page/Page.h"
101 #include "core/page/PagePopupController.h"
102 #include "core/page/PrintContext.h"
103 #include "core/frame/Settings.h"
104 #include "core/frame/animation/AnimationController.h"
105 #include "core/rendering/CompositedLayerMapping.h"
106 #include "core/rendering/RenderLayer.h"
107 #include "core/rendering/RenderLayerCompositor.h"
108 #include "core/rendering/RenderMenuList.h"
109 #include "core/rendering/RenderObject.h"
110 #include "core/rendering/RenderTreeAsText.h"
111 #include "core/rendering/RenderView.h"
112 #include "core/testing/GCObservation.h"
113 #include "core/workers/WorkerThread.h"
114 #include "platform/ColorChooser.h"
115 #include "platform/Cursor.h"
116 #include "platform/Language.h"
117 #include "platform/TraceEvent.h"
118 #include "platform/geometry/IntRect.h"
119 #include "platform/geometry/LayoutRect.h"
120 #include "platform/graphics/GraphicsLayer.h"
121 #include "platform/graphics/filters/FilterOperation.h"
122 #include "platform/graphics/filters/FilterOperations.h"
123 #include "platform/graphics/gpu/SharedGraphicsContext3D.h"
124 #include "platform/weborigin/SchemeRegistry.h"
125 #include "public/platform/WebLayer.h"
126 #include "wtf/InstanceCounter.h"
127 #include "wtf/dtoa.h"
128 #include "wtf/text/StringBuffer.h"
129
130 namespace WebCore {
131
132 static MockPagePopupDriver* s_pagePopupDriver = 0;
133
134 using namespace HTMLNames;
135
136 class InspectorFrontendChannelDummy : public InspectorFrontendChannel {
137 public:
138 explicit InspectorFrontendChannelDummy(Page*);
~InspectorFrontendChannelDummy()139 virtual ~InspectorFrontendChannelDummy() { }
140 virtual bool sendMessageToFrontend(const String& message) OVERRIDE;
141
142 private:
143 Page* m_frontendPage;
144 };
145
InspectorFrontendChannelDummy(Page * page)146 InspectorFrontendChannelDummy::InspectorFrontendChannelDummy(Page* page)
147 : m_frontendPage(page)
148 {
149 }
150
sendMessageToFrontend(const String & message)151 bool InspectorFrontendChannelDummy::sendMessageToFrontend(const String& message)
152 {
153 return InspectorClient::doDispatchMessageOnFrontendPage(m_frontendPage, message);
154 }
155
markerTypesFrom(const String & markerType,DocumentMarker::MarkerTypes & result)156 static bool markerTypesFrom(const String& markerType, DocumentMarker::MarkerTypes& result)
157 {
158 if (markerType.isEmpty() || equalIgnoringCase(markerType, "all"))
159 result = DocumentMarker::AllMarkers();
160 else if (equalIgnoringCase(markerType, "Spelling"))
161 result = DocumentMarker::Spelling;
162 else if (equalIgnoringCase(markerType, "Grammar"))
163 result = DocumentMarker::Grammar;
164 else if (equalIgnoringCase(markerType, "TextMatch"))
165 result = DocumentMarker::TextMatch;
166 else
167 return false;
168
169 return true;
170 }
171
spellCheckRequester(Document * document)172 static SpellCheckRequester* spellCheckRequester(Document* document)
173 {
174 if (!document || !document->frame())
175 return 0;
176 return &document->frame()->spellChecker().spellCheckRequester();
177 }
178
179 const char* Internals::internalsId = "internals";
180
create(Document * document)181 PassRefPtr<Internals> Internals::create(Document* document)
182 {
183 return adoptRef(new Internals(document));
184 }
185
~Internals()186 Internals::~Internals()
187 {
188 }
189
resetToConsistentState(Page * page)190 void Internals::resetToConsistentState(Page* page)
191 {
192 ASSERT(page);
193
194 page->setDeviceScaleFactor(1);
195 page->setIsCursorVisible(true);
196 page->setPageScaleFactor(1, IntPoint(0, 0));
197 page->setPagination(Pagination());
198 TextRun::setAllowsRoundingHacks(false);
199 WebCore::overrideUserPreferredLanguages(Vector<String>());
200 delete s_pagePopupDriver;
201 s_pagePopupDriver = 0;
202 page->chrome().client().resetPagePopupDriver();
203 if (!page->mainFrame()->spellChecker().isContinuousSpellCheckingEnabled())
204 page->mainFrame()->spellChecker().toggleContinuousSpellChecking();
205 if (page->mainFrame()->editor().isOverwriteModeEnabled())
206 page->mainFrame()->editor().toggleOverwriteModeEnabled();
207
208 if (ScrollingCoordinator* scrollingCoordinator = page->scrollingCoordinator())
209 scrollingCoordinator->reset();
210
211 page->mainFrame()->view()->clear();
212 }
213
Internals(Document * document)214 Internals::Internals(Document* document)
215 : ContextLifecycleObserver(document)
216 , m_runtimeFlags(InternalRuntimeFlags::create())
217 , m_scrollingCoordinator(document->page() ? document->page()->scrollingCoordinator() : 0)
218 {
219 }
220
contextDocument() const221 Document* Internals::contextDocument() const
222 {
223 return toDocument(executionContext());
224 }
225
frame() const226 Frame* Internals::frame() const
227 {
228 if (!contextDocument())
229 return 0;
230 return contextDocument()->frame();
231 }
232
settings() const233 InternalSettings* Internals::settings() const
234 {
235 Document* document = contextDocument();
236 if (!document)
237 return 0;
238 Page* page = document->page();
239 if (!page)
240 return 0;
241 return InternalSettings::from(page);
242 }
243
runtimeFlags() const244 InternalRuntimeFlags* Internals::runtimeFlags() const
245 {
246 return m_runtimeFlags.get();
247 }
248
profilers()249 InternalProfilers* Internals::profilers()
250 {
251 if (!m_profilers)
252 m_profilers = InternalProfilers::create();
253 return m_profilers.get();
254 }
255
workerThreadCount() const256 unsigned Internals::workerThreadCount() const
257 {
258 return WorkerThread::workerThreadCount();
259 }
260
address(Node * node)261 String Internals::address(Node* node)
262 {
263 char buf[32];
264 sprintf(buf, "%p", node);
265
266 return String(buf);
267 }
268
observeGC(ScriptValue scriptValue)269 PassRefPtr<GCObservation> Internals::observeGC(ScriptValue scriptValue)
270 {
271 v8::Handle<v8::Value> observedValue = scriptValue.v8Value();
272 ASSERT(!observedValue.IsEmpty());
273 if (observedValue->IsNull() || observedValue->IsUndefined()) {
274 V8ThrowException::throwTypeError("value to observe is null or undefined", v8::Isolate::GetCurrent());
275 return 0;
276 }
277
278 return GCObservation::create(observedValue);
279 }
280
updateStyleAndReturnAffectedElementCount(ExceptionState & exceptionState) const281 unsigned Internals::updateStyleAndReturnAffectedElementCount(ExceptionState& exceptionState) const
282 {
283 Document* document = contextDocument();
284 if (!document) {
285 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
286 return 0;
287 }
288
289 unsigned beforeCount = document->styleEngine()->resolverAccessCount();
290 document->updateStyleIfNeeded();
291 return document->styleEngine()->resolverAccessCount() - beforeCount;
292 }
293
isPreloaded(const String & url)294 bool Internals::isPreloaded(const String& url)
295 {
296 Document* document = contextDocument();
297 return document->fetcher()->isPreloaded(url);
298 }
299
isLoadingFromMemoryCache(const String & url)300 bool Internals::isLoadingFromMemoryCache(const String& url)
301 {
302 if (!contextDocument())
303 return false;
304 Resource* resource = memoryCache()->resourceForURL(contextDocument()->completeURL(url));
305 return resource && resource->status() == Resource::Cached;
306 }
307
crash()308 void Internals::crash()
309 {
310 CRASH();
311 }
312
setStyleResolverStatsEnabled(bool enabled)313 void Internals::setStyleResolverStatsEnabled(bool enabled)
314 {
315 Document* document = contextDocument();
316 if (enabled)
317 document->ensureStyleResolver().enableStats(StyleResolver::ReportSlowStats);
318 else
319 document->ensureStyleResolver().disableStats();
320 }
321
styleResolverStatsReport(ExceptionState & exceptionState) const322 String Internals::styleResolverStatsReport(ExceptionState& exceptionState) const
323 {
324 Document* document = contextDocument();
325 if (!document->ensureStyleResolver().stats()) {
326 exceptionState.throwDOMException(InvalidStateError, "Style resolver stats not enabled");
327 return String();
328 }
329 return document->ensureStyleResolver().stats()->report();
330 }
331
styleResolverStatsTotalsReport(ExceptionState & exceptionState) const332 String Internals::styleResolverStatsTotalsReport(ExceptionState& exceptionState) const
333 {
334 Document* document = contextDocument();
335 if (!document->ensureStyleResolver().statsTotals()) {
336 exceptionState.throwDOMException(InvalidStateError, "Style resolver stats not enabled");
337 return String();
338 }
339 return document->ensureStyleResolver().statsTotals()->report();
340 }
341
createContentElement(ExceptionState & exceptionState)342 PassRefPtr<Element> Internals::createContentElement(ExceptionState& exceptionState)
343 {
344 Document* document = contextDocument();
345 if (!document) {
346 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
347 return 0;
348 }
349
350 return HTMLContentElement::create(*document);
351 }
352
isValidContentSelect(Element * insertionPoint,ExceptionState & exceptionState)353 bool Internals::isValidContentSelect(Element* insertionPoint, ExceptionState& exceptionState)
354 {
355 if (!insertionPoint || !insertionPoint->isInsertionPoint()) {
356 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
357 return false;
358 }
359
360 return isHTMLContentElement(insertionPoint) && toHTMLContentElement(insertionPoint)->isSelectValid();
361 }
362
treeScopeRootNode(Node * node,ExceptionState & exceptionState)363 Node* Internals::treeScopeRootNode(Node* node, ExceptionState& exceptionState)
364 {
365 if (!node) {
366 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
367 return 0;
368 }
369
370 return node->treeScope().rootNode();
371 }
372
parentTreeScope(Node * node,ExceptionState & exceptionState)373 Node* Internals::parentTreeScope(Node* node, ExceptionState& exceptionState)
374 {
375 if (!node) {
376 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
377 return 0;
378 }
379 const TreeScope* parentTreeScope = node->treeScope().parentTreeScope();
380 return parentTreeScope ? parentTreeScope->rootNode() : 0;
381 }
382
hasSelectorForIdInShadow(Element * host,const String & idValue,ExceptionState & exceptionState)383 bool Internals::hasSelectorForIdInShadow(Element* host, const String& idValue, ExceptionState& exceptionState)
384 {
385 if (!host || !host->shadow()) {
386 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
387 return 0;
388 }
389
390 return host->shadow()->ensureSelectFeatureSet().hasSelectorForId(idValue);
391 }
392
hasSelectorForClassInShadow(Element * host,const String & className,ExceptionState & exceptionState)393 bool Internals::hasSelectorForClassInShadow(Element* host, const String& className, ExceptionState& exceptionState)
394 {
395 if (!host || !host->shadow()) {
396 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
397 return 0;
398 }
399
400 return host->shadow()->ensureSelectFeatureSet().hasSelectorForClass(className);
401 }
402
hasSelectorForAttributeInShadow(Element * host,const String & attributeName,ExceptionState & exceptionState)403 bool Internals::hasSelectorForAttributeInShadow(Element* host, const String& attributeName, ExceptionState& exceptionState)
404 {
405 if (!host || !host->shadow()) {
406 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
407 return 0;
408 }
409
410 return host->shadow()->ensureSelectFeatureSet().hasSelectorForAttribute(attributeName);
411 }
412
hasSelectorForPseudoClassInShadow(Element * host,const String & pseudoClass,ExceptionState & exceptionState)413 bool Internals::hasSelectorForPseudoClassInShadow(Element* host, const String& pseudoClass, ExceptionState& exceptionState)
414 {
415 if (!host || !host->shadow()) {
416 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
417 return 0;
418 }
419
420 const SelectRuleFeatureSet& featureSet = host->shadow()->ensureSelectFeatureSet();
421 if (pseudoClass == "checked")
422 return featureSet.hasSelectorForChecked();
423 if (pseudoClass == "enabled")
424 return featureSet.hasSelectorForEnabled();
425 if (pseudoClass == "disabled")
426 return featureSet.hasSelectorForDisabled();
427 if (pseudoClass == "indeterminate")
428 return featureSet.hasSelectorForIndeterminate();
429 if (pseudoClass == "link")
430 return featureSet.hasSelectorForLink();
431 if (pseudoClass == "target")
432 return featureSet.hasSelectorForTarget();
433 if (pseudoClass == "visited")
434 return featureSet.hasSelectorForVisited();
435
436 ASSERT_NOT_REACHED();
437 return false;
438 }
439
compareTreeScopePosition(const Node * node1,const Node * node2,ExceptionState & exceptionState) const440 unsigned short Internals::compareTreeScopePosition(const Node* node1, const Node* node2, ExceptionState& exceptionState) const
441 {
442 if (!node1 || !node2) {
443 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
444 return 0;
445 }
446 const TreeScope* treeScope1 = node1->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node1)) :
447 node1->isShadowRoot() ? static_cast<const TreeScope*>(toShadowRoot(node1)) : 0;
448 const TreeScope* treeScope2 = node2->isDocumentNode() ? static_cast<const TreeScope*>(toDocument(node2)) :
449 node2->isShadowRoot() ? static_cast<const TreeScope*>(toShadowRoot(node2)) : 0;
450 if (!treeScope1 || !treeScope2) {
451 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
452 return 0;
453 }
454 return treeScope1->comparePosition(*treeScope2);
455 }
456
numberOfActiveAnimations() const457 unsigned Internals::numberOfActiveAnimations() const
458 {
459 Frame* contextFrame = frame();
460 Document* document = contextFrame->document();
461 if (RuntimeEnabledFeatures::webAnimationsCSSEnabled())
462 return document->timeline()->numberOfActiveAnimationsForTesting() + document->transitionTimeline()->numberOfActiveAnimationsForTesting();
463 return contextFrame->animation().numberOfActiveAnimations(document);
464 }
465
pauseAnimations(double pauseTime,ExceptionState & exceptionState)466 void Internals::pauseAnimations(double pauseTime, ExceptionState& exceptionState)
467 {
468 if (pauseTime < 0) {
469 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
470 return;
471 }
472
473 if (RuntimeEnabledFeatures::webAnimationsCSSEnabled()) {
474 frame()->document()->timeline()->pauseAnimationsForTesting(pauseTime);
475 frame()->document()->transitionTimeline()->pauseAnimationsForTesting(pauseTime);
476 } else {
477 frame()->animation().pauseAnimationsForTesting(pauseTime);
478 }
479 }
480
hasShadowInsertionPoint(const Node * root,ExceptionState & exceptionState) const481 bool Internals::hasShadowInsertionPoint(const Node* root, ExceptionState& exceptionState) const
482 {
483 if (root && root->isShadowRoot())
484 return toShadowRoot(root)->containsShadowElements();
485
486 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
487 return 0;
488 }
489
hasContentElement(const Node * root,ExceptionState & exceptionState) const490 bool Internals::hasContentElement(const Node* root, ExceptionState& exceptionState) const
491 {
492 if (root && root->isShadowRoot())
493 return toShadowRoot(root)->containsContentElements();
494
495 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
496 return 0;
497 }
498
countElementShadow(const Node * root,ExceptionState & exceptionState) const499 size_t Internals::countElementShadow(const Node* root, ExceptionState& exceptionState) const
500 {
501 if (!root || !root->isShadowRoot()) {
502 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
503 return 0;
504 }
505 return toShadowRoot(root)->childShadowRootCount();
506 }
507
nextSiblingByWalker(Node * node,ExceptionState & exceptionState)508 Node* Internals::nextSiblingByWalker(Node* node, ExceptionState& exceptionState)
509 {
510 if (!node) {
511 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
512 return 0;
513 }
514 ComposedTreeWalker walker(node);
515 walker.nextSibling();
516 return walker.get();
517 }
518
firstChildByWalker(Node * node,ExceptionState & exceptionState)519 Node* Internals::firstChildByWalker(Node* node, ExceptionState& exceptionState)
520 {
521 if (!node) {
522 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
523 return 0;
524 }
525 ComposedTreeWalker walker(node);
526 walker.firstChild();
527 return walker.get();
528 }
529
lastChildByWalker(Node * node,ExceptionState & exceptionState)530 Node* Internals::lastChildByWalker(Node* node, ExceptionState& exceptionState)
531 {
532 if (!node) {
533 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
534 return 0;
535 }
536 ComposedTreeWalker walker(node);
537 walker.lastChild();
538 return walker.get();
539 }
540
nextNodeByWalker(Node * node,ExceptionState & exceptionState)541 Node* Internals::nextNodeByWalker(Node* node, ExceptionState& exceptionState)
542 {
543 if (!node) {
544 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
545 return 0;
546 }
547 ComposedTreeWalker walker(node);
548 walker.next();
549 return walker.get();
550 }
551
previousNodeByWalker(Node * node,ExceptionState & exceptionState)552 Node* Internals::previousNodeByWalker(Node* node, ExceptionState& exceptionState)
553 {
554 if (!node) {
555 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
556 return 0;
557 }
558 ComposedTreeWalker walker(node);
559 walker.previous();
560 return walker.get();
561 }
562
elementRenderTreeAsText(Element * element,ExceptionState & exceptionState)563 String Internals::elementRenderTreeAsText(Element* element, ExceptionState& exceptionState)
564 {
565 if (!element) {
566 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
567 return String();
568 }
569
570 String representation = externalRepresentation(element);
571 if (representation.isEmpty()) {
572 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
573 return String();
574 }
575
576 return representation;
577 }
578
numberOfScopedHTMLStyleChildren(const Node * scope,ExceptionState & exceptionState) const579 size_t Internals::numberOfScopedHTMLStyleChildren(const Node* scope, ExceptionState& exceptionState) const
580 {
581 if (scope && (scope->isElementNode() || scope->isShadowRoot()))
582 return scope->numberOfScopedHTMLStyleChildren();
583
584 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
585 return 0;
586 }
587
computedStyleIncludingVisitedInfo(Node * node,ExceptionState & exceptionState) const588 PassRefPtr<CSSComputedStyleDeclaration> Internals::computedStyleIncludingVisitedInfo(Node* node, ExceptionState& exceptionState) const
589 {
590 if (!node) {
591 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
592 return 0;
593 }
594
595 bool allowVisitedStyle = true;
596 return CSSComputedStyleDeclaration::create(node, allowVisitedStyle);
597 }
598
ensureShadowRoot(Element * host,ExceptionState & exceptionState)599 ShadowRoot* Internals::ensureShadowRoot(Element* host, ExceptionState& exceptionState)
600 {
601 if (!host) {
602 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
603 return 0;
604 }
605
606 if (ElementShadow* shadow = host->shadow())
607 return shadow->youngestShadowRoot();
608
609 return host->createShadowRoot(exceptionState).get();
610 }
611
shadowRoot(Element * host,ExceptionState & exceptionState)612 ShadowRoot* Internals::shadowRoot(Element* host, ExceptionState& exceptionState)
613 {
614 // FIXME: Internals::shadowRoot() in tests should be converted to youngestShadowRoot() or oldestShadowRoot().
615 // https://bugs.webkit.org/show_bug.cgi?id=78465
616 return youngestShadowRoot(host, exceptionState);
617 }
618
youngestShadowRoot(Element * host,ExceptionState & exceptionState)619 ShadowRoot* Internals::youngestShadowRoot(Element* host, ExceptionState& exceptionState)
620 {
621 if (!host) {
622 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
623 return 0;
624 }
625
626 if (ElementShadow* shadow = host->shadow())
627 return shadow->youngestShadowRoot();
628 return 0;
629 }
630
oldestShadowRoot(Element * host,ExceptionState & exceptionState)631 ShadowRoot* Internals::oldestShadowRoot(Element* host, ExceptionState& exceptionState)
632 {
633 if (!host) {
634 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
635 return 0;
636 }
637
638 if (ElementShadow* shadow = host->shadow())
639 return shadow->oldestShadowRoot();
640 return 0;
641 }
642
youngerShadowRoot(Node * shadow,ExceptionState & exceptionState)643 ShadowRoot* Internals::youngerShadowRoot(Node* shadow, ExceptionState& exceptionState)
644 {
645 if (!shadow || !shadow->isShadowRoot()) {
646 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
647 return 0;
648 }
649
650 return toShadowRoot(shadow)->youngerShadowRoot();
651 }
652
olderShadowRoot(Node * shadow,ExceptionState & exceptionState)653 ShadowRoot* Internals::olderShadowRoot(Node* shadow, ExceptionState& exceptionState)
654 {
655 if (!shadow || !shadow->isShadowRoot()) {
656 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
657 return 0;
658 }
659
660 return toShadowRoot(shadow)->olderShadowRoot();
661 }
662
shadowRootType(const Node * root,ExceptionState & exceptionState) const663 String Internals::shadowRootType(const Node* root, ExceptionState& exceptionState) const
664 {
665 if (!root || !root->isShadowRoot()) {
666 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
667 return String();
668 }
669
670 switch (toShadowRoot(root)->type()) {
671 case ShadowRoot::UserAgentShadowRoot:
672 return String("UserAgentShadowRoot");
673 case ShadowRoot::AuthorShadowRoot:
674 return String("AuthorShadowRoot");
675 default:
676 ASSERT_NOT_REACHED();
677 return String("Unknown");
678 }
679 }
680
shadowPseudoId(Element * element,ExceptionState & exceptionState)681 String Internals::shadowPseudoId(Element* element, ExceptionState& exceptionState)
682 {
683 if (!element) {
684 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
685 return String();
686 }
687
688 return element->shadowPseudoId().string();
689 }
690
setShadowPseudoId(Element * element,const String & id,ExceptionState & exceptionState)691 void Internals::setShadowPseudoId(Element* element, const String& id, ExceptionState& exceptionState)
692 {
693 if (!element) {
694 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
695 return;
696 }
697
698 return element->setPseudo(id);
699 }
700
visiblePlaceholder(Element * element)701 String Internals::visiblePlaceholder(Element* element)
702 {
703 if (element && isHTMLTextFormControlElement(element)) {
704 if (toHTMLTextFormControlElement(element)->placeholderShouldBeVisible())
705 return toHTMLTextFormControlElement(element)->placeholderElement()->textContent();
706 }
707
708 return String();
709 }
710
selectColorInColorChooser(Element * element,const String & colorValue)711 void Internals::selectColorInColorChooser(Element* element, const String& colorValue)
712 {
713 if (!element->hasTagName(inputTag))
714 return;
715 toHTMLInputElement(element)->selectColorInColorChooser(Color(colorValue));
716 }
717
formControlStateOfHistoryItem(ExceptionState & exceptionState)718 Vector<String> Internals::formControlStateOfHistoryItem(ExceptionState& exceptionState)
719 {
720 HistoryItem* mainItem = frame()->loader().currentItem();
721 if (!mainItem) {
722 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
723 return Vector<String>();
724 }
725 return mainItem->documentState();
726 }
727
setFormControlStateOfHistoryItem(const Vector<String> & state,ExceptionState & exceptionState)728 void Internals::setFormControlStateOfHistoryItem(const Vector<String>& state, ExceptionState& exceptionState)
729 {
730 HistoryItem* mainItem = frame()->loader().currentItem();
731 if (!mainItem) {
732 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
733 return;
734 }
735 mainItem->setDocumentState(state);
736 }
737
setEnableMockPagePopup(bool enabled,ExceptionState & exceptionState)738 void Internals::setEnableMockPagePopup(bool enabled, ExceptionState& exceptionState)
739 {
740 Document* document = contextDocument();
741 if (!document || !document->page())
742 return;
743 Page* page = document->page();
744 if (!enabled) {
745 page->chrome().client().resetPagePopupDriver();
746 return;
747 }
748 if (!s_pagePopupDriver)
749 s_pagePopupDriver = MockPagePopupDriver::create(page->mainFrame()).leakPtr();
750 page->chrome().client().setPagePopupDriver(s_pagePopupDriver);
751 }
752
pagePopupController()753 PassRefPtr<PagePopupController> Internals::pagePopupController()
754 {
755 return s_pagePopupDriver ? s_pagePopupDriver->pagePopupController() : 0;
756 }
757
unscaledViewportRect(ExceptionState & exceptionState)758 PassRefPtr<ClientRect> Internals::unscaledViewportRect(ExceptionState& exceptionState)
759 {
760 Document* document = contextDocument();
761 if (!document || !document->view()) {
762 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
763 return ClientRect::create();
764 }
765
766 return ClientRect::create(document->view()->visibleContentRect());
767 }
768
absoluteCaretBounds(ExceptionState & exceptionState)769 PassRefPtr<ClientRect> Internals::absoluteCaretBounds(ExceptionState& exceptionState)
770 {
771 Document* document = contextDocument();
772 if (!document || !document->frame()) {
773 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
774 return ClientRect::create();
775 }
776
777 return ClientRect::create(document->frame()->selection().absoluteCaretBounds());
778 }
779
boundingBox(Element * element,ExceptionState & exceptionState)780 PassRefPtr<ClientRect> Internals::boundingBox(Element* element, ExceptionState& exceptionState)
781 {
782 if (!element) {
783 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
784 return ClientRect::create();
785 }
786
787 element->document().updateLayoutIgnorePendingStylesheets();
788 RenderObject* renderer = element->renderer();
789 if (!renderer)
790 return ClientRect::create();
791 return ClientRect::create(renderer->absoluteBoundingBoxRectIgnoringTransforms());
792 }
793
inspectorHighlightRects(Document * document,ExceptionState & exceptionState)794 PassRefPtr<ClientRectList> Internals::inspectorHighlightRects(Document* document, ExceptionState& exceptionState)
795 {
796 if (!document || !document->page()) {
797 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
798 return ClientRectList::create();
799 }
800
801 Highlight highlight;
802 document->page()->inspectorController().getHighlight(&highlight);
803 return ClientRectList::create(highlight.quads);
804 }
805
markerCountForNode(Node * node,const String & markerType,ExceptionState & exceptionState)806 unsigned Internals::markerCountForNode(Node* node, const String& markerType, ExceptionState& exceptionState)
807 {
808 if (!node) {
809 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
810 return 0;
811 }
812
813 DocumentMarker::MarkerTypes markerTypes = 0;
814 if (!markerTypesFrom(markerType, markerTypes)) {
815 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
816 return 0;
817 }
818
819 return node->document().markers()->markersFor(node, markerTypes).size();
820 }
821
activeMarkerCountForNode(Node * node,ExceptionState & exceptionState)822 unsigned Internals::activeMarkerCountForNode(Node* node, ExceptionState& exceptionState)
823 {
824 if (!node) {
825 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
826 return 0;
827 }
828
829 // Only TextMatch markers can be active.
830 DocumentMarker::MarkerType markerType = DocumentMarker::TextMatch;
831 Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerType);
832
833 unsigned activeMarkerCount = 0;
834 for (Vector<DocumentMarker*>::iterator iter = markers.begin(); iter != markers.end(); ++iter) {
835 if ((*iter)->activeMatch())
836 activeMarkerCount++;
837 }
838
839 return activeMarkerCount;
840 }
841
markerAt(Node * node,const String & markerType,unsigned index,ExceptionState & exceptionState)842 DocumentMarker* Internals::markerAt(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
843 {
844 if (!node) {
845 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
846 return 0;
847 }
848
849 DocumentMarker::MarkerTypes markerTypes = 0;
850 if (!markerTypesFrom(markerType, markerTypes)) {
851 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
852 return 0;
853 }
854
855 Vector<DocumentMarker*> markers = node->document().markers()->markersFor(node, markerTypes);
856 if (markers.size() <= index)
857 return 0;
858 return markers[index];
859 }
860
markerRangeForNode(Node * node,const String & markerType,unsigned index,ExceptionState & exceptionState)861 PassRefPtr<Range> Internals::markerRangeForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
862 {
863 DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
864 if (!marker)
865 return 0;
866 return Range::create(node->document(), node, marker->startOffset(), node, marker->endOffset());
867 }
868
markerDescriptionForNode(Node * node,const String & markerType,unsigned index,ExceptionState & exceptionState)869 String Internals::markerDescriptionForNode(Node* node, const String& markerType, unsigned index, ExceptionState& exceptionState)
870 {
871 DocumentMarker* marker = markerAt(node, markerType, index, exceptionState);
872 if (!marker)
873 return String();
874 return marker->description();
875 }
876
addTextMatchMarker(const Range * range,bool isActive)877 void Internals::addTextMatchMarker(const Range* range, bool isActive)
878 {
879 range->ownerDocument().updateLayoutIgnorePendingStylesheets();
880 range->ownerDocument().markers()->addTextMatchMarker(range, isActive);
881 }
882
setMarkersActive(Node * node,unsigned startOffset,unsigned endOffset,bool active,ExceptionState & exceptionState)883 void Internals::setMarkersActive(Node* node, unsigned startOffset, unsigned endOffset, bool active, ExceptionState& exceptionState)
884 {
885 if (!node) {
886 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
887 return;
888 }
889
890 node->document().markers()->setMarkersActive(node, startOffset, endOffset, active);
891 }
892
setScrollViewPosition(Document * document,long x,long y,ExceptionState & exceptionState)893 void Internals::setScrollViewPosition(Document* document, long x, long y, ExceptionState& exceptionState)
894 {
895 if (!document || !document->view()) {
896 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
897 return;
898 }
899
900 FrameView* frameView = document->view();
901 bool constrainsScrollingToContentEdgeOldValue = frameView->constrainsScrollingToContentEdge();
902 bool scrollbarsSuppressedOldValue = frameView->scrollbarsSuppressed();
903
904 frameView->setConstrainsScrollingToContentEdge(false);
905 frameView->setScrollbarsSuppressed(false);
906 frameView->setScrollOffsetFromInternals(IntPoint(x, y));
907 frameView->setScrollbarsSuppressed(scrollbarsSuppressedOldValue);
908 frameView->setConstrainsScrollingToContentEdge(constrainsScrollingToContentEdgeOldValue);
909 }
910
setPagination(Document * document,const String & mode,int gap,int pageLength,ExceptionState & exceptionState)911 void Internals::setPagination(Document* document, const String& mode, int gap, int pageLength, ExceptionState& exceptionState)
912 {
913 if (!document || !document->page()) {
914 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
915 return;
916 }
917 Page* page = document->page();
918
919 Pagination pagination;
920 if (mode == "Unpaginated")
921 pagination.mode = Pagination::Unpaginated;
922 else if (mode == "LeftToRightPaginated")
923 pagination.mode = Pagination::LeftToRightPaginated;
924 else if (mode == "RightToLeftPaginated")
925 pagination.mode = Pagination::RightToLeftPaginated;
926 else if (mode == "TopToBottomPaginated")
927 pagination.mode = Pagination::TopToBottomPaginated;
928 else if (mode == "BottomToTopPaginated")
929 pagination.mode = Pagination::BottomToTopPaginated;
930 else {
931 exceptionState.throwUninformativeAndGenericDOMException(SyntaxError);
932 return;
933 }
934
935 pagination.gap = gap;
936 pagination.pageLength = pageLength;
937 page->setPagination(pagination);
938 }
939
viewportAsText(Document * document,float,int availableWidth,int availableHeight,ExceptionState & exceptionState)940 String Internals::viewportAsText(Document* document, float, int availableWidth, int availableHeight, ExceptionState& exceptionState)
941 {
942 if (!document || !document->page()) {
943 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
944 return String();
945 }
946
947 document->updateLayoutIgnorePendingStylesheets();
948
949 Page* page = document->page();
950
951 // Update initial viewport size.
952 IntSize initialViewportSize(availableWidth, availableHeight);
953 document->page()->mainFrame()->view()->setFrameRect(IntRect(IntPoint::zero(), initialViewportSize));
954
955 ViewportDescription description = page->viewportDescription();
956 PageScaleConstraints constraints = description.resolve(initialViewportSize);
957
958 constraints.fitToContentsWidth(constraints.layoutSize.width(), availableWidth);
959
960 StringBuilder builder;
961
962 builder.appendLiteral("viewport size ");
963 builder.append(String::number(constraints.layoutSize.width()));
964 builder.append('x');
965 builder.append(String::number(constraints.layoutSize.height()));
966
967 builder.appendLiteral(" scale ");
968 builder.append(String::number(constraints.initialScale));
969 builder.appendLiteral(" with limits [");
970 builder.append(String::number(constraints.minimumScale));
971 builder.appendLiteral(", ");
972 builder.append(String::number(constraints.maximumScale));
973
974 builder.appendLiteral("] and userScalable ");
975 builder.append(description.userZoom ? "true" : "false");
976
977 return builder.toString();
978 }
979
wasLastChangeUserEdit(Element * textField,ExceptionState & exceptionState)980 bool Internals::wasLastChangeUserEdit(Element* textField, ExceptionState& exceptionState)
981 {
982 if (!textField) {
983 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
984 return false;
985 }
986
987 if (textField->hasTagName(inputTag))
988 return toHTMLInputElement(textField)->lastChangeWasUserEdit();
989
990 // FIXME: We should be using hasTagName instead but Windows port doesn't link QualifiedNames properly.
991 if (textField->tagName() == "TEXTAREA")
992 return toHTMLTextAreaElement(textField)->lastChangeWasUserEdit();
993
994 exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
995 return false;
996 }
997
elementShouldAutoComplete(Element * element,ExceptionState & exceptionState)998 bool Internals::elementShouldAutoComplete(Element* element, ExceptionState& exceptionState)
999 {
1000 if (!element) {
1001 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1002 return false;
1003 }
1004
1005 if (element->hasTagName(inputTag))
1006 return toHTMLInputElement(element)->shouldAutocomplete();
1007
1008 exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
1009 return false;
1010 }
1011
suggestedValue(Element * element,ExceptionState & exceptionState)1012 String Internals::suggestedValue(Element* element, ExceptionState& exceptionState)
1013 {
1014 if (!element) {
1015 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1016 return String();
1017 }
1018
1019 if (!element->hasTagName(inputTag)) {
1020 exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
1021 return String();
1022 }
1023
1024 return toHTMLInputElement(element)->suggestedValue();
1025 }
1026
setSuggestedValue(Element * element,const String & value,ExceptionState & exceptionState)1027 void Internals::setSuggestedValue(Element* element, const String& value, ExceptionState& exceptionState)
1028 {
1029 if (!element) {
1030 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1031 return;
1032 }
1033
1034 if (!element->hasTagName(inputTag)) {
1035 exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
1036 return;
1037 }
1038
1039 toHTMLInputElement(element)->setSuggestedValue(value);
1040 }
1041
setEditingValue(Element * element,const String & value,ExceptionState & exceptionState)1042 void Internals::setEditingValue(Element* element, const String& value, ExceptionState& exceptionState)
1043 {
1044 if (!element) {
1045 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1046 return;
1047 }
1048
1049 if (!element->hasTagName(inputTag)) {
1050 exceptionState.throwUninformativeAndGenericDOMException(InvalidNodeTypeError);
1051 return;
1052 }
1053
1054 toHTMLInputElement(element)->setEditingValue(value);
1055 }
1056
setAutofilled(Element * element,bool enabled,ExceptionState & exceptionState)1057 void Internals::setAutofilled(Element* element, bool enabled, ExceptionState& exceptionState)
1058 {
1059 if (!element->isFormControlElement()) {
1060 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1061 return;
1062 }
1063 toHTMLFormControlElement(element)->setAutofilled(enabled);
1064 }
1065
scrollElementToRect(Element * element,long x,long y,long w,long h,ExceptionState & exceptionState)1066 void Internals::scrollElementToRect(Element* element, long x, long y, long w, long h, ExceptionState& exceptionState)
1067 {
1068 if (!element || !element->document().view()) {
1069 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1070 return;
1071 }
1072 FrameView* frameView = element->document().view();
1073 frameView->scrollElementToRect(element, IntRect(x, y, w, h));
1074 }
1075
paintControlTints(Document * document,ExceptionState & exceptionState)1076 void Internals::paintControlTints(Document* document, ExceptionState& exceptionState)
1077 {
1078 if (!document || !document->view()) {
1079 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1080 return;
1081 }
1082
1083 FrameView* frameView = document->view();
1084 frameView->paintControlTints();
1085 }
1086
rangeFromLocationAndLength(Element * scope,int rangeLocation,int rangeLength,ExceptionState & exceptionState)1087 PassRefPtr<Range> Internals::rangeFromLocationAndLength(Element* scope, int rangeLocation, int rangeLength, ExceptionState& exceptionState)
1088 {
1089 if (!scope) {
1090 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1091 return 0;
1092 }
1093
1094 // TextIterator depends on Layout information, make sure layout it up to date.
1095 scope->document().updateLayoutIgnorePendingStylesheets();
1096
1097 return PlainTextRange(rangeLocation, rangeLocation + rangeLength).createRange(*scope);
1098 }
1099
locationFromRange(Element * scope,const Range * range,ExceptionState & exceptionState)1100 unsigned Internals::locationFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
1101 {
1102 if (!scope || !range) {
1103 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1104 return 0;
1105 }
1106
1107 // PlainTextRange depends on Layout information, make sure layout it up to date.
1108 scope->document().updateLayoutIgnorePendingStylesheets();
1109
1110 return PlainTextRange::create(*scope, *range).start();
1111 }
1112
lengthFromRange(Element * scope,const Range * range,ExceptionState & exceptionState)1113 unsigned Internals::lengthFromRange(Element* scope, const Range* range, ExceptionState& exceptionState)
1114 {
1115 if (!scope || !range) {
1116 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1117 return 0;
1118 }
1119
1120 // PlainTextRange depends on Layout information, make sure layout it up to date.
1121 scope->document().updateLayoutIgnorePendingStylesheets();
1122
1123 return PlainTextRange::create(*scope, *range).length();
1124 }
1125
rangeAsText(const Range * range,ExceptionState & exceptionState)1126 String Internals::rangeAsText(const Range* range, ExceptionState& exceptionState)
1127 {
1128 if (!range) {
1129 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1130 return String();
1131 }
1132
1133 return range->text();
1134 }
1135
touchPositionAdjustedToBestClickableNode(long x,long y,long width,long height,Document * document,ExceptionState & exceptionState)1136 PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
1137 {
1138 if (!document || !document->frame()) {
1139 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1140 return 0;
1141 }
1142
1143 document->updateLayout();
1144
1145 IntSize radius(width / 2, height / 2);
1146 IntPoint point(x + radius.width(), y + radius.height());
1147
1148 Node* targetNode;
1149 IntPoint adjustedPoint;
1150
1151 bool foundNode = document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1152 if (foundNode)
1153 return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
1154
1155 return 0;
1156 }
1157
touchNodeAdjustedToBestClickableNode(long x,long y,long width,long height,Document * document,ExceptionState & exceptionState)1158 Node* Internals::touchNodeAdjustedToBestClickableNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
1159 {
1160 if (!document || !document->frame()) {
1161 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1162 return 0;
1163 }
1164
1165 document->updateLayout();
1166
1167 IntSize radius(width / 2, height / 2);
1168 IntPoint point(x + radius.width(), y + radius.height());
1169
1170 Node* targetNode;
1171 IntPoint adjustedPoint;
1172 document->frame()->eventHandler().bestClickableNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1173 return targetNode;
1174 }
1175
touchPositionAdjustedToBestContextMenuNode(long x,long y,long width,long height,Document * document,ExceptionState & exceptionState)1176 PassRefPtr<DOMPoint> Internals::touchPositionAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
1177 {
1178 if (!document || !document->frame()) {
1179 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1180 return 0;
1181 }
1182
1183 document->updateLayout();
1184
1185 IntSize radius(width / 2, height / 2);
1186 IntPoint point(x + radius.width(), y + radius.height());
1187
1188 Node* targetNode = 0;
1189 IntPoint adjustedPoint;
1190
1191 bool foundNode = document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1192 if (foundNode)
1193 return DOMPoint::create(adjustedPoint.x(), adjustedPoint.y());
1194
1195 return DOMPoint::create(x, y);
1196 }
1197
touchNodeAdjustedToBestContextMenuNode(long x,long y,long width,long height,Document * document,ExceptionState & exceptionState)1198 Node* Internals::touchNodeAdjustedToBestContextMenuNode(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
1199 {
1200 if (!document || !document->frame()) {
1201 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1202 return 0;
1203 }
1204
1205 document->updateLayout();
1206
1207 IntSize radius(width / 2, height / 2);
1208 IntPoint point(x + radius.width(), y + radius.height());
1209
1210 Node* targetNode = 0;
1211 IntPoint adjustedPoint;
1212 document->frame()->eventHandler().bestContextMenuNodeForTouchPoint(point, radius, adjustedPoint, targetNode);
1213 return targetNode;
1214 }
1215
bestZoomableAreaForTouchPoint(long x,long y,long width,long height,Document * document,ExceptionState & exceptionState)1216 PassRefPtr<ClientRect> Internals::bestZoomableAreaForTouchPoint(long x, long y, long width, long height, Document* document, ExceptionState& exceptionState)
1217 {
1218 if (!document || !document->frame()) {
1219 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1220 return 0;
1221 }
1222
1223 document->updateLayout();
1224
1225 IntSize radius(width / 2, height / 2);
1226 IntPoint point(x + radius.width(), y + radius.height());
1227
1228 Node* targetNode;
1229 IntRect zoomableArea;
1230 bool foundNode = document->frame()->eventHandler().bestZoomableAreaForTouchPoint(point, radius, zoomableArea, targetNode);
1231 if (foundNode)
1232 return ClientRect::create(zoomableArea);
1233
1234 return 0;
1235 }
1236
1237
lastSpellCheckRequestSequence(Document * document,ExceptionState & exceptionState)1238 int Internals::lastSpellCheckRequestSequence(Document* document, ExceptionState& exceptionState)
1239 {
1240 SpellCheckRequester* requester = spellCheckRequester(document);
1241
1242 if (!requester) {
1243 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1244 return -1;
1245 }
1246
1247 return requester->lastRequestSequence();
1248 }
1249
lastSpellCheckProcessedSequence(Document * document,ExceptionState & exceptionState)1250 int Internals::lastSpellCheckProcessedSequence(Document* document, ExceptionState& exceptionState)
1251 {
1252 SpellCheckRequester* requester = spellCheckRequester(document);
1253
1254 if (!requester) {
1255 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1256 return -1;
1257 }
1258
1259 return requester->lastProcessedSequence();
1260 }
1261
userPreferredLanguages() const1262 Vector<String> Internals::userPreferredLanguages() const
1263 {
1264 return WebCore::userPreferredLanguages();
1265 }
1266
setUserPreferredLanguages(const Vector<String> & languages)1267 void Internals::setUserPreferredLanguages(const Vector<String>& languages)
1268 {
1269 WebCore::overrideUserPreferredLanguages(languages);
1270 }
1271
wheelEventHandlerCount(Document * document,ExceptionState & exceptionState)1272 unsigned Internals::wheelEventHandlerCount(Document* document, ExceptionState& exceptionState)
1273 {
1274 if (!document) {
1275 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1276 return 0;
1277 }
1278
1279 return WheelController::from(document)->wheelEventHandlerCount();
1280 }
1281
touchEventHandlerCount(Document * document,ExceptionState & exceptionState)1282 unsigned Internals::touchEventHandlerCount(Document* document, ExceptionState& exceptionState)
1283 {
1284 if (!document) {
1285 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1286 return 0;
1287 }
1288
1289 const TouchEventTargetSet* touchHandlers = document->touchEventTargets();
1290 if (!touchHandlers)
1291 return 0;
1292
1293 unsigned count = 0;
1294 for (TouchEventTargetSet::const_iterator iter = touchHandlers->begin(); iter != touchHandlers->end(); ++iter)
1295 count += iter->value;
1296 return count;
1297 }
1298
findRenderLayerForGraphicsLayer(RenderLayer * searchRoot,GraphicsLayer * graphicsLayer,String * layerType)1299 static RenderLayer* findRenderLayerForGraphicsLayer(RenderLayer* searchRoot, GraphicsLayer* graphicsLayer, String* layerType)
1300 {
1301 if (searchRoot->hasCompositedLayerMapping() && graphicsLayer == searchRoot->compositedLayerMapping()->mainGraphicsLayer())
1302 return searchRoot;
1303
1304 GraphicsLayer* layerForScrolling = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrolling() : 0;
1305 if (graphicsLayer == layerForScrolling) {
1306 *layerType = "scrolling";
1307 return searchRoot;
1308 }
1309
1310 GraphicsLayer* layerForHorizontalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForHorizontalScrollbar() : 0;
1311 if (graphicsLayer == layerForHorizontalScrollbar) {
1312 *layerType = "horizontalScrollbar";
1313 return searchRoot;
1314 }
1315
1316 GraphicsLayer* layerForVerticalScrollbar = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForVerticalScrollbar() : 0;
1317 if (graphicsLayer == layerForVerticalScrollbar) {
1318 *layerType = "verticalScrollbar";
1319 return searchRoot;
1320 }
1321
1322 GraphicsLayer* layerForScrollCorner = searchRoot->scrollableArea() ? searchRoot->scrollableArea()->layerForScrollCorner() : 0;
1323 if (graphicsLayer == layerForScrollCorner) {
1324 *layerType = "scrollCorner";
1325 return searchRoot;
1326 }
1327
1328 for (RenderLayer* child = searchRoot->firstChild(); child; child = child->nextSibling()) {
1329 RenderLayer* foundLayer = findRenderLayerForGraphicsLayer(child, graphicsLayer, layerType);
1330 if (foundLayer)
1331 return foundLayer;
1332 }
1333
1334 return 0;
1335 }
1336
1337 // Given a vector of rects, merge those that are adjacent, leaving empty rects
1338 // in the place of no longer used slots. This is intended to simplify the list
1339 // of rects returned by an SkRegion (which have been split apart for sorting
1340 // purposes). No attempt is made to do this efficiently (eg. by relying on the
1341 // sort criteria of SkRegion).
mergeRects(blink::WebVector<blink::WebRect> & rects)1342 static void mergeRects(blink::WebVector<blink::WebRect>& rects)
1343 {
1344 for (size_t i = 0; i < rects.size(); ++i) {
1345 if (rects[i].isEmpty())
1346 continue;
1347 bool updated;
1348 do {
1349 updated = false;
1350 for (size_t j = i+1; j < rects.size(); ++j) {
1351 if (rects[j].isEmpty())
1352 continue;
1353 // Try to merge rects[j] into rects[i] along the 4 possible edges.
1354 if (rects[i].y == rects[j].y && rects[i].height == rects[j].height) {
1355 if (rects[i].x + rects[i].width == rects[j].x) {
1356 rects[i].width += rects[j].width;
1357 rects[j] = blink::WebRect();
1358 updated = true;
1359 } else if (rects[i].x == rects[j].x + rects[j].width) {
1360 rects[i].x = rects[j].x;
1361 rects[i].width += rects[j].width;
1362 rects[j] = blink::WebRect();
1363 updated = true;
1364 }
1365 } else if (rects[i].x == rects[j].x && rects[i].width == rects[j].width) {
1366 if (rects[i].y + rects[i].height == rects[j].y) {
1367 rects[i].height += rects[j].height;
1368 rects[j] = blink::WebRect();
1369 updated = true;
1370 } else if (rects[i].y == rects[j].y + rects[j].height) {
1371 rects[i].y = rects[j].y;
1372 rects[i].height += rects[j].height;
1373 rects[j] = blink::WebRect();
1374 updated = true;
1375 }
1376 }
1377 }
1378 } while (updated);
1379 }
1380 }
1381
accumulateLayerRectList(RenderLayerCompositor * compositor,GraphicsLayer * graphicsLayer,LayerRectList * rects)1382 static void accumulateLayerRectList(RenderLayerCompositor* compositor, GraphicsLayer* graphicsLayer, LayerRectList* rects)
1383 {
1384 blink::WebVector<blink::WebRect> layerRects = graphicsLayer->platformLayer()->touchEventHandlerRegion();
1385 if (!layerRects.isEmpty()) {
1386 mergeRects(layerRects);
1387 String layerType;
1388 RenderLayer* renderLayer = findRenderLayerForGraphicsLayer(compositor->rootRenderLayer(), graphicsLayer, &layerType);
1389 Node* node = renderLayer ? renderLayer->renderer()->node() : 0;
1390 for (size_t i = 0; i < layerRects.size(); ++i) {
1391 if (!layerRects[i].isEmpty())
1392 rects->append(node, layerType, ClientRect::create(layerRects[i]));
1393 }
1394 }
1395
1396 size_t numChildren = graphicsLayer->children().size();
1397 for (size_t i = 0; i < numChildren; ++i)
1398 accumulateLayerRectList(compositor, graphicsLayer->children()[i], rects);
1399 }
1400
touchEventTargetLayerRects(Document * document,ExceptionState & exceptionState)1401 PassRefPtr<LayerRectList> Internals::touchEventTargetLayerRects(Document* document, ExceptionState& exceptionState)
1402 {
1403 if (!document || !document->view() || !document->page() || document != contextDocument()) {
1404 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1405 return 0;
1406 }
1407
1408 // Do any pending layout and compositing update (which may call touchEventTargetRectsChange) to ensure this
1409 // really takes any previous changes into account.
1410 forceCompositingUpdate(document, exceptionState);
1411 if (exceptionState.hadException())
1412 return 0;
1413
1414 if (RenderView* view = document->renderView()) {
1415 if (RenderLayerCompositor* compositor = view->compositor()) {
1416 if (GraphicsLayer* rootLayer = compositor->rootGraphicsLayer()) {
1417 RefPtr<LayerRectList> rects = LayerRectList::create();
1418 accumulateLayerRectList(compositor, rootLayer, rects.get());
1419 return rects;
1420 }
1421 }
1422 }
1423
1424 return 0;
1425 }
1426
nodesFromRect(Document * document,int centerX,int centerY,unsigned topPadding,unsigned rightPadding,unsigned bottomPadding,unsigned leftPadding,bool ignoreClipping,bool allowShadowContent,bool allowChildFrameContent,ExceptionState & exceptionState) const1427 PassRefPtr<NodeList> Internals::nodesFromRect(Document* document, int centerX, int centerY, unsigned topPadding, unsigned rightPadding,
1428 unsigned bottomPadding, unsigned leftPadding, bool ignoreClipping, bool allowShadowContent, bool allowChildFrameContent, ExceptionState& exceptionState) const
1429 {
1430 if (!document || !document->frame() || !document->frame()->view()) {
1431 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1432 return 0;
1433 }
1434
1435 Frame* frame = document->frame();
1436 FrameView* frameView = document->view();
1437 RenderView* renderView = document->renderView();
1438
1439 if (!renderView)
1440 return 0;
1441
1442 float zoomFactor = frame->pageZoomFactor();
1443 LayoutPoint point = roundedLayoutPoint(FloatPoint(centerX * zoomFactor + frameView->scrollX(), centerY * zoomFactor + frameView->scrollY()));
1444
1445 HitTestRequest::HitTestRequestType hitType = HitTestRequest::ReadOnly | HitTestRequest::Active;
1446 if (ignoreClipping)
1447 hitType |= HitTestRequest::IgnoreClipping;
1448 if (!allowShadowContent)
1449 hitType |= HitTestRequest::ConfusingAndOftenMisusedDisallowShadowContent;
1450 if (allowChildFrameContent)
1451 hitType |= HitTestRequest::AllowChildFrameContent;
1452
1453 HitTestRequest request(hitType);
1454
1455 // When ignoreClipping is false, this method returns null for coordinates outside of the viewport.
1456 if (!request.ignoreClipping() && !frameView->visibleContentRect().intersects(HitTestLocation::rectForPoint(point, topPadding, rightPadding, bottomPadding, leftPadding)))
1457 return 0;
1458
1459 Vector<RefPtr<Node> > matches;
1460
1461 // Need padding to trigger a rect based hit test, but we want to return a NodeList
1462 // so we special case this.
1463 if (!topPadding && !rightPadding && !bottomPadding && !leftPadding) {
1464 HitTestResult result(point);
1465 renderView->hitTest(request, result);
1466 if (result.innerNode())
1467 matches.append(result.innerNode()->deprecatedShadowAncestorNode());
1468 } else {
1469 HitTestResult result(point, topPadding, rightPadding, bottomPadding, leftPadding);
1470 renderView->hitTest(request, result);
1471 copyToVector(result.rectBasedTestResult(), matches);
1472 }
1473
1474 return StaticNodeList::adopt(matches);
1475 }
1476
emitInspectorDidBeginFrame(int frameId)1477 void Internals::emitInspectorDidBeginFrame(int frameId)
1478 {
1479 contextDocument()->page()->inspectorController().didBeginFrame(frameId);
1480 }
1481
emitInspectorDidCancelFrame()1482 void Internals::emitInspectorDidCancelFrame()
1483 {
1484 contextDocument()->page()->inspectorController().didCancelFrame();
1485 }
1486
hasSpellingMarker(Document * document,int from,int length,ExceptionState &)1487 bool Internals::hasSpellingMarker(Document* document, int from, int length, ExceptionState&)
1488 {
1489 if (!document || !document->frame())
1490 return 0;
1491
1492 return document->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Spelling, from, length);
1493 }
1494
setContinuousSpellCheckingEnabled(bool enabled,ExceptionState &)1495 void Internals::setContinuousSpellCheckingEnabled(bool enabled, ExceptionState&)
1496 {
1497 if (!contextDocument() || !contextDocument()->frame())
1498 return;
1499
1500 if (enabled != contextDocument()->frame()->spellChecker().isContinuousSpellCheckingEnabled())
1501 contextDocument()->frame()->spellChecker().toggleContinuousSpellChecking();
1502 }
1503
isOverwriteModeEnabled(Document * document,ExceptionState &)1504 bool Internals::isOverwriteModeEnabled(Document* document, ExceptionState&)
1505 {
1506 if (!document || !document->frame())
1507 return 0;
1508
1509 return document->frame()->editor().isOverwriteModeEnabled();
1510 }
1511
toggleOverwriteModeEnabled(Document * document,ExceptionState &)1512 void Internals::toggleOverwriteModeEnabled(Document* document, ExceptionState&)
1513 {
1514 if (!document || !document->frame())
1515 return;
1516
1517 document->frame()->editor().toggleOverwriteModeEnabled();
1518 }
1519
numberOfLiveNodes() const1520 unsigned Internals::numberOfLiveNodes() const
1521 {
1522 return InspectorCounters::counterValue(InspectorCounters::NodeCounter);
1523 }
1524
numberOfLiveDocuments() const1525 unsigned Internals::numberOfLiveDocuments() const
1526 {
1527 return InspectorCounters::counterValue(InspectorCounters::DocumentCounter);
1528 }
1529
dumpRefCountedInstanceCounts() const1530 String Internals::dumpRefCountedInstanceCounts() const
1531 {
1532 return WTF::dumpRefCountedInstanceCounts();
1533 }
1534
consoleMessageArgumentCounts(Document * document) const1535 Vector<String> Internals::consoleMessageArgumentCounts(Document* document) const
1536 {
1537 InstrumentingAgents* instrumentingAgents = instrumentationForPage(document->page());
1538 if (!instrumentingAgents)
1539 return Vector<String>();
1540 InspectorConsoleAgent* consoleAgent = instrumentingAgents->inspectorConsoleAgent();
1541 if (!consoleAgent)
1542 return Vector<String>();
1543 Vector<unsigned> counts = consoleAgent->consoleMessageArgumentCounts();
1544 Vector<String> result(counts.size());
1545 for (size_t i = 0; i < counts.size(); i++)
1546 result[i] = String::number(counts[i]);
1547 return result;
1548 }
1549
openDummyInspectorFrontend(const String & url)1550 PassRefPtr<DOMWindow> Internals::openDummyInspectorFrontend(const String& url)
1551 {
1552 Page* page = contextDocument()->frame()->page();
1553 ASSERT(page);
1554
1555 DOMWindow* window = page->mainFrame()->domWindow();
1556 ASSERT(window);
1557
1558 m_frontendWindow = window->open(url, "", "", window, window);
1559 ASSERT(m_frontendWindow);
1560
1561 Page* frontendPage = m_frontendWindow->document()->page();
1562 ASSERT(frontendPage);
1563
1564 OwnPtr<InspectorFrontendClientLocal> frontendClient = adoptPtr(new InspectorFrontendClientLocal(page->inspectorController(), frontendPage));
1565
1566 frontendPage->inspectorController().setInspectorFrontendClient(frontendClient.release());
1567
1568 m_frontendChannel = adoptPtr(new InspectorFrontendChannelDummy(frontendPage));
1569
1570 page->inspectorController().connectFrontend(m_frontendChannel.get());
1571
1572 return m_frontendWindow;
1573 }
1574
closeDummyInspectorFrontend()1575 void Internals::closeDummyInspectorFrontend()
1576 {
1577 Page* page = contextDocument()->frame()->page();
1578 ASSERT(page);
1579 ASSERT(m_frontendWindow);
1580
1581 page->inspectorController().disconnectFrontend();
1582
1583 m_frontendChannel.release();
1584
1585 m_frontendWindow->close(m_frontendWindow->executionContext());
1586 m_frontendWindow.release();
1587 }
1588
setMemoryCacheCapacities(unsigned long minDeadBytes,unsigned long maxDeadBytes,unsigned long totalBytes)1589 Vector<unsigned long> Internals::setMemoryCacheCapacities(unsigned long minDeadBytes, unsigned long maxDeadBytes, unsigned long totalBytes)
1590 {
1591 Vector<unsigned long> result;
1592 result.append(memoryCache()->minDeadCapacity());
1593 result.append(memoryCache()->maxDeadCapacity());
1594 result.append(memoryCache()->capacity());
1595 memoryCache()->setCapacities(minDeadBytes, maxDeadBytes, totalBytes);
1596 return result;
1597 }
1598
setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize,int maximumSingleResourceContentSize,ExceptionState & exceptionState)1599 void Internals::setInspectorResourcesDataSizeLimits(int maximumResourcesContentSize, int maximumSingleResourceContentSize, ExceptionState& exceptionState)
1600 {
1601 Page* page = contextDocument()->frame()->page();
1602 if (!page) {
1603 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1604 return;
1605 }
1606 page->inspectorController().setResourcesDataSizeLimitsFromInternals(maximumResourcesContentSize, maximumSingleResourceContentSize);
1607 }
1608
hasGrammarMarker(Document * document,int from,int length,ExceptionState &)1609 bool Internals::hasGrammarMarker(Document* document, int from, int length, ExceptionState&)
1610 {
1611 if (!document || !document->frame())
1612 return 0;
1613
1614 return document->frame()->spellChecker().selectionStartHasMarkerFor(DocumentMarker::Grammar, from, length);
1615 }
1616
numberOfScrollableAreas(Document * document,ExceptionState &)1617 unsigned Internals::numberOfScrollableAreas(Document* document, ExceptionState&)
1618 {
1619 unsigned count = 0;
1620 Frame* frame = document->frame();
1621 if (frame->view()->scrollableAreas())
1622 count += frame->view()->scrollableAreas()->size();
1623
1624 for (Frame* child = frame->tree().firstChild(); child; child = child->tree().nextSibling()) {
1625 if (child->view() && child->view()->scrollableAreas())
1626 count += child->view()->scrollableAreas()->size();
1627 }
1628
1629 return count;
1630 }
1631
isPageBoxVisible(Document * document,int pageNumber,ExceptionState & exceptionState)1632 bool Internals::isPageBoxVisible(Document* document, int pageNumber, ExceptionState& exceptionState)
1633 {
1634 if (!document) {
1635 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1636 return false;
1637 }
1638
1639 return document->isPageBoxVisible(pageNumber);
1640 }
1641
layerTreeAsText(Document * document,ExceptionState & exceptionState) const1642 String Internals::layerTreeAsText(Document* document, ExceptionState& exceptionState) const
1643 {
1644 return layerTreeAsText(document, 0, exceptionState);
1645 }
1646
elementLayerTreeAsText(Element * element,ExceptionState & exceptionState) const1647 String Internals::elementLayerTreeAsText(Element* element, ExceptionState& exceptionState) const
1648 {
1649 return elementLayerTreeAsText(element, 0, exceptionState);
1650 }
1651
paintOrderList(Element * element,ExceptionState & exceptionState,RenderLayerStackingNode::PaintOrderListType type)1652 static PassRefPtr<NodeList> paintOrderList(Element* element, ExceptionState& exceptionState, RenderLayerStackingNode::PaintOrderListType type)
1653 {
1654 if (!element) {
1655 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1656 return 0;
1657 }
1658
1659 element->document().updateLayout();
1660
1661 RenderObject* renderer = element->renderer();
1662 if (!renderer || !renderer->isBox()) {
1663 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1664 return 0;
1665 }
1666
1667 RenderLayer* layer = toRenderBox(renderer)->layer();
1668 if (!layer) {
1669 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1670 return 0;
1671 }
1672
1673 Vector<RefPtr<Node> > nodes;
1674 layer->stackingNode()->computePaintOrderList(type, nodes);
1675 return StaticNodeList::adopt(nodes);
1676 }
1677
paintOrderListBeforePromote(Element * element,ExceptionState & exceptionState)1678 PassRefPtr<NodeList> Internals::paintOrderListBeforePromote(Element* element, ExceptionState& exceptionState)
1679 {
1680 return paintOrderList(element, exceptionState, RenderLayerStackingNode::BeforePromote);
1681 }
1682
paintOrderListAfterPromote(Element * element,ExceptionState & exceptionState)1683 PassRefPtr<NodeList> Internals::paintOrderListAfterPromote(Element* element, ExceptionState& exceptionState)
1684 {
1685 return paintOrderList(element, exceptionState, RenderLayerStackingNode::AfterPromote);
1686 }
1687
scrollsWithRespectTo(Element * element1,Element * element2,ExceptionState & exceptionState)1688 bool Internals::scrollsWithRespectTo(Element* element1, Element* element2, ExceptionState& exceptionState)
1689 {
1690 if (!element1 || !element2) {
1691 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1692 return 0;
1693 }
1694
1695 element1->document().updateLayout();
1696
1697 RenderObject* renderer1 = element1->renderer();
1698 RenderObject* renderer2 = element2->renderer();
1699 if (!renderer1 || !renderer2 || !renderer1->isBox() || !renderer2->isBox()) {
1700 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1701 return 0;
1702 }
1703
1704 RenderLayer* layer1 = toRenderBox(renderer1)->layer();
1705 RenderLayer* layer2 = toRenderBox(renderer2)->layer();
1706 if (!layer1 || !layer2) {
1707 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1708 return 0;
1709 }
1710
1711 return layer1->scrollsWithRespectTo(layer2);
1712 }
1713
isUnclippedDescendant(Element * element,ExceptionState & exceptionState)1714 bool Internals::isUnclippedDescendant(Element* element, ExceptionState& exceptionState)
1715 {
1716 if (!element) {
1717 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1718 return 0;
1719 }
1720
1721 element->document().updateLayout();
1722
1723 RenderObject* renderer = element->renderer();
1724 if (!renderer || !renderer->isBox()) {
1725 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1726 return 0;
1727 }
1728
1729 RenderLayer* layer = toRenderBox(renderer)->layer();
1730 if (!layer) {
1731 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1732 return 0;
1733 }
1734
1735 return layer->isUnclippedDescendant();
1736 }
1737
needsCompositedScrolling(Element * element,ExceptionState & exceptionState)1738 bool Internals::needsCompositedScrolling(Element* element, ExceptionState& exceptionState)
1739 {
1740 if (!element) {
1741 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1742 return 0;
1743 }
1744
1745 element->document().updateLayout();
1746
1747 RenderObject* renderer = element->renderer();
1748 if (!renderer || !renderer->isBox()) {
1749 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1750 return 0;
1751 }
1752
1753 RenderLayer* layer = toRenderBox(renderer)->layer();
1754 if (!layer) {
1755 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1756 return 0;
1757 }
1758
1759 return layer->needsCompositedScrolling();
1760 }
1761
layerTreeAsText(Document * document,unsigned flags,ExceptionState & exceptionState) const1762 String Internals::layerTreeAsText(Document* document, unsigned flags, ExceptionState& exceptionState) const
1763 {
1764 if (!document || !document->frame()) {
1765 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1766 return String();
1767 }
1768
1769 return document->frame()->layerTreeAsText(flags);
1770 }
1771
elementLayerTreeAsText(Element * element,unsigned flags,ExceptionState & exceptionState) const1772 String Internals::elementLayerTreeAsText(Element* element, unsigned flags, ExceptionState& exceptionState) const
1773 {
1774 if (!element) {
1775 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1776 return String();
1777 }
1778
1779 element->document().updateLayout();
1780
1781 RenderObject* renderer = element->renderer();
1782 if (!renderer || !renderer->isBox()) {
1783 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1784 return String();
1785 }
1786
1787 RenderLayer* layer = toRenderBox(renderer)->layer();
1788 if (!layer
1789 || !layer->hasCompositedLayerMapping()
1790 || !layer->compositedLayerMapping()->mainGraphicsLayer()) {
1791 // Don't raise exception in these cases which may be normally used in tests.
1792 return String();
1793 }
1794
1795 return layer->compositedLayerMapping()->mainGraphicsLayer()->layerTreeAsText(flags);
1796 }
1797
getRenderLayerForElement(Element * element,ExceptionState & exceptionState)1798 static RenderLayer* getRenderLayerForElement(Element* element, ExceptionState& exceptionState)
1799 {
1800 if (!element) {
1801 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1802 return 0;
1803 }
1804
1805 RenderObject* renderer = element->renderer();
1806 if (!renderer || !renderer->isBox()) {
1807 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1808 return 0;
1809 }
1810
1811 RenderLayer* layer = toRenderBox(renderer)->layer();
1812 if (!layer) {
1813 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1814 return 0;
1815 }
1816
1817 return layer;
1818 }
1819
setNeedsCompositedScrolling(Element * element,unsigned needsCompositedScrolling,ExceptionState & exceptionState)1820 void Internals::setNeedsCompositedScrolling(Element* element, unsigned needsCompositedScrolling, ExceptionState& exceptionState)
1821 {
1822 if (!element) {
1823 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1824 return;
1825 }
1826
1827 element->document().updateLayout();
1828
1829 if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState))
1830 layer->scrollableArea()->setForceNeedsCompositedScrolling(static_cast<ForceNeedsCompositedScrollingMode>(needsCompositedScrolling));
1831 }
1832
repaintRectsAsText(Document * document,ExceptionState & exceptionState) const1833 String Internals::repaintRectsAsText(Document* document, ExceptionState& exceptionState) const
1834 {
1835 if (!document || !document->frame()) {
1836 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1837 return String();
1838 }
1839
1840 return document->frame()->trackedRepaintRectsAsText();
1841 }
1842
repaintRects(Element * element,ExceptionState & exceptionState) const1843 PassRefPtr<ClientRectList> Internals::repaintRects(Element* element, ExceptionState& exceptionState) const
1844 {
1845 if (!element) {
1846 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1847 return 0;
1848 }
1849
1850 if (RenderLayer* layer = getRenderLayerForElement(element, exceptionState)) {
1851 if (layer->compositingState() == PaintsIntoOwnBacking) {
1852 OwnPtr<Vector<FloatRect> > rects = layer->collectTrackedRepaintRects();
1853 ASSERT(rects.get());
1854 Vector<FloatQuad> quads(rects->size());
1855 for (size_t i = 0; i < rects->size(); ++i)
1856 quads[i] = FloatRect(rects->at(i));
1857 return ClientRectList::create(quads);
1858 }
1859 }
1860
1861 // It's an error to call this on an element that's not composited.
1862 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1863 return 0;
1864 }
1865
scrollingStateTreeAsText(Document * document,ExceptionState & exceptionState) const1866 String Internals::scrollingStateTreeAsText(Document* document, ExceptionState& exceptionState) const
1867 {
1868 return String();
1869 }
1870
mainThreadScrollingReasons(Document * document,ExceptionState & exceptionState) const1871 String Internals::mainThreadScrollingReasons(Document* document, ExceptionState& exceptionState) const
1872 {
1873 if (!document || !document->frame()) {
1874 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1875 return String();
1876 }
1877
1878 // Force a re-layout and a compositing update.
1879 document->updateLayout();
1880 RenderView* view = document->renderView();
1881 if (view->compositor())
1882 view->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
1883
1884 Page* page = document->page();
1885 if (!page)
1886 return String();
1887
1888 return page->mainThreadScrollingReasonsAsText();
1889 }
1890
nonFastScrollableRects(Document * document,ExceptionState & exceptionState) const1891 PassRefPtr<ClientRectList> Internals::nonFastScrollableRects(Document* document, ExceptionState& exceptionState) const
1892 {
1893 if (!document || !document->frame()) {
1894 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1895 return 0;
1896 }
1897
1898 Page* page = document->page();
1899 if (!page)
1900 return 0;
1901
1902 return page->nonFastScrollableRects(document->frame());
1903 }
1904
garbageCollectDocumentResources(Document * document,ExceptionState & exceptionState) const1905 void Internals::garbageCollectDocumentResources(Document* document, ExceptionState& exceptionState) const
1906 {
1907 if (!document) {
1908 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1909 return;
1910 }
1911 ResourceFetcher* fetcher = document->fetcher();
1912 if (!fetcher)
1913 return;
1914 fetcher->garbageCollectDocumentResources();
1915 }
1916
evictAllResources() const1917 void Internals::evictAllResources() const
1918 {
1919 memoryCache()->evictResources();
1920 }
1921
allowRoundingHacks() const1922 void Internals::allowRoundingHacks() const
1923 {
1924 TextRun::setAllowsRoundingHacks(true);
1925 }
1926
counterValue(Element * element)1927 String Internals::counterValue(Element* element)
1928 {
1929 if (!element)
1930 return String();
1931
1932 return counterValueForElement(element);
1933 }
1934
pageNumber(Element * element,float pageWidth,float pageHeight)1935 int Internals::pageNumber(Element* element, float pageWidth, float pageHeight)
1936 {
1937 if (!element)
1938 return 0;
1939
1940 return PrintContext::pageNumberForElement(element, FloatSize(pageWidth, pageHeight));
1941 }
1942
iconURLs(Document * document,int iconTypesMask) const1943 Vector<String> Internals::iconURLs(Document* document, int iconTypesMask) const
1944 {
1945 Vector<IconURL> iconURLs = document->iconURLs(iconTypesMask);
1946 Vector<String> array;
1947
1948 Vector<IconURL>::const_iterator iter(iconURLs.begin());
1949 for (; iter != iconURLs.end(); ++iter)
1950 array.append(iter->m_iconURL.string());
1951
1952 return array;
1953 }
1954
shortcutIconURLs(Document * document) const1955 Vector<String> Internals::shortcutIconURLs(Document* document) const
1956 {
1957 return iconURLs(document, Favicon);
1958 }
1959
allIconURLs(Document * document) const1960 Vector<String> Internals::allIconURLs(Document* document) const
1961 {
1962 return iconURLs(document, Favicon | TouchIcon | TouchPrecomposedIcon);
1963 }
1964
numberOfPages(float pageWidth,float pageHeight)1965 int Internals::numberOfPages(float pageWidth, float pageHeight)
1966 {
1967 if (!frame())
1968 return -1;
1969
1970 return PrintContext::numberOfPages(frame(), FloatSize(pageWidth, pageHeight));
1971 }
1972
pageProperty(String propertyName,int pageNumber,ExceptionState & exceptionState) const1973 String Internals::pageProperty(String propertyName, int pageNumber, ExceptionState& exceptionState) const
1974 {
1975 if (!frame()) {
1976 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1977 return String();
1978 }
1979
1980 return PrintContext::pageProperty(frame(), propertyName.utf8().data(), pageNumber);
1981 }
1982
pageSizeAndMarginsInPixels(int pageNumber,int width,int height,int marginTop,int marginRight,int marginBottom,int marginLeft,ExceptionState & exceptionState) const1983 String Internals::pageSizeAndMarginsInPixels(int pageNumber, int width, int height, int marginTop, int marginRight, int marginBottom, int marginLeft, ExceptionState& exceptionState) const
1984 {
1985 if (!frame()) {
1986 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1987 return String();
1988 }
1989
1990 return PrintContext::pageSizeAndMarginsInPixels(frame(), pageNumber, width, height, marginTop, marginRight, marginBottom, marginLeft);
1991 }
1992
setDeviceScaleFactor(float scaleFactor,ExceptionState & exceptionState)1993 void Internals::setDeviceScaleFactor(float scaleFactor, ExceptionState& exceptionState)
1994 {
1995 Document* document = contextDocument();
1996 if (!document || !document->page()) {
1997 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
1998 return;
1999 }
2000 Page* page = document->page();
2001 page->setDeviceScaleFactor(scaleFactor);
2002 }
2003
setIsCursorVisible(Document * document,bool isVisible,ExceptionState & exceptionState)2004 void Internals::setIsCursorVisible(Document* document, bool isVisible, ExceptionState& exceptionState)
2005 {
2006 if (!document || !document->page()) {
2007 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2008 return;
2009 }
2010 document->page()->setIsCursorVisible(isVisible);
2011 }
2012
webkitWillEnterFullScreenForElement(Document * document,Element * element)2013 void Internals::webkitWillEnterFullScreenForElement(Document* document, Element* element)
2014 {
2015 if (!document)
2016 return;
2017 FullscreenElementStack::from(document)->webkitWillEnterFullScreenForElement(element);
2018 }
2019
webkitDidEnterFullScreenForElement(Document * document,Element * element)2020 void Internals::webkitDidEnterFullScreenForElement(Document* document, Element* element)
2021 {
2022 if (!document)
2023 return;
2024 FullscreenElementStack::from(document)->webkitDidEnterFullScreenForElement(element);
2025 }
2026
webkitWillExitFullScreenForElement(Document * document,Element * element)2027 void Internals::webkitWillExitFullScreenForElement(Document* document, Element* element)
2028 {
2029 if (!document)
2030 return;
2031 FullscreenElementStack::from(document)->webkitWillExitFullScreenForElement(element);
2032 }
2033
webkitDidExitFullScreenForElement(Document * document,Element * element)2034 void Internals::webkitDidExitFullScreenForElement(Document* document, Element* element)
2035 {
2036 if (!document)
2037 return;
2038 FullscreenElementStack::from(document)->webkitDidExitFullScreenForElement(element);
2039 }
2040
registerURLSchemeAsBypassingContentSecurityPolicy(const String & scheme)2041 void Internals::registerURLSchemeAsBypassingContentSecurityPolicy(const String& scheme)
2042 {
2043 SchemeRegistry::registerURLSchemeAsBypassingContentSecurityPolicy(scheme);
2044 }
2045
removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String & scheme)2046 void Internals::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(const String& scheme)
2047 {
2048 SchemeRegistry::removeURLSchemeRegisteredAsBypassingContentSecurityPolicy(scheme);
2049 }
2050
mallocStatistics() const2051 PassRefPtr<MallocStatistics> Internals::mallocStatistics() const
2052 {
2053 return MallocStatistics::create();
2054 }
2055
typeConversions() const2056 PassRefPtr<TypeConversions> Internals::typeConversions() const
2057 {
2058 return TypeConversions::create();
2059 }
2060
getReferencedFilePaths() const2061 Vector<String> Internals::getReferencedFilePaths() const
2062 {
2063 frame()->loader().saveDocumentAndScrollState();
2064 return FormController::getReferencedFilePaths(frame()->loader().currentItem()->documentState());
2065 }
2066
startTrackingRepaints(Document * document,ExceptionState & exceptionState)2067 void Internals::startTrackingRepaints(Document* document, ExceptionState& exceptionState)
2068 {
2069 if (!document || !document->view()) {
2070 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2071 return;
2072 }
2073
2074 FrameView* frameView = document->view();
2075 frameView->setTracksRepaints(true);
2076 }
2077
stopTrackingRepaints(Document * document,ExceptionState & exceptionState)2078 void Internals::stopTrackingRepaints(Document* document, ExceptionState& exceptionState)
2079 {
2080 if (!document || !document->view()) {
2081 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2082 return;
2083 }
2084
2085 FrameView* frameView = document->view();
2086 frameView->setTracksRepaints(false);
2087 }
2088
updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionState & exceptionState)2089 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(ExceptionState& exceptionState)
2090 {
2091 updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(0, exceptionState);
2092 }
2093
updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node * node,ExceptionState & exceptionState)2094 void Internals::updateLayoutIgnorePendingStylesheetsAndRunPostLayoutTasks(Node* node, ExceptionState& exceptionState)
2095 {
2096 Document* document;
2097 if (!node) {
2098 document = contextDocument();
2099 } else if (node->isDocumentNode()) {
2100 document = toDocument(node);
2101 } else if (node->hasTagName(HTMLNames::iframeTag)) {
2102 document = toHTMLIFrameElement(node)->contentDocument();
2103 } else {
2104 exceptionState.throwUninformativeAndGenericDOMException(TypeError);
2105 return;
2106 }
2107 document->updateLayoutIgnorePendingStylesheets(Document::RunPostLayoutTasksSynchronously);
2108 }
2109
draggableRegions(Document * document,ExceptionState & exceptionState)2110 PassRefPtr<ClientRectList> Internals::draggableRegions(Document* document, ExceptionState& exceptionState)
2111 {
2112 return annotatedRegions(document, true, exceptionState);
2113 }
2114
nonDraggableRegions(Document * document,ExceptionState & exceptionState)2115 PassRefPtr<ClientRectList> Internals::nonDraggableRegions(Document* document, ExceptionState& exceptionState)
2116 {
2117 return annotatedRegions(document, false, exceptionState);
2118 }
2119
annotatedRegions(Document * document,bool draggable,ExceptionState & exceptionState)2120 PassRefPtr<ClientRectList> Internals::annotatedRegions(Document* document, bool draggable, ExceptionState& exceptionState)
2121 {
2122 if (!document || !document->view()) {
2123 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2124 return ClientRectList::create();
2125 }
2126
2127 document->updateLayout();
2128 document->view()->updateAnnotatedRegions();
2129 Vector<AnnotatedRegionValue> regions = document->annotatedRegions();
2130
2131 Vector<FloatQuad> quads;
2132 for (size_t i = 0; i < regions.size(); ++i) {
2133 if (regions[i].draggable == draggable)
2134 quads.append(FloatQuad(regions[i].bounds));
2135 }
2136 return ClientRectList::create(quads);
2137 }
2138
cursorTypeToString(Cursor::Type cursorType)2139 static const char* cursorTypeToString(Cursor::Type cursorType)
2140 {
2141 switch (cursorType) {
2142 case Cursor::Pointer: return "Pointer";
2143 case Cursor::Cross: return "Cross";
2144 case Cursor::Hand: return "Hand";
2145 case Cursor::IBeam: return "IBeam";
2146 case Cursor::Wait: return "Wait";
2147 case Cursor::Help: return "Help";
2148 case Cursor::EastResize: return "EastResize";
2149 case Cursor::NorthResize: return "NorthResize";
2150 case Cursor::NorthEastResize: return "NorthEastResize";
2151 case Cursor::NorthWestResize: return "NorthWestResize";
2152 case Cursor::SouthResize: return "SouthResize";
2153 case Cursor::SouthEastResize: return "SouthEastResize";
2154 case Cursor::SouthWestResize: return "SouthWestResize";
2155 case Cursor::WestResize: return "WestResize";
2156 case Cursor::NorthSouthResize: return "NorthSouthResize";
2157 case Cursor::EastWestResize: return "EastWestResize";
2158 case Cursor::NorthEastSouthWestResize: return "NorthEastSouthWestResize";
2159 case Cursor::NorthWestSouthEastResize: return "NorthWestSouthEastResize";
2160 case Cursor::ColumnResize: return "ColumnResize";
2161 case Cursor::RowResize: return "RowResize";
2162 case Cursor::MiddlePanning: return "MiddlePanning";
2163 case Cursor::EastPanning: return "EastPanning";
2164 case Cursor::NorthPanning: return "NorthPanning";
2165 case Cursor::NorthEastPanning: return "NorthEastPanning";
2166 case Cursor::NorthWestPanning: return "NorthWestPanning";
2167 case Cursor::SouthPanning: return "SouthPanning";
2168 case Cursor::SouthEastPanning: return "SouthEastPanning";
2169 case Cursor::SouthWestPanning: return "SouthWestPanning";
2170 case Cursor::WestPanning: return "WestPanning";
2171 case Cursor::Move: return "Move";
2172 case Cursor::VerticalText: return "VerticalText";
2173 case Cursor::Cell: return "Cell";
2174 case Cursor::ContextMenu: return "ContextMenu";
2175 case Cursor::Alias: return "Alias";
2176 case Cursor::Progress: return "Progress";
2177 case Cursor::NoDrop: return "NoDrop";
2178 case Cursor::Copy: return "Copy";
2179 case Cursor::None: return "None";
2180 case Cursor::NotAllowed: return "NotAllowed";
2181 case Cursor::ZoomIn: return "ZoomIn";
2182 case Cursor::ZoomOut: return "ZoomOut";
2183 case Cursor::Grab: return "Grab";
2184 case Cursor::Grabbing: return "Grabbing";
2185 case Cursor::Custom: return "Custom";
2186 }
2187
2188 ASSERT_NOT_REACHED();
2189 return "UNKNOWN";
2190 }
2191
getCurrentCursorInfo(Document * document,ExceptionState & exceptionState)2192 String Internals::getCurrentCursorInfo(Document* document, ExceptionState& exceptionState)
2193 {
2194 if (!document || !document->frame()) {
2195 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2196 return String();
2197 }
2198
2199 Cursor cursor = document->frame()->eventHandler().currentMouseCursor();
2200
2201 StringBuilder result;
2202 result.append("type=");
2203 result.append(cursorTypeToString(cursor.type()));
2204 result.append(" hotSpot=");
2205 result.appendNumber(cursor.hotSpot().x());
2206 result.append(",");
2207 result.appendNumber(cursor.hotSpot().y());
2208 if (cursor.image()) {
2209 IntSize size = cursor.image()->size();
2210 result.append(" image=");
2211 result.appendNumber(size.width());
2212 result.append("x");
2213 result.appendNumber(size.height());
2214 }
2215 if (cursor.imageScaleFactor() != 1) {
2216 result.append(" scale=");
2217 NumberToStringBuffer buffer;
2218 result.append(numberToFixedPrecisionString(cursor.imageScaleFactor(), 8, buffer, true));
2219 }
2220
2221 return result.toString();
2222 }
2223
serializeObject(PassRefPtr<SerializedScriptValue> value) const2224 PassRefPtr<ArrayBuffer> Internals::serializeObject(PassRefPtr<SerializedScriptValue> value) const
2225 {
2226 String stringValue = value->toWireString();
2227 RefPtr<ArrayBuffer> buffer = ArrayBuffer::createUninitialized(stringValue.length(), sizeof(UChar));
2228 stringValue.copyTo(static_cast<UChar*>(buffer->data()), 0, stringValue.length());
2229 return buffer.release();
2230 }
2231
deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const2232 PassRefPtr<SerializedScriptValue> Internals::deserializeBuffer(PassRefPtr<ArrayBuffer> buffer) const
2233 {
2234 String value(static_cast<const UChar*>(buffer->data()), buffer->byteLength() / sizeof(UChar));
2235 return SerializedScriptValue::createFromWire(value);
2236 }
2237
forceReload(bool endToEnd)2238 void Internals::forceReload(bool endToEnd)
2239 {
2240 frame()->loader().reload(endToEnd ? EndToEndReload : NormalReload);
2241 }
2242
selectionBounds(ExceptionState & exceptionState)2243 PassRefPtr<ClientRect> Internals::selectionBounds(ExceptionState& exceptionState)
2244 {
2245 Document* document = contextDocument();
2246 if (!document || !document->frame()) {
2247 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2248 return 0;
2249 }
2250
2251 return ClientRect::create(document->frame()->selection().bounds());
2252 }
2253
markerTextForListItem(Element * element,ExceptionState & exceptionState)2254 String Internals::markerTextForListItem(Element* element, ExceptionState& exceptionState)
2255 {
2256 if (!element) {
2257 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2258 return String();
2259 }
2260 return WebCore::markerTextForListItem(element);
2261 }
2262
getImageSourceURL(Element * element,ExceptionState & exceptionState)2263 String Internals::getImageSourceURL(Element* element, ExceptionState& exceptionState)
2264 {
2265 if (!element) {
2266 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2267 return String();
2268 }
2269 return element->imageSourceURL();
2270 }
2271
baseURL(Document * document,ExceptionState & exceptionState)2272 String Internals::baseURL(Document* document, ExceptionState& exceptionState)
2273 {
2274 if (!document) {
2275 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2276 return String();
2277 }
2278
2279 return document->baseURL().string();
2280 }
2281
isSelectPopupVisible(Node * node)2282 bool Internals::isSelectPopupVisible(Node* node)
2283 {
2284 if (!node->hasTagName(HTMLNames::selectTag))
2285 return false;
2286
2287 HTMLSelectElement* select = toHTMLSelectElement(node);
2288
2289 RenderObject* renderer = select->renderer();
2290 if (!renderer->isMenuList())
2291 return false;
2292
2293 RenderMenuList* menuList = toRenderMenuList(renderer);
2294 return menuList->popupIsVisible();
2295 }
2296
loseSharedGraphicsContext3D()2297 bool Internals::loseSharedGraphicsContext3D()
2298 {
2299 RefPtr<GraphicsContext3D> sharedContext = SharedGraphicsContext3D::get();
2300 if (!sharedContext)
2301 return false;
2302 sharedContext->extensions()->loseContextCHROMIUM(Extensions3D::GUILTY_CONTEXT_RESET_ARB, Extensions3D::INNOCENT_CONTEXT_RESET_ARB);
2303 // To prevent tests that call loseSharedGraphicsContext3D from being
2304 // flaky, we call finish so that the context is guaranteed to be lost
2305 // synchronously (i.e. before returning).
2306 sharedContext->finish();
2307 return true;
2308 }
2309
forceCompositingUpdate(Document * document,ExceptionState & exceptionState)2310 void Internals::forceCompositingUpdate(Document* document, ExceptionState& exceptionState)
2311 {
2312 if (!document || !document->renderView()) {
2313 exceptionState.throwUninformativeAndGenericDOMException(InvalidAccessError);
2314 return;
2315 }
2316
2317 document->updateLayout();
2318
2319 RenderView* view = document->renderView();
2320 if (view->compositor())
2321 view->compositor()->updateCompositingLayers(CompositingUpdateFinishAllDeferredWork);
2322 }
2323
isCompositorFramePending(Document * document,ExceptionState & exceptionState)2324 bool Internals::isCompositorFramePending(Document* document, ExceptionState& exceptionState)
2325 {
2326 if (!document || !document->renderView()) {
2327 exceptionState.throwDOMException(InvalidAccessError, document ? "The document's render view cannot be retrieved." : "The document provided is invalid.");
2328 return false;
2329 }
2330
2331 return document->page()->chrome().client().isCompositorFramePending();
2332 }
2333
setZoomFactor(float factor)2334 void Internals::setZoomFactor(float factor)
2335 {
2336 frame()->setPageZoomFactor(factor);
2337 }
2338
2339 }
2340