InspectorPageAgent.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349
  1. /*
  2. * Copyright (C) 2011 Google Inc. All rights reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions are
  6. * met:
  7. *
  8. * * Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * * Redistributions in binary form must reproduce the above
  11. * copyright notice, this list of conditions and the following disclaimer
  12. * in the documentation and/or other materials provided with the
  13. * distribution.
  14. * * Neither the name of Google Inc. nor the names of its
  15. * contributors may be used to endorse or promote products derived from
  16. * this software without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  19. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  20. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  21. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  22. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  23. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  24. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  25. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  26. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  28. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "config.h"
  31. #if ENABLE(INSPECTOR)
  32. #include "InspectorPageAgent.h"
  33. #include "CachedCSSStyleSheet.h"
  34. #include "CachedFont.h"
  35. #include "CachedImage.h"
  36. #include "CachedResource.h"
  37. #include "CachedResourceLoader.h"
  38. #include "CachedScript.h"
  39. #include "ContentSearchUtils.h"
  40. #include "Cookie.h"
  41. #include "CookieJar.h"
  42. #include "DOMImplementation.h"
  43. #include "DOMPatchSupport.h"
  44. #include "DOMWrapperWorld.h"
  45. #include "DeviceOrientationController.h"
  46. #include "Document.h"
  47. #include "DocumentLoader.h"
  48. #include "Frame.h"
  49. #include "FrameLoader.h"
  50. #include "FrameView.h"
  51. #include "GeolocationController.h"
  52. #include "GeolocationError.h"
  53. #include "HTMLFrameOwnerElement.h"
  54. #include "HTMLNames.h"
  55. #include "IdentifiersFactory.h"
  56. #include "InjectedScriptManager.h"
  57. #include "InspectorAgent.h"
  58. #include "InspectorClient.h"
  59. #include "InspectorFrontend.h"
  60. #include "InspectorInstrumentation.h"
  61. #include "InspectorOverlay.h"
  62. #include "InspectorState.h"
  63. #include "InspectorValues.h"
  64. #include "InstrumentingAgents.h"
  65. #include "MemoryCache.h"
  66. #include "Page.h"
  67. #include "RegularExpression.h"
  68. #include "ResourceBuffer.h"
  69. #include "ScriptController.h"
  70. #include "ScriptObject.h"
  71. #include "SecurityOrigin.h"
  72. #include "Settings.h"
  73. #include "TextEncoding.h"
  74. #include "TextResourceDecoder.h"
  75. #include "UserGestureIndicator.h"
  76. #include <wtf/CurrentTime.h>
  77. #include <wtf/ListHashSet.h>
  78. #include <wtf/Vector.h>
  79. #include <wtf/text/Base64.h>
  80. #include <wtf/text/StringBuilder.h>
  81. namespace WebCore {
  82. namespace PageAgentState {
  83. static const char pageAgentEnabled[] = "pageAgentEnabled";
  84. static const char pageAgentScriptExecutionDisabled[] = "pageAgentScriptExecutionDisabled";
  85. static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
  86. static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
  87. static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
  88. static const char pageAgentFontScaleFactorOverride[] = "pageAgentFontScaleFactorOverride";
  89. static const char pageAgentFitWindow[] = "pageAgentFitWindow";
  90. static const char pageAgentShowFPSCounter[] = "pageAgentShowFPSCounter";
  91. static const char pageAgentContinuousPaintingEnabled[] = "pageAgentContinuousPaintingEnabled";
  92. static const char pageAgentShowPaintRects[] = "pageAgentShowPaintRects";
  93. static const char pageAgentShowDebugBorders[] = "pageAgentShowDebugBorders";
  94. #if ENABLE(TOUCH_EVENTS)
  95. static const char touchEventEmulationEnabled[] = "touchEventEmulationEnabled";
  96. #endif
  97. static const char pageAgentEmulatedMedia[] = "pageAgentEmulatedMedia";
  98. }
  99. static bool decodeBuffer(const char* buffer, unsigned size, const String& textEncodingName, String* result)
  100. {
  101. if (buffer) {
  102. TextEncoding encoding(textEncodingName);
  103. if (!encoding.isValid())
  104. encoding = WindowsLatin1Encoding();
  105. *result = encoding.decode(buffer, size);
  106. return true;
  107. }
  108. return false;
  109. }
  110. static bool prepareCachedResourceBuffer(CachedResource* cachedResource, bool* hasZeroSize)
  111. {
  112. *hasZeroSize = false;
  113. if (!cachedResource)
  114. return false;
  115. // Zero-sized resources don't have data at all -- so fake the empty buffer, instead of indicating error by returning 0.
  116. if (!cachedResource->encodedSize()) {
  117. *hasZeroSize = true;
  118. return true;
  119. }
  120. if (cachedResource->isPurgeable()) {
  121. // If the resource is purgeable then make it unpurgeable to get
  122. // get its data. This might fail, in which case we return an
  123. // empty String.
  124. // FIXME: should we do something else in the case of a purged
  125. // resource that informs the user why there is no data in the
  126. // inspector?
  127. if (!cachedResource->makePurgeable(false))
  128. return false;
  129. }
  130. return true;
  131. }
  132. static bool hasTextContent(CachedResource* cachedResource)
  133. {
  134. InspectorPageAgent::ResourceType type = InspectorPageAgent::cachedResourceType(*cachedResource);
  135. return type == InspectorPageAgent::DocumentResource || type == InspectorPageAgent::StylesheetResource || type == InspectorPageAgent::ScriptResource || type == InspectorPageAgent::XHRResource;
  136. }
  137. static PassRefPtr<TextResourceDecoder> createXHRTextDecoder(const String& mimeType, const String& textEncodingName)
  138. {
  139. RefPtr<TextResourceDecoder> decoder;
  140. if (!textEncodingName.isEmpty())
  141. decoder = TextResourceDecoder::create("text/plain", textEncodingName);
  142. else if (DOMImplementation::isXMLMIMEType(mimeType.lower())) {
  143. decoder = TextResourceDecoder::create("application/xml");
  144. decoder->useLenientXMLDecoding();
  145. } else if (equalIgnoringCase(mimeType, "text/html"))
  146. decoder = TextResourceDecoder::create("text/html", "UTF-8");
  147. else
  148. decoder = TextResourceDecoder::create("text/plain", "UTF-8");
  149. return decoder;
  150. }
  151. bool InspectorPageAgent::cachedResourceContent(CachedResource* cachedResource, String* result, bool* base64Encoded)
  152. {
  153. bool hasZeroSize;
  154. bool prepared = prepareCachedResourceBuffer(cachedResource, &hasZeroSize);
  155. if (!prepared)
  156. return false;
  157. *base64Encoded = !hasTextContent(cachedResource);
  158. if (*base64Encoded) {
  159. RefPtr<SharedBuffer> buffer = hasZeroSize ? SharedBuffer::create() : cachedResource->resourceBuffer()->sharedBuffer();
  160. if (!buffer)
  161. return false;
  162. *result = base64Encode(buffer->data(), buffer->size());
  163. return true;
  164. }
  165. if (hasZeroSize) {
  166. *result = "";
  167. return true;
  168. }
  169. if (cachedResource) {
  170. switch (cachedResource->type()) {
  171. case CachedResource::CSSStyleSheet:
  172. *result = static_cast<CachedCSSStyleSheet*>(cachedResource)->sheetText(false);
  173. return true;
  174. case CachedResource::Script:
  175. *result = static_cast<CachedScript*>(cachedResource)->script();
  176. return true;
  177. case CachedResource::RawResource: {
  178. ResourceBuffer* buffer = cachedResource->resourceBuffer();
  179. if (!buffer)
  180. return false;
  181. RefPtr<TextResourceDecoder> decoder = createXHRTextDecoder(cachedResource->response().mimeType(), cachedResource->response().textEncodingName());
  182. // We show content for raw resources only for certain mime types (text, html and xml). Otherwise decoder will be null.
  183. if (!decoder)
  184. return false;
  185. String content = decoder->decode(buffer->data(), buffer->size());
  186. *result = content + decoder->flush();
  187. return true;
  188. }
  189. default:
  190. ResourceBuffer* buffer = cachedResource->resourceBuffer();
  191. return decodeBuffer(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, cachedResource->encoding(), result);
  192. }
  193. }
  194. return false;
  195. }
  196. bool InspectorPageAgent::mainResourceContent(Frame* frame, bool withBase64Encode, String* result)
  197. {
  198. RefPtr<ResourceBuffer> buffer = frame->loader()->documentLoader()->mainResourceData();
  199. if (!buffer)
  200. return false;
  201. String textEncodingName = frame->document()->inputEncoding();
  202. return InspectorPageAgent::dataContent(buffer->data(), buffer->size(), textEncodingName, withBase64Encode, result);
  203. }
  204. // static
  205. bool InspectorPageAgent::sharedBufferContent(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, bool withBase64Encode, String* result)
  206. {
  207. return dataContent(buffer ? buffer->data() : 0, buffer ? buffer->size() : 0, textEncodingName, withBase64Encode, result);
  208. }
  209. bool InspectorPageAgent::dataContent(const char* data, unsigned size, const String& textEncodingName, bool withBase64Encode, String* result)
  210. {
  211. if (withBase64Encode) {
  212. *result = base64Encode(data, size);
  213. return true;
  214. }
  215. return decodeBuffer(data, size, textEncodingName, result);
  216. }
  217. PassOwnPtr<InspectorPageAgent> InspectorPageAgent::create(InstrumentingAgents* instrumentingAgents, Page* page, InspectorAgent* inspectorAgent, InspectorCompositeState* state, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
  218. {
  219. return adoptPtr(new InspectorPageAgent(instrumentingAgents, page, inspectorAgent, state, injectedScriptManager, client, overlay));
  220. }
  221. // static
  222. void InspectorPageAgent::resourceContent(ErrorString* errorString, Frame* frame, const KURL& url, String* result, bool* base64Encoded)
  223. {
  224. DocumentLoader* loader = assertDocumentLoader(errorString, frame);
  225. if (!loader)
  226. return;
  227. RefPtr<SharedBuffer> buffer;
  228. bool success = false;
  229. if (equalIgnoringFragmentIdentifier(url, loader->url())) {
  230. *base64Encoded = false;
  231. success = mainResourceContent(frame, *base64Encoded, result);
  232. }
  233. if (!success)
  234. success = cachedResourceContent(cachedResource(frame, url), result, base64Encoded);
  235. if (!success)
  236. *errorString = "No resource with given URL found";
  237. }
  238. //static
  239. String InspectorPageAgent::sourceMapURLForResource(CachedResource* cachedResource)
  240. {
  241. DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeader, (ASCIILiteral("SourceMap")));
  242. DEFINE_STATIC_LOCAL(String, sourceMapHTTPHeaderDeprecated, (ASCIILiteral("X-SourceMap")));
  243. if (!cachedResource)
  244. return String();
  245. // Scripts are handled in a separate path.
  246. if (cachedResource->type() != CachedResource::CSSStyleSheet)
  247. return String();
  248. String sourceMapHeader = cachedResource->response().httpHeaderField(sourceMapHTTPHeader);
  249. if (!sourceMapHeader.isEmpty())
  250. return sourceMapHeader;
  251. sourceMapHeader = cachedResource->response().httpHeaderField(sourceMapHTTPHeaderDeprecated);
  252. if (!sourceMapHeader.isEmpty())
  253. return sourceMapHeader;
  254. String content;
  255. bool base64Encoded;
  256. if (InspectorPageAgent::cachedResourceContent(cachedResource, &content, &base64Encoded) && !base64Encoded)
  257. return ContentSearchUtils::findStylesheetSourceMapURL(content);
  258. return String();
  259. }
  260. CachedResource* InspectorPageAgent::cachedResource(Frame* frame, const KURL& url)
  261. {
  262. CachedResource* cachedResource = frame->document()->cachedResourceLoader()->cachedResource(url);
  263. if (!cachedResource) {
  264. ResourceRequest request(url);
  265. #if ENABLE(CACHE_PARTITIONING)
  266. request.setCachePartition(frame->document()->topOrigin()->cachePartition());
  267. #endif
  268. cachedResource = memoryCache()->resourceForRequest(request);
  269. }
  270. return cachedResource;
  271. }
  272. TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::resourceTypeJson(InspectorPageAgent::ResourceType resourceType)
  273. {
  274. switch (resourceType) {
  275. case DocumentResource:
  276. return TypeBuilder::Page::ResourceType::Document;
  277. case ImageResource:
  278. return TypeBuilder::Page::ResourceType::Image;
  279. case FontResource:
  280. return TypeBuilder::Page::ResourceType::Font;
  281. case StylesheetResource:
  282. return TypeBuilder::Page::ResourceType::Stylesheet;
  283. case ScriptResource:
  284. return TypeBuilder::Page::ResourceType::Script;
  285. case XHRResource:
  286. return TypeBuilder::Page::ResourceType::XHR;
  287. case WebSocketResource:
  288. return TypeBuilder::Page::ResourceType::WebSocket;
  289. case OtherResource:
  290. return TypeBuilder::Page::ResourceType::Other;
  291. }
  292. return TypeBuilder::Page::ResourceType::Other;
  293. }
  294. InspectorPageAgent::ResourceType InspectorPageAgent::cachedResourceType(const CachedResource& cachedResource)
  295. {
  296. switch (cachedResource.type()) {
  297. case CachedResource::ImageResource:
  298. return InspectorPageAgent::ImageResource;
  299. case CachedResource::FontResource:
  300. return InspectorPageAgent::FontResource;
  301. case CachedResource::CSSStyleSheet:
  302. // Fall through.
  303. #if ENABLE(XSLT)
  304. case CachedResource::XSLStyleSheet:
  305. #endif
  306. return InspectorPageAgent::StylesheetResource;
  307. case CachedResource::Script:
  308. return InspectorPageAgent::ScriptResource;
  309. case CachedResource::RawResource:
  310. return InspectorPageAgent::XHRResource;
  311. case CachedResource::MainResource:
  312. return InspectorPageAgent::DocumentResource;
  313. default:
  314. break;
  315. }
  316. return InspectorPageAgent::OtherResource;
  317. }
  318. TypeBuilder::Page::ResourceType::Enum InspectorPageAgent::cachedResourceTypeJson(const CachedResource& cachedResource)
  319. {
  320. return resourceTypeJson(cachedResourceType(cachedResource));
  321. }
  322. InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents, Page* page, InspectorAgent* inspectorAgent, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorClient* client, InspectorOverlay* overlay)
  323. : InspectorBaseAgent<InspectorPageAgent>("Page", instrumentingAgents, inspectorState)
  324. , m_page(page)
  325. , m_inspectorAgent(inspectorAgent)
  326. , m_injectedScriptManager(injectedScriptManager)
  327. , m_client(client)
  328. , m_frontend(0)
  329. , m_overlay(overlay)
  330. , m_lastScriptIdentifier(0)
  331. , m_enabled(false)
  332. , m_isFirstLayoutAfterOnLoad(false)
  333. , m_originalScriptExecutionDisabled(false)
  334. , m_geolocationOverridden(false)
  335. , m_ignoreScriptsEnabledNotification(false)
  336. {
  337. }
  338. void InspectorPageAgent::setFrontend(InspectorFrontend* frontend)
  339. {
  340. m_frontend = frontend->page();
  341. }
  342. void InspectorPageAgent::clearFrontend()
  343. {
  344. ErrorString error;
  345. disable(&error);
  346. #if ENABLE(TOUCH_EVENTS)
  347. updateTouchEventEmulationInPage(false);
  348. #endif
  349. m_frontend = 0;
  350. }
  351. void InspectorPageAgent::restore()
  352. {
  353. if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
  354. ErrorString error;
  355. enable(&error);
  356. bool scriptExecutionDisabled = m_state->getBoolean(PageAgentState::pageAgentScriptExecutionDisabled);
  357. setScriptExecutionDisabled(0, scriptExecutionDisabled);
  358. bool showPaintRects = m_state->getBoolean(PageAgentState::pageAgentShowPaintRects);
  359. setShowPaintRects(0, showPaintRects);
  360. bool showDebugBorders = m_state->getBoolean(PageAgentState::pageAgentShowDebugBorders);
  361. setShowDebugBorders(0, showDebugBorders);
  362. bool showFPSCounter = m_state->getBoolean(PageAgentState::pageAgentShowFPSCounter);
  363. setShowFPSCounter(0, showFPSCounter);
  364. String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
  365. setEmulatedMedia(0, emulatedMedia);
  366. bool continuousPaintingEnabled = m_state->getBoolean(PageAgentState::pageAgentContinuousPaintingEnabled);
  367. setContinuousPaintingEnabled(0, continuousPaintingEnabled);
  368. int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
  369. int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
  370. double currentFontScaleFactor = m_state->getDouble(PageAgentState::pageAgentFontScaleFactorOverride);
  371. bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
  372. updateViewMetrics(currentWidth, currentHeight, currentFontScaleFactor, currentFitWindow);
  373. #if ENABLE(TOUCH_EVENTS)
  374. updateTouchEventEmulationInPage(m_state->getBoolean(PageAgentState::touchEventEmulationEnabled));
  375. #endif
  376. }
  377. }
  378. void InspectorPageAgent::webViewResized(const IntSize& size)
  379. {
  380. int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
  381. m_overlay->resize(currentWidth ? size : IntSize());
  382. }
  383. void InspectorPageAgent::enable(ErrorString*)
  384. {
  385. m_enabled = true;
  386. m_state->setBoolean(PageAgentState::pageAgentEnabled, true);
  387. m_instrumentingAgents->setInspectorPageAgent(this);
  388. if (Frame* frame = mainFrame()) {
  389. if (Settings* settings = frame->settings())
  390. m_originalScriptExecutionDisabled = !settings->isScriptEnabled();
  391. }
  392. }
  393. void InspectorPageAgent::disable(ErrorString*)
  394. {
  395. m_enabled = false;
  396. m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
  397. m_state->remove(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
  398. m_instrumentingAgents->setInspectorPageAgent(0);
  399. setScriptExecutionDisabled(0, m_originalScriptExecutionDisabled);
  400. setShowPaintRects(0, false);
  401. setShowDebugBorders(0, false);
  402. setShowFPSCounter(0, false);
  403. setEmulatedMedia(0, "");
  404. setContinuousPaintingEnabled(0, false);
  405. if (!deviceMetricsChanged(0, 0, 1, false))
  406. return;
  407. // When disabling the agent, reset the override values if necessary.
  408. updateViewMetrics(0, 0, 1, false);
  409. m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
  410. m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
  411. m_state->setDouble(PageAgentState::pageAgentFontScaleFactorOverride, 1);
  412. m_state->setBoolean(PageAgentState::pageAgentFitWindow, false);
  413. }
  414. void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
  415. {
  416. RefPtr<InspectorObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
  417. if (!scripts) {
  418. scripts = InspectorObject::create();
  419. m_state->setObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad, scripts);
  420. }
  421. // Assure we don't override existing ids -- m_lastScriptIdentifier could get out of sync WRT actual
  422. // scripts once we restored the scripts from the cookie during navigation.
  423. do {
  424. *identifier = String::number(++m_lastScriptIdentifier);
  425. } while (scripts->find(*identifier) != scripts->end());
  426. scripts->setString(*identifier, source);
  427. }
  428. void InspectorPageAgent::removeScriptToEvaluateOnLoad(ErrorString* error, const String& identifier)
  429. {
  430. RefPtr<InspectorObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
  431. if (!scripts || scripts->find(identifier) == scripts->end()) {
  432. *error = "Script not found";
  433. return;
  434. }
  435. scripts->remove(identifier);
  436. }
  437. void InspectorPageAgent::reload(ErrorString*, const bool* const optionalIgnoreCache, const String* optionalScriptToEvaluateOnLoad, const String* optionalScriptPreprocessor)
  438. {
  439. m_pendingScriptToEvaluateOnLoadOnce = optionalScriptToEvaluateOnLoad ? *optionalScriptToEvaluateOnLoad : "";
  440. m_pendingScriptPreprocessor = optionalScriptPreprocessor ? *optionalScriptPreprocessor : "";
  441. m_page->mainFrame()->loader()->reload(optionalIgnoreCache ? *optionalIgnoreCache : false);
  442. }
  443. void InspectorPageAgent::navigate(ErrorString*, const String& url)
  444. {
  445. UserGestureIndicator indicator(DefinitelyProcessingNewUserGesture);
  446. Frame* frame = m_page->mainFrame();
  447. frame->loader()->changeLocation(frame->document()->securityOrigin(), frame->document()->completeURL(url), "", false, false);
  448. }
  449. static PassRefPtr<TypeBuilder::Page::Cookie> buildObjectForCookie(const Cookie& cookie)
  450. {
  451. return TypeBuilder::Page::Cookie::create()
  452. .setName(cookie.name)
  453. .setValue(cookie.value)
  454. .setDomain(cookie.domain)
  455. .setPath(cookie.path)
  456. .setExpires(cookie.expires)
  457. .setSize((cookie.name.length() + cookie.value.length()))
  458. .setHttpOnly(cookie.httpOnly)
  459. .setSecure(cookie.secure)
  460. .setSession(cookie.session)
  461. .release();
  462. }
  463. static PassRefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > buildArrayForCookies(ListHashSet<Cookie>& cookiesList)
  464. {
  465. RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> > cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
  466. ListHashSet<Cookie>::iterator end = cookiesList.end();
  467. ListHashSet<Cookie>::iterator it = cookiesList.begin();
  468. for (int i = 0; it != end; ++it, i++)
  469. cookies->addItem(buildObjectForCookie(*it));
  470. return cookies;
  471. }
  472. static Vector<CachedResource*> cachedResourcesForFrame(Frame* frame)
  473. {
  474. Vector<CachedResource*> result;
  475. const CachedResourceLoader::DocumentResourceMap& allResources = frame->document()->cachedResourceLoader()->allCachedResources();
  476. CachedResourceLoader::DocumentResourceMap::const_iterator end = allResources.end();
  477. for (CachedResourceLoader::DocumentResourceMap::const_iterator it = allResources.begin(); it != end; ++it) {
  478. CachedResource* cachedResource = it->value.get();
  479. switch (cachedResource->type()) {
  480. case CachedResource::ImageResource:
  481. // Skip images that were not auto loaded (images disabled in the user agent).
  482. case CachedResource::FontResource:
  483. // Skip fonts that were referenced in CSS but never used/downloaded.
  484. if (cachedResource->stillNeedsLoad())
  485. continue;
  486. break;
  487. default:
  488. // All other CachedResource types download immediately.
  489. break;
  490. }
  491. result.append(cachedResource);
  492. }
  493. return result;
  494. }
  495. static Vector<KURL> allResourcesURLsForFrame(Frame* frame)
  496. {
  497. Vector<KURL> result;
  498. result.append(frame->loader()->documentLoader()->url());
  499. Vector<CachedResource*> allResources = cachedResourcesForFrame(frame);
  500. for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it)
  501. result.append((*it)->url());
  502. return result;
  503. }
  504. void InspectorPageAgent::getCookies(ErrorString*, RefPtr<TypeBuilder::Array<TypeBuilder::Page::Cookie> >& cookies, WTF::String* cookiesString)
  505. {
  506. // If we can get raw cookies.
  507. ListHashSet<Cookie> rawCookiesList;
  508. // If we can't get raw cookies - fall back to String representation
  509. StringBuilder stringCookiesList;
  510. // Return value to getRawCookies should be the same for every call because
  511. // the return value is platform/network backend specific, and the call will
  512. // always return the same true/false value.
  513. bool rawCookiesImplemented = false;
  514. for (Frame* frame = mainFrame(); frame; frame = frame->tree()->traverseNext(mainFrame())) {
  515. Document* document = frame->document();
  516. Vector<KURL> allURLs = allResourcesURLsForFrame(frame);
  517. for (Vector<KURL>::const_iterator it = allURLs.begin(); it != allURLs.end(); ++it) {
  518. Vector<Cookie> docCookiesList;
  519. rawCookiesImplemented = getRawCookies(document, KURL(ParsedURLString, *it), docCookiesList);
  520. if (!rawCookiesImplemented) {
  521. // FIXME: We need duplication checking for the String representation of cookies.
  522. //
  523. // Exceptions are thrown by cookie() in sandboxed frames. That won't happen here
  524. // because "document" is the document of the main frame of the page.
  525. stringCookiesList.append(document->cookie(ASSERT_NO_EXCEPTION));
  526. } else {
  527. int cookiesSize = docCookiesList.size();
  528. for (int i = 0; i < cookiesSize; i++) {
  529. if (!rawCookiesList.contains(docCookiesList[i]))
  530. rawCookiesList.add(docCookiesList[i]);
  531. }
  532. }
  533. }
  534. }
  535. // FIXME: Do not return empty string/empty array. Make returns optional instead. https://bugs.webkit.org/show_bug.cgi?id=80855
  536. if (rawCookiesImplemented) {
  537. cookies = buildArrayForCookies(rawCookiesList);
  538. *cookiesString = "";
  539. } else {
  540. cookies = TypeBuilder::Array<TypeBuilder::Page::Cookie>::create();
  541. *cookiesString = stringCookiesList.toString();
  542. }
  543. }
  544. void InspectorPageAgent::deleteCookie(ErrorString*, const String& cookieName, const String& url)
  545. {
  546. KURL parsedURL(ParsedURLString, url);
  547. for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame()))
  548. WebCore::deleteCookie(frame->document(), parsedURL, cookieName);
  549. }
  550. void InspectorPageAgent::getResourceTree(ErrorString*, RefPtr<TypeBuilder::Page::FrameResourceTree>& object)
  551. {
  552. object = buildObjectForFrameTree(m_page->mainFrame());
  553. }
  554. void InspectorPageAgent::getResourceContent(ErrorString* errorString, const String& frameId, const String& url, String* content, bool* base64Encoded)
  555. {
  556. Frame* frame = assertFrame(errorString, frameId);
  557. if (!frame)
  558. return;
  559. resourceContent(errorString, frame, KURL(ParsedURLString, url), content, base64Encoded);
  560. }
  561. static bool textContentForCachedResource(CachedResource* cachedResource, String* result)
  562. {
  563. if (hasTextContent(cachedResource)) {
  564. String content;
  565. bool base64Encoded;
  566. if (InspectorPageAgent::cachedResourceContent(cachedResource, result, &base64Encoded)) {
  567. ASSERT(!base64Encoded);
  568. return true;
  569. }
  570. }
  571. return false;
  572. }
  573. void InspectorPageAgent::searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchMatch> >& results)
  574. {
  575. results = TypeBuilder::Array<TypeBuilder::Page::SearchMatch>::create();
  576. bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
  577. bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
  578. Frame* frame = frameForId(frameId);
  579. KURL kurl(ParsedURLString, url);
  580. FrameLoader* frameLoader = frame ? frame->loader() : 0;
  581. DocumentLoader* loader = frameLoader ? frameLoader->documentLoader() : 0;
  582. if (!loader)
  583. return;
  584. String content;
  585. bool success = false;
  586. if (equalIgnoringFragmentIdentifier(kurl, loader->url()))
  587. success = mainResourceContent(frame, false, &content);
  588. if (!success) {
  589. CachedResource* resource = cachedResource(frame, kurl);
  590. if (resource)
  591. success = textContentForCachedResource(resource, &content);
  592. }
  593. if (!success)
  594. return;
  595. results = ContentSearchUtils::searchInTextByLines(content, query, caseSensitive, isRegex);
  596. }
  597. static PassRefPtr<TypeBuilder::Page::SearchResult> buildObjectForSearchResult(const String& frameId, const String& url, int matchesCount)
  598. {
  599. return TypeBuilder::Page::SearchResult::create()
  600. .setUrl(url)
  601. .setFrameId(frameId)
  602. .setMatchesCount(matchesCount)
  603. .release();
  604. }
  605. void InspectorPageAgent::searchInResources(ErrorString*, const String& text, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchResult> >& results)
  606. {
  607. RefPtr<TypeBuilder::Array<TypeBuilder::Page::SearchResult> > searchResults = TypeBuilder::Array<TypeBuilder::Page::SearchResult>::create();
  608. bool isRegex = optionalIsRegex ? *optionalIsRegex : false;
  609. bool caseSensitive = optionalCaseSensitive ? *optionalCaseSensitive : false;
  610. RegularExpression regex = ContentSearchUtils::createSearchRegex(text, caseSensitive, isRegex);
  611. for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext(m_page->mainFrame())) {
  612. String content;
  613. Vector<CachedResource*> allResources = cachedResourcesForFrame(frame);
  614. for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
  615. CachedResource* cachedResource = *it;
  616. if (textContentForCachedResource(cachedResource, &content)) {
  617. int matchesCount = ContentSearchUtils::countRegularExpressionMatches(regex, content);
  618. if (matchesCount)
  619. searchResults->addItem(buildObjectForSearchResult(frameId(frame), cachedResource->url(), matchesCount));
  620. }
  621. }
  622. if (mainResourceContent(frame, false, &content)) {
  623. int matchesCount = ContentSearchUtils::countRegularExpressionMatches(regex, content);
  624. if (matchesCount)
  625. searchResults->addItem(buildObjectForSearchResult(frameId(frame), frame->document()->url(), matchesCount));
  626. }
  627. }
  628. results = searchResults;
  629. }
  630. void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const String& frameId, const String& html)
  631. {
  632. Frame* frame = assertFrame(errorString, frameId);
  633. if (!frame)
  634. return;
  635. Document* document = frame->document();
  636. if (!document) {
  637. *errorString = "No Document instance to set HTML for";
  638. return;
  639. }
  640. DOMPatchSupport::patchDocument(document, html);
  641. }
  642. void InspectorPageAgent::canOverrideDeviceMetrics(ErrorString*, bool* result)
  643. {
  644. *result = m_client->canOverrideDeviceMetrics();
  645. }
  646. void InspectorPageAgent::setDeviceMetricsOverride(ErrorString* errorString, int width, int height, double fontScaleFactor, bool fitWindow)
  647. {
  648. const static long maxDimension = 10000000;
  649. if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
  650. *errorString = makeString("Width and height values must be positive, not greater than ", String::number(maxDimension));
  651. return;
  652. }
  653. if (!width ^ !height) {
  654. *errorString = "Both width and height must be either zero or non-zero at once";
  655. return;
  656. }
  657. if (fontScaleFactor <= 0) {
  658. *errorString = "fontScaleFactor must be positive";
  659. return;
  660. }
  661. if (!deviceMetricsChanged(width, height, fontScaleFactor, fitWindow))
  662. return;
  663. m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
  664. m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
  665. m_state->setDouble(PageAgentState::pageAgentFontScaleFactorOverride, fontScaleFactor);
  666. m_state->setBoolean(PageAgentState::pageAgentFitWindow, fitWindow);
  667. updateViewMetrics(width, height, fontScaleFactor, fitWindow);
  668. }
  669. bool InspectorPageAgent::deviceMetricsChanged(int width, int height, double fontScaleFactor, bool fitWindow)
  670. {
  671. // These two always fit an int.
  672. int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
  673. int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
  674. double currentFontScaleFactor = m_state->getDouble(PageAgentState::pageAgentFontScaleFactorOverride);
  675. bool currentFitWindow = m_state->getBoolean(PageAgentState::pageAgentFitWindow);
  676. return width != currentWidth || height != currentHeight || fontScaleFactor != currentFontScaleFactor || fitWindow != currentFitWindow;
  677. }
  678. void InspectorPageAgent::setShowPaintRects(ErrorString*, bool show)
  679. {
  680. m_state->setBoolean(PageAgentState::pageAgentShowPaintRects, show);
  681. m_client->setShowPaintRects(show);
  682. if (!show && mainFrame() && mainFrame()->view())
  683. mainFrame()->view()->invalidate();
  684. }
  685. void InspectorPageAgent::canShowDebugBorders(ErrorString*, bool* outParam)
  686. {
  687. *outParam = m_client->canShowDebugBorders();
  688. }
  689. void InspectorPageAgent::setShowDebugBorders(ErrorString*, bool show)
  690. {
  691. m_state->setBoolean(PageAgentState::pageAgentShowDebugBorders, show);
  692. m_client->setShowDebugBorders(show);
  693. if (mainFrame() && mainFrame()->view())
  694. mainFrame()->view()->invalidate();
  695. }
  696. void InspectorPageAgent::canShowFPSCounter(ErrorString*, bool* outParam)
  697. {
  698. *outParam = m_client->canShowFPSCounter();
  699. }
  700. void InspectorPageAgent::setShowFPSCounter(ErrorString*, bool show)
  701. {
  702. m_state->setBoolean(PageAgentState::pageAgentShowFPSCounter, show);
  703. m_client->setShowFPSCounter(show);
  704. if (mainFrame() && mainFrame()->view())
  705. mainFrame()->view()->invalidate();
  706. }
  707. void InspectorPageAgent::canContinuouslyPaint(ErrorString*, bool* outParam)
  708. {
  709. *outParam = m_client->canContinuouslyPaint();
  710. }
  711. void InspectorPageAgent::setContinuousPaintingEnabled(ErrorString*, bool enabled)
  712. {
  713. m_state->setBoolean(PageAgentState::pageAgentContinuousPaintingEnabled, enabled);
  714. m_client->setContinuousPaintingEnabled(enabled);
  715. if (!enabled && mainFrame() && mainFrame()->view())
  716. mainFrame()->view()->invalidate();
  717. }
  718. void InspectorPageAgent::getScriptExecutionStatus(ErrorString*, PageCommandHandler::Result::Enum* status)
  719. {
  720. bool disabledByScriptController = false;
  721. bool disabledInSettings = false;
  722. Frame* frame = mainFrame();
  723. if (frame) {
  724. disabledByScriptController = !frame->script()->canExecuteScripts(NotAboutToExecuteScript);
  725. if (frame->settings())
  726. disabledInSettings = !frame->settings()->isScriptEnabled();
  727. }
  728. if (!disabledByScriptController) {
  729. *status = PageCommandHandler::Result::Allowed;
  730. return;
  731. }
  732. if (disabledInSettings)
  733. *status = PageCommandHandler::Result::Disabled;
  734. else
  735. *status = PageCommandHandler::Result::Forbidden;
  736. }
  737. void InspectorPageAgent::setScriptExecutionDisabled(ErrorString*, bool value)
  738. {
  739. m_state->setBoolean(PageAgentState::pageAgentScriptExecutionDisabled, value);
  740. if (!mainFrame())
  741. return;
  742. Settings* settings = mainFrame()->settings();
  743. if (settings) {
  744. m_ignoreScriptsEnabledNotification = true;
  745. settings->setScriptEnabled(!value);
  746. m_ignoreScriptsEnabledNotification = false;
  747. }
  748. }
  749. void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
  750. {
  751. if (world != mainThreadNormalWorld())
  752. return;
  753. if (frame == m_page->mainFrame())
  754. m_injectedScriptManager->discardInjectedScripts();
  755. if (!m_frontend)
  756. return;
  757. RefPtr<InspectorObject> scripts = m_state->getObject(PageAgentState::pageAgentScriptsToEvaluateOnLoad);
  758. if (scripts) {
  759. InspectorObject::const_iterator end = scripts->end();
  760. for (InspectorObject::const_iterator it = scripts->begin(); it != end; ++it) {
  761. String scriptText;
  762. if (it->value->asString(&scriptText))
  763. frame->script()->executeScript(scriptText);
  764. }
  765. }
  766. if (!m_scriptToEvaluateOnLoadOnce.isEmpty())
  767. frame->script()->executeScript(m_scriptToEvaluateOnLoadOnce);
  768. }
  769. void InspectorPageAgent::domContentEventFired()
  770. {
  771. m_isFirstLayoutAfterOnLoad = true;
  772. m_frontend->domContentEventFired(currentTime());
  773. }
  774. void InspectorPageAgent::loadEventFired()
  775. {
  776. m_frontend->loadEventFired(currentTime());
  777. }
  778. void InspectorPageAgent::frameNavigated(DocumentLoader* loader)
  779. {
  780. if (loader->frame() == m_page->mainFrame()) {
  781. m_scriptToEvaluateOnLoadOnce = m_pendingScriptToEvaluateOnLoadOnce;
  782. m_scriptPreprocessor = m_pendingScriptPreprocessor;
  783. m_pendingScriptToEvaluateOnLoadOnce = String();
  784. m_pendingScriptPreprocessor = String();
  785. }
  786. m_frontend->frameNavigated(buildObjectForFrame(loader->frame()));
  787. }
  788. void InspectorPageAgent::frameDetached(Frame* frame)
  789. {
  790. HashMap<Frame*, String>::iterator iterator = m_frameToIdentifier.find(frame);
  791. if (iterator != m_frameToIdentifier.end()) {
  792. m_frontend->frameDetached(iterator->value);
  793. m_identifierToFrame.remove(iterator->value);
  794. m_frameToIdentifier.remove(iterator);
  795. }
  796. }
  797. Frame* InspectorPageAgent::mainFrame()
  798. {
  799. return m_page->mainFrame();
  800. }
  801. Frame* InspectorPageAgent::frameForId(const String& frameId)
  802. {
  803. return frameId.isEmpty() ? 0 : m_identifierToFrame.get(frameId);
  804. }
  805. String InspectorPageAgent::frameId(Frame* frame)
  806. {
  807. if (!frame)
  808. return "";
  809. String identifier = m_frameToIdentifier.get(frame);
  810. if (identifier.isNull()) {
  811. identifier = IdentifiersFactory::createIdentifier();
  812. m_frameToIdentifier.set(frame, identifier);
  813. m_identifierToFrame.set(identifier, frame);
  814. }
  815. return identifier;
  816. }
  817. bool InspectorPageAgent::hasIdForFrame(Frame* frame) const
  818. {
  819. return frame && m_frameToIdentifier.contains(frame);
  820. }
  821. String InspectorPageAgent::loaderId(DocumentLoader* loader)
  822. {
  823. if (!loader)
  824. return "";
  825. String identifier = m_loaderToIdentifier.get(loader);
  826. if (identifier.isNull()) {
  827. identifier = IdentifiersFactory::createIdentifier();
  828. m_loaderToIdentifier.set(loader, identifier);
  829. }
  830. return identifier;
  831. }
  832. Frame* InspectorPageAgent::findFrameWithSecurityOrigin(const String& originRawString)
  833. {
  834. for (Frame* frame = m_page->mainFrame(); frame; frame = frame->tree()->traverseNext()) {
  835. RefPtr<SecurityOrigin> documentOrigin = frame->document()->securityOrigin();
  836. if (documentOrigin->toRawString() == originRawString)
  837. return frame;
  838. }
  839. return 0;
  840. }
  841. Frame* InspectorPageAgent::assertFrame(ErrorString* errorString, const String& frameId)
  842. {
  843. Frame* frame = frameForId(frameId);
  844. if (!frame)
  845. *errorString = "No frame for given id found";
  846. return frame;
  847. }
  848. // static
  849. DocumentLoader* InspectorPageAgent::assertDocumentLoader(ErrorString* errorString, Frame* frame)
  850. {
  851. FrameLoader* frameLoader = frame->loader();
  852. DocumentLoader* documentLoader = frameLoader ? frameLoader->documentLoader() : 0;
  853. if (!documentLoader)
  854. *errorString = "No documentLoader for given frame found";
  855. return documentLoader;
  856. }
  857. void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
  858. {
  859. HashMap<DocumentLoader*, String>::iterator iterator = m_loaderToIdentifier.find(loader);
  860. if (iterator != m_loaderToIdentifier.end())
  861. m_loaderToIdentifier.remove(iterator);
  862. }
  863. void InspectorPageAgent::frameStartedLoading(Frame* frame)
  864. {
  865. m_frontend->frameStartedLoading(frameId(frame));
  866. }
  867. void InspectorPageAgent::frameStoppedLoading(Frame* frame)
  868. {
  869. m_frontend->frameStoppedLoading(frameId(frame));
  870. }
  871. void InspectorPageAgent::frameScheduledNavigation(Frame* frame, double delay)
  872. {
  873. m_frontend->frameScheduledNavigation(frameId(frame), delay);
  874. }
  875. void InspectorPageAgent::frameClearedScheduledNavigation(Frame* frame)
  876. {
  877. m_frontend->frameClearedScheduledNavigation(frameId(frame));
  878. }
  879. void InspectorPageAgent::willRunJavaScriptDialog(const String& message)
  880. {
  881. m_frontend->javascriptDialogOpening(message);
  882. }
  883. void InspectorPageAgent::didRunJavaScriptDialog()
  884. {
  885. m_frontend->javascriptDialogClosed();
  886. }
  887. void InspectorPageAgent::applyScreenWidthOverride(long* width)
  888. {
  889. long widthOverride = m_state->getLong(PageAgentState::pageAgentScreenWidthOverride);
  890. if (widthOverride)
  891. *width = widthOverride;
  892. }
  893. void InspectorPageAgent::applyScreenHeightOverride(long* height)
  894. {
  895. long heightOverride = m_state->getLong(PageAgentState::pageAgentScreenHeightOverride);
  896. if (heightOverride)
  897. *height = heightOverride;
  898. }
  899. void InspectorPageAgent::didPaint(GraphicsContext* context, const LayoutRect& rect)
  900. {
  901. if (!m_enabled || m_client->overridesShowPaintRects() || !m_state->getBoolean(PageAgentState::pageAgentShowPaintRects))
  902. return;
  903. static int colorSelector = 0;
  904. const Color colors[] = {
  905. Color(0xFF, 0, 0, 0x3F),
  906. Color(0xFF, 0, 0xFF, 0x3F),
  907. Color(0, 0, 0xFF, 0x3F),
  908. };
  909. LayoutRect inflatedRect(rect);
  910. inflatedRect.inflate(-1);
  911. m_overlay->drawOutline(context, inflatedRect, colors[colorSelector++ % WTF_ARRAY_LENGTH(colors)]);
  912. }
  913. void InspectorPageAgent::didLayout()
  914. {
  915. bool isFirstLayout = m_isFirstLayoutAfterOnLoad;
  916. if (isFirstLayout)
  917. m_isFirstLayoutAfterOnLoad = false;
  918. if (!m_enabled)
  919. return;
  920. if (isFirstLayout) {
  921. int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
  922. int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
  923. if (currentWidth && currentHeight)
  924. m_client->autoZoomPageToFitWidth();
  925. }
  926. m_overlay->update();
  927. }
  928. void InspectorPageAgent::didScroll()
  929. {
  930. if (m_enabled)
  931. m_overlay->update();
  932. }
  933. void InspectorPageAgent::didRecalculateStyle()
  934. {
  935. if (m_enabled)
  936. m_overlay->update();
  937. }
  938. void InspectorPageAgent::scriptsEnabled(bool isEnabled)
  939. {
  940. if (m_ignoreScriptsEnabledNotification)
  941. return;
  942. m_frontend->scriptsEnabled(isEnabled);
  943. }
  944. PassRefPtr<TypeBuilder::Page::Frame> InspectorPageAgent::buildObjectForFrame(Frame* frame)
  945. {
  946. RefPtr<TypeBuilder::Page::Frame> frameObject = TypeBuilder::Page::Frame::create()
  947. .setId(frameId(frame))
  948. .setLoaderId(loaderId(frame->loader()->documentLoader()))
  949. .setUrl(frame->document()->url().string())
  950. .setMimeType(frame->loader()->documentLoader()->responseMIMEType())
  951. .setSecurityOrigin(frame->document()->securityOrigin()->toRawString());
  952. if (frame->tree()->parent())
  953. frameObject->setParentId(frameId(frame->tree()->parent()));
  954. if (frame->ownerElement()) {
  955. String name = frame->ownerElement()->getNameAttribute();
  956. if (name.isEmpty())
  957. name = frame->ownerElement()->getAttribute(HTMLNames::idAttr);
  958. frameObject->setName(name);
  959. }
  960. return frameObject;
  961. }
  962. PassRefPtr<TypeBuilder::Page::FrameResourceTree> InspectorPageAgent::buildObjectForFrameTree(Frame* frame)
  963. {
  964. RefPtr<TypeBuilder::Page::Frame> frameObject = buildObjectForFrame(frame);
  965. RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources> > subresources = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree::Resources>::create();
  966. RefPtr<TypeBuilder::Page::FrameResourceTree> result = TypeBuilder::Page::FrameResourceTree::create()
  967. .setFrame(frameObject)
  968. .setResources(subresources);
  969. Vector<CachedResource*> allResources = cachedResourcesForFrame(frame);
  970. for (Vector<CachedResource*>::const_iterator it = allResources.begin(); it != allResources.end(); ++it) {
  971. CachedResource* cachedResource = *it;
  972. RefPtr<TypeBuilder::Page::FrameResourceTree::Resources> resourceObject = TypeBuilder::Page::FrameResourceTree::Resources::create()
  973. .setUrl(cachedResource->url())
  974. .setType(cachedResourceTypeJson(*cachedResource))
  975. .setMimeType(cachedResource->response().mimeType());
  976. if (cachedResource->wasCanceled())
  977. resourceObject->setCanceled(true);
  978. else if (cachedResource->status() == CachedResource::LoadError)
  979. resourceObject->setFailed(true);
  980. String sourceMappingURL = InspectorPageAgent::sourceMapURLForResource(cachedResource);
  981. if (!sourceMappingURL.isEmpty())
  982. resourceObject->setSourceMapURL(sourceMappingURL);
  983. subresources->addItem(resourceObject);
  984. }
  985. RefPtr<TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree> > childrenArray;
  986. for (Frame* child = frame->tree()->firstChild(); child; child = child->tree()->nextSibling()) {
  987. if (!childrenArray) {
  988. childrenArray = TypeBuilder::Array<TypeBuilder::Page::FrameResourceTree>::create();
  989. result->setChildFrames(childrenArray);
  990. }
  991. childrenArray->addItem(buildObjectForFrameTree(child));
  992. }
  993. return result;
  994. }
  995. void InspectorPageAgent::updateViewMetrics(int width, int height, double fontScaleFactor, bool fitWindow)
  996. {
  997. m_client->overrideDeviceMetrics(width, height, static_cast<float>(fontScaleFactor), fitWindow);
  998. Document* document = mainFrame()->document();
  999. if (document)
  1000. document->styleResolverChanged(RecalcStyleImmediately);
  1001. InspectorInstrumentation::mediaQueryResultChanged(document);
  1002. }
  1003. #if ENABLE(TOUCH_EVENTS)
  1004. void InspectorPageAgent::updateTouchEventEmulationInPage(bool enabled)
  1005. {
  1006. m_state->setBoolean(PageAgentState::touchEventEmulationEnabled, enabled);
  1007. if (mainFrame() && mainFrame()->settings())
  1008. mainFrame()->settings()->setTouchEventEmulationEnabled(enabled);
  1009. }
  1010. #endif
  1011. void InspectorPageAgent::setGeolocationOverride(ErrorString* error, const double* latitude, const double* longitude, const double* accuracy)
  1012. {
  1013. #if ENABLE (GEOLOCATION)
  1014. GeolocationController* controller = GeolocationController::from(m_page);
  1015. GeolocationPosition* position = 0;
  1016. if (!controller) {
  1017. *error = "Internal error: unable to override geolocation";
  1018. return;
  1019. }
  1020. position = controller->lastPosition();
  1021. if (!m_geolocationOverridden && position)
  1022. m_platformGeolocationPosition = position;
  1023. m_geolocationOverridden = true;
  1024. if (latitude && longitude && accuracy)
  1025. m_geolocationPosition = GeolocationPosition::create(currentTimeMS(), *latitude, *longitude, *accuracy);
  1026. else
  1027. m_geolocationPosition.clear();
  1028. controller->positionChanged(0); // Kick location update.
  1029. #else
  1030. *error = "Geolocation is not available";
  1031. UNUSED_PARAM(latitude);
  1032. UNUSED_PARAM(longitude);
  1033. UNUSED_PARAM(accuracy);
  1034. #endif
  1035. }
  1036. void InspectorPageAgent::clearGeolocationOverride(ErrorString* error)
  1037. {
  1038. if (!m_geolocationOverridden)
  1039. return;
  1040. #if ENABLE(GEOLOCATION)
  1041. UNUSED_PARAM(error);
  1042. m_geolocationOverridden = false;
  1043. m_geolocationPosition.clear();
  1044. GeolocationController* controller = GeolocationController::from(m_page);
  1045. if (controller && m_platformGeolocationPosition.get())
  1046. controller->positionChanged(m_platformGeolocationPosition.get());
  1047. #else
  1048. *error = "Geolocation is not available";
  1049. #endif
  1050. }
  1051. void InspectorPageAgent::canOverrideGeolocation(ErrorString*, bool* out_param)
  1052. {
  1053. #if ENABLE(GEOLOCATION)
  1054. *out_param = true;
  1055. #else
  1056. *out_param = false;
  1057. #endif
  1058. }
  1059. GeolocationPosition* InspectorPageAgent::overrideGeolocationPosition(GeolocationPosition* position)
  1060. {
  1061. if (m_geolocationOverridden) {
  1062. if (position)
  1063. m_platformGeolocationPosition = position;
  1064. return m_geolocationPosition.get();
  1065. }
  1066. return position;
  1067. }
  1068. void InspectorPageAgent::setDeviceOrientationOverride(ErrorString* error, double alpha, double beta, double gamma)
  1069. {
  1070. DeviceOrientationController* controller = DeviceOrientationController::from(m_page);
  1071. if (!controller) {
  1072. *error = "Internal error: unable to override device orientation";
  1073. return;
  1074. }
  1075. ErrorString clearError;
  1076. clearDeviceOrientationOverride(&clearError);
  1077. m_deviceOrientation = DeviceOrientationData::create(true, alpha, true, beta, true, gamma);
  1078. controller->didChangeDeviceOrientation(m_deviceOrientation.get());
  1079. }
  1080. void InspectorPageAgent::clearDeviceOrientationOverride(ErrorString*)
  1081. {
  1082. m_deviceOrientation.clear();
  1083. }
  1084. void InspectorPageAgent::canOverrideDeviceOrientation(ErrorString*, bool* outParam)
  1085. {
  1086. #if ENABLE(DEVICE_ORIENTATION)
  1087. *outParam = true;
  1088. #else
  1089. *outParam = false;
  1090. #endif
  1091. }
  1092. DeviceOrientationData* InspectorPageAgent::overrideDeviceOrientation(DeviceOrientationData* deviceOrientation)
  1093. {
  1094. if (m_deviceOrientation)
  1095. deviceOrientation = m_deviceOrientation.get();
  1096. return deviceOrientation;
  1097. }
  1098. void InspectorPageAgent::setTouchEmulationEnabled(ErrorString* error, bool enabled)
  1099. {
  1100. #if ENABLE(TOUCH_EVENTS)
  1101. if (m_state->getBoolean(PageAgentState::touchEventEmulationEnabled) == enabled)
  1102. return;
  1103. UNUSED_PARAM(error);
  1104. updateTouchEventEmulationInPage(enabled);
  1105. #else
  1106. *error = "Touch events emulation not supported";
  1107. UNUSED_PARAM(enabled);
  1108. #endif
  1109. }
  1110. void InspectorPageAgent::setEmulatedMedia(ErrorString*, const String& media)
  1111. {
  1112. String currentMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
  1113. if (media == currentMedia)
  1114. return;
  1115. m_state->setString(PageAgentState::pageAgentEmulatedMedia, media);
  1116. Document* document = 0;
  1117. if (m_page->mainFrame())
  1118. document = m_page->mainFrame()->document();
  1119. if (document) {
  1120. document->styleResolverChanged(RecalcStyleImmediately);
  1121. document->updateLayout();
  1122. }
  1123. }
  1124. void InspectorPageAgent::applyEmulatedMedia(String* media)
  1125. {
  1126. String emulatedMedia = m_state->getString(PageAgentState::pageAgentEmulatedMedia);
  1127. if (!emulatedMedia.isEmpty())
  1128. *media = emulatedMedia;
  1129. }
  1130. void InspectorPageAgent::getCompositingBordersVisible(ErrorString* error, bool* outParam)
  1131. {
  1132. Settings* settings = m_page->settings();
  1133. if (!settings) {
  1134. *error = "Internal error: unable to read settings";
  1135. return;
  1136. }
  1137. *outParam = settings->showDebugBorders() || settings->showRepaintCounter();
  1138. }
  1139. void InspectorPageAgent::setCompositingBordersVisible(ErrorString*, bool visible)
  1140. {
  1141. Settings* settings = m_page->settings();
  1142. if (!settings)
  1143. return;
  1144. settings->setShowDebugBorders(visible);
  1145. settings->setShowRepaintCounter(visible);
  1146. }
  1147. void InspectorPageAgent::captureScreenshot(ErrorString* errorString, String* data)
  1148. {
  1149. if (!m_client->captureScreenshot(data))
  1150. *errorString = "Could not capture screenshot";
  1151. }
  1152. void InspectorPageAgent::handleJavaScriptDialog(ErrorString* errorString, bool accept, const String* promptText)
  1153. {
  1154. if (!m_client->handleJavaScriptDialog(accept, promptText))
  1155. *errorString = "Could not handle JavaScript dialog";
  1156. }
  1157. } // namespace WebCore
  1158. #endif // ENABLE(INSPECTOR)