2 (function (xpath, value) {
3 function getElement(xpath, within) {
5 if (within === null || within === undefined) {
8 result = document.evaluate(xpath, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
9 if (result.snapshotLength !== 1) {
12 return result.snapshotItem(0);
15 function isInput(element) {
16 if (element === null || element === undefined) {
19 return (element.tagName.toLowerCase() == "input");
22 function isTextArea(element) {
23 if (element === null || element === undefined) {
26 return (element.tagName.toLowerCase() == "textarea");
29 function isSelect(element) {
30 if (element === null || element === undefined) {
33 return (element.tagName.toLowerCase() == "select");
36 function deselectAllOptions(element) {
37 var i, l = element.options.length;
38 for (i = 0; i < l; i++) {
39 element.options[i].selected = false;
43 function xpathStringLiteral(s) {
44 if (s.indexOf('"') === -1)
46 if (s.indexOf("'") === -1)
48 return 'concat("' + s.replace(/"/g, '",\'"\',"') + '")';
51 function clickOnElement(element) {
52 // create a mouse click event
53 var event = document.createEvent('MouseEvents');
54 event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
56 // send click to element
57 element.dispatchEvent(event);
59 //After dispatching the event let's wait for 2 seconds at least...
60 return setTimeout(function () {
64 function dispatchChange(element) {
65 var tagName =element.tagName.toLowerCase();
66 var elementType = element.getAttribute("type");
67 if (tagName != "option" || (tagName == "input" && elementType == "radio")){
70 //Force the change when element is option
72 event = document.createEvent('HTMLEvents');
73 event.initEvent('change', true, false);
74 element.dispatchEvent(event);
78 function selectOptionOnElement(element, option, multiple) {
79 var polterAgent = window.__poltergeist;
80 var escapedOption = xpathStringLiteral(option);
81 // The value of an option is the normalized version of its text when it has no value attribute
82 var optionQuery = ".//option[@value = " + escapedOption + " or (not(@value) and normalize-space(.) = " + escapedOption + ")]";
83 var ids = polterAgent.find("xpath", optionQuery, element);
84 var polterNode = polterAgent.get(ids[0]);
85 var optionElement = polterNode.element;
87 if (multiple || !element.multiple) {
88 if (!optionElement.selected) {
89 clickOnElement(optionElement);
90 optionElement.selected = true;
92 return dispatchChange(optionElement);
95 deselectAllOptions(element);
96 clickOnElement(optionElement);
97 optionElement.selected = true;
98 return dispatchChange(optionElement);
101 function selectSetValue(element, value) {
103 if ((Array.isArray && Array.isArray(value)) || (value instanceof Array)) {
104 deselectAllOptions(element);
105 for (option in value) {
106 if (value.hasOwnProperty(option)) {
107 selectOptionOnElement(element, value[option], true);
113 selectOptionOnElement(element, value, false);
117 function selectRadioValue(element, value) {
118 if (element.value === value) {
119 clickOnElement(element);
120 element.checked=true;
121 dispatchChange(element);
125 var formElements = element.form.elements;
126 var name = element.getAttribute("name");
133 for (i = 0; i < formElements.length; i++) {
134 radioElement = formElements[i];
135 if (radioElement.tagName.toLowerCase() == 'input' && radioElement.type.toLowerCase() == 'radio' && radioElement.name === name) {
136 if (value === radioElement.value) {
137 clickOnElement(radioElement);
138 radioElement.checked=true;
139 dispatchChange(radioElement);
148 function inputSetValue(element, value, elementXpath) {
149 var allowedTypes = ['submit', 'image', 'button', 'reset'];
150 var elementType = element.type.toLowerCase();
151 var textLikeInputType = ['file', 'text', 'password', 'url', 'email', 'search', 'number', 'tel', 'range', 'date', 'month', 'week', 'time', 'datetime', 'color', 'datetime-local'];
153 if (allowedTypes.indexOf(elementType) !== -1) {
157 if (elementType == "checkbox") {
158 var booleanValue = false;
159 if (value == "1" || value == 1) {
161 } else if (value == "0" || value == 0) {
162 booleanValue = false;
164 if ((element.checked && !booleanValue) || (!element.checked && booleanValue)) {
165 clickOnElement(element);
166 dispatchChange(element);
171 if (elementType == "radio") {
172 return selectRadioValue(element, value);
175 if (textLikeInputType.indexOf(elementType) !== -1) {
176 return textAreaSetValue(elementXpath, value);
179 //No support for the moment for file stuff or other input types
184 function textAreaSetValue(elementXpath, value) {
185 var polterAgent = window.__poltergeist;
186 var ids = polterAgent.find("xpath", elementXpath, document);
187 var polterNode = polterAgent.get(ids[0]);
188 polterNode.set(value);
192 var node = getElement(xpath);
197 if (isSelect(node)) {
198 return selectSetValue(node, value);
202 return inputSetValue(node, value, xpath);
205 if (isTextArea(node)) {
206 return textAreaSetValue(xpath, value);
209 //for the moment everything else also to textArea stuff
210 return textAreaSetValue(xpath, value);
212 }('{{xpath}}', JSON.parse('{{ value }}')));