1
0
mirror of https://github.com/gryf/pentadactyl-pm.git synced 2025-12-20 23:37:59 +01:00

Fix tab number updates in FF36. Closes issue 300.

This commit is contained in:
Kris Maglione
2011-01-26 16:22:29 -05:00
parent a6fe97b787
commit 218562e21b
48 changed files with 498 additions and 8666 deletions

View File

@@ -1,307 +0,0 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is MozMill Test code.
*
* The Initial Developer of the Original Code is the Mozilla Foundation.
* Portions created by the Initial Developer are Copyright (C) 2010
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Adrian Kalla <akalla@aviary.pl>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
// Include required modules
var domUtils = require("dom-utils");
var screenshot = require("screenshot");
var utils = require("utils");
const jumlib = {};
Components.utils.import("resource://mozmill/modules/jum.js", jumlib);
/**
* Callback function for parsing the results of testing for duplicated
* access keys.
*
* This function processes the access keys found in one access keys scope
* looking for access keys that are listed more than one time.
* At the end, it calls the screenshot.create to create a screenshot with the
* elements containing the broken access keys highlighted.
*
* @param {array of array of object} accessKeysSet
* @param {MozmillController} controller
*/
function checkAccessKeysResults(controller, accessKeysSet) {
// Sort the access keys to have them in a A->Z order
var accessKeysList = accessKeysSet.sort();
// List of access keys
var aKeysList = [];
// List of values to identify the access keys
var valueList = [];
// List of rectangles of nodes containing access keys
var rects = [];
// List of rectangles of nodes with broken access keys
var badRects = [];
// Makes lists of all access keys and the values the access keys are in
for (var i = 0; i < accessKeysList.length; i++) {
var accessKey = accessKeysList[i][0];
var node = accessKeysList[i][1];
// Set the id and label to be shown in the console
var id = node.id || "(id is undefined)";
var label = node.label || "(label is undefined)";
var box = node.boxObject;
var innerIds = [];
var innerRects = [];
// if the access key is already in our list, take it out to replace it
// later
if (accessKey == aKeysList[aKeysList.length-1]) {
innerIds = valueList.pop();
innerRects = rects.pop();
} else {
aKeysList.push([accessKey]);
}
innerIds.push("[id: " + id + ", label: " + label + "]");
valueList.push(innerIds);
innerRects.push([box.x, box.y, box.width, box.height]);
rects.push(innerRects);
}
// Go through all access keys and find the duplicated ones
for (var i = 0; i < valueList.length; i++) {
// Only access keys contained in more than one node are the ones we are
// looking for
if (valueList[i].length > 1) {
for (var j = 0; j < rects[i].length; j++) {
badRects.push(rects[i][j]);
}
jumlib.assert(false, 'accessKey: ' + aKeysList[i] +
' found in string\'s: ' + valueList[i].join(", "));
}
}
// If we have found broken access keys, make a screenshot
if (badRects.length > 0) {
screenshot.create(controller, badRects);
}
}
/**
* Callback function for testing for cropped elements.
*
* Checks if the XUL boxObject has screen coordinates outside of
* the screen coordinates of its parent. If there's no parent, return.
*
* @param {node} child
* @returns List of boxes that can be highlighted on a screenshot
* @type {array of array of int}
*/
function checkDimensions(child) {
if (!child.boxObject)
return [];
var childBox = child.boxObject;
var parent = childBox.parentBox;
// toplevel element or hidden elements, like script tags
if (!parent || parent == child.element || !parent.boxObject) {
return [];
}
var parentBox = parent.boxObject;
var badRects = [];
// check width
if (childBox.height && childBox.screenX < parentBox.screenX) {
badRects.push([childBox.x, childBox.y, parentBox.x - childBox.x,
childBox.height]);
jumlib.assert(false, 'Node is cut off at the left: ' +
_reportNode(child) + '. Parent node: ' + _reportNode(parent));
}
if (childBox.height && childBox.screenX + childBox.width >
parentBox.screenX + parentBox.width) {
badRects.push([parentBox.x + parentBox.width, childBox.y,
childBox.x + childBox.width - parentBox.x - parentBox.width,
childBox.height]);
jumlib.assert(false, 'Node is cut off at the right: ' +
_reportNode(child) + '. Parent node: ' + _reportNode(parent));
}
// check height
// We don't want to test menupopup's, as they always report the full height
// of all items in the popup
if (child.nodeName != 'menupopup' && parent.nodeName != 'menupopup') {
if (childBox.width && childBox.screenY < parentBox.screenY) {
badRects.push([childBox.x, childBox.y, parentBox.y - childBox.y,
childBox.width]);
jumlib.assert(false, 'Node is cut off at the top: ' +
_reportNode(child) + '. Parent node: ' + _reportNode(parent));
}
if (childBox.width && childBox.screenY + childBox.height >
parentBox.screenY + parentBox.height) {
badRects.push([childBox.x, parentBox.y + parentBox.height,
childBox.width,
childBox.y + childBox.height - parentBox.y - parentBox.height]);
jumlib.assert(false, 'Node is cut off at the bottom: ' +
_reportNode(child) + '. Parent node: ' + _reportNode(parent));
}
}
return badRects;
}
/**
* Filters out nodes which should not be tested because they are not in the
* current access key scope.
*
* @param {node} node
* @returns Filter status of the given node
* @type {array of array of int}
*/
function filterAccessKeys(node) {
// Menus will need a separate filter set
var notAllowedLocalNames = ["menu", "menubar", "menupopup", "popupset"];
if (!node.disabled && !node.collapsed && !node.hidden &&
notAllowedLocalNames.indexOf(node.localName) == -1) {
// Code specific to the preferences panes to reject out not visible nodes
// in the panes.
if (node.parentNode && (node.parentNode.localName == "prefwindow" &&
node.parentNode.currentPane.id != node.id) ||
((node.parentNode.localName == "tabpanels" ||
node.parentNode.localName == "deck") &&
node.parentNode.selectedPanel.id != node.id)) {
return domUtils.DOMWalker.FILTER_REJECT;
// end of the specific code
} else if (node.accessKey) {
return domUtils.DOMWalker.FILTER_ACCEPT;
} else {
return domUtils.DOMWalker.FILTER_SKIP;
}
} else {
// we don't want to test not visible elements
return domUtils.DOMWalker.FILTER_REJECT;
}
}
/**
* Filters out nodes which should not be tested because they are not visible
*
* @param {node} node
* @returns Filter status of the given node
* @type {array of array of int}
*/
function filterCroppedNodes(node) {
if (!node.boxObject) {
return domUtils.DOMWalker.FILTER_SKIP;
} else {
if (!node.disabled && !node.collapsed && !node.hidden) {
// Code specific to the preferences panes to reject out not visible nodes
// in the panes.
if (node.parentNode && (node.parentNode.localName == "prefwindow" &&
node.parentNode.currentPane.id != node.id) ||
((node.parentNode.localName == "tabpanels" ||
node.parentNode.localName == "deck") &&
node.parentNode.selectedPanel.id != node.id)) {
return domUtils.DOMWalker.FILTER_REJECT;
// end of the specific code
} else {
return domUtils.DOMWalker.FILTER_ACCEPT;
}
} else {
// we don't want to test not visible elements
return domUtils.DOMWalker.FILTER_REJECT;
}
}
}
/**
* Callback function for testing access keys. To be used with the DOMWalker.
*
* It packs a submitted node and its access key into a double array
*
* @param {node} node Node containing the access key
* @returns lower-cased access key and its node in a nested array
* @type {array of array}
*/
function prepareAccessKey(node) {
return [[node.accessKey.toLowerCase(), node]];
}
/**
* Callback function for parsing the results of testing for cropped elements.
*
* This function calls the screenshot.create method if there is at least one
* box.
*
* @param {array of array of int} boxes
* @param {MozmillController} controller
*/
function processDimensionsResults(controller, boxes) {
if (boxes && boxes.length > 0) {
screenshot.create(controller, boxes);
}
}
/**
* Tries to return a useful string identificator of the given node
*
* @param {node} node
* @returns Identificator of the node
* @type {String}
*/
function _reportNode(node) {
if (node.id) {
return "id: " + node.id;
} else if (node.label) {
return "label: " + node.label;
} else if (node.value) {
return "value: " + node.value;
} else if (node.hasAttributes()) {
var attrs = "node attributes: ";
for (var i = node.attributes.length - 1; i >= 0; i--) {
attrs += node.attributes[i].name + "->" + node.attributes[i].value + ";";
}
return attrs;
} else {
return "anonymous node";
}
}
// Export of functions
exports.checkAccessKeysResults = checkAccessKeysResults;
exports.checkDimensions = checkDimensions;
exports.filterAccessKeys = filterAccessKeys;
exports.filterCroppedNodes = filterCroppedNodes;
exports.prepareAccessKey = prepareAccessKey;
exports.processDimensionsResults = processDimensionsResults;