InspectorDOMAgent.cpp 61 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839
  1. /*
  2. * Copyright (C) 2009 Apple Inc. All rights reserved.
  3. * Copyright (C) 2011 Google Inc. All rights reserved.
  4. * Copyright (C) 2009 Joseph Pecoraro
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. *
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
  16. * its contributors may be used to endorse or promote products derived
  17. * from this software without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
  20. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  21. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  22. * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
  23. * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  24. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  25. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
  26. * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  27. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  28. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  29. */
  30. #include "config.h"
  31. #if ENABLE(INSPECTOR)
  32. #include "InspectorDOMAgent.h"
  33. #include "Attr.h"
  34. #include "CSSComputedStyleDeclaration.h"
  35. #include "CSSPropertyNames.h"
  36. #include "CSSPropertySourceData.h"
  37. #include "CSSRule.h"
  38. #include "CSSRuleList.h"
  39. #include "CSSStyleRule.h"
  40. #include "CSSStyleSheet.h"
  41. #include "CharacterData.h"
  42. #include "ContainerNode.h"
  43. #include "Cookie.h"
  44. #include "CookieJar.h"
  45. #include "DOMEditor.h"
  46. #include "DOMPatchSupport.h"
  47. #include "DOMWindow.h"
  48. #include "Document.h"
  49. #include "DocumentFragment.h"
  50. #include "DocumentType.h"
  51. #include "Element.h"
  52. #include "ElementShadow.h"
  53. #include "Event.h"
  54. #include "EventContext.h"
  55. #include "EventListener.h"
  56. #include "EventNames.h"
  57. #include "EventTarget.h"
  58. #include "File.h"
  59. #include "FileList.h"
  60. #include "Frame.h"
  61. #include "FrameTree.h"
  62. #include "HTMLElement.h"
  63. #include "HTMLFrameOwnerElement.h"
  64. #include "HTMLInputElement.h"
  65. #include "HTMLNames.h"
  66. #include "HTMLTemplateElement.h"
  67. #include "HitTestResult.h"
  68. #include "IdentifiersFactory.h"
  69. #include "InjectedScriptManager.h"
  70. #include "InspectorClient.h"
  71. #include "InspectorFrontend.h"
  72. #include "InspectorHistory.h"
  73. #include "InspectorOverlay.h"
  74. #include "InspectorPageAgent.h"
  75. #include "InspectorState.h"
  76. #include "InstrumentingAgents.h"
  77. #include "IntRect.h"
  78. #include "MutationEvent.h"
  79. #include "Node.h"
  80. #include "NodeList.h"
  81. #include "NodeTraversal.h"
  82. #include "Page.h"
  83. #include "Pasteboard.h"
  84. #include "RenderStyle.h"
  85. #include "RenderStyleConstants.h"
  86. #include "ScriptEventListener.h"
  87. #include "Settings.h"
  88. #include "ShadowRoot.h"
  89. #include "StylePropertySet.h"
  90. #include "StyleResolver.h"
  91. #include "StyleSheetList.h"
  92. #include "Text.h"
  93. #include "XPathResult.h"
  94. #include "htmlediting.h"
  95. #include "markup.h"
  96. #include <wtf/text/CString.h>
  97. #include <wtf/text/WTFString.h>
  98. #include <wtf/HashSet.h>
  99. #include <wtf/ListHashSet.h>
  100. #include <wtf/OwnPtr.h>
  101. #include <wtf/Vector.h>
  102. namespace WebCore {
  103. using namespace HTMLNames;
  104. namespace DOMAgentState {
  105. static const char documentRequested[] = "documentRequested";
  106. };
  107. static const size_t maxTextSize = 10000;
  108. static const UChar ellipsisUChar[] = { 0x2026, 0 };
  109. static Color parseColor(const RefPtr<InspectorObject>* colorObject)
  110. {
  111. if (!colorObject || !(*colorObject))
  112. return Color::transparent;
  113. int r;
  114. int g;
  115. int b;
  116. bool success = (*colorObject)->getNumber("r", &r);
  117. success |= (*colorObject)->getNumber("g", &g);
  118. success |= (*colorObject)->getNumber("b", &b);
  119. if (!success)
  120. return Color::transparent;
  121. double a;
  122. success = (*colorObject)->getNumber("a", &a);
  123. if (!success)
  124. return Color(r, g, b);
  125. // Clamp alpha to the [0..1] range.
  126. if (a < 0)
  127. a = 0;
  128. else if (a > 1)
  129. a = 1;
  130. return Color(r, g, b, static_cast<int>(a * 255));
  131. }
  132. static Color parseConfigColor(const String& fieldName, InspectorObject* configObject)
  133. {
  134. const RefPtr<InspectorObject> colorObject = configObject->getObject(fieldName);
  135. return parseColor(&colorObject);
  136. }
  137. static bool parseQuad(const RefPtr<InspectorArray>& quadArray, FloatQuad* quad)
  138. {
  139. if (!quadArray)
  140. return false;
  141. const size_t coordinatesInQuad = 8;
  142. double coordinates[coordinatesInQuad];
  143. if (quadArray->length() != coordinatesInQuad)
  144. return false;
  145. for (size_t i = 0; i < coordinatesInQuad; ++i) {
  146. if (!quadArray->get(i)->asNumber(coordinates + i))
  147. return false;
  148. }
  149. quad->setP1(FloatPoint(coordinates[0], coordinates[1]));
  150. quad->setP2(FloatPoint(coordinates[2], coordinates[3]));
  151. quad->setP3(FloatPoint(coordinates[4], coordinates[5]));
  152. quad->setP4(FloatPoint(coordinates[6], coordinates[7]));
  153. return true;
  154. }
  155. class RevalidateStyleAttributeTask {
  156. WTF_MAKE_FAST_ALLOCATED;
  157. public:
  158. RevalidateStyleAttributeTask(InspectorDOMAgent*);
  159. void scheduleFor(Element*);
  160. void reset() { m_timer.stop(); }
  161. void onTimer(Timer<RevalidateStyleAttributeTask>*);
  162. private:
  163. InspectorDOMAgent* m_domAgent;
  164. Timer<RevalidateStyleAttributeTask> m_timer;
  165. HashSet<RefPtr<Element> > m_elements;
  166. };
  167. RevalidateStyleAttributeTask::RevalidateStyleAttributeTask(InspectorDOMAgent* domAgent)
  168. : m_domAgent(domAgent)
  169. , m_timer(this, &RevalidateStyleAttributeTask::onTimer)
  170. {
  171. }
  172. void RevalidateStyleAttributeTask::scheduleFor(Element* element)
  173. {
  174. m_elements.add(element);
  175. if (!m_timer.isActive())
  176. m_timer.startOneShot(0);
  177. }
  178. void RevalidateStyleAttributeTask::onTimer(Timer<RevalidateStyleAttributeTask>*)
  179. {
  180. // The timer is stopped on m_domAgent destruction, so this method will never be called after m_domAgent has been destroyed.
  181. Vector<Element*> elements;
  182. for (HashSet<RefPtr<Element> >::iterator it = m_elements.begin(), end = m_elements.end(); it != end; ++it)
  183. elements.append(it->get());
  184. m_domAgent->styleAttributeInvalidated(elements);
  185. m_elements.clear();
  186. }
  187. String InspectorDOMAgent::toErrorString(const ExceptionCode& ec)
  188. {
  189. if (ec) {
  190. ExceptionCodeDescription description(ec);
  191. return description.name;
  192. }
  193. return "";
  194. }
  195. InspectorDOMAgent::InspectorDOMAgent(InstrumentingAgents* instrumentingAgents, InspectorPageAgent* pageAgent, InspectorCompositeState* inspectorState, InjectedScriptManager* injectedScriptManager, InspectorOverlay* overlay, InspectorClient* client)
  196. : InspectorBaseAgent<InspectorDOMAgent>("DOM", instrumentingAgents, inspectorState)
  197. , m_pageAgent(pageAgent)
  198. , m_injectedScriptManager(injectedScriptManager)
  199. , m_overlay(overlay)
  200. , m_client(client)
  201. , m_frontend(0)
  202. , m_domListener(0)
  203. , m_lastNodeId(1)
  204. , m_lastBackendNodeId(-1)
  205. , m_searchingForNode(false)
  206. , m_suppressAttributeModifiedEvent(false)
  207. {
  208. }
  209. InspectorDOMAgent::~InspectorDOMAgent()
  210. {
  211. reset();
  212. ASSERT(!m_searchingForNode);
  213. }
  214. void InspectorDOMAgent::setFrontend(InspectorFrontend* frontend)
  215. {
  216. ASSERT(!m_frontend);
  217. m_history = adoptPtr(new InspectorHistory());
  218. m_domEditor = adoptPtr(new DOMEditor(m_history.get()));
  219. m_frontend = frontend->dom();
  220. m_instrumentingAgents->setInspectorDOMAgent(this);
  221. m_document = m_pageAgent->mainFrame()->document();
  222. if (m_nodeToFocus)
  223. focusNode();
  224. }
  225. void InspectorDOMAgent::clearFrontend()
  226. {
  227. ASSERT(m_frontend);
  228. m_history.clear();
  229. m_domEditor.clear();
  230. ErrorString error;
  231. setSearchingForNode(&error, false, 0);
  232. hideHighlight(&error);
  233. m_frontend = 0;
  234. m_instrumentingAgents->setInspectorDOMAgent(0);
  235. m_state->setBoolean(DOMAgentState::documentRequested, false);
  236. reset();
  237. }
  238. void InspectorDOMAgent::restore()
  239. {
  240. // Reset document to avoid early return from setDocument.
  241. m_document = 0;
  242. setDocument(m_pageAgent->mainFrame()->document());
  243. }
  244. Vector<Document*> InspectorDOMAgent::documents()
  245. {
  246. Vector<Document*> result;
  247. for (Frame* frame = m_document->frame(); frame; frame = frame->tree()->traverseNext()) {
  248. Document* document = frame->document();
  249. if (!document)
  250. continue;
  251. result.append(document);
  252. }
  253. return result;
  254. }
  255. void InspectorDOMAgent::reset()
  256. {
  257. if (m_history)
  258. m_history->reset();
  259. m_searchResults.clear();
  260. discardBindings();
  261. if (m_revalidateStyleAttrTask)
  262. m_revalidateStyleAttrTask->reset();
  263. m_document = 0;
  264. }
  265. void InspectorDOMAgent::setDOMListener(DOMListener* listener)
  266. {
  267. m_domListener = listener;
  268. }
  269. void InspectorDOMAgent::setDocument(Document* doc)
  270. {
  271. if (doc == m_document.get())
  272. return;
  273. reset();
  274. m_document = doc;
  275. if (!m_state->getBoolean(DOMAgentState::documentRequested))
  276. return;
  277. // Immediately communicate 0 document or document that has finished loading.
  278. if (!doc || !doc->parsing())
  279. m_frontend->documentUpdated();
  280. }
  281. void InspectorDOMAgent::releaseDanglingNodes()
  282. {
  283. m_danglingNodeToIdMaps.clear();
  284. }
  285. int InspectorDOMAgent::bind(Node* node, NodeToIdMap* nodesMap)
  286. {
  287. int id = nodesMap->get(node);
  288. if (id)
  289. return id;
  290. id = m_lastNodeId++;
  291. nodesMap->set(node, id);
  292. m_idToNode.set(id, node);
  293. m_idToNodesMap.set(id, nodesMap);
  294. return id;
  295. }
  296. void InspectorDOMAgent::unbind(Node* node, NodeToIdMap* nodesMap)
  297. {
  298. int id = nodesMap->get(node);
  299. if (!id)
  300. return;
  301. m_idToNode.remove(id);
  302. if (node->isFrameOwnerElement()) {
  303. const HTMLFrameOwnerElement* frameOwner = static_cast<const HTMLFrameOwnerElement*>(node);
  304. Document* contentDocument = frameOwner->contentDocument();
  305. if (m_domListener)
  306. m_domListener->didRemoveDocument(contentDocument);
  307. if (contentDocument)
  308. unbind(contentDocument, nodesMap);
  309. }
  310. if (node->isElementNode()) {
  311. if (ElementShadow* shadow = toElement(node)->shadow()) {
  312. if (ShadowRoot* root = shadow->shadowRoot())
  313. unbind(root, nodesMap);
  314. }
  315. }
  316. nodesMap->remove(node);
  317. if (m_domListener)
  318. m_domListener->didRemoveDOMNode(node);
  319. bool childrenRequested = m_childrenRequested.contains(id);
  320. if (childrenRequested) {
  321. // Unbind subtree known to client recursively.
  322. m_childrenRequested.remove(id);
  323. Node* child = innerFirstChild(node);
  324. while (child) {
  325. unbind(child, nodesMap);
  326. child = innerNextSibling(child);
  327. }
  328. }
  329. }
  330. Node* InspectorDOMAgent::assertNode(ErrorString* errorString, int nodeId)
  331. {
  332. Node* node = nodeForId(nodeId);
  333. if (!node) {
  334. *errorString = "Could not find node with given id";
  335. return 0;
  336. }
  337. return node;
  338. }
  339. Document* InspectorDOMAgent::assertDocument(ErrorString* errorString, int nodeId)
  340. {
  341. Node* node = assertNode(errorString, nodeId);
  342. if (!node)
  343. return 0;
  344. if (!(node->isDocumentNode())) {
  345. *errorString = "Document is not available";
  346. return 0;
  347. }
  348. return toDocument(node);
  349. }
  350. Element* InspectorDOMAgent::assertElement(ErrorString* errorString, int nodeId)
  351. {
  352. Node* node = assertNode(errorString, nodeId);
  353. if (!node)
  354. return 0;
  355. if (node->nodeType() != Node::ELEMENT_NODE) {
  356. *errorString = "Node is not an Element";
  357. return 0;
  358. }
  359. return toElement(node);
  360. }
  361. Node* InspectorDOMAgent::assertEditableNode(ErrorString* errorString, int nodeId)
  362. {
  363. Node* node = assertNode(errorString, nodeId);
  364. if (!node)
  365. return 0;
  366. if (node->isInShadowTree()) {
  367. *errorString = "Can not edit nodes from shadow trees";
  368. return 0;
  369. }
  370. return node;
  371. }
  372. Element* InspectorDOMAgent::assertEditableElement(ErrorString* errorString, int nodeId)
  373. {
  374. Element* element = assertElement(errorString, nodeId);
  375. if (!element)
  376. return 0;
  377. if (element->isInShadowTree()) {
  378. *errorString = "Can not edit elements from shadow trees";
  379. return 0;
  380. }
  381. return element;
  382. }
  383. void InspectorDOMAgent::getDocument(ErrorString* errorString, RefPtr<TypeBuilder::DOM::Node>& root)
  384. {
  385. m_state->setBoolean(DOMAgentState::documentRequested, true);
  386. if (!m_document) {
  387. *errorString = "Document is not available";
  388. return;
  389. }
  390. // Reset backend state.
  391. RefPtr<Document> doc = m_document;
  392. reset();
  393. m_document = doc;
  394. root = buildObjectForNode(m_document.get(), 2, &m_documentNodeToIdMap);
  395. }
  396. void InspectorDOMAgent::pushChildNodesToFrontend(int nodeId, int depth)
  397. {
  398. Node* node = nodeForId(nodeId);
  399. if (!node || (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE && node->nodeType() != Node::DOCUMENT_FRAGMENT_NODE))
  400. return;
  401. NodeToIdMap* nodeMap = m_idToNodesMap.get(nodeId);
  402. if (m_childrenRequested.contains(nodeId)) {
  403. if (depth <= 1)
  404. return;
  405. depth--;
  406. for (node = innerFirstChild(node); node; node = innerNextSibling(node)) {
  407. int childNodeId = nodeMap->get(node);
  408. ASSERT(childNodeId);
  409. pushChildNodesToFrontend(childNodeId, depth);
  410. }
  411. return;
  412. }
  413. RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodeMap);
  414. m_frontend->setChildNodes(nodeId, children.release());
  415. }
  416. void InspectorDOMAgent::discardBindings()
  417. {
  418. m_documentNodeToIdMap.clear();
  419. m_idToNode.clear();
  420. releaseDanglingNodes();
  421. m_childrenRequested.clear();
  422. m_backendIdToNode.clear();
  423. m_nodeGroupToBackendIdMap.clear();
  424. }
  425. int InspectorDOMAgent::pushNodeToFrontend(ErrorString* errorString, int documentNodeId, Node* nodeToPush)
  426. {
  427. Document* document = assertDocument(errorString, documentNodeId);
  428. if (!document)
  429. return 0;
  430. if (nodeToPush->document() != document) {
  431. *errorString = "Node is not part of the document with given id";
  432. return 0;
  433. }
  434. return pushNodePathToFrontend(nodeToPush);
  435. }
  436. Node* InspectorDOMAgent::nodeForId(int id)
  437. {
  438. if (!id)
  439. return 0;
  440. HashMap<int, Node*>::iterator it = m_idToNode.find(id);
  441. if (it != m_idToNode.end())
  442. return it->value;
  443. return 0;
  444. }
  445. void InspectorDOMAgent::requestChildNodes(ErrorString* errorString, int nodeId, const int* depth)
  446. {
  447. int sanitizedDepth;
  448. if (!depth)
  449. sanitizedDepth = 1;
  450. else if (*depth == -1)
  451. sanitizedDepth = INT_MAX;
  452. else if (*depth > 0)
  453. sanitizedDepth = *depth;
  454. else {
  455. *errorString = "Please provide a positive integer as a depth or -1 for entire subtree";
  456. return;
  457. }
  458. pushChildNodesToFrontend(nodeId, sanitizedDepth);
  459. }
  460. void InspectorDOMAgent::querySelector(ErrorString* errorString, int nodeId, const String& selectors, int* elementId)
  461. {
  462. *elementId = 0;
  463. Node* node = assertNode(errorString, nodeId);
  464. if (!node)
  465. return;
  466. ExceptionCode ec = 0;
  467. RefPtr<Element> element = node->querySelector(selectors, ec);
  468. if (ec) {
  469. *errorString = "DOM Error while querying";
  470. return;
  471. }
  472. if (element)
  473. *elementId = pushNodePathToFrontend(element.get());
  474. }
  475. void InspectorDOMAgent::querySelectorAll(ErrorString* errorString, int nodeId, const String& selectors, RefPtr<TypeBuilder::Array<int> >& result)
  476. {
  477. Node* node = assertNode(errorString, nodeId);
  478. if (!node)
  479. return;
  480. ExceptionCode ec = 0;
  481. RefPtr<NodeList> nodes = node->querySelectorAll(selectors, ec);
  482. if (ec) {
  483. *errorString = "DOM Error while querying";
  484. return;
  485. }
  486. result = TypeBuilder::Array<int>::create();
  487. for (unsigned i = 0; i < nodes->length(); ++i)
  488. result->addItem(pushNodePathToFrontend(nodes->item(i)));
  489. }
  490. int InspectorDOMAgent::pushNodePathToFrontend(Node* nodeToPush)
  491. {
  492. ASSERT(nodeToPush); // Invalid input
  493. if (!m_document)
  494. return 0;
  495. if (!m_documentNodeToIdMap.contains(m_document))
  496. return 0;
  497. // Return id in case the node is known.
  498. int result = m_documentNodeToIdMap.get(nodeToPush);
  499. if (result)
  500. return result;
  501. Node* node = nodeToPush;
  502. Vector<Node*> path;
  503. NodeToIdMap* danglingMap = 0;
  504. while (true) {
  505. Node* parent = innerParentNode(node);
  506. if (!parent) {
  507. // Node being pushed is detached -> push subtree root.
  508. OwnPtr<NodeToIdMap> newMap = adoptPtr(new NodeToIdMap);
  509. danglingMap = newMap.get();
  510. m_danglingNodeToIdMaps.append(newMap.release());
  511. RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
  512. children->addItem(buildObjectForNode(node, 0, danglingMap));
  513. m_frontend->setChildNodes(0, children);
  514. break;
  515. } else {
  516. path.append(parent);
  517. if (m_documentNodeToIdMap.get(parent))
  518. break;
  519. else
  520. node = parent;
  521. }
  522. }
  523. NodeToIdMap* map = danglingMap ? danglingMap : &m_documentNodeToIdMap;
  524. for (int i = path.size() - 1; i >= 0; --i) {
  525. int nodeId = map->get(path.at(i));
  526. ASSERT(nodeId);
  527. pushChildNodesToFrontend(nodeId);
  528. }
  529. return map->get(nodeToPush);
  530. }
  531. int InspectorDOMAgent::boundNodeId(Node* node)
  532. {
  533. return m_documentNodeToIdMap.get(node);
  534. }
  535. BackendNodeId InspectorDOMAgent::backendNodeIdForNode(Node* node, const String& nodeGroup)
  536. {
  537. if (!node)
  538. return 0;
  539. if (!m_nodeGroupToBackendIdMap.contains(nodeGroup))
  540. m_nodeGroupToBackendIdMap.set(nodeGroup, NodeToBackendIdMap());
  541. NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value;
  542. BackendNodeId id = map.get(node);
  543. if (!id) {
  544. id = --m_lastBackendNodeId;
  545. map.set(node, id);
  546. m_backendIdToNode.set(id, std::make_pair(node, nodeGroup));
  547. }
  548. return id;
  549. }
  550. void InspectorDOMAgent::releaseBackendNodeIds(ErrorString* errorString, const String& nodeGroup)
  551. {
  552. if (m_nodeGroupToBackendIdMap.contains(nodeGroup)) {
  553. NodeToBackendIdMap& map = m_nodeGroupToBackendIdMap.find(nodeGroup)->value;
  554. for (NodeToBackendIdMap::iterator it = map.begin(); it != map.end(); ++it)
  555. m_backendIdToNode.remove(it->value);
  556. m_nodeGroupToBackendIdMap.remove(nodeGroup);
  557. return;
  558. }
  559. *errorString = "Group name not found";
  560. }
  561. void InspectorDOMAgent::setAttributeValue(ErrorString* errorString, int elementId, const String& name, const String& value)
  562. {
  563. Element* element = assertEditableElement(errorString, elementId);
  564. if (!element)
  565. return;
  566. m_domEditor->setAttribute(element, name, value, errorString);
  567. }
  568. void InspectorDOMAgent::setAttributesAsText(ErrorString* errorString, int elementId, const String& text, const String* const name)
  569. {
  570. Element* element = assertEditableElement(errorString, elementId);
  571. if (!element)
  572. return;
  573. RefPtr<HTMLElement> parsedElement = createHTMLElement(element->document(), spanTag);
  574. ExceptionCode ec = 0;
  575. parsedElement.get()->setInnerHTML("<span " + text + "></span>", ec);
  576. if (ec) {
  577. *errorString = InspectorDOMAgent::toErrorString(ec);
  578. return;
  579. }
  580. Node* child = parsedElement->firstChild();
  581. if (!child) {
  582. *errorString = "Could not parse value as attributes";
  583. return;
  584. }
  585. Element* childElement = toElement(child);
  586. if (!childElement->hasAttributes() && name) {
  587. m_domEditor->removeAttribute(element, *name, errorString);
  588. return;
  589. }
  590. bool foundOriginalAttribute = false;
  591. unsigned numAttrs = childElement->attributeCount();
  592. for (unsigned i = 0; i < numAttrs; ++i) {
  593. // Add attribute pair
  594. const Attribute* attribute = childElement->attributeItem(i);
  595. foundOriginalAttribute = foundOriginalAttribute || (name && attribute->name().toString() == *name);
  596. if (!m_domEditor->setAttribute(element, attribute->name().toString(), attribute->value(), errorString))
  597. return;
  598. }
  599. if (!foundOriginalAttribute && name && !name->stripWhiteSpace().isEmpty())
  600. m_domEditor->removeAttribute(element, *name, errorString);
  601. }
  602. void InspectorDOMAgent::removeAttribute(ErrorString* errorString, int elementId, const String& name)
  603. {
  604. Element* element = assertEditableElement(errorString, elementId);
  605. if (!element)
  606. return;
  607. m_domEditor->removeAttribute(element, name, errorString);
  608. }
  609. void InspectorDOMAgent::removeNode(ErrorString* errorString, int nodeId)
  610. {
  611. Node* node = assertEditableNode(errorString, nodeId);
  612. if (!node)
  613. return;
  614. ContainerNode* parentNode = node->parentNode();
  615. if (!parentNode) {
  616. *errorString = "Can not remove detached node";
  617. return;
  618. }
  619. m_domEditor->removeChild(parentNode, node, errorString);
  620. }
  621. void InspectorDOMAgent::setNodeName(ErrorString* errorString, int nodeId, const String& tagName, int* newId)
  622. {
  623. *newId = 0;
  624. Node* oldNode = nodeForId(nodeId);
  625. if (!oldNode || !oldNode->isElementNode())
  626. return;
  627. ExceptionCode ec = 0;
  628. RefPtr<Element> newElem = oldNode->document()->createElement(tagName, ec);
  629. if (ec)
  630. return;
  631. // Copy over the original node's attributes.
  632. newElem->cloneAttributesFromElement(*toElement(oldNode));
  633. // Copy over the original node's children.
  634. Node* child;
  635. while ((child = oldNode->firstChild())) {
  636. if (!m_domEditor->insertBefore(newElem.get(), child, 0, errorString))
  637. return;
  638. }
  639. // Replace the old node with the new node
  640. ContainerNode* parent = oldNode->parentNode();
  641. if (!m_domEditor->insertBefore(parent, newElem.get(), oldNode->nextSibling(), errorString))
  642. return;
  643. if (!m_domEditor->removeChild(parent, oldNode, errorString))
  644. return;
  645. *newId = pushNodePathToFrontend(newElem.get());
  646. if (m_childrenRequested.contains(nodeId))
  647. pushChildNodesToFrontend(*newId);
  648. }
  649. void InspectorDOMAgent::getOuterHTML(ErrorString* errorString, int nodeId, WTF::String* outerHTML)
  650. {
  651. Node* node = assertNode(errorString, nodeId);
  652. if (!node)
  653. return;
  654. *outerHTML = createMarkup(node);
  655. }
  656. void InspectorDOMAgent::setOuterHTML(ErrorString* errorString, int nodeId, const String& outerHTML)
  657. {
  658. if (!nodeId) {
  659. DOMPatchSupport domPatchSupport(m_domEditor.get(), m_document.get());
  660. domPatchSupport.patchDocument(outerHTML);
  661. return;
  662. }
  663. Node* node = assertEditableNode(errorString, nodeId);
  664. if (!node)
  665. return;
  666. Document* document = node->isDocumentNode() ? toDocument(node) : node->ownerDocument();
  667. if (!document || (!document->isHTMLDocument() && !document->isXHTMLDocument()
  668. #if ENABLE(SVG)
  669. && !document->isSVGDocument()
  670. #endif
  671. )) {
  672. *errorString = "Not an HTML/XML document";
  673. return;
  674. }
  675. Node* newNode = 0;
  676. if (!m_domEditor->setOuterHTML(node, outerHTML, &newNode, errorString))
  677. return;
  678. if (!newNode) {
  679. // The only child node has been deleted.
  680. return;
  681. }
  682. int newId = pushNodePathToFrontend(newNode);
  683. bool childrenRequested = m_childrenRequested.contains(nodeId);
  684. if (childrenRequested)
  685. pushChildNodesToFrontend(newId);
  686. }
  687. void InspectorDOMAgent::setNodeValue(ErrorString* errorString, int nodeId, const String& value)
  688. {
  689. Node* node = assertEditableNode(errorString, nodeId);
  690. if (!node)
  691. return;
  692. if (node->nodeType() != Node::TEXT_NODE) {
  693. *errorString = "Can only set value of text nodes";
  694. return;
  695. }
  696. m_domEditor->replaceWholeText(toText(node), value, errorString);
  697. }
  698. void InspectorDOMAgent::getEventListenersForNode(ErrorString* errorString, int nodeId, const String* objectGroup, RefPtr<TypeBuilder::Array<TypeBuilder::DOM::EventListener> >& listenersArray)
  699. {
  700. listenersArray = TypeBuilder::Array<TypeBuilder::DOM::EventListener>::create();
  701. Node* node = assertNode(errorString, nodeId);
  702. if (!node)
  703. return;
  704. Vector<EventListenerInfo> eventInformation;
  705. getEventListeners(node, eventInformation, true);
  706. // Get Capturing Listeners (in this order)
  707. size_t eventInformationLength = eventInformation.size();
  708. for (size_t i = 0; i < eventInformationLength; ++i) {
  709. const EventListenerInfo& info = eventInformation[i];
  710. const EventListenerVector& vector = info.eventListenerVector;
  711. for (size_t j = 0; j < vector.size(); ++j) {
  712. const RegisteredEventListener& listener = vector[j];
  713. if (listener.useCapture)
  714. listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
  715. }
  716. }
  717. // Get Bubbling Listeners (reverse order)
  718. for (size_t i = eventInformationLength; i; --i) {
  719. const EventListenerInfo& info = eventInformation[i - 1];
  720. const EventListenerVector& vector = info.eventListenerVector;
  721. for (size_t j = 0; j < vector.size(); ++j) {
  722. const RegisteredEventListener& listener = vector[j];
  723. if (!listener.useCapture)
  724. listenersArray->addItem(buildObjectForEventListener(listener, info.eventType, info.node, objectGroup));
  725. }
  726. }
  727. }
  728. void InspectorDOMAgent::getEventListeners(Node* node, Vector<EventListenerInfo>& eventInformation, bool includeAncestors)
  729. {
  730. // The Node's Ancestors including self.
  731. Vector<Node*> ancestors;
  732. // Push this node as the firs element.
  733. ancestors.append(node);
  734. if (includeAncestors) {
  735. for (ContainerNode* ancestor = node->parentOrShadowHostNode(); ancestor; ancestor = ancestor->parentOrShadowHostNode())
  736. ancestors.append(ancestor);
  737. }
  738. // Nodes and their Listeners for the concerned event types (order is top to bottom)
  739. for (size_t i = ancestors.size(); i; --i) {
  740. Node* ancestor = ancestors[i - 1];
  741. EventTargetData* d = ancestor->eventTargetData();
  742. if (!d)
  743. continue;
  744. // Get the list of event types this Node is concerned with
  745. Vector<AtomicString> eventTypes = d->eventListenerMap.eventTypes();
  746. for (size_t j = 0; j < eventTypes.size(); ++j) {
  747. AtomicString& type = eventTypes[j];
  748. const EventListenerVector& listeners = ancestor->getEventListeners(type);
  749. EventListenerVector filteredListeners;
  750. filteredListeners.reserveCapacity(listeners.size());
  751. for (size_t k = 0; k < listeners.size(); ++k) {
  752. if (listeners[k].listener->type() == EventListener::JSEventListenerType)
  753. filteredListeners.append(listeners[k]);
  754. }
  755. if (!filteredListeners.isEmpty())
  756. eventInformation.append(EventListenerInfo(ancestor, type, filteredListeners));
  757. }
  758. }
  759. }
  760. void InspectorDOMAgent::performSearch(ErrorString*, const String& whitespaceTrimmedQuery, String* searchId, int* resultCount)
  761. {
  762. // FIXME: Few things are missing here:
  763. // 1) Search works with node granularity - number of matches within node is not calculated.
  764. // 2) There is no need to push all search results to the front-end at a time, pushing next / previous result
  765. // is sufficient.
  766. unsigned queryLength = whitespaceTrimmedQuery.length();
  767. bool startTagFound = !whitespaceTrimmedQuery.find('<');
  768. bool endTagFound = whitespaceTrimmedQuery.reverseFind('>') + 1 == queryLength;
  769. bool startQuoteFound = !whitespaceTrimmedQuery.find('"');
  770. bool endQuoteFound = whitespaceTrimmedQuery.reverseFind('"') + 1 == queryLength;
  771. bool exactAttributeMatch = startQuoteFound && endQuoteFound;
  772. String tagNameQuery = whitespaceTrimmedQuery;
  773. String attributeQuery = whitespaceTrimmedQuery;
  774. if (startTagFound)
  775. tagNameQuery = tagNameQuery.right(tagNameQuery.length() - 1);
  776. if (endTagFound)
  777. tagNameQuery = tagNameQuery.left(tagNameQuery.length() - 1);
  778. if (startQuoteFound)
  779. attributeQuery = attributeQuery.right(attributeQuery.length() - 1);
  780. if (endQuoteFound)
  781. attributeQuery = attributeQuery.left(attributeQuery.length() - 1);
  782. Vector<Document*> docs = documents();
  783. ListHashSet<Node*> resultCollector;
  784. for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
  785. Document* document = *it;
  786. Node* node = document->documentElement();
  787. if (!node)
  788. continue;
  789. // Manual plain text search.
  790. while ((node = NodeTraversal::next(node, document->documentElement()))) {
  791. switch (node->nodeType()) {
  792. case Node::TEXT_NODE:
  793. case Node::COMMENT_NODE:
  794. case Node::CDATA_SECTION_NODE: {
  795. String text = node->nodeValue();
  796. if (text.findIgnoringCase(whitespaceTrimmedQuery) != notFound)
  797. resultCollector.add(node);
  798. break;
  799. }
  800. case Node::ELEMENT_NODE: {
  801. if ((!startTagFound && !endTagFound && (node->nodeName().findIgnoringCase(tagNameQuery) != notFound))
  802. || (startTagFound && endTagFound && equalIgnoringCase(node->nodeName(), tagNameQuery))
  803. || (startTagFound && !endTagFound && node->nodeName().startsWith(tagNameQuery, false))
  804. || (!startTagFound && endTagFound && node->nodeName().endsWith(tagNameQuery, false))) {
  805. resultCollector.add(node);
  806. break;
  807. }
  808. // Go through all attributes and serialize them.
  809. const Element* element = toElement(node);
  810. if (!element->hasAttributes())
  811. break;
  812. unsigned numAttrs = element->attributeCount();
  813. for (unsigned i = 0; i < numAttrs; ++i) {
  814. // Add attribute pair
  815. const Attribute* attribute = element->attributeItem(i);
  816. if (attribute->localName().find(whitespaceTrimmedQuery) != notFound) {
  817. resultCollector.add(node);
  818. break;
  819. }
  820. size_t foundPosition = attribute->value().find(attributeQuery);
  821. if (foundPosition != notFound) {
  822. if (!exactAttributeMatch || (!foundPosition && attribute->value().length() == attributeQuery.length())) {
  823. resultCollector.add(node);
  824. break;
  825. }
  826. }
  827. }
  828. break;
  829. }
  830. default:
  831. break;
  832. }
  833. }
  834. // XPath evaluation
  835. for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
  836. Document* document = *it;
  837. ExceptionCode ec = 0;
  838. RefPtr<XPathResult> result = document->evaluate(whitespaceTrimmedQuery, document, 0, XPathResult::ORDERED_NODE_SNAPSHOT_TYPE, 0, ec);
  839. if (ec || !result)
  840. continue;
  841. unsigned long size = result->snapshotLength(ec);
  842. for (unsigned long i = 0; !ec && i < size; ++i) {
  843. Node* node = result->snapshotItem(i, ec);
  844. if (ec)
  845. break;
  846. if (node->nodeType() == Node::ATTRIBUTE_NODE)
  847. node = static_cast<Attr*>(node)->ownerElement();
  848. resultCollector.add(node);
  849. }
  850. }
  851. // Selector evaluation
  852. for (Vector<Document*>::iterator it = docs.begin(); it != docs.end(); ++it) {
  853. Document* document = *it;
  854. ExceptionCode ec = 0;
  855. RefPtr<NodeList> nodeList = document->querySelectorAll(whitespaceTrimmedQuery, ec);
  856. if (ec || !nodeList)
  857. continue;
  858. unsigned size = nodeList->length();
  859. for (unsigned i = 0; i < size; ++i)
  860. resultCollector.add(nodeList->item(i));
  861. }
  862. }
  863. *searchId = IdentifiersFactory::createIdentifier();
  864. SearchResults::iterator resultsIt = m_searchResults.add(*searchId, Vector<RefPtr<Node> >()).iterator;
  865. for (ListHashSet<Node*>::iterator it = resultCollector.begin(); it != resultCollector.end(); ++it)
  866. resultsIt->value.append(*it);
  867. *resultCount = resultsIt->value.size();
  868. }
  869. void InspectorDOMAgent::getSearchResults(ErrorString* errorString, const String& searchId, int fromIndex, int toIndex, RefPtr<TypeBuilder::Array<int> >& nodeIds)
  870. {
  871. SearchResults::iterator it = m_searchResults.find(searchId);
  872. if (it == m_searchResults.end()) {
  873. *errorString = "No search session with given id found";
  874. return;
  875. }
  876. int size = it->value.size();
  877. if (fromIndex < 0 || toIndex > size || fromIndex >= toIndex) {
  878. *errorString = "Invalid search result range";
  879. return;
  880. }
  881. nodeIds = TypeBuilder::Array<int>::create();
  882. for (int i = fromIndex; i < toIndex; ++i)
  883. nodeIds->addItem(pushNodePathToFrontend((it->value)[i].get()));
  884. }
  885. void InspectorDOMAgent::discardSearchResults(ErrorString*, const String& searchId)
  886. {
  887. m_searchResults.remove(searchId);
  888. }
  889. bool InspectorDOMAgent::handleMousePress()
  890. {
  891. if (!m_searchingForNode)
  892. return false;
  893. if (Node* node = m_overlay->highlightedNode()) {
  894. inspect(node);
  895. return true;
  896. }
  897. return false;
  898. }
  899. bool InspectorDOMAgent::handleTouchEvent(Node* node)
  900. {
  901. if (!m_searchingForNode)
  902. return false;
  903. if (node && m_inspectModeHighlightConfig) {
  904. m_overlay->highlightNode(node, *m_inspectModeHighlightConfig);
  905. inspect(node);
  906. return true;
  907. }
  908. return false;
  909. }
  910. void InspectorDOMAgent::inspect(Node* inspectedNode)
  911. {
  912. ErrorString error;
  913. RefPtr<Node> node = inspectedNode;
  914. setSearchingForNode(&error, false, 0);
  915. if (node->nodeType() != Node::ELEMENT_NODE && node->nodeType() != Node::DOCUMENT_NODE)
  916. node = node->parentNode();
  917. m_nodeToFocus = node;
  918. focusNode();
  919. }
  920. void InspectorDOMAgent::focusNode()
  921. {
  922. if (!m_frontend)
  923. return;
  924. ASSERT(m_nodeToFocus);
  925. RefPtr<Node> node = m_nodeToFocus.get();
  926. m_nodeToFocus = 0;
  927. Document* document = node->ownerDocument();
  928. if (!document)
  929. return;
  930. Frame* frame = document->frame();
  931. if (!frame)
  932. return;
  933. InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
  934. if (injectedScript.hasNoValue())
  935. return;
  936. injectedScript.inspectNode(node.get());
  937. }
  938. void InspectorDOMAgent::mouseDidMoveOverElement(const HitTestResult& result, unsigned)
  939. {
  940. if (!m_searchingForNode)
  941. return;
  942. Node* node = result.innerNode();
  943. while (node && node->nodeType() == Node::TEXT_NODE)
  944. node = node->parentNode();
  945. if (node && m_inspectModeHighlightConfig)
  946. m_overlay->highlightNode(node, *m_inspectModeHighlightConfig);
  947. }
  948. void InspectorDOMAgent::setSearchingForNode(ErrorString* errorString, bool enabled, InspectorObject* highlightInspectorObject)
  949. {
  950. if (m_searchingForNode == enabled)
  951. return;
  952. m_searchingForNode = enabled;
  953. if (enabled) {
  954. m_inspectModeHighlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject);
  955. if (!m_inspectModeHighlightConfig)
  956. return;
  957. } else
  958. hideHighlight(errorString);
  959. }
  960. PassOwnPtr<HighlightConfig> InspectorDOMAgent::highlightConfigFromInspectorObject(ErrorString* errorString, InspectorObject* highlightInspectorObject)
  961. {
  962. if (!highlightInspectorObject) {
  963. *errorString = "Internal error: highlight configuration parameter is missing";
  964. return nullptr;
  965. }
  966. OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
  967. bool showInfo = false; // Default: false (do not show a tooltip).
  968. highlightInspectorObject->getBoolean("showInfo", &showInfo);
  969. highlightConfig->showInfo = showInfo;
  970. bool showRulers = false; // Default: false (do not show rulers).
  971. highlightInspectorObject->getBoolean("showRulers", &showRulers);
  972. highlightConfig->showRulers = showRulers;
  973. highlightConfig->content = parseConfigColor("contentColor", highlightInspectorObject);
  974. highlightConfig->contentOutline = parseConfigColor("contentOutlineColor", highlightInspectorObject);
  975. highlightConfig->padding = parseConfigColor("paddingColor", highlightInspectorObject);
  976. highlightConfig->border = parseConfigColor("borderColor", highlightInspectorObject);
  977. highlightConfig->margin = parseConfigColor("marginColor", highlightInspectorObject);
  978. return highlightConfig.release();
  979. }
  980. void InspectorDOMAgent::setInspectModeEnabled(ErrorString* errorString, bool enabled, const RefPtr<InspectorObject>* highlightConfig)
  981. {
  982. setSearchingForNode(errorString, enabled, highlightConfig ? highlightConfig->get() : 0);
  983. }
  984. void InspectorDOMAgent::highlightRect(ErrorString*, int x, int y, int width, int height, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
  985. {
  986. OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad(FloatRect(x, y, width, height)));
  987. innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates);
  988. }
  989. void InspectorDOMAgent::highlightQuad(ErrorString* errorString, const RefPtr<InspectorArray>& quadArray, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
  990. {
  991. OwnPtr<FloatQuad> quad = adoptPtr(new FloatQuad());
  992. if (!parseQuad(quadArray, quad.get())) {
  993. *errorString = "Invalid Quad format";
  994. return;
  995. }
  996. innerHighlightQuad(quad.release(), color, outlineColor, usePageCoordinates);
  997. }
  998. void InspectorDOMAgent::innerHighlightQuad(PassOwnPtr<FloatQuad> quad, const RefPtr<InspectorObject>* color, const RefPtr<InspectorObject>* outlineColor, const bool* usePageCoordinates)
  999. {
  1000. OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
  1001. highlightConfig->content = parseColor(color);
  1002. highlightConfig->contentOutline = parseColor(outlineColor);
  1003. highlightConfig->usePageCoordinates = usePageCoordinates ? *usePageCoordinates : false;
  1004. m_overlay->highlightQuad(quad, *highlightConfig);
  1005. }
  1006. void InspectorDOMAgent::highlightNode(ErrorString* errorString, const RefPtr<InspectorObject>& highlightInspectorObject, const int* nodeId, const String* objectId)
  1007. {
  1008. Node* node = 0;
  1009. if (nodeId) {
  1010. node = assertNode(errorString, *nodeId);
  1011. } else if (objectId) {
  1012. InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(*objectId);
  1013. node = injectedScript.nodeForObjectId(*objectId);
  1014. if (!node)
  1015. *errorString = "Node for given objectId not found";
  1016. } else
  1017. *errorString = "Either nodeId or objectId must be specified";
  1018. if (!node)
  1019. return;
  1020. OwnPtr<HighlightConfig> highlightConfig = highlightConfigFromInspectorObject(errorString, highlightInspectorObject.get());
  1021. if (!highlightConfig)
  1022. return;
  1023. m_overlay->highlightNode(node, *highlightConfig);
  1024. }
  1025. void InspectorDOMAgent::highlightFrame(
  1026. ErrorString*,
  1027. const String& frameId,
  1028. const RefPtr<InspectorObject>* color,
  1029. const RefPtr<InspectorObject>* outlineColor)
  1030. {
  1031. Frame* frame = m_pageAgent->frameForId(frameId);
  1032. if (frame && frame->ownerElement()) {
  1033. OwnPtr<HighlightConfig> highlightConfig = adoptPtr(new HighlightConfig());
  1034. highlightConfig->showInfo = true; // Always show tooltips for frames.
  1035. highlightConfig->content = parseColor(color);
  1036. highlightConfig->contentOutline = parseColor(outlineColor);
  1037. m_overlay->highlightNode(frame->ownerElement(), *highlightConfig);
  1038. }
  1039. }
  1040. void InspectorDOMAgent::hideHighlight(ErrorString*)
  1041. {
  1042. m_overlay->hideHighlight();
  1043. }
  1044. void InspectorDOMAgent::moveTo(ErrorString* errorString, int nodeId, int targetElementId, const int* const anchorNodeId, int* newNodeId)
  1045. {
  1046. Node* node = assertEditableNode(errorString, nodeId);
  1047. if (!node)
  1048. return;
  1049. Element* targetElement = assertEditableElement(errorString, targetElementId);
  1050. if (!targetElement)
  1051. return;
  1052. Node* anchorNode = 0;
  1053. if (anchorNodeId && *anchorNodeId) {
  1054. anchorNode = assertEditableNode(errorString, *anchorNodeId);
  1055. if (!anchorNode)
  1056. return;
  1057. if (anchorNode->parentNode() != targetElement) {
  1058. *errorString = "Anchor node must be child of the target element";
  1059. return;
  1060. }
  1061. }
  1062. if (!m_domEditor->insertBefore(targetElement, node, anchorNode, errorString))
  1063. return;
  1064. *newNodeId = pushNodePathToFrontend(node);
  1065. }
  1066. void InspectorDOMAgent::undo(ErrorString* errorString)
  1067. {
  1068. ExceptionCode ec = 0;
  1069. m_history->undo(ec);
  1070. *errorString = InspectorDOMAgent::toErrorString(ec);
  1071. }
  1072. void InspectorDOMAgent::redo(ErrorString* errorString)
  1073. {
  1074. ExceptionCode ec = 0;
  1075. m_history->redo(ec);
  1076. *errorString = InspectorDOMAgent::toErrorString(ec);
  1077. }
  1078. void InspectorDOMAgent::markUndoableState(ErrorString*)
  1079. {
  1080. m_history->markUndoableState();
  1081. }
  1082. void InspectorDOMAgent::focus(ErrorString* errorString, int nodeId)
  1083. {
  1084. Element* element = assertElement(errorString, nodeId);
  1085. if (!element)
  1086. return;
  1087. if (!element->isFocusable()) {
  1088. *errorString = "Element is not focusable";
  1089. return;
  1090. }
  1091. element->focus();
  1092. }
  1093. void InspectorDOMAgent::setFileInputFiles(ErrorString* errorString, int nodeId, const RefPtr<InspectorArray>& files)
  1094. {
  1095. if (!m_client->canSetFileInputFiles()) {
  1096. *errorString = "Cannot set file input files";
  1097. return;
  1098. }
  1099. Node* node = assertNode(errorString, nodeId);
  1100. if (!node)
  1101. return;
  1102. HTMLInputElement* element = node->toInputElement();
  1103. if (!element || !element->isFileUpload()) {
  1104. *errorString = "Node is not a file input element";
  1105. return;
  1106. }
  1107. RefPtr<FileList> fileList = FileList::create();
  1108. for (InspectorArray::const_iterator iter = files->begin(); iter != files->end(); ++iter) {
  1109. String path;
  1110. if (!(*iter)->asString(&path)) {
  1111. *errorString = "Files must be strings";
  1112. return;
  1113. }
  1114. fileList->append(File::create(path));
  1115. }
  1116. element->setFiles(fileList);
  1117. }
  1118. void InspectorDOMAgent::resolveNode(ErrorString* errorString, int nodeId, const String* const objectGroup, RefPtr<TypeBuilder::Runtime::RemoteObject>& result)
  1119. {
  1120. String objectGroupName = objectGroup ? *objectGroup : "";
  1121. Node* node = nodeForId(nodeId);
  1122. if (!node) {
  1123. *errorString = "No node with given id found";
  1124. return;
  1125. }
  1126. RefPtr<TypeBuilder::Runtime::RemoteObject> object = resolveNode(node, objectGroupName);
  1127. if (!object) {
  1128. *errorString = "Node with given id does not belong to the document";
  1129. return;
  1130. }
  1131. result = object;
  1132. }
  1133. void InspectorDOMAgent::getAttributes(ErrorString* errorString, int nodeId, RefPtr<TypeBuilder::Array<String> >& result)
  1134. {
  1135. Element* element = assertElement(errorString, nodeId);
  1136. if (!element)
  1137. return;
  1138. result = buildArrayForElementAttributes(element);
  1139. }
  1140. void InspectorDOMAgent::requestNode(ErrorString*, const String& objectId, int* nodeId)
  1141. {
  1142. InjectedScript injectedScript = m_injectedScriptManager->injectedScriptForObjectId(objectId);
  1143. Node* node = injectedScript.nodeForObjectId(objectId);
  1144. if (node)
  1145. *nodeId = pushNodePathToFrontend(node);
  1146. else
  1147. *nodeId = 0;
  1148. }
  1149. // static
  1150. String InspectorDOMAgent::documentURLString(Document* document)
  1151. {
  1152. if (!document || document->url().isNull())
  1153. return "";
  1154. return document->url().string();
  1155. }
  1156. static String documentBaseURLString(Document* document)
  1157. {
  1158. return document->completeURL("").string();
  1159. }
  1160. PassRefPtr<TypeBuilder::DOM::Node> InspectorDOMAgent::buildObjectForNode(Node* node, int depth, NodeToIdMap* nodesMap)
  1161. {
  1162. int id = bind(node, nodesMap);
  1163. String nodeName;
  1164. String localName;
  1165. String nodeValue;
  1166. switch (node->nodeType()) {
  1167. case Node::TEXT_NODE:
  1168. case Node::COMMENT_NODE:
  1169. case Node::CDATA_SECTION_NODE:
  1170. nodeValue = node->nodeValue();
  1171. if (nodeValue.length() > maxTextSize) {
  1172. nodeValue = nodeValue.left(maxTextSize);
  1173. nodeValue.append(ellipsisUChar);
  1174. }
  1175. break;
  1176. case Node::ATTRIBUTE_NODE:
  1177. localName = node->localName();
  1178. break;
  1179. case Node::DOCUMENT_FRAGMENT_NODE:
  1180. case Node::DOCUMENT_NODE:
  1181. case Node::ELEMENT_NODE:
  1182. default:
  1183. nodeName = node->nodeName();
  1184. localName = node->localName();
  1185. break;
  1186. }
  1187. RefPtr<TypeBuilder::DOM::Node> value = TypeBuilder::DOM::Node::create()
  1188. .setNodeId(id)
  1189. .setNodeType(static_cast<int>(node->nodeType()))
  1190. .setNodeName(nodeName)
  1191. .setLocalName(localName)
  1192. .setNodeValue(nodeValue);
  1193. if (node->isContainerNode()) {
  1194. int nodeCount = innerChildNodeCount(node);
  1195. value->setChildNodeCount(nodeCount);
  1196. RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = buildArrayForContainerChildren(node, depth, nodesMap);
  1197. if (children->length() > 0)
  1198. value->setChildren(children.release());
  1199. }
  1200. if (node->isElementNode()) {
  1201. Element* element = toElement(node);
  1202. value->setAttributes(buildArrayForElementAttributes(element));
  1203. if (node->isFrameOwnerElement()) {
  1204. HTMLFrameOwnerElement* frameOwner = static_cast<HTMLFrameOwnerElement*>(node);
  1205. Frame* frame = frameOwner->contentFrame();
  1206. if (frame)
  1207. value->setFrameId(m_pageAgent->frameId(frame));
  1208. Document* doc = frameOwner->contentDocument();
  1209. if (doc)
  1210. value->setContentDocument(buildObjectForNode(doc, 0, nodesMap));
  1211. }
  1212. ElementShadow* shadow = element->shadow();
  1213. if (shadow) {
  1214. RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > shadowRoots = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
  1215. if (ShadowRoot* root = shadow->shadowRoot())
  1216. shadowRoots->addItem(buildObjectForNode(root, 0, nodesMap));
  1217. value->setShadowRoots(shadowRoots);
  1218. }
  1219. #if ENABLE(TEMPLATE_ELEMENT)
  1220. if (element->hasTagName(HTMLNames::templateTag))
  1221. value->setTemplateContent(buildObjectForNode(static_cast<HTMLTemplateElement*>(element)->content(), 0, nodesMap));
  1222. #endif
  1223. } else if (node->isDocumentNode()) {
  1224. Document* document = toDocument(node);
  1225. value->setDocumentURL(documentURLString(document));
  1226. value->setBaseURL(documentBaseURLString(document));
  1227. value->setXmlVersion(document->xmlVersion());
  1228. } else if (node->nodeType() == Node::DOCUMENT_TYPE_NODE) {
  1229. DocumentType* docType = static_cast<DocumentType*>(node);
  1230. value->setPublicId(docType->publicId());
  1231. value->setSystemId(docType->systemId());
  1232. value->setInternalSubset(docType->internalSubset());
  1233. } else if (node->isAttributeNode()) {
  1234. Attr* attribute = static_cast<Attr*>(node);
  1235. value->setName(attribute->name());
  1236. value->setValue(attribute->value());
  1237. }
  1238. return value.release();
  1239. }
  1240. PassRefPtr<TypeBuilder::Array<String> > InspectorDOMAgent::buildArrayForElementAttributes(Element* element)
  1241. {
  1242. RefPtr<TypeBuilder::Array<String> > attributesValue = TypeBuilder::Array<String>::create();
  1243. // Go through all attributes and serialize them.
  1244. if (!element->hasAttributes())
  1245. return attributesValue.release();
  1246. unsigned numAttrs = element->attributeCount();
  1247. for (unsigned i = 0; i < numAttrs; ++i) {
  1248. // Add attribute pair
  1249. const Attribute* attribute = element->attributeItem(i);
  1250. attributesValue->addItem(attribute->name().toString());
  1251. attributesValue->addItem(attribute->value());
  1252. }
  1253. return attributesValue.release();
  1254. }
  1255. PassRefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > InspectorDOMAgent::buildArrayForContainerChildren(Node* container, int depth, NodeToIdMap* nodesMap)
  1256. {
  1257. RefPtr<TypeBuilder::Array<TypeBuilder::DOM::Node> > children = TypeBuilder::Array<TypeBuilder::DOM::Node>::create();
  1258. if (depth == 0) {
  1259. // Special-case the only text child - pretend that container's children have been requested.
  1260. Node* firstChild = container->firstChild();
  1261. if (firstChild && firstChild->nodeType() == Node::TEXT_NODE && !firstChild->nextSibling()) {
  1262. children->addItem(buildObjectForNode(firstChild, 0, nodesMap));
  1263. m_childrenRequested.add(bind(container, nodesMap));
  1264. }
  1265. return children.release();
  1266. }
  1267. Node* child = innerFirstChild(container);
  1268. depth--;
  1269. m_childrenRequested.add(bind(container, nodesMap));
  1270. while (child) {
  1271. children->addItem(buildObjectForNode(child, depth, nodesMap));
  1272. child = innerNextSibling(child);
  1273. }
  1274. return children.release();
  1275. }
  1276. PassRefPtr<TypeBuilder::DOM::EventListener> InspectorDOMAgent::buildObjectForEventListener(const RegisteredEventListener& registeredEventListener, const AtomicString& eventType, Node* node, const String* objectGroupId)
  1277. {
  1278. RefPtr<EventListener> eventListener = registeredEventListener.listener;
  1279. Document* document = node->document();
  1280. RefPtr<TypeBuilder::DOM::EventListener> value = TypeBuilder::DOM::EventListener::create()
  1281. .setType(eventType)
  1282. .setUseCapture(registeredEventListener.useCapture)
  1283. .setIsAttribute(eventListener->isAttribute())
  1284. .setNodeId(pushNodePathToFrontend(node))
  1285. .setHandlerBody(eventListenerHandlerBody(document, eventListener.get()));
  1286. if (objectGroupId) {
  1287. ScriptValue functionValue = eventListenerHandler(document, eventListener.get());
  1288. if (!functionValue.hasNoValue()) {
  1289. Frame* frame = document->frame();
  1290. if (frame) {
  1291. ScriptState* scriptState = eventListenerHandlerScriptState(frame, eventListener.get());
  1292. if (scriptState) {
  1293. InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(scriptState);
  1294. if (!injectedScript.hasNoValue()) {
  1295. RefPtr<TypeBuilder::Runtime::RemoteObject> valueJson = injectedScript.wrapObject(functionValue, *objectGroupId);
  1296. value->setHandler(valueJson);
  1297. }
  1298. }
  1299. }
  1300. }
  1301. }
  1302. String sourceName;
  1303. String scriptId;
  1304. int lineNumber;
  1305. if (eventListenerHandlerLocation(node->document(), eventListener.get(), sourceName, scriptId, lineNumber)) {
  1306. RefPtr<TypeBuilder::Debugger::Location> location = TypeBuilder::Debugger::Location::create()
  1307. .setScriptId(scriptId)
  1308. .setLineNumber(lineNumber);
  1309. value->setLocation(location);
  1310. if (!sourceName.isEmpty())
  1311. value->setSourceName(sourceName);
  1312. }
  1313. return value.release();
  1314. }
  1315. Node* InspectorDOMAgent::innerFirstChild(Node* node)
  1316. {
  1317. node = node->firstChild();
  1318. while (isWhitespace(node))
  1319. node = node->nextSibling();
  1320. return node;
  1321. }
  1322. Node* InspectorDOMAgent::innerNextSibling(Node* node)
  1323. {
  1324. do {
  1325. node = node->nextSibling();
  1326. } while (isWhitespace(node));
  1327. return node;
  1328. }
  1329. Node* InspectorDOMAgent::innerPreviousSibling(Node* node)
  1330. {
  1331. do {
  1332. node = node->previousSibling();
  1333. } while (isWhitespace(node));
  1334. return node;
  1335. }
  1336. unsigned InspectorDOMAgent::innerChildNodeCount(Node* node)
  1337. {
  1338. unsigned count = 0;
  1339. Node* child = innerFirstChild(node);
  1340. while (child) {
  1341. count++;
  1342. child = innerNextSibling(child);
  1343. }
  1344. return count;
  1345. }
  1346. Node* InspectorDOMAgent::innerParentNode(Node* node)
  1347. {
  1348. if (node->isDocumentNode()) {
  1349. Document* document = toDocument(node);
  1350. return document->ownerElement();
  1351. }
  1352. return node->parentNode();
  1353. }
  1354. bool InspectorDOMAgent::isWhitespace(Node* node)
  1355. {
  1356. //TODO: pull ignoreWhitespace setting from the frontend and use here.
  1357. return node && node->nodeType() == Node::TEXT_NODE && node->nodeValue().stripWhiteSpace().length() == 0;
  1358. }
  1359. void InspectorDOMAgent::mainFrameDOMContentLoaded()
  1360. {
  1361. // Re-push document once it is loaded.
  1362. discardBindings();
  1363. if (m_state->getBoolean(DOMAgentState::documentRequested))
  1364. m_frontend->documentUpdated();
  1365. }
  1366. void InspectorDOMAgent::loadEventFired(Document* document)
  1367. {
  1368. Element* frameOwner = document->ownerElement();
  1369. if (!frameOwner)
  1370. return;
  1371. int frameOwnerId = m_documentNodeToIdMap.get(frameOwner);
  1372. if (!frameOwnerId)
  1373. return;
  1374. // Re-add frame owner element together with its new children.
  1375. int parentId = m_documentNodeToIdMap.get(innerParentNode(frameOwner));
  1376. m_frontend->childNodeRemoved(parentId, frameOwnerId);
  1377. unbind(frameOwner, &m_documentNodeToIdMap);
  1378. RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(frameOwner, 0, &m_documentNodeToIdMap);
  1379. Node* previousSibling = innerPreviousSibling(frameOwner);
  1380. int prevId = previousSibling ? m_documentNodeToIdMap.get(previousSibling) : 0;
  1381. m_frontend->childNodeInserted(parentId, prevId, value.release());
  1382. }
  1383. void InspectorDOMAgent::didInsertDOMNode(Node* node)
  1384. {
  1385. if (isWhitespace(node))
  1386. return;
  1387. // We could be attaching existing subtree. Forget the bindings.
  1388. unbind(node, &m_documentNodeToIdMap);
  1389. ContainerNode* parent = node->parentNode();
  1390. if (!parent)
  1391. return;
  1392. int parentId = m_documentNodeToIdMap.get(parent);
  1393. // Return if parent is not mapped yet.
  1394. if (!parentId)
  1395. return;
  1396. if (!m_childrenRequested.contains(parentId)) {
  1397. // No children are mapped yet -> only notify on changes of hasChildren.
  1398. m_frontend->childNodeCountUpdated(parentId, innerChildNodeCount(parent));
  1399. } else {
  1400. // Children have been requested -> return value of a new child.
  1401. Node* prevSibling = innerPreviousSibling(node);
  1402. int prevId = prevSibling ? m_documentNodeToIdMap.get(prevSibling) : 0;
  1403. RefPtr<TypeBuilder::DOM::Node> value = buildObjectForNode(node, 0, &m_documentNodeToIdMap);
  1404. m_frontend->childNodeInserted(parentId, prevId, value.release());
  1405. }
  1406. }
  1407. void InspectorDOMAgent::didRemoveDOMNode(Node* node)
  1408. {
  1409. if (isWhitespace(node))
  1410. return;
  1411. ContainerNode* parent = node->parentNode();
  1412. // If parent is not mapped yet -> ignore the event.
  1413. if (!m_documentNodeToIdMap.contains(parent))
  1414. return;
  1415. int parentId = m_documentNodeToIdMap.get(parent);
  1416. if (!m_childrenRequested.contains(parentId)) {
  1417. // No children are mapped yet -> only notify on changes of hasChildren.
  1418. if (innerChildNodeCount(parent) == 1)
  1419. m_frontend->childNodeCountUpdated(parentId, 0);
  1420. } else
  1421. m_frontend->childNodeRemoved(parentId, m_documentNodeToIdMap.get(node));
  1422. unbind(node, &m_documentNodeToIdMap);
  1423. }
  1424. void InspectorDOMAgent::willModifyDOMAttr(Element*, const AtomicString& oldValue, const AtomicString& newValue)
  1425. {
  1426. m_suppressAttributeModifiedEvent = (oldValue == newValue);
  1427. }
  1428. void InspectorDOMAgent::didModifyDOMAttr(Element* element, const AtomicString& name, const AtomicString& value)
  1429. {
  1430. bool shouldSuppressEvent = m_suppressAttributeModifiedEvent;
  1431. m_suppressAttributeModifiedEvent = false;
  1432. if (shouldSuppressEvent)
  1433. return;
  1434. int id = boundNodeId(element);
  1435. // If node is not mapped yet -> ignore the event.
  1436. if (!id)
  1437. return;
  1438. if (m_domListener)
  1439. m_domListener->didModifyDOMAttr(element);
  1440. m_frontend->attributeModified(id, name, value);
  1441. }
  1442. void InspectorDOMAgent::didRemoveDOMAttr(Element* element, const AtomicString& name)
  1443. {
  1444. int id = boundNodeId(element);
  1445. // If node is not mapped yet -> ignore the event.
  1446. if (!id)
  1447. return;
  1448. if (m_domListener)
  1449. m_domListener->didModifyDOMAttr(element);
  1450. m_frontend->attributeRemoved(id, name);
  1451. }
  1452. void InspectorDOMAgent::styleAttributeInvalidated(const Vector<Element*>& elements)
  1453. {
  1454. RefPtr<TypeBuilder::Array<int> > nodeIds = TypeBuilder::Array<int>::create();
  1455. for (unsigned i = 0, size = elements.size(); i < size; ++i) {
  1456. Element* element = elements.at(i);
  1457. int id = boundNodeId(element);
  1458. // If node is not mapped yet -> ignore the event.
  1459. if (!id)
  1460. continue;
  1461. if (m_domListener)
  1462. m_domListener->didModifyDOMAttr(element);
  1463. nodeIds->addItem(id);
  1464. }
  1465. m_frontend->inlineStyleInvalidated(nodeIds.release());
  1466. }
  1467. void InspectorDOMAgent::characterDataModified(CharacterData* characterData)
  1468. {
  1469. int id = m_documentNodeToIdMap.get(characterData);
  1470. if (!id) {
  1471. // Push text node if it is being created.
  1472. didInsertDOMNode(characterData);
  1473. return;
  1474. }
  1475. m_frontend->characterDataModified(id, characterData->data());
  1476. }
  1477. void InspectorDOMAgent::didInvalidateStyleAttr(Node* node)
  1478. {
  1479. int id = m_documentNodeToIdMap.get(node);
  1480. // If node is not mapped yet -> ignore the event.
  1481. if (!id)
  1482. return;
  1483. if (!m_revalidateStyleAttrTask)
  1484. m_revalidateStyleAttrTask = adoptPtr(new RevalidateStyleAttributeTask(this));
  1485. m_revalidateStyleAttrTask->scheduleFor(toElement(node));
  1486. }
  1487. void InspectorDOMAgent::didPushShadowRoot(Element* host, ShadowRoot* root)
  1488. {
  1489. int hostId = m_documentNodeToIdMap.get(host);
  1490. if (hostId)
  1491. m_frontend->shadowRootPushed(hostId, buildObjectForNode(root, 0, &m_documentNodeToIdMap));
  1492. }
  1493. void InspectorDOMAgent::willPopShadowRoot(Element* host, ShadowRoot* root)
  1494. {
  1495. int hostId = m_documentNodeToIdMap.get(host);
  1496. int rootId = m_documentNodeToIdMap.get(root);
  1497. if (hostId && rootId)
  1498. m_frontend->shadowRootPopped(hostId, rootId);
  1499. }
  1500. void InspectorDOMAgent::frameDocumentUpdated(Frame* frame)
  1501. {
  1502. Document* document = frame->document();
  1503. if (!document)
  1504. return;
  1505. Page* page = frame->page();
  1506. ASSERT(page);
  1507. if (frame != page->mainFrame())
  1508. return;
  1509. // Only update the main frame document, nested frame document updates are not required
  1510. // (will be handled by loadEventFired()).
  1511. setDocument(document);
  1512. }
  1513. Node* InspectorDOMAgent::nodeForPath(const String& path)
  1514. {
  1515. // The path is of form "1,HTML,2,BODY,1,DIV"
  1516. if (!m_document)
  1517. return 0;
  1518. Node* node = m_document.get();
  1519. Vector<String> pathTokens;
  1520. path.split(",", false, pathTokens);
  1521. if (!pathTokens.size())
  1522. return 0;
  1523. for (size_t i = 0; i < pathTokens.size() - 1; i += 2) {
  1524. bool success = true;
  1525. unsigned childNumber = pathTokens[i].toUInt(&success);
  1526. if (!success)
  1527. return 0;
  1528. if (childNumber >= innerChildNodeCount(node))
  1529. return 0;
  1530. Node* child = innerFirstChild(node);
  1531. String childName = pathTokens[i + 1];
  1532. for (size_t j = 0; child && j < childNumber; ++j)
  1533. child = innerNextSibling(child);
  1534. if (!child || child->nodeName() != childName)
  1535. return 0;
  1536. node = child;
  1537. }
  1538. return node;
  1539. }
  1540. void InspectorDOMAgent::pushNodeByPathToFrontend(ErrorString* errorString, const String& path, int* nodeId)
  1541. {
  1542. if (Node* node = nodeForPath(path))
  1543. *nodeId = pushNodePathToFrontend(node);
  1544. else
  1545. *errorString = "No node with given path found";
  1546. }
  1547. void InspectorDOMAgent::pushNodeByBackendIdToFrontend(ErrorString* errorString, BackendNodeId backendNodeId, int* nodeId)
  1548. {
  1549. if (!m_backendIdToNode.contains(backendNodeId)) {
  1550. *errorString = "No node with given backend id found";
  1551. return;
  1552. }
  1553. Node* node = m_backendIdToNode.get(backendNodeId).first;
  1554. String nodeGroup = m_backendIdToNode.get(backendNodeId).second;
  1555. *nodeId = pushNodePathToFrontend(node);
  1556. if (nodeGroup == "") {
  1557. m_backendIdToNode.remove(backendNodeId);
  1558. m_nodeGroupToBackendIdMap.find(nodeGroup)->value.remove(node);
  1559. }
  1560. }
  1561. PassRefPtr<TypeBuilder::Runtime::RemoteObject> InspectorDOMAgent::resolveNode(Node* node, const String& objectGroup)
  1562. {
  1563. Document* document = node->isDocumentNode() ? node->document() : node->ownerDocument();
  1564. Frame* frame = document ? document->frame() : 0;
  1565. if (!frame)
  1566. return 0;
  1567. InjectedScript injectedScript = m_injectedScriptManager->injectedScriptFor(mainWorldScriptState(frame));
  1568. if (injectedScript.hasNoValue())
  1569. return 0;
  1570. return injectedScript.wrapNode(node, objectGroup);
  1571. }
  1572. } // namespace WebCore
  1573. #endif // ENABLE(INSPECTOR)