I'm working on a Chrome Extension. For now, there is one content script which returns an XPath of clicked element. Another content script adds an iframe
into the current html
page. In this iframe
there is a textarea
field which should show the xpath
of the element
when user clicks on it.
Unfortunately it does not work. The xpath
is correctly generated (tested using console.log(path)
but the command:
$('#xh-bar').contents().find('#product-path').val('some_val');
Doesn't alter the textarea
. Do you know where is the problem? I've tried to change the order of bar.js
and xpathget.js
but it did not help.
manifest.json
{
"manifest_version": 2,
"name": "Product",
"description": "This is a plugin collaborating with product.com",
"version": "1.0",
"browser_action": {
"default_icon": "spy-icon.png",
"default_popup": "popup.html",
"default_title": "Click here!"
},
"icons":{
"64":"spy-icon.png"
},
"background": {
"scripts": ["authentication.js"]
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery-3.1.1.min.js","xpathget.js","bar.js"]
}
],
"permissions": [
"activeTab",
"https://ajax.googleapis.com/",
"cookies",
"<all_urls>"
],
"web_accessible_resources": [
"bar.html",
],
"content_security_policy": "script-src 'self' https://ajax.googleapis.com; object-src 'self'"
}
xpathget.js
document.onclick = function (event) {
if (event === undefined) event = window.event; // IE hack
var target = 'target' in event ? event.target : event.srcElement; // another IE hack
var root = document.compatMode === 'CSS1Compat' ? document.documentElement : document.body;
var mxy = [event.clientX + root.scrollLeft, event.clientY + root.scrollTop];
var path = getPathTo(target);
var txy = getPageXY(target);
alert(path);
$('#xh-bar').contents().find('#product-spy-price').val('some_val'); # THIS SHOULD ALTER THE TEXTAREA
}
function getPathTo(element) {
if (element.id !== '')
return 'id("' + element.id + '")';
if (element === document.body)
return element.tagName;
var ix = 0;
var siblings = element.parentNode.childNodes;
for (var i = 0; i < siblings.length; i++) {
var sibling = siblings[i];
if (sibling === element)
return getPathTo(element.parentNode) + '/' + element.tagName + '[' + (ix + 1) + ']';
if (sibling.nodeType === 1 && sibling.tagName === element.tagName)
ix++;
}
}
function getPageXY(element) {
var x = 0, y = 0;
while (element) {
x += element.offsetLeft;
y += element.offsetTop;
element = element.offsetParent;
}
return [x, y];
}
bar.js
$(document).ready(function () {
$('body').append('<iframe src="chrome-extension://some_id/bar.html" id="xh-bar" class=""></iframe>');
});
And the generated iframe is:
<iframe src="chrome-extension://haifbndknpepdhjlcnmpoemlmomnidpe/bar.html" id="xh-bar" class="">HERE IS THE BAR.HTML</iframe>
This is the bar.html
in case it helps:
<!doctype html>
<html>
<head>
<title>Product Client</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="bootstrap/bootstrap.min.js"></script>
<script src="bootstrap/html5shiv.js"></script>
<script src="bootstrap/respond.min.js"></script>
<script src="bootstrap/usebootstrap.js"></script>
<script src="popup.js"></script>
<script src="productspy.js"></script>
<script src="xpathget.js"></script>
<script src="jsplugins/jquery.cookie.js"></script>
<script src="authentication.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css">
<link href="theme/bootstrap.css" rel="stylesheet">
<link href="theme/usebootstrap.css" rel="stylesheet">
</head>
<body>
<div class="smaller">
<h1>Product Client - Select the product price</h1>
<hr>
<form class="form-horizontal">
<fieldset>
<!-- Form Name -->
<legend>Form Name</legend>
<!-- Text input-->
<div class="form-group">
<label class="col-md-4 control-label" for="textinput">Product Name</label>
<div class="col-md-4">
<input id="textinput" name="textinput" type="text" placeholder="Nissan Patrol"
class="form-control input-md" required="">
</div>
</div>
<!-- Textarea -->
<div class="form-group">
<label class="col-md-4 control-label" for="price">Price</label>
<div class="col-md-4">
<textarea class="form-control" id="product-spy-price" name="price" readonly>This will show the price</textarea>
</div>
</div>
<!-- Button -->
<div class="form-group">
<label class="col-md-4 control-label" for="submit">Send product</label>
<div class="col-md-4">
<button id="submit" name="submit" class="btn btn-primary">Send</button>
</div>
</div>
</fieldset>
</form>
</div>
</body>
</html>
This is in console after: console.log($('#xh-bar').contents());
Uncaught SecurityError: Failed to read the 'contentDocument' property from 'HTMLIFrameElement': Blocked a frame with origin "http://stackoverflow.com" from accessing a frame with origin "chrome-extension://haifbndknpepdhjlcnmpoemlmomnidpe". The frame requesting access has a protocol of "http", the frame being accessed has a protocol of "chrome-extension". Protocols must match.
$('#xh-bar').contents()
return when logged to console? – charlietflpostMessage
API. Also look into settingdocument.domain
in the iframe – charlietfl