|
|
@ -114,11 +114,11 @@ $(document).ready(function () {
|
|
|
|
e.preventDefault()
|
|
|
|
e.preventDefault()
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// When the mouse moves we know which element it should be above
|
|
|
|
|
|
|
|
// mousedown will link that to the UI (select the right action, highlight etc)
|
|
|
|
$('#browsersteps-selector-canvas').bind('mousedown', function (e) {
|
|
|
|
$('#browsersteps-selector-canvas').bind('mousedown', function (e) {
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
|
|
|
// https://developer.mozilla.org/en-US/docs/Web/API/MouseEvent
|
|
|
|
e.preventDefault()
|
|
|
|
e.preventDefault()
|
|
|
|
console.log(e);
|
|
|
|
|
|
|
|
console.log("current xpath in index is " + current_selected_i);
|
|
|
|
|
|
|
|
last_click_xy = {'x': parseInt((1 / x_scale) * e.offsetX), 'y': parseInt((1 / y_scale) * e.offsetY)}
|
|
|
|
last_click_xy = {'x': parseInt((1 / x_scale) * e.offsetX), 'y': parseInt((1 / y_scale) * e.offsetY)}
|
|
|
|
process_selected(current_selected_i);
|
|
|
|
process_selected(current_selected_i);
|
|
|
|
current_selected_i = false;
|
|
|
|
current_selected_i = false;
|
|
|
@ -132,6 +132,7 @@ $(document).ready(function () {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Debounce and find the current most 'interesting' element we are hovering above
|
|
|
|
$('#browsersteps-selector-canvas').bind('mousemove', function (e) {
|
|
|
|
$('#browsersteps-selector-canvas').bind('mousemove', function (e) {
|
|
|
|
if (!xpath_data) {
|
|
|
|
if (!xpath_data) {
|
|
|
|
return;
|
|
|
|
return;
|
|
|
@ -151,41 +152,38 @@ $(document).ready(function () {
|
|
|
|
current_selected_i = false;
|
|
|
|
current_selected_i = false;
|
|
|
|
// Reverse order - the most specific one should be deeper/"laster"
|
|
|
|
// Reverse order - the most specific one should be deeper/"laster"
|
|
|
|
// Basically, find the most 'deepest'
|
|
|
|
// Basically, find the most 'deepest'
|
|
|
|
//$('#browsersteps-selector-canvas').css('cursor', 'pointer');
|
|
|
|
var possible_elements = [];
|
|
|
|
for (var i = xpath_data['size_pos'].length; i !== 0; i--) {
|
|
|
|
xpath_data['size_pos'].forEach(function (item, index) {
|
|
|
|
// draw all of them? let them choose somehow?
|
|
|
|
|
|
|
|
var sel = xpath_data['size_pos'][i - 1];
|
|
|
|
|
|
|
|
// If we are in a bounding-box
|
|
|
|
// If we are in a bounding-box
|
|
|
|
if (e.offsetY > sel.top * y_scale && e.offsetY < sel.top * y_scale + sel.height * y_scale
|
|
|
|
if (e.offsetY > item.top * y_scale && e.offsetY < item.top * y_scale + item.height * y_scale
|
|
|
|
&&
|
|
|
|
&&
|
|
|
|
e.offsetX > sel.left * y_scale && e.offsetX < sel.left * y_scale + sel.width * y_scale
|
|
|
|
e.offsetX > item.left * y_scale && e.offsetX < item.left * y_scale + item.width * y_scale
|
|
|
|
|
|
|
|
|
|
|
|
) {
|
|
|
|
) {
|
|
|
|
// Only highlight these interesting types
|
|
|
|
// There could be many elements here, record them all and then we'll find out which is the most 'useful'
|
|
|
|
if (1) {
|
|
|
|
// (input, textarea, button, A etc)
|
|
|
|
ctx.strokeRect(sel.left * x_scale, sel.top * y_scale, sel.width * x_scale, sel.height * y_scale);
|
|
|
|
possible_elements.push(item);
|
|
|
|
ctx.fillRect(sel.left * x_scale, sel.top * y_scale, sel.width * x_scale, sel.height * y_scale);
|
|
|
|
|
|
|
|
current_selected_i = i - 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// find the smallest one at this x,y
|
|
|
|
|
|
|
|
// does it mean sort the xpath list by size (w*h) i think so!
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (include_text_elements[0].checked === true) {
|
|
|
|
|
|
|
|
// blue one with background instead?
|
|
|
|
|
|
|
|
ctx.fillStyle = 'rgba(0,0,255, 0.1)';
|
|
|
|
|
|
|
|
ctx.strokeStyle = 'rgba(0,0,200, 0.7)';
|
|
|
|
|
|
|
|
$('#browsersteps-selector-canvas').css('cursor', 'grab');
|
|
|
|
|
|
|
|
ctx.strokeRect(sel.left * x_scale, sel.top * y_scale, sel.width * x_scale, sel.height * y_scale);
|
|
|
|
|
|
|
|
ctx.fillRect(sel.left * x_scale, sel.top * y_scale, sel.width * x_scale, sel.height * y_scale);
|
|
|
|
|
|
|
|
current_selected_i = i - 1;
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// Find the best one
|
|
|
|
|
|
|
|
if (possible_elements.length) {
|
|
|
|
|
|
|
|
possible_elements.forEach(function (item, index) {
|
|
|
|
|
|
|
|
if (["a", "input", "textarea", "button"].includes(item['tagName'])) {
|
|
|
|
|
|
|
|
current_selected_i = item;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!current_selected_i) {
|
|
|
|
|
|
|
|
current_selected_i = possible_elements[0];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
sel = xpath_data['size_pos'][current_selected_i];
|
|
|
|
|
|
|
|
ctx.strokeRect(current_selected_i.left * x_scale, current_selected_i.top * y_scale, current_selected_i.width * x_scale, current_selected_i.height * y_scale);
|
|
|
|
|
|
|
|
ctx.fillRect(current_selected_i.left * x_scale, current_selected_i.top * y_scale, current_selected_i.width * x_scale, current_selected_i.height * y_scale);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
}.debounce(10));
|
|
|
|
}.debounce(10));
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
@ -195,16 +193,16 @@ $(document).ready(function () {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// callback for clicking on an xpath on the canvas
|
|
|
|
// callback for clicking on an xpath on the canvas
|
|
|
|
function process_selected(xpath_data_index) {
|
|
|
|
function process_selected(selected_in_xpath_list) {
|
|
|
|
found_something = false;
|
|
|
|
found_something = false;
|
|
|
|
var first_available = $("ul#browser_steps li.empty").first();
|
|
|
|
var first_available = $("ul#browser_steps li.empty").first();
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (xpath_data_index !== false) {
|
|
|
|
if (selected_in_xpath_list !== false) {
|
|
|
|
// Nothing focused, so fill in a new one
|
|
|
|
// Nothing focused, so fill in a new one
|
|
|
|
// if inpt type button or <button>
|
|
|
|
// if inpt type button or <button>
|
|
|
|
// from the top, find the next not used one and use it
|
|
|
|
// from the top, find the next not used one and use it
|
|
|
|
var x = xpath_data['size_pos'][xpath_data_index];
|
|
|
|
var x = selected_in_xpath_list;
|
|
|
|
console.log(x);
|
|
|
|
console.log(x);
|
|
|
|
if (x && first_available.length) {
|
|
|
|
if (x && first_available.length) {
|
|
|
|
// @todo will it let you click shit that has a layer ontop? probably not.
|
|
|
|
// @todo will it let you click shit that has a layer ontop? probably not.
|
|
|
@ -227,21 +225,6 @@ $(document).ready(function () {
|
|
|
|
found_something = true;
|
|
|
|
found_something = true;
|
|
|
|
//}
|
|
|
|
//}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
first_available.xpath_data_index = xpath_data_index;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (!found_something) {
|
|
|
|
|
|
|
|
if (include_text_elements[0].checked === true) {
|
|
|
|
|
|
|
|
// Suggest that we use as filter?
|
|
|
|
|
|
|
|
// @todo filters should always be in the last steps, nothing non-filter after it
|
|
|
|
|
|
|
|
found_something = true;
|
|
|
|
|
|
|
|
ctx.strokeStyle = 'rgba(0,0,255, 0.9)';
|
|
|
|
|
|
|
|
ctx.fillStyle = 'rgba(0,0,255, 0.1)';
|
|
|
|
|
|
|
|
$('select', first_available).val('Extract text and use as filter').change();
|
|
|
|
|
|
|
|
$('input[type=text]', first_available).first().val(x['xpath']);
|
|
|
|
|
|
|
|
include_text_elements[0].checked = false;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|