VulpesOS/gaia/apps/system/test/marionette/lib/selection_helper.js
OverSu b38dea0597 Publish Vulpes Preview 15 sources for desktop, Android and Tundra
Share Gaia assets and adapters, keep private profiles and development documents local, and update both public READMEs.
2026-09-30 23:13:03 +02:00

186 lines
5.6 KiB
JavaScript
Executable file

'use strict';
var Actions = require('marionette-client').Actions;
function SelectionHelper(client, element) {
this.client = client;
this.isInputOrTextarea =
(element.getAttribute('tagName') === 'INPUT' ||
element.getAttribute('tagName') === 'TEXTAREA');
this.element = element;
this.action = new Actions(this.client);
}
module.exports = SelectionHelper;
SelectionHelper.prototype = {
get content() {
if (this.isInputOrTextarea) {
return this.element.getAttribute('value');
} else {
return this.element.text;
}
},
get selectedContent() {
return this.client.executeScript(this.getSelectionCmd() +
'return sel.toString();', [this.element], null, 'system');
},
getSelectionCmd: function() {
if (this.isInputOrTextarea) {
return 'var sel = arguments[0].editor.selection;';
} else {
return 'var sel = window.getSelection();';
}
},
selectionRectList: function(idx) {
var cmd = this.getSelectionCmd() + 'return sel.getRangeAt(' + idx + ')' +
'.getClientRects();';
return this.client.executeScript(cmd, [this.element], null, 'system');
},
rangeCount: function() {
var cmd = this.getSelectionCmd() + 'return sel.rangeCount;';
return this.client.executeScript(cmd, [this.element], null, 'system');
},
/**
* Move caret by absolute position.
*
* @param {Object} data
* {caretA: {
* offset: {
* x: //poistion relative to element,
* y: //poistion relative to element
* },
* caretB: {
* offset: {
* x: //poistion relative to element,
* y: //poistion relative to element
* }
* }}
*
*/
moveCaretByPosition: function(data) {
var caretPositions = this.selectionLocationHelper();
if (data.caretA) {
this.action.flick(this.element, caretPositions.caretA.x,
caretPositions.caretA.y + 15,
caretPositions.caretA.x + data.caretA.offset.x,
caretPositions.caretA.y + 15 + data.caretA.offset.y).perform();
this.client.wait(500);
}
if (data.caretB) {
this.action.flick(this.element, caretPositions.caretB.x,
caretPositions.caretB.y + 15,
caretPositions.caretB.x + data.caretB.offset.x,
caretPositions.caretB.y + 15 + data.caretB.offset.y).perform();
}
},
/**
* Move caret by word's position.
*
* @param {Object} data
* {caretA: {offset: //integer}, caretB: {offset //integer}}
*
*/
moveCaretByWords: function(data) {
if (!this.isInputOrTextarea) {
console.log('only support input or textarea');
return;
}
var caretA = data.caretA;
var caretB = data.caretB;
var caretPositions = this.selectionLocationHelper();
var content = this.content;
var contentLength = content.length;
this.client.executeScript('arguments[0].setSelectionRange(' +
(caretA ? caretA.offset : 0) + ',' +
(contentLength + (caretB ? caretB.offset : 0)) + ' )',
[this.element]);
var newCaretPositions = this.selectionLocationHelper();
var eltSize = this.element.size();
this.action.tap(this.element, eltSize.width / 2, eltSize.height / 2)
.wait(2).press(this.element, eltSize.width / 2, eltSize.height / 2).
moveByOffset(0, 0).wait(2).release().perform();
var flickPosition = {};
if (caretA) {
flickPosition.caretA = {
offset: {
x: newCaretPositions.caretA.x - caretPositions.caretA.x,
y: newCaretPositions.caretA.y - caretPositions.caretA.y
}
};
}
if (caretB) {
flickPosition.caretB = {
offset: {
x: newCaretPositions.caretB.x - caretPositions.caretB.x,
y: newCaretPositions.caretB.y - caretPositions.caretB.y
}
};
}
this.moveCaretByPosition(flickPosition);
},
selectionLocationHelper: function(locationType) {
var rangeCount = this.rangeCount();
var firstRectList = this.selectionRectList(0);
var lastRectList = this.selectionRectList(rangeCount - 1);
var lastListLength = lastRectList.length;
var firstRect = firstRectList[0];
var lastRect = lastRectList[lastListLength - 1];
var originX = this.element.location.x;
var originY = this.element.location.y;
var startPos = 'left';
var endPos = 'right';
var startYOffset, endYOffset;
if (this.element.getAttribute('dir') === 'rtl') {
startPos = 'right';
endPos = 'left';
}
if (locationType === 'center') {
startYOffset = firstRect.height / 2;
endYOffset = lastRect.height / 2;
} else if (locationType === 'caret') {
startYOffset = firstRect.height + 5;
endYOffset = lastRect.height + 5;
} else {
startYOffset = endYOffset = 0;
}
return {
caretA: {
x: firstRect[startPos] - originX,
y: firstRect.top + startYOffset - originY
},
caretB: {
x: lastRect[endPos] - originX,
y: lastRect.top + endYOffset - originY
}
};
},
selectAll: function() {
var cmd;
if (this.isInputOrTextarea) {
cmd = 'var len = arguments[0].value.length; arguments[0].focus();' +
'arguments[0].setSelectionRange(0, len);';
} else {
cmd = 'var range = document.createRange();' +
'range.setStart(arguments[0].firstChild, 0);' +
'range.setEnd(arguments[0].lastChild, 0);' +
'var sel = window.getSelection();' +
'sel.removeAllRanges(); sel.addRange(range);';
}
this.client.executeScript(cmd, [this.element]);
}
};