function $(id) {
return document.getElementById(id);
}
function createFormControlDataSet() {
// A list of labelable elements resides in http://www.whatwg.org/specs/web-apps/current-work/multipage/forms.html#category-label
var formControlClassNames = [
'HTMLButtonElement',
'HTMLDataListElement',
'HTMLFieldSetElement',
'HTMLInputElement',
'HTMLLabelElement',
'HTMLLegendElement',
'HTMLMeterElement',
'HTMLObjectElement',
'HTMLOptGroupElement',
'HTMLOptionElement',
'HTMLOutputElement',
'HTMLProgressElement',
'HTMLSelectElement',
'HTMLTextAreaElement'
];
var formControlDataSet = {};
for (var i = 0; i < formControlClassNames.length; i++) {
var className = formControlClassNames[i];
var tagName = className.toLowerCase().substring(4, className.length - 7);
var element = document.createElement(tagName);
formControlDataSet[tagName] = {
inputType: null,
isLabelable: true,
isSupported: element.toString() == '[object ' + className + ']',
name: tagName,
tagName: tagName,
};
}
formControlDataSet.datalist.isLabelable = false;
formControlDataSet.fieldset.isLabelable = false;
formControlDataSet.label.isLabelable = false;
formControlDataSet.legend.isLabelable = false;
formControlDataSet.object.isLabelable = false;
formControlDataSet.optgroup.isLabelable = false;
formControlDataSet.option.isLabelable = false;
// Input type names reside in http://www.whatwg.org/specs/web-apps/current-work/multipage/the-input-element.html
var inputTypeNames = [
'button',
'checkbox',
'color',
'date',
'datetime',
'datetime-local',
'email',
'file',
'hidden',
'image',
'month',
'number',
'password',
'radio',
'range',
'reset',
'search',
'submit',
'tel',
'text',
'time',
'url',
'week',
];
for (var i = 0; i < inputTypeNames.length; i++) {
var typeName = inputTypeNames[i];
var name = typeName + 'Type';
var element = document.createElement('input');
element.type = typeName;
formControlDataSet[name] = {
inputType: typeName,
isLabelable: true,
isSupported: element.type == typeName,
name: name,
tagName: 'input',
};
}
formControlDataSet.hiddenType.isLabelable = false;
return formControlDataSet;
}
function getAbsoluteRect(element) {
var rect = element.getBoundingClientRect();
rect.top += document.scrollingElement.scrollTop;
rect.bottom += document.scrollingElement.scrollTop;
rect.left += document.scrollingElement.scrollLeft;
rect.right += document.scrollingElement.scrollLeft;
return rect;
}
function searchCancelButtonPosition(element) {
var offset = cumulativeOffset(element);
var pos = {};
pos.x = offset[0] + element.offsetWidth - 9;
pos.y = offset[1] + element.offsetHeight / 2;
return pos;
}
function rtlSearchCancelButtonPosition(element) {
var offset = cumulativeOffset(element);
var pos = {};
pos.x = offset[0] + 9;
pos.y = offset[1] + element.offsetHeight / 2;
return pos;
}
function mouseMoveToIndexInListbox(index, listboxId) {
var listbox = document.getElementById(listboxId);
var itemHeight = Math.floor(listbox.offsetHeight / listbox.size);
var border = 1;
var y = border + index * itemHeight;
if (window.eventSender)
eventSender.mouseMoveTo(listbox.offsetLeft + border, listbox.offsetTop + y - window.pageYOffset);
}
function getUserAgentShadowTextContent(element) {
return internals.shadowRoot(element).textContent;
};
function cumulativeOffset(element) {
var x = 0;
var y = 0;
var parentFrame = element.ownerDocument.defaultView.frameElement;
if (parentFrame) {
var parentFrameOffset = cumulativeOffset(parentFrame);
x = parentFrameOffset[0];
y = parentFrameOffset[1];
}
if (element.parentNode) {
do {
x += element.offsetLeft || 0;
y += element.offsetTop || 0;
element = element.offsetParent;
} while (element);
}
return [x, y];
}
function elementCenterPosition(element) {
var offset = cumulativeOffset(element);
var centerX = offset[0] + element.offsetWidth / 2;
var centerY = offset[1] + element.offsetHeight / 2;
return [centerX, centerY];
}
function hoverOverElement(element) {
var center = elementCenterPosition(element);
eventSender.mouseMoveTo(center[0], center[1]);
}
function clickElement(element) {
hoverOverElement(element);
eventSender.mouseDown();
eventSender.mouseUp();
}
function pressElement(element) {
hoverOverElement(element);
eventSender.mouseDown();
}
function traverseNextNode(node, stayWithin) {
var nextNode = node.firstChild;
if (nextNode)
return nextNode;
if (stayWithin && node === stayWithin)
return null;
nextNode = node.nextSibling;
if (nextNode)
return nextNode;
nextNode = node;
while (nextNode && !nextNode.nextSibling && (!stayWithin || !nextNode.parentNode || nextNode.parentNode !== stayWithin))
nextNode = nextNode.parentNode;
if (!nextNode)
return null;
return nextNode.nextSibling;
}
function getElementByPseudoId(root, pseudoId) {
if (!window.internals)
return null;
var node = root;
while (node) {
if (node.nodeType === Node.ELEMENT_NODE && internals.shadowPseudoId(node) === pseudoId)
return node;
node = traverseNextNode(node, root);
}
return null;
}
function doneLater() {
setTimeout(function() {
testRunner.notifyDone();
}, 0);
}
function waitUntilLoadedAndAutofocused(callback) {
var loaded = false;
var autofocused = false;
// Use doneLater() because some rendering tests need repaint after focus.
callback = callback || doneLater;
// Does both of waitUntilDone and jsTestIsAsync because we want to support
// tests with/without js-test.js.
testRunner.waitUntilDone();
window.jsTestIsAsync = true;
window.addEventListener('load', function() {
loaded = true;
if (autofocused)
callback();
}, false);
document.addEventListener('focusin', function() {
if (internals.hasAutofocusRequest(document))
return;
if (autofocused)
return;
autofocused = true;
if (loaded)
callback();
}, false);
}
function sendString(str) {
if (!window.eventSender) {
console.log('Require eventSender.');
return;
}
for (var i = 0; i < str.length; ++i) {
var key = str.charAt(i);
if (key == '\n')
key = 'Enter';
eventSender.keyDown(key);
}
}