|
36 | 36 | if (el.hasAttribute(attr) &&
|
37 | 37 | el.getAttribute(attr).length > 0) {
|
38 | 38 | the_attr = el.getAttribute(attr);
|
| 39 | + if (the_attr.includes('"')) |
| 40 | + the_attr = the_attr.replace('"', '\\"'); |
| 41 | + if (the_attr.includes("'")) |
| 42 | + the_attr = the_attr.replace("'", "\\'"); |
39 | 43 | selector += '[' + attr + '="' + the_attr + '"]';
|
40 | 44 | path.unshift(selector);
|
41 | 45 | break;
|
|
56 | 60 | var ssOccurrences = function(string, subString, allowOverlapping) {
|
57 | 61 | string += '';
|
58 | 62 | subString += '';
|
59 |
| - if (subString.length <= 0) { |
| 63 | + if (subString.length <= 0) |
60 | 64 | return (string.length + 1);
|
61 |
| - } |
62 | 65 | var n = 0;
|
63 | 66 | var pos = 0;
|
64 | 67 | var step = allowOverlapping ? 1 : subString.length;
|
|
142 | 145 | contains_tags.push('a');
|
143 | 146 | contains_tags.push('b');
|
144 | 147 | contains_tags.push('i');
|
145 |
| - contains_tags.push('td'); |
146 | 148 | contains_tags.push('h1');
|
147 | 149 | contains_tags.push('h2');
|
148 | 150 | contains_tags.push('h3');
|
149 | 151 | contains_tags.push('h4');
|
| 152 | + contains_tags.push('td'); |
150 | 153 | contains_tags.push('code');
|
151 | 154 | contains_tags.push('button');
|
| 155 | + contains_tags.push('strong'); |
152 | 156 | all_by_tag = [];
|
| 157 | + inner_text = el.innerText.trim(); |
153 | 158 | for (var i = 0; i < contains_tags.length; i++) {
|
154 | 159 | if (tag_name == contains_tags[i] &&
|
155 |
| - el.innerText.trim().length > 1 && |
156 |
| - el.innerText.trim().length <= 64) |
| 160 | + inner_text.length >= 2 && inner_text.length <= 64) |
157 | 161 | {
|
158 | 162 | t_count = 0;
|
159 |
| - inner_text = el.innerText.trim(); |
160 | 163 | all_by_tag[i] = document.querySelectorAll(contains_tags[i]);
|
161 | 164 | for (var j = 0; j < all_by_tag[i].length; j++) {
|
162 | 165 | if (all_by_tag[i][j].innerText.includes(inner_text))
|
163 |
| - { |
164 | 166 | t_count += 1;
|
165 |
| - } |
166 | 167 | }
|
167 |
| - if (t_count === 1 && !inner_text.includes('\n')) |
168 |
| - { |
| 168 | + if (t_count === 1 && !inner_text.includes('\n')) { |
169 | 169 | inner_text = inner_text.replace("'", "\\'");
|
170 | 170 | inner_text = inner_text.replace('"', '\\"');
|
171 | 171 | return tag_name += ':contains("'+inner_text+'")';
|
172 | 172 | }
|
173 | 173 | }
|
174 | 174 | }
|
| 175 | + if (tag_name == "span" && inner_text.length > 1 && inner_text.length <= 64) |
| 176 | + { |
| 177 | + parent_element = el.parentElement; |
| 178 | + parent_tag_name = parent_element.tagName.toLowerCase(); |
| 179 | + grand_element = parent_element.parentElement; |
| 180 | + grand_tag_name = grand_element.tagName.toLowerCase(); |
| 181 | + if (parent_tag_name == "button" || grand_tag_name == "button") { |
| 182 | + qsa_element = "span"; |
| 183 | + if (parent_tag_name == "button") |
| 184 | + qsa_element = "button > span"; |
| 185 | + else { qsa_element = "button > "+parent_tag_name+" > span" } |
| 186 | + t_count = 0; |
| 187 | + all_el_found = document.querySelectorAll(qsa_element); |
| 188 | + for (var j = 0; j < all_el_found.length; j++) { |
| 189 | + if (all_el_found[j].innerText.includes(inner_text)) |
| 190 | + t_count += 1; |
| 191 | + } |
| 192 | + if (t_count === 1 && !inner_text.includes('\n')) { |
| 193 | + inner_text = inner_text.replace("'", "\\'"); |
| 194 | + inner_text = inner_text.replace('"', '\\"'); |
| 195 | + return qsa_element += ':contains("'+inner_text+'")'; |
| 196 | + } |
| 197 | + } |
| 198 | + } |
175 | 199 | best_selector = selector_by_id;
|
176 | 200 | lowest_child_count = child_count_by_id;
|
177 | 201 | for (var i = 0; i < non_id_attributes.length; i++) {
|
|
187 | 211 |
|
188 | 212 | var AllTheAnchorTags = document.getElementsByTagName("a");
|
189 | 213 | for (var i = 0; i < AllTheAnchorTags.length; i++) {
|
190 |
| - AllTheAnchorTags[i].addEventListener('click', |
191 |
| - function (event) { |
192 |
| - if (this.origin && |
193 |
| - this.origin != 'null' && |
194 |
| - this.origin != document.location.origin) |
195 |
| - { |
196 |
| - if (this.hasAttribute('href')) |
197 |
| - { |
198 |
| - event.preventDefault(); |
199 |
| - window.open(this.href, '_blank').focus(); |
200 |
| - } |
| 214 | + AllTheAnchorTags[i].addEventListener('click', function (event) { |
| 215 | + if (this.origin && |
| 216 | + this.origin != 'null' && |
| 217 | + this.origin != document.location.origin) |
| 218 | + { |
| 219 | + if (this.hasAttribute('href')) { |
| 220 | + event.preventDefault(); |
| 221 | + window.open(this.href, '_blank').focus(); |
201 | 222 | }
|
202 |
| - }, |
| 223 | + } |
| 224 | + }, |
203 | 225 | false);
|
204 | 226 | }
|
205 | 227 |
|
206 | 228 | var reset_recorder_state = function() {
|
207 | 229 | document.recorded_actions = [];
|
208 | 230 | sessionStorage.setItem('pause_recorder', 'no');
|
209 | 231 | const d_now = Date.now();
|
210 |
| - if (sessionStorage.getItem('recorder_activated') === 'yes') |
211 |
| - { |
| 232 | + if (sessionStorage.getItem('recorder_activated') === 'yes') { |
212 | 233 | ss_ra = JSON.parse(sessionStorage.getItem('recorded_actions'));
|
213 | 234 | document.recorded_actions = ss_ra;
|
214 | 235 | w_orig = window.location.origin;
|
215 | 236 | w_href = window.location.href;
|
216 | 237 | ra_len = document.recorded_actions.length;
|
217 |
| - if (ra_len > 0 && |
218 |
| - document.recorded_actions[ra_len-1][0] === 'begin') |
219 |
| - { |
| 238 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][0] === 'begin') { |
220 | 239 | document.recorded_actions.pop();
|
221 | 240 | document.recorded_actions.push(['begin', w_orig, w_href, d_now]);
|
222 | 241 | }
|
223 | 242 | else if (ra_len > 0 &&
|
224 |
| - document.recorded_actions[ra_len-1][0] === '_url_') |
| 243 | + document.recorded_actions[ra_len-1][0] === '_url_') |
225 | 244 | {
|
226 | 245 | document.recorded_actions.pop();
|
227 | 246 | document.recorded_actions.push(['_url_', w_orig, w_href, d_now]);
|
|
230 | 249 | document.recorded_actions.push(['_url_', w_orig, w_href, d_now]);
|
231 | 250 | }
|
232 | 251 | }
|
233 |
| - else |
234 |
| - { |
235 |
| - sessionStorage.setItem('recorder_activated', 'yes') |
| 252 | + else { |
| 253 | + sessionStorage.setItem('recorder_activated', 'yes'); |
236 | 254 | w_orig = window.location.origin;
|
237 | 255 | w_href = window.location.href;
|
238 | 256 | document.recorded_actions.push(['begin', w_orig, w_href, d_now]);
|
|
280 | 298 | {
|
281 | 299 | document.recorded_actions.pop();
|
282 | 300 | }
|
283 |
| - if (element.draggable === true) { |
| 301 | + if (element.draggable === true) |
284 | 302 | document.recorded_actions.push(['drags', selector, '', d_now]);
|
285 |
| - } |
286 | 303 | json_rec_act = JSON.stringify(document.recorded_actions);
|
287 | 304 | sessionStorage.setItem('recorded_actions', json_rec_act);
|
288 | 305 | });
|
|
292 | 309 | if (sessionStorage.getItem('pause_recorder') === 'yes')
|
293 | 310 | return;
|
294 | 311 | ra_len = document.recorded_actions.length;
|
295 |
| - if (ra_len > 0 && |
296 |
| - document.recorded_actions[ra_len-1][0] === 'drags') |
| 312 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][0] === 'drags') |
297 | 313 | {
|
298 | 314 | document.recorded_actions.pop();
|
299 | 315 | json_rec_act = JSON.stringify(document.recorded_actions);
|
|
309 | 325 | const element = event.target;
|
310 | 326 | const selector = getBestSelector(element);
|
311 | 327 | ra_len = document.recorded_actions.length;
|
312 |
| - if (ra_len > 0 && |
313 |
| - document.recorded_actions[ra_len-1][0] === 'drags') |
| 328 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][0] === 'drags') |
314 | 329 | {
|
315 | 330 | drg_s = document.recorded_actions[ra_len-1][1];
|
316 | 331 | document.recorded_actions.pop();
|
|
337 | 352 | }
|
338 | 353 | else if (tag_name === 'input' && element.type === 'range')
|
339 | 354 | {
|
340 |
| - if (ra_len > 0 && |
341 |
| - document.recorded_actions[ra_len-1][1] === selector) |
| 355 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][1] === selector) |
342 | 356 | {
|
343 | 357 | document.recorded_actions.pop();
|
344 | 358 | ra_len = document.recorded_actions.length;
|
345 | 359 | }
|
346 | 360 | // Do it twice for click and multiple changes.
|
347 |
| - if (ra_len > 0 && |
348 |
| - document.recorded_actions[ra_len-1][1] === selector) |
| 361 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][1] === selector) |
349 | 362 | {
|
350 | 363 | document.recorded_actions.pop();
|
351 | 364 | ra_len = document.recorded_actions.length;
|
352 | 365 | }
|
353 | 366 | value = element.value;
|
354 | 367 | document.recorded_actions.push(['set_v', selector, value, d_now]);
|
355 | 368 | }
|
356 |
| - else if (tag_name === 'input' && element.type === 'file') |
357 |
| - { |
358 |
| - if (ra_len > 0 && |
359 |
| - document.recorded_actions[ra_len-1][1] === selector) |
| 369 | + else if (tag_name === 'input' && element.type === 'file') { |
| 370 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][1] === selector) |
360 | 371 | {
|
361 | 372 | document.recorded_actions.pop();
|
362 | 373 | ra_len = document.recorded_actions.length;
|
|
368 | 379 | document.recorded_actions[ra_len-1][1] === selector &&
|
369 | 380 | tag_name === 'input' && element.type === 'checkbox')
|
370 | 381 | {
|
371 |
| - // The checkbox state only needs to be set once. |
| 382 | + // The checkbox state only needs to be set once. (Pop duplicates.) |
372 | 383 | document.recorded_actions.pop();
|
373 | 384 | ra_len = document.recorded_actions.length;
|
374 |
| - if (ra_len > 0 && |
375 |
| - document.recorded_actions[ra_len-1][1] === selector) |
376 |
| - { |
377 |
| - // Pop the duplicate if present. |
| 385 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][1] === selector) |
378 | 386 | document.recorded_actions.pop();
|
379 |
| - } |
380 | 387 | }
|
381 | 388 | // Go back to `if`, not `else if`.
|
382 |
| - if (tag_name === 'input' && element.type === 'checkbox' && |
383 |
| - element.checked) |
| 389 | + if (tag_name === 'input' && element.type === 'checkbox' && element.checked) |
384 | 390 | {
|
385 | 391 | document.recorded_actions.push(['c_box', selector, 'yes', d_now]);
|
386 | 392 | }
|
|
402 | 408 | const selector = getBestSelector(element);
|
403 | 409 | ra_len = document.recorded_actions.length;
|
404 | 410 | tag_name = element.tagName.toLowerCase();
|
405 |
| - if (ra_len > 0 && |
406 |
| - document.recorded_actions[ra_len-1][0] === 'mo_dn') |
407 |
| - { |
| 411 | + if (ra_len > 0 && document.recorded_actions[ra_len-1][0] === 'mo_dn') { |
408 | 412 | document.recorded_actions.pop();
|
409 | 413 | }
|
410 |
| - if (tag_name === 'select') |
411 |
| - { |
412 |
| - // Do Nothing (Handle select in 'change' action.) |
| 414 | + if (tag_name === 'select') { |
| 415 | + // Do Nothing. (Handle select in 'change' action.) |
413 | 416 | }
|
414 | 417 | else {
|
415 | 418 | document.recorded_actions.push(['mo_dn', selector, '', d_now]);
|
|
427 | 430 | const selector = getBestSelector(element);
|
428 | 431 | ra_len = document.recorded_actions.length;
|
429 | 432 | tag_name = element.tagName.toLowerCase();
|
| 433 | + parent_element = element.parentElement; |
| 434 | + parent_tag_name = parent_element.tagName.toLowerCase(); |
| 435 | + grand_element = ""; |
| 436 | + grand_tag_name = ""; |
| 437 | + origin = ""; |
| 438 | + if (parent_element.parentElement != 'null') { |
| 439 | + grand_element = parent_element.parentElement; |
| 440 | + grand_tag_name = grand_element.tagName.toLowerCase(); |
| 441 | + } |
430 | 442 | if (ra_len > 0 &&
|
431 | 443 | document.recorded_actions[ra_len-1][1] === selector &&
|
432 | 444 | (document.recorded_actions[ra_len-1][0] === 'mo_dn' ||
|
433 |
| - tag_name === 'a') && tag_name !== 'select') |
| 445 | + tag_name === 'a' || parent_tag_name === 'a') && |
| 446 | + tag_name !== 'select') |
434 | 447 | {
|
435 |
| - ahref = ''; |
| 448 | + href = ''; |
436 | 449 | if (tag_name === 'a' &&
|
437 | 450 | element.hasAttribute('href') &&
|
438 | 451 | element.getAttribute('href').length > 0 &&
|
439 | 452 | element.origin != 'null')
|
440 | 453 | {
|
441 |
| - // Because getAttribute('href') could start with '/'. |
442 |
| - ahref = element.href; |
| 454 | + href = element.href; |
| 455 | + origin = element.origin; |
| 456 | + } |
| 457 | + else if (parent_tag_name === 'a' && |
| 458 | + parent_element.hasAttribute('href') && |
| 459 | + parent_element.getAttribute('href').length > 0 && |
| 460 | + parent_element.origin != 'null') |
| 461 | + { |
| 462 | + href = parent_element.href; |
| 463 | + origin = parent_element.origin; |
| 464 | + } |
| 465 | + else if (grand_tag_name === 'a' && |
| 466 | + grand_element.hasAttribute('href') && |
| 467 | + grand_element.getAttribute('href').length > 0 && |
| 468 | + grand_element.origin != 'null') |
| 469 | + { |
| 470 | + href = grand_element.href; |
| 471 | + origin = grand_element.origin; |
443 | 472 | }
|
444 | 473 | document.recorded_actions.pop();
|
445 | 474 | child_sep = ' > ';
|
446 |
| - if (tag_name === "a" && !element.hasAttribute('onclick') && |
447 |
| - selector.includes(child_sep) && ahref.length > 0) |
| 475 | + child_count = ssOccurrences(selector, child_sep); |
| 476 | + if ((tag_name === "a" && !element.hasAttribute('onclick') && |
| 477 | + child_count > 0 && href.length > 0) || |
| 478 | + (parent_tag_name === "a" && href.length > 0 && |
| 479 | + child_count > 1 && !parent_element.hasAttribute('onclick')) || |
| 480 | + (grand_tag_name === "a" && href.length > 0 && |
| 481 | + child_count > 2 && !grand_element.hasAttribute('onclick'))) |
448 | 482 | {
|
449 |
| - origin = element.origin; |
450 | 483 | w_orig = window.location.origin;
|
451 |
| - if (origin === w_orig) |
452 |
| - { |
453 |
| - document.recorded_actions.push( |
454 |
| - ['_url_', origin, ahref, d_now]); |
| 484 | + if (origin === w_orig) { |
| 485 | + document.recorded_actions.push(['_url_', origin, href, d_now]); |
455 | 486 | }
|
456 | 487 | else {
|
457 |
| - document.recorded_actions.push( |
458 |
| - ['begin', origin, ahref, d_now]); |
| 488 | + document.recorded_actions.push(['begin', origin, href, d_now]); |
459 | 489 | }
|
460 | 490 | }
|
461 | 491 | else {
|
462 |
| - document.recorded_actions.push( |
463 |
| - ['click', selector, ahref, d_now]); |
| 492 | + document.recorded_actions.push(['click', selector, href, d_now]); |
464 | 493 | }
|
465 | 494 | // Switch to hover_click() if in a dropdown.
|
466 |
| - if (element.parentElement.classList.contains( |
467 |
| - 'dropdown-content') && |
468 |
| - element.parentElement.parentElement.classList.contains( |
469 |
| - 'dropdown')) |
| 495 | + if (element.parentElement.classList.contains('dropdown-content') && |
| 496 | + element.parentElement.parentElement.classList.contains('dropdown')) |
470 | 497 | {
|
471 | 498 | ch_s = selector;
|
472 | 499 | pa_el = element.parentElement.parentElement;
|
473 | 500 | pa_s = getBestSelector(pa_el);
|
474 | 501 | if (pa_el.childElementCount >= 2 &&
|
475 |
| - !pa_el.firstElementChild.classList.contains( |
476 |
| - 'dropdown-content')) |
| 502 | + !pa_el.firstElementChild.classList.contains('dropdown-content')) |
477 | 503 | {
|
478 | 504 | pa_el = pa_el.firstElementChild;
|
479 | 505 | pa_s = getBestSelector(pa_el);
|
|
532 | 558 | });
|
533 | 559 | document.body.addEventListener('keyup', function (event) {
|
534 | 560 | if (typeof document.recorded_actions === 'undefined')
|
535 |
| - reset_recorder_state(); |
| 561 | + reset_recorder_state(); |
536 | 562 | // Controls for Pausing and Resuming the Recorder.
|
537 | 563 | if (event.key.toLowerCase() === 'escape' &&
|
538 | 564 | sessionStorage.getItem('pause_recorder') === 'no')
|
|
582 | 608 | {
|
583 | 609 | skip_input = true;
|
584 | 610 | }
|
585 |
| - if (!skip_input) |
586 |
| - { |
| 611 | + if (!skip_input) { |
587 | 612 | document.recorded_actions.push(
|
588 | 613 | ['input', selector, element.value, d_now]);
|
589 | 614 | }
|
|
0 commit comments