annotate vendor/jcalderonzumba/mink-phantomjs-driver/src/Resources/Script/set_value.js.twig @ 19:fa3358dc1485 tip

Add ndrum files
author Chris Cannam
date Wed, 28 Aug 2019 13:14:47 +0100
parents 4c8ae668cc8c
children
rev   line source
Chris@0 1 {% autoescape 'js' %}
Chris@0 2 (function (xpath, value) {
Chris@0 3 function getElement(xpath, within) {
Chris@0 4 var result;
Chris@0 5 if (within === null || within === undefined) {
Chris@0 6 within = document;
Chris@0 7 }
Chris@0 8 result = document.evaluate(xpath, within, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
Chris@0 9 if (result.snapshotLength !== 1) {
Chris@0 10 return null;
Chris@0 11 }
Chris@0 12 return result.snapshotItem(0);
Chris@0 13 }
Chris@0 14
Chris@0 15 function isInput(element) {
Chris@0 16 if (element === null || element === undefined) {
Chris@0 17 return false;
Chris@0 18 }
Chris@0 19 return (element.tagName.toLowerCase() == "input");
Chris@0 20 }
Chris@0 21
Chris@0 22 function isTextArea(element) {
Chris@0 23 if (element === null || element === undefined) {
Chris@0 24 return false;
Chris@0 25 }
Chris@0 26 return (element.tagName.toLowerCase() == "textarea");
Chris@0 27 }
Chris@0 28
Chris@0 29 function isSelect(element) {
Chris@0 30 if (element === null || element === undefined) {
Chris@0 31 return false;
Chris@0 32 }
Chris@0 33 return (element.tagName.toLowerCase() == "select");
Chris@0 34 }
Chris@0 35
Chris@0 36 function deselectAllOptions(element) {
Chris@0 37 var i, l = element.options.length;
Chris@0 38 for (i = 0; i < l; i++) {
Chris@0 39 element.options[i].selected = false;
Chris@0 40 }
Chris@0 41 }
Chris@0 42
Chris@0 43 function xpathStringLiteral(s) {
Chris@0 44 if (s.indexOf('"') === -1)
Chris@0 45 return '"' + s + '"';
Chris@0 46 if (s.indexOf("'") === -1)
Chris@0 47 return "'" + s + "'";
Chris@0 48 return 'concat("' + s.replace(/"/g, '",\'"\',"') + '")';
Chris@0 49 }
Chris@0 50
Chris@0 51 function clickOnElement(element) {
Chris@0 52 // create a mouse click event
Chris@0 53 var event = document.createEvent('MouseEvents');
Chris@0 54 event.initMouseEvent('click', true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
Chris@0 55
Chris@0 56 // send click to element
Chris@0 57 element.dispatchEvent(event);
Chris@0 58
Chris@0 59 //After dispatching the event let's wait for 2 seconds at least...
Chris@0 60 return setTimeout(function () {
Chris@0 61 }, 2);
Chris@0 62 }
Chris@0 63
Chris@0 64 function dispatchChange(element) {
Chris@0 65 var tagName =element.tagName.toLowerCase();
Chris@0 66 var elementType = element.getAttribute("type");
Chris@0 67 if (tagName != "option" || (tagName == "input" && elementType == "radio")){
Chris@0 68 return true;
Chris@0 69 }
Chris@0 70 //Force the change when element is option
Chris@0 71 var event;
Chris@0 72 event = document.createEvent('HTMLEvents');
Chris@0 73 event.initEvent('change', true, false);
Chris@0 74 element.dispatchEvent(event);
Chris@0 75 return true;
Chris@0 76 }
Chris@0 77
Chris@0 78 function selectOptionOnElement(element, option, multiple) {
Chris@0 79 var polterAgent = window.__poltergeist;
Chris@0 80 var escapedOption = xpathStringLiteral(option);
Chris@0 81 // The value of an option is the normalized version of its text when it has no value attribute
Chris@0 82 var optionQuery = ".//option[@value = " + escapedOption + " or (not(@value) and normalize-space(.) = " + escapedOption + ")]";
Chris@0 83 var ids = polterAgent.find("xpath", optionQuery, element);
Chris@0 84 var polterNode = polterAgent.get(ids[0]);
Chris@0 85 var optionElement = polterNode.element;
Chris@0 86
Chris@0 87 if (multiple || !element.multiple) {
Chris@0 88 if (!optionElement.selected) {
Chris@0 89 clickOnElement(optionElement);
Chris@0 90 optionElement.selected = true;
Chris@0 91 }
Chris@0 92 return dispatchChange(optionElement);
Chris@0 93 }
Chris@0 94
Chris@0 95 deselectAllOptions(element);
Chris@0 96 clickOnElement(optionElement);
Chris@0 97 optionElement.selected = true;
Chris@0 98 return dispatchChange(optionElement);
Chris@0 99 }
Chris@0 100
Chris@0 101 function selectSetValue(element, value) {
Chris@0 102 var option;
Chris@0 103 if ((Array.isArray && Array.isArray(value)) || (value instanceof Array)) {
Chris@0 104 deselectAllOptions(element);
Chris@0 105 for (option in value) {
Chris@0 106 if (value.hasOwnProperty(option)) {
Chris@0 107 selectOptionOnElement(element, value[option], true);
Chris@0 108 }
Chris@0 109 }
Chris@0 110 return true;
Chris@0 111 }
Chris@0 112
Chris@0 113 selectOptionOnElement(element, value, false);
Chris@0 114 return true;
Chris@0 115 }
Chris@0 116
Chris@0 117 function selectRadioValue(element, value) {
Chris@0 118 if (element.value === value) {
Chris@0 119 clickOnElement(element);
Chris@0 120 element.checked=true;
Chris@0 121 dispatchChange(element);
Chris@0 122 return true;
Chris@0 123 }
Chris@0 124
Chris@0 125 var formElements = element.form.elements;
Chris@0 126 var name = element.getAttribute("name");
Chris@0 127 var radioElement, i;
Chris@0 128
Chris@0 129 if (!name) {
Chris@0 130 return null;
Chris@0 131 }
Chris@0 132
Chris@0 133 for (i = 0; i < formElements.length; i++) {
Chris@0 134 radioElement = formElements[i];
Chris@0 135 if (radioElement.tagName.toLowerCase() == 'input' && radioElement.type.toLowerCase() == 'radio' && radioElement.name === name) {
Chris@0 136 if (value === radioElement.value) {
Chris@0 137 clickOnElement(radioElement);
Chris@0 138 radioElement.checked=true;
Chris@0 139 dispatchChange(radioElement);
Chris@0 140 return true;
Chris@0 141 }
Chris@0 142 }
Chris@0 143 }
Chris@0 144
Chris@0 145 return null;
Chris@0 146 }
Chris@0 147
Chris@0 148 function inputSetValue(element, value, elementXpath) {
Chris@0 149 var allowedTypes = ['submit', 'image', 'button', 'reset'];
Chris@0 150 var elementType = element.type.toLowerCase();
Chris@0 151 var textLikeInputType = ['file', 'text', 'password', 'url', 'email', 'search', 'number', 'tel', 'range', 'date', 'month', 'week', 'time', 'datetime', 'color', 'datetime-local'];
Chris@0 152
Chris@0 153 if (allowedTypes.indexOf(elementType) !== -1) {
Chris@0 154 return null;
Chris@0 155 }
Chris@0 156
Chris@0 157 if (elementType == "checkbox") {
Chris@0 158 var booleanValue = false;
Chris@0 159 if (value == "1" || value == 1) {
Chris@0 160 booleanValue = true;
Chris@0 161 } else if (value == "0" || value == 0) {
Chris@0 162 booleanValue = false;
Chris@0 163 }
Chris@0 164 if ((element.checked && !booleanValue) || (!element.checked && booleanValue)) {
Chris@0 165 clickOnElement(element);
Chris@0 166 dispatchChange(element);
Chris@0 167 }
Chris@0 168 return true;
Chris@0 169 }
Chris@0 170
Chris@0 171 if (elementType == "radio") {
Chris@0 172 return selectRadioValue(element, value);
Chris@0 173 }
Chris@0 174
Chris@0 175 if (textLikeInputType.indexOf(elementType) !== -1) {
Chris@0 176 return textAreaSetValue(elementXpath, value);
Chris@0 177 }
Chris@0 178
Chris@0 179 //No support for the moment for file stuff or other input types
Chris@0 180 return null;
Chris@0 181
Chris@0 182 }
Chris@0 183
Chris@0 184 function textAreaSetValue(elementXpath, value) {
Chris@0 185 var polterAgent = window.__poltergeist;
Chris@0 186 var ids = polterAgent.find("xpath", elementXpath, document);
Chris@0 187 var polterNode = polterAgent.get(ids[0]);
Chris@0 188 polterNode.set(value);
Chris@0 189 return true;
Chris@0 190 }
Chris@0 191
Chris@0 192 var node = getElement(xpath);
Chris@0 193 if (node === null) {
Chris@0 194 return null;
Chris@0 195 }
Chris@0 196
Chris@0 197 if (isSelect(node)) {
Chris@0 198 return selectSetValue(node, value);
Chris@0 199 }
Chris@0 200
Chris@0 201 if (isInput(node)) {
Chris@0 202 return inputSetValue(node, value, xpath);
Chris@0 203 }
Chris@0 204
Chris@0 205 if (isTextArea(node)) {
Chris@0 206 return textAreaSetValue(xpath, value);
Chris@0 207 }
Chris@0 208
Chris@0 209 //for the moment everything else also to textArea stuff
Chris@0 210 return textAreaSetValue(xpath, value);
Chris@0 211
Chris@0 212 }('{{xpath}}', JSON.parse('{{ value }}')));
Chris@0 213 {% endautoescape %}