From 3ed8c1ddd3f8e92938d826d1856dfa51b7ccd5a4 Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 12 Aug 2011 15:52:31 -0700 Subject: [PATCH 1/8] Ignored some files --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 7f1cf67..bf60e9f 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ static-files/webxray.js browser-addon/chrome/webxray.js src/settings.local.js static-files/mix-master-dialog +.idea/ \ No newline at end of file From 7eca5a3a02f71dbb9e7e9c2b8c5894102a4b7653 Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 12 Aug 2011 16:16:10 -0700 Subject: [PATCH 2/8] updated the bookmarklet to use the first iframe document instead if available as the root document --- src/get-bookmarklet-url.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/get-bookmarklet-url.js b/src/get-bookmarklet-url.js index 9f738cd..645345b 100644 --- a/src/get-bookmarklet-url.js +++ b/src/get-bookmarklet-url.js @@ -7,7 +7,7 @@ var Webxray = (function() { getBookmarkletURL: function getBookmarkletURL(baseURI) { baseURI = baseURI || document.baseURI; - var baseCode = "(function(){var script=document.createElement('script');script.src='http://localhost:8000/webxray.js';script.className='webxray';document.head.appendChild(script);})();"; + var baseCode = '(function(){var a=document.getElementsByTagName("iframe")[0],a=a?a.contentDocument:document,b=a.createElement("script");b.src="http://localhost:8000/webxray.js";b.className="webxray";a.head.appendChild(b)})();'; var code = baseCode.replace('http://localhost:8000/', baseURI); return 'javascript:' + code; From f2e53608ed9ac594bb445f7f372b21710786cabd Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 12 Aug 2011 16:57:46 -0700 Subject: [PATCH 3/8] Added the option to press 'X' to get the XPath of the currently focused element --- src/input.js | 4 ++++ src/mix-master.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/input.js b/src/input.js index 97342e8..a4ab136 100644 --- a/src/input.js +++ b/src/input.js @@ -111,6 +111,10 @@ case keys.I: mixMaster.infoForFocusedElement(); return true; + + case keys.X: + mixMaster.xpathForFocusedElement(); + return true; case keys.SPACE: if (pressed[keys.C]) { diff --git a/src/mix-master.js b/src/mix-master.js index d8833ab..2219ecf 100644 --- a/src/mix-master.js +++ b/src/mix-master.js @@ -95,6 +95,29 @@ html = '' + html + ''; return $(html); }, + createXpathFromElement: function(elem) { + /** + * Taken from the XPath function in Aardvark + * http://karmatics.com/aardvark/ + */ + var path = ""; + for (; elem && elem.nodeType == 1; elem = elem.parentNode) { + var index = 1; + for (var sib = elem.previousSibling; sib; sib = sib.previousSibling) { + if (sib.nodeType == 1 && sib.tagName == elem.tagName) + index++; + } + var xname = "xhtml:" + elem.tagName.toLowerCase(); + if (elem.id) { + xname += "[@id='" + elem.id + "']"; + } else { + if (index > 1) + xname += "[" + index + "]"; + } + path = "/" + xname + path; + } + return path; + }, deleteFocusedElement: function deleteFocusedElement() { var elementToDelete = focused.getPrimaryElement(); if (elementToDelete) { @@ -126,6 +149,11 @@ open(url, 'info'); } }, + xpathForFocusedElement: function xpathForFocusedElement() { + var element = focused.getPrimaryElement(); + var xpath = self.createXpathFromElement(element); + alert(xpath); + }, replaceElement: function(elementToReplace, html) { var newContent = self.htmlToJQuery(html); runCommand("ReplaceWithCmd", { From c7144efdc6a649db9f2e86dd16263e3902ba0e3c Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Tue, 16 Aug 2011 17:18:54 -0700 Subject: [PATCH 4/8] A more compact and user-friendly Xpath method --- src/mix-master.js | 53 +++++++++++++++++++++++++++++------------------ 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/src/mix-master.js b/src/mix-master.js index 2219ecf..5d89ed2 100644 --- a/src/mix-master.js +++ b/src/mix-master.js @@ -95,28 +95,41 @@ html = '' + html + ''; return $(html); }, - createXpathFromElement: function(elem) { - /** - * Taken from the XPath function in Aardvark - * http://karmatics.com/aardvark/ - */ - var path = ""; - for (; elem && elem.nodeType == 1; elem = elem.parentNode) { - var index = 1; - for (var sib = elem.previousSibling; sib; sib = sib.previousSibling) { - if (sib.nodeType == 1 && sib.tagName == elem.tagName) - index++; + createXpathFromElement: function xpathFromElement(doc, element) { + if (element == doc || !element) { + return "/"; + } + + var nodeList; + if (element.id) { + nodeList = doc.evaluate("//*[@id='" + element.id + "']", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + if (nodeList.snapshotLength == 1) { + return "//*[@id='" + element.id + "']"; } - var xname = "xhtml:" + elem.tagName.toLowerCase(); - if (elem.id) { - xname += "[@id='" + elem.id + "']"; - } else { - if (index > 1) - xname += "[" + index + "]"; + } + + var parentSelector = "", + relativeElement = doc; + + if (element.parentNode != doc) { + parentSelector = xpathFromElement(doc, element.parentNode); + // TODO: extract our evaluate someplace so changes are easier + relativeElement = doc.evaluate(parentSelector, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + } + + nodeList = doc.evaluate(element.nodeName, relativeElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + + if (nodeList.snapshotLength == 1) { + return (parentSelector + "/" + element.nodeName).trim(); + } else { + for (var i = 0; i < nodeList.snapshotLength; ++i) { + if (element == nodeList.snapshotItem(i)) { + return (parentSelector + "/" + element.nodeName + "[" + (i + 1) + "]").trim(); + } } - path = "/" + xname + path; + + throw new Error("Node not found by tag name"); } - return path; }, deleteFocusedElement: function deleteFocusedElement() { var elementToDelete = focused.getPrimaryElement(); @@ -151,7 +164,7 @@ }, xpathForFocusedElement: function xpathForFocusedElement() { var element = focused.getPrimaryElement(); - var xpath = self.createXpathFromElement(element); + var xpath = self.createXpathFromElement(document, element); alert(xpath); }, replaceElement: function(elementToReplace, html) { From 22e42355579a2cfce87cbed8433f8e09761edd52 Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Tue, 16 Aug 2011 17:29:53 -0700 Subject: [PATCH 5/8] ignore .DS_Store --- .gitignore | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index bf60e9f..7395241 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,5 @@ static-files/webxray.js browser-addon/chrome/webxray.js src/settings.local.js static-files/mix-master-dialog -.idea/ \ No newline at end of file +.idea/ +.DS_Store From 89252bbf70038f09c54aff444f4ec3cb97869bdb Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 11 Nov 2011 17:04:14 -0800 Subject: [PATCH 6/8] Added XPath dialog option (X) --- .gitignore | 2 ++ src/get-bookmarklet-url.js | 1 + src/input.js | 8 +++++- src/locale/en.js | 3 ++- src/mix-master.js | 48 ++++++++++++++++++++++++++++++++++ static-files/xpath-dialog.html | 28 ++++++++++++++++++++ 6 files changed, 88 insertions(+), 2 deletions(-) create mode 100644 static-files/xpath-dialog.html diff --git a/.gitignore b/.gitignore index 7f1cf67..7395241 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ static-files/webxray.js browser-addon/chrome/webxray.js src/settings.local.js static-files/mix-master-dialog +.idea/ +.DS_Store diff --git a/src/get-bookmarklet-url.js b/src/get-bookmarklet-url.js index 9f738cd..94b572c 100644 --- a/src/get-bookmarklet-url.js +++ b/src/get-bookmarklet-url.js @@ -8,6 +8,7 @@ var Webxray = (function() { baseURI = baseURI || document.baseURI; var baseCode = "(function(){var script=document.createElement('script');script.src='http://localhost:8000/webxray.js';script.className='webxray';document.head.appendChild(script);})();"; + var baseCode = '(function(){var doc=document.getElementsByTagName("iframe")[0],doc=doc?doc.contentDocument:document,script=doc.createElement("script");script.src="http://localhost:8000/webxray.js";script.className="webxray";doc.head.appendChild(script)})();'; var code = baseCode.replace('http://localhost:8000/', baseURI); return 'javascript:' + code; diff --git a/src/input.js b/src/input.js index 15e661f..4098dde 100644 --- a/src/input.js +++ b/src/input.js @@ -318,7 +318,8 @@ {key: 'RIGHT', cmd: 'redo'}, {key: 'UP', cmd: 'dom-ascend'}, {key: 'DOWN', cmd: 'dom-descend'}, - {key: 'P', cmd: 'uproot'} + {key: 'P', cmd: 'uproot'}, + {key: 'X', cmd: 'xpath'} ], showKeyboardHelp: function() { var help = jQuery.createKeyboardHelpReference(self.keyboardHelp); @@ -345,6 +346,11 @@ P: function() { persistence.saveHistoryToDOM(); jQuery.openUprootDialog(self); + }, + X: function() { + mixMaster.xpathForFocusedElement({ + input: self + }); } }); diff --git a/src/locale/en.js b/src/locale/en.js index fd9d07f..b6641d0 100644 --- a/src/locale/en.js +++ b/src/locale/en.js @@ -89,6 +89,7 @@ "redo": "Redo", "dom-ascend": "Ascend to parent element", "dom-descend": "Descend to child element", - "uproot": "Publish your remix" + "uproot": "Publish your remix", + "xpath": "Get the element's XPath" }); })(jQuery); \ No newline at end of file diff --git a/src/mix-master.js b/src/mix-master.js index 6985c71..9a42fd3 100644 --- a/src/mix-master.js +++ b/src/mix-master.js @@ -95,6 +95,42 @@ html = '' + html + ''; return $(html); }, + createXpathFromElement: function xpathFromElement(doc, element) { + if (element == doc || !element) { + return "/"; + } + + var nodeList; + if (element.id) { + nodeList = doc.evaluate("//*[@id='" + element.id + "']", doc, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + if (nodeList.snapshotLength == 1) { + return "//*[@id='" + element.id + "']"; + } + } + + var parentSelector = "", + relativeElement = doc; + + if (element.parentNode != doc) { + parentSelector = xpathFromElement(doc, element.parentNode); + // TODO: extract our evaluate someplace so changes are easier + relativeElement = doc.evaluate(parentSelector, doc, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue; + } + + nodeList = doc.evaluate(element.nodeName, relativeElement, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null); + + if (nodeList.snapshotLength == 1) { + return (parentSelector + "/" + element.nodeName).trim(); + } else { + for (var i = 0; i < nodeList.snapshotLength; ++i) { + if (element == nodeList.snapshotItem(i)) { + return (parentSelector + "/" + element.nodeName + "[" + (i + 1) + "]").trim(); + } + } + + throw new Error("Node not found by tag name"); + } + }, deleteFocusedElement: function deleteFocusedElement() { var elementToDelete = focused.getPrimaryElement(); if (elementToDelete) { @@ -126,6 +162,18 @@ open(url, 'info'); } }, + xpathForFocusedElement: function xpathForFocusedElement(options) { + var element = focused.getPrimaryElement(); + var xpath = self.createXpathFromElement(document, element); + //alert(xpath); + jQuery.simpleModalDialog({ + input: options.input, + url: 'xpath-dialog.html', + payload: JSON.stringify({ + xpath: xpath + }) + }); + }, replaceElement: function(elementToReplace, html) { var newContent = self.htmlToJQuery(html); runCommand("ReplaceWithCmd", { diff --git a/static-files/xpath-dialog.html b/static-files/xpath-dialog.html new file mode 100644 index 0000000..2ee561c --- /dev/null +++ b/static-files/xpath-dialog.html @@ -0,0 +1,28 @@ + + +Get Element XPath + +
+
+
Close +
+
+ +
+ +
+
+ + From 817ffc220f71e065c039e31b0938c7830b8c0f79 Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 11 Nov 2011 17:50:58 -0800 Subject: [PATCH 7/8] Added baseURI for xpath-dialog.html --- src/mix-master.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/mix-master.js b/src/mix-master.js index 9a42fd3..3a96e46 100644 --- a/src/mix-master.js +++ b/src/mix-master.js @@ -165,10 +165,9 @@ xpathForFocusedElement: function xpathForFocusedElement(options) { var element = focused.getPrimaryElement(); var xpath = self.createXpathFromElement(document, element); - //alert(xpath); jQuery.simpleModalDialog({ input: options.input, - url: 'xpath-dialog.html', + url: jQuery.webxraySettings.baseURI + 'xpath-dialog.html', payload: JSON.stringify({ xpath: xpath }) From a0e08454f6accb9d8de294b238de995a0b9a62f5 Mon Sep 17 00:00:00 2001 From: Eliseo Soto Date: Fri, 11 Nov 2011 17:56:33 -0800 Subject: [PATCH 8/8] Fixed .gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 7395241..65a7d10 100644 --- a/.gitignore +++ b/.gitignore @@ -2,5 +2,8 @@ static-files/webxray.js browser-addon/chrome/webxray.js src/settings.local.js static-files/mix-master-dialog +/locale +/src/locale/*.json +~/src/locale/en.json .idea/ .DS_Store