Posted By

preasha on 12/19/08


Tagged

js greasemonkey wkw wer kennt wen


Versions (?)

GM_BuddyGrabber


 / Published in: JavaScript
 

Because WKW is a german social community, wird auch deutsch Kommentiert: Sobald der Kalender-Bereich aufgerufen wird, gesellt sich oben in der Menüzeile ein neuer Punkt hinzu "Grab BDdays!". Ein klick darauf listet alle Buddies mitsamt Geburtstagen auf. Das Script ist noch nicht fertig. Das Kernfeature - der Export als VCS-Datei - fehlt noch, die Codedokumentation ist nicht sauber, genauso wie der Code an sich. Ein funktionierender Prototype quasi.

  1. // ==UserScript==
  2. // @name WKW-ElemGrabber
  3. // @namespace http://dev.3muskeeters.com
  4. // @description Grabs birthday dates of all your buddies
  5. // @include http://www.wer-kennt-wen.de/events/calendar/year/*
  6. // ==/UserScript==
  7.  
  8. /*
  9. - Grabs birthday dates, saves them in an Array ( key: BDAY00000 -> value: SURNAME NAME--X--DD-MM )
  10. */
  11.  
  12. //--------------------------------------------------------------------------------------
  13. // Some obvious prototyping
  14. //--------------------------------------------------------------------------------------
  15. //
  16. //
  17. // @method Checks wether a key already exists (using the double equal as log. op.)
  18. //
  19. Array.prototype.contains = function(strKey)
  20. {
  21. for (key in this)
  22. {
  23. if (key == strKey)
  24. {
  25. return true;
  26. }
  27. }
  28. return false;
  29. }
  30. //
  31. // @method Counts all contained (associative) keys
  32. //
  33. Array.prototype.getLength = function()
  34. {
  35. var i = 0;
  36. for each (k in this)
  37. {
  38. if (typeof(k) != "function")
  39. {
  40. i++;
  41. }
  42. }
  43. return i;
  44. }
  45. //
  46. //--------------------------------------------------------------------------------------
  47. //--------------------------------------------------------------------------------------
  48. //
  49. // @name CElementGrabber()
  50. // @class Baseclass for the whole grabbing thing.
  51. //
  52. function CElementGrabber()
  53. {
  54. var aTempNodes = new Array(); // holds all requested resources
  55. var addElement, getElement, dumpElements; // Dummy declaration, used by following closure
  56.  
  57. ( // BEGIN GETTER/SETTER CLOSURE
  58.  
  59. function()
  60. {
  61. var grabbedElements = new Array();
  62.  
  63. //
  64. // @name addElement(key, value)
  65. // @method Setter for array of grabbed elements
  66. // @params nothing to explain; only key has to be != null/undefined
  67. //
  68. addElement = function(key, value)
  69. {
  70. try
  71. {
  72. if (key)
  73. {
  74. //GM_log("addElement( " + key + " , " + value + " );");
  75. grabbedElements[key] = value;
  76. }
  77. else
  78. {
  79. throw new TypeError("Invalid element was returned from XPath query");
  80. }
  81. }
  82. catch (error)
  83. {
  84. alert(error.name + ": " + error.message);
  85. }
  86. };
  87. //
  88. // @name getElement(index)
  89. // @method Getter for array of grabbed elements
  90. // @params key: the key that should be returned; if key is omitted,
  91. // a whole "copy" of grabbedElements is being returned
  92. //
  93. getElement = function(key)
  94. {
  95. // no index passed => return complete "copy" of array
  96. if (key == undefined)
  97. {
  98. return (
  99. function(tmp)
  100. {
  101. //GM_log(" getElement(undefined): WHOLE ARRAY");
  102. return tmp;
  103. }
  104.  
  105. )(grabbedElements);
  106. }
  107. // valid index passed
  108. else if ((typeof(key) == "string") && key)
  109. {
  110. //GM_log("getElement( " + key + " ): " + grabbedElements[key]);
  111. return grabbedElements[key];
  112. }
  113. // invalid parameter
  114. else
  115. {
  116. return null;
  117. }
  118.  
  119. };
  120.  
  121. dumpElements = function()
  122. {
  123. //GM_log("Listing the content of grabbedElements:\n\n");
  124. for (key in grabbedElements)
  125. {
  126. GM_log("grabbedElements[ " + key + "] = " + grabbedElements[key])
  127. }
  128. };
  129. }
  130. )() // END GETTER/SETTER CLOSURE
  131.  
  132.  
  133.  
  134. //
  135. //--------------------------------------------------------------------------------------
  136. //--------------------------------------------------------------------------------------
  137. //
  138. // @name dump()
  139. // @method Privileged method, lists all grabbed Elements in error console
  140. //
  141. this.dump = function()
  142. {
  143. dumpElements();
  144. }
  145.  
  146.  
  147.  
  148. //
  149. //--------------------------------------------------------------------------------------
  150. //--------------------------------------------------------------------------------------
  151. //
  152. // @name grab(strRule, strURL)
  153. // @method privileged method; Executes a XPath query to the current document, if nodes are found
  154. // the given callback function is called with argsCallback as argument
  155. // @params strRule: string, xpath query to execute
  156. // aUrlList: array, contains all urls that should be filtered
  157. //
  158. this.grab = function(strXPathExpr, aUrlList)
  159. {
  160. //GM_log("ENTER grab");
  161. try
  162. {
  163. if (!!aUrlList) // when a url list is passed
  164. {
  165. for (var i = 0; i < aUrlList.length; i++)
  166. {
  167. if (!load(aUrlList[i], filterElements, [strXPathExpr])) // when load() wasn't successfull
  168. {
  169. throw new Error("Error occured while loading url: " + aUrlList[i]);
  170. }
  171. }
  172. //alert("All urls in aUrlList loaded");
  173. }
  174. else // only the current document should be filtered
  175. {
  176. filterElements(strXPathExpr);
  177. }
  178. }
  179. catch (error)
  180. {
  181. alert("grab()->try-statement: " + error.name + ": " + error.message);
  182. return false;
  183. }
  184. //GM_log("LEAVE grab");
  185. }
  186.  
  187.  
  188.  
  189. //
  190. //--------------------------------------------------------------------------------------
  191. //--------------------------------------------------------------------------------------
  192. //
  193. // @name filterElements(strURL, strExpression)
  194. // @method callback function; Gets called through load(), applies a passed xpath to the
  195. // current document and passes each matched node to getBDayDetails()
  196. // @params strURL: string, the current url
  197. // strExpression: string, xpath to apply
  198. //
  199. function filterElements(strURL, aArgs)
  200. {
  201. //GM_log("ENTER filterElements");
  202. var result = document.evaluate( aArgs[0],
  203. aTempNodes[aArgs[1]],
  204. null,
  205. XPathResult.ORDERED_NODE_ITERATOR_TYPE,
  206. null
  207. );
  208. var currentNode =
  209. {
  210. count: 1,
  211. node: result.iterateNext()
  212. };
  213.  
  214. while (currentNode.node)
  215. {
  216. // there are nodes in result to iterate through
  217. try
  218. {
  219. getBDayDetails(currentNode.node, currentNode.count, strURL);
  220. currentNode.count++;
  221. currentNode.node = result.iterateNext();
  222. }
  223. catch (error)
  224. {
  225. alert("filterElements()->try-statement: " + error.name + ": " + error.message);
  226. return false;
  227. }
  228. }
  229. if (aArgs[1] == 11)
  230. {
  231. startInjecting();
  232. }
  233. return true;
  234. //GM_log("LEAVE filterElements");
  235. }
  236.  
  237.  
  238.  
  239. //
  240. //--------------------------------------------------------------------------------------
  241. //--------------------------------------------------------------------------------------
  242. //
  243. // @name getBDayDetails(nodeCapture, numIndex, strURL)
  244. // @method Callback function; Gets captured node, index of that node and some optionally passed
  245. // in arguments in a string.
  246. // @params nodeCapture: dom-node, the captured node
  247. // numIndex: number, the index of the node inside the whole captured collection
  248. // aPassedArgs: array, the optionally passed in arguments
  249. //
  250. function getBDayDetails(nodeCapture, numIndex, strURL)
  251. {
  252.  
  253. var aBirthday = new Array();
  254. var nodecollSpans = nodeCapture.parentNode.parentNode.parentNode.getElementsByTagName("span");
  255. for (var i = 0; i < nodecollSpans.length; i++)
  256. {
  257. if (nodecollSpans[i].getAttribute("class") == "day")
  258. {
  259. aBirthday["day"] = nodecollSpans[i].childNodes[0].nodeValue;
  260. i = nodecollSpans.length;
  261. }
  262.  
  263. }
  264.  
  265. var aREReturn = /^http:\/\/www\.wer-kennt-wen\.de\/events\/calendar\/year\/(\d{4,4})\/month\/(\d{1,2})/.exec(strURL);
  266.  
  267. // month
  268. aBirthday["month"] = aREReturn[2];
  269. // year
  270. aBirthday["year"] = aREReturn[1];
  271. // name of birthday child
  272. if (nodeCapture.hasAttribute("title")) // birthday of a buddy
  273. {
  274. if (nodeCapture.getAttribute("title").length)
  275. {
  276. // using unicode-ranges cause some dumbasses are using "funny" symbols
  277. // i am wondering why the wkw-team permitted those characters
  278. aBirthday["who"] = /([\u0000-\uFFFF]+)\swird\s\d{2,3}/.exec(nodeCapture.getAttribute("title"))[1];
  279. }
  280. }
  281. else // thats my own birthday, returning
  282. {
  283. return false;
  284. }
  285.  
  286. //GM_log(" Capture #" + numIndex + "/" + getElement("BDAY-COUNTER") + ": " + aBirthday["who"] + " -> " + aBirthday["day"] + "-" + aBirthday["month"] + "-" + aBirthday["year"]);
  287.  
  288. if (parseInt(getElement("BDAY-COUNTER")) >= 0)
  289. {
  290. // bday counter already exists, so we increment him by one
  291. addElement("BDAY-COUNTER", parseInt(getElement("BDAY-COUNTER")) + 1);
  292. }
  293. else
  294. {
  295. // bday coutner doesnt exist, so we create him
  296. addElement("BDAY-COUNTER", 1);
  297. }
  298. //GM_log(" Current BDay-Counter: " + getElement("BDAY-COUNTER"));
  299.  
  300. addElement(("BDAY" + decorateNumber(getElement("BDAY-COUNTER"), 5)), (aBirthday["who"] + "--X--" + aBirthday["month"] + "-" + aBirthday["day"]));
  301.  
  302.  
  303. return true;
  304. }
  305.  
  306.  
  307.  
  308. //
  309. //--------------------------------------------------------------------------------------
  310. //--------------------------------------------------------------------------------------
  311. //
  312. // @name decorateNumber(numInput, templength)
  313. // @method private method, takes a string and "fills" him up with zeros up to a legth
  314. // specified by numLength. If the passed in string is already longer than numLength
  315. // it will be returned without any modification.
  316. // @params numInput: string, number that should be decorated
  317. // numLength: number, the length numInput should be filled up to
  318. //
  319. function decorateNumber(numInput, numLength)
  320. {
  321. if (numInput.toString().length < numLength) {
  322.  
  323. var strTemp = new String();
  324. for (var i =0; i < numLength - String(numInput).length; i++)
  325. {
  326. strTemp += "0";
  327. }
  328. return strTemp + numInput.toString();
  329. }
  330. else
  331. {
  332. return numInput;
  333. }
  334.  
  335. }
  336.  
  337.  
  338.  
  339. //
  340. //--------------------------------------------------------------------------------------
  341. //--------------------------------------------------------------------------------------
  342. //
  343. // @name loadURL(strURL, cbFunc, aCbArgs)
  344. // @method private method; Requests the resource at the given url
  345. // @params strURL: str, url to request
  346. // cbFunc: function ref; callback function thats gonna be passed through
  347. // aCbArgs: array; arguments that are gonna be passed through
  348. //
  349. function load(strURL, cbFunc, aCbArgs)
  350. {
  351. //GM_log("ENTER load");
  352. if (new RegExp(/http\:\/\/[\w0-9-_\.@\/\+\?]+/).test(strURL))
  353. {
  354. var objReqDetails = {
  355. method: "GET",
  356. url: strURL,
  357. headers: {
  358. "User-Agent": "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.0.4)",
  359. "Accept": "application/atom+xml,application/xml,text/xml",
  360. "Referer": "http://www.wer-kennt-wen.de/events/calendar",
  361. "Cookie": document.cookie.split(/__utma=.*;\s(?=__utma=)/)[1],
  362. "Accept-Language": "de-de,en-us;q=0.7,en;q=0.3",
  363. "Accept-Encoding": "gzip,deflate",
  364. "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.7",
  365. "Keep-Alive": "300",
  366. "Connection": "keep-alive"
  367. },
  368. onerror: handleReqError,
  369. onreadystatechange: function(respDetails)
  370. {
  371. if (respDetails.readyState == 4)
  372. {
  373. interpretRespData(respDetails, strURL, cbFunc, aCbArgs);
  374. }
  375. }
  376. };
  377. GM_xmlhttpRequest(objReqDetails);
  378. //GM_log("LEAVE grab");
  379. return true;
  380. }
  381. else
  382. {
  383. alert("load: You gave me an invalid url");
  384. //GM_log("LEAVE grab");
  385. return false;
  386. }
  387. }
  388.  
  389.  
  390.  
  391. //
  392. //--------------------------------------------------------------------------------------
  393. //--------------------------------------------------------------------------------------
  394. //
  395. // @name interpretRespData(responseDetails, strURL, cbFunc, aCbArgs)
  396. // @method Joins the properties contained in responseDetails, and alerts the result
  397. // @params responseDetails: object, details about the request process
  398. // strURL: string; url of requested resource -> passed through
  399. // cbFunc: callback function; passed through
  400. // aCbArgs: array; arguments for callback function -> passed through
  401. //
  402. function interpretRespData(responseDetails, strURL, cbFunc, aCbArgs)
  403. {
  404. /*
  405. GM_log("ENTERED interpretRespData");
  406. GM_log(" interpretRespData-> complete. The request is completed and all response data is available in other fields");
  407. GM_log(" interpretRespData-> HTTP-Status: " + responseDetails.statusText);
  408. GM_log(" interpretRespData-> Response headers: " + responseDetails.responseHeaders);
  409. GM_log(" interpretRespData-> Status: " + responseDetails.status);
  410. */
  411.  
  412. var currIndex = changeDocElement(responseDetails.responseText);
  413. aCbArgs.push(currIndex)
  414. cbFunc(strURL, aCbArgs);
  415.  
  416. //GM_log("LEAVING interpretRespData");
  417. }
  418.  
  419.  
  420.  
  421. //
  422. //--------------------------------------------------------------------------------------
  423. //--------------------------------------------------------------------------------------
  424. function handleReqError(responseDetails)
  425. {
  426. //GM_log("ENTERED handleReqError");
  427.  
  428. var strMsg = "handleReqError-> During the request/response an error occured.\n" +
  429. "handleReqError-> Status text: " + responseDetails.statusText;
  430. alert(strMsg);
  431.  
  432. //GM_log("LEAVING handleReqError");
  433. }
  434.  
  435.  
  436.  
  437. //
  438. //--------------------------------------------------------------------------------------
  439. //--------------------------------------------------------------------------------------
  440. //
  441. // @name changeDocElement(strInnerHTML)
  442. // @method private method; replaces the current body with the one in strInnerHTML
  443. // @params strInnerHTML: string; contains the new html code
  444. //
  445. function changeDocElement(strInnerHTML)
  446. {
  447. var currIndex = aTempNodes.push(document.createElement("div")) - 1;
  448. aTempNodes[currIndex].innerHTML = /(\x3Cbody[\s\u0000-\uFFFF]*?\x3E)([\s\u0000-\uFFFF]*)(\x3C\/body\x3E)/.exec(strInnerHTML)[2];
  449. return currIndex;
  450. }
  451.  
  452.  
  453.  
  454. //
  455. //--------------------------------------------------------------------------------------
  456. //--------------------------------------------------------------------------------------
  457. this.save = function()
  458. {
  459.  
  460. // checking for bday counter inside the greasemonkey space
  461. if (getData("BDAY-COUNTER") == null)
  462. {
  463. // bday coutner doesnt exist, so we create him
  464. saveData("BDAY-COUNTER", 0);
  465. }
  466.  
  467. var numGrabbedElements = parseInt(getElement("BDAY-COUNTER"));
  468.  
  469. if (numGrabbedElements != NaN)
  470. {
  471. alert(" grabbedElements.length = " + getElement().getLength());
  472. alert(" numGrabbedElements = " + numGrabbedElements);
  473.  
  474. //dumpElements();
  475.  
  476. for (var i=1; i <= numGrabbedElements; i++)
  477. {
  478. alert("i: " + i + " / " + decorateNumber(i, 5));
  479. var strTmpKey = "BDAY" + decorateNumber(i, 5);
  480. alert(strTmpKey);
  481. var tmpValues = { key: strTmpKey,
  482. value: getElement(strTmpKey)
  483. };
  484. GM_log(" Saving: " + tmpValues.key + " -> " + tmpValues.value);
  485. saveData(tmpValues.key, tmpValues.value);
  486. saveData("BDAY-COUNTER", parseInt(getData("BDAY-COUNTER")) + 1);
  487. }
  488. alert("Everything saved!");
  489.  
  490. }
  491. else
  492. {
  493. return false;
  494. }
  495. }
  496.  
  497.  
  498.  
  499. //
  500. //--------------------------------------------------------------------------------------
  501. //--------------------------------------------------------------------------------------
  502. //
  503. // @name saveData(key, value)
  504. // @method Saving a key-value pair into the gm persistent memory
  505. // @params key: string, property name
  506. // value: string, value
  507. //
  508. function saveData(key, value)
  509. {
  510. if (!!key)
  511. {
  512. GM_setValue(key, value);
  513. }
  514. }
  515.  
  516.  
  517.  
  518. //
  519. //--------------------------------------------------------------------------------------
  520. //--------------------------------------------------------------------------------------
  521. //
  522. // @name getData(searchKey)
  523. // @method Looks for a key with searchKey as name and returns his value
  524. // @params searchKey: string, property name to search for
  525. //
  526. function getData(searchKey)
  527. {
  528. var value = GM_getValue(searchKey);
  529. if (value == undefined)
  530. {
  531. value = null;
  532. alert("No key \"" + searchKey + "\" found");
  533. }
  534. return value;
  535. }
  536.  
  537.  
  538.  
  539. function insertTable(refNode)
  540. {
  541. var aBuddies = new Array();
  542.  
  543.  
  544.  
  545.  
  546. // formular container
  547. var myForm = document.createElement("form");
  548. with (myForm)
  549. {
  550. setAttribute("action", "");
  551. setAttribute("method", "post");
  552. setAttribute("id", "myForm");
  553.  
  554. var n = document.createElement("div");
  555. n.setAttribute("id", "col1");
  556. n.setAttribute("class", "formColumn");
  557. appendChild(n);
  558.  
  559. n = document.createElement("div");
  560. n.setAttribute("id", "col2");
  561. n.setAttribute("class", "formColumn");
  562. appendChild(n);
  563.  
  564. n = document.createElement("div");
  565. n.setAttribute("id", "col3");
  566. n.setAttribute("class", "formColumn");
  567. appendChild(n);
  568.  
  569. n = document.createElement("div");
  570. n.setAttribute("id", "col4");
  571. n.setAttribute("class", "formColumn");
  572. appendChild(n);
  573.  
  574. n = document.createElement("br");
  575. n.setAttribute("class", "clearer");
  576. appendChild(n);
  577. }
  578.  
  579. // css für myForm
  580. GM_addStyle("#myForm { display: block; width: 100%; float: left; }");
  581. GM_addStyle(".formColumn { float: left; width: 24%; margin-top: 15px; margin-bottom: 35px; margin-left: 1%; }");
  582. GM_addStyle(".formColumn label { display:block; background-color:#f4f4f4; margin: 4px 0; padding: 2px 0; border: none; }");
  583. GM_addStyle(".formColumn label.accent { background-color: #e0e9f8; }");
  584. GM_addStyle(".formColumn label input { margin-right: 7px }");
  585. GM_addStyle(".clearer { clear: both; }")
  586. GM_addStyle("#col4 input { margin-top: 4px; margin-left: 15px; }");
  587.  
  588.  
  589. // myForm in dom einfügen, damit getElementById greift
  590. if (document.getElementById("myForm") == null)
  591. {
  592. refNode.appendChild(myForm);
  593. }
  594. else
  595. {
  596. refNode.replaceChild(myForm, document.getElementById("myForm"));
  597. }
  598.  
  599. // kontrollvariablen für contentbefüllung
  600. var counter = new Number(1);
  601. var nextStep = new Number(0);
  602. var linesPerCol = Math.ceil(parseInt(getElement("BDAY-COUNTER")) / 3);
  603.  
  604.  
  605. // contentspalten befüllen
  606. for (j = 1; j <= 3; j++)
  607. {
  608.  
  609. // zwischenziele setzen
  610. (j < 3) ? nextStep += linesPerCol : nextStep = parseInt(getElement("BDAY-COUNTER")) - 1;
  611.  
  612.  
  613. with (document.getElementById("col" + j))
  614. {
  615. var tmpLabel;
  616.  
  617. while (counter <= nextStep)
  618. {
  619. tmpLabel = document.createElement("label");
  620. if (counter % 2)
  621. {
  622. tmpLabel.setAttribute("class", "accent");
  623. }
  624. var tmpCheckbox = document.createElement("input");
  625. tmpCheckbox.setAttribute("type", "checkbox");
  626. tmpCheckbox.setAttribute("name", "name_" + aBuddies[counter]);
  627. tmpCheckbox.setAttribute("value", "value_" + counter);
  628. tmpCheckbox.setAttribute("checked", "true");
  629. var strRe = /([\u0000-\uFFFF]*)--X--([\u0000-\uFFFF]*)/.exec(getElement("BDAY" + decorateNumber(counter, 5)));
  630. var tmpTitle = document.createTextNode(strRe[1] + " (" + strRe[2] + ")");
  631. //var tmpBr = document.createElement("br");
  632.  
  633. tmpLabel.appendChild(tmpCheckbox);
  634. tmpLabel.appendChild(tmpTitle);
  635. //tmpLabel.appendChild(tmpBr);
  636.  
  637. appendChild(tmpLabel);
  638.  
  639. counter++;
  640. }
  641. }
  642. }
  643.  
  644. // button in vierte spalte einfügen
  645. var tmpButton = document.createElement("input");
  646. with (tmpButton)
  647. {
  648. setAttribute("type", "submit");
  649. setAttribute("name", "name_ABsenden");
  650. setAttribute("value", "Ausgewählte Exportieren");
  651. setAttribute("id", "myBtn");
  652. //addEventListener("click", cbOnSubmit, false);
  653. }
  654. document.getElementById("col4").appendChild(tmpButton);
  655.  
  656.  
  657.  
  658. }
  659.  
  660. function removeNodes(aNodeList)
  661. {
  662. while (aNodeList.length)
  663. {
  664. var n = aNodeList.pop();
  665. n.parentNode.removeChild(n);
  666. }
  667. }
  668.  
  669. function cbChangeSel(e)
  670. {
  671. var selPatterns = {
  672.  
  673. pattern: "//input[@type='checkbox']",
  674. all: function(refNode)
  675. {
  676. refNode.checked = true;
  677. },
  678. none: function(refNode)
  679. {
  680. refNode.checked = false;
  681. },
  682. invert: function(refNode)
  683. {
  684. if (refNode.checked)
  685. {
  686. refNode.checked = false;
  687. }
  688. else
  689. {
  690. refNode.checked = true;
  691. }
  692. }
  693.  
  694. };
  695. var result = document.evaluate(selPatterns.pattern, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  696.  
  697.  
  698. for (var i = 0; i < result.snapshotLength; i++)
  699. {
  700. selPatterns[e.target.id](result.snapshotItem(i));
  701. }
  702.  
  703. }
  704.  
  705.  
  706. function changeText(refNode)
  707. {
  708. with (refNode)
  709. {
  710. childNodes[1].childNodes[0].nodeValue = "Geburtstage als VCS-Termin exportieren";
  711.  
  712.  
  713. with (childNodes[3])
  714. {
  715. title = tagName;
  716. href = "javascript:void()";
  717. id = "all";
  718. addEventListener("click", cbChangeSel, false);
  719. childNodes[0].nodeValue = "Alle auswählen";
  720. }
  721.  
  722. with (childNodes[5])
  723. {
  724. title = tagName;
  725. href = "javascript:void()";
  726. id = "none";
  727. addEventListener("click", cbChangeSel, false);
  728. childNodes[0].nodeValue = "Auswahl aufheben";
  729. }
  730.  
  731. with (childNodes[7])
  732. {
  733. title = tagName;
  734. href = "javascript:void()";
  735. id = "invert";
  736. addEventListener("click", cbChangeSel, false);
  737. childNodes[0].nodeValue = "Auswahl umkehren";
  738. }
  739. }
  740. }
  741.  
  742. function cbClick(eventObj)
  743. {
  744. removeNodes(getRefNode("//div[@id='rahmen']/table/tbody/tr/td[@valign='top']/h2[1]/following-sibling::*"));
  745.  
  746. var targetNode = getRefNode("//div[@id='rahmen']/table/tbody/tr/td[@valign='top']");
  747. changeText(targetNode);
  748. insertTable(targetNode);
  749. }
  750.  
  751. function getRefNode(strXPath)
  752. {
  753. var result = document.evaluate(strXPath, document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  754. if (result.snapshotLength == 1)
  755. {
  756. return result.snapshotItem(0);
  757. }
  758. else
  759. {
  760. var aTmp = [];
  761. for (var i = 0; i < result.snapshotLength; i++)
  762. {
  763. aTmp.push(result.snapshotItem(i));
  764. }
  765. return aTmp;
  766. }
  767. }
  768.  
  769.  
  770. function startInjecting()
  771. {
  772. cbClick();
  773. }
  774.  
  775. } // END CLASS "CElementGrabber"
  776.  
  777.  
  778. function start()
  779. {
  780. var myGrabber = new CElementGrabber();
  781. var aUrls = [];
  782. for (var k = 1; k <= 12; k++)
  783. {
  784. aUrls.push("http://www.wer-kennt-wen.de/events/calendar/year/2009/month/" + k);
  785. }
  786. myGrabber.grab("//td[starts-with(@class,'thisMonth')]/div[@class='clearfix']/ul[@class='events']/li[@class='birthday']/a", aUrls);
  787. }
  788.  
  789. var res = document.evaluate("//div[@id='navigation']/ul/li[not(@class)][last()]", document, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
  790. var myRefNode = res.snapshotItem(0);
  791. var myClonedRefNode = myRefNode.cloneNode(true);
  792. with (myClonedRefNode.childNodes[0])
  793. {
  794. title = tagName;
  795. addEventListener("click", start, false);
  796. href = "javascript:void()";
  797. childNodes[0].nodeValue = "Grab BDays!";
  798. }
  799. myRefNode.parentNode.appendChild(myClonedRefNode);

Report this snippet  

You need to login to post a comment.