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', 'HTMLKeygenElement', '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 pos = {}; pos.x = element.offsetLeft + element.offsetWidth - 9; pos.y = element.offsetTop + 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.youngestShadowRoot(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 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) eventSender.keyDown(str.charAt(i)); }