mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 20:30:41 +00:00
Merge m-i to m-c
This commit is contained in:
commit
bf91c75128
@ -332,7 +332,7 @@ toolkit/library/target: ../ldap/target
|
||||
endif
|
||||
ifndef MOZ_FOLD_LIBS
|
||||
ifndef MOZ_NATIVE_SQLITE
|
||||
security/build/target: db/sqlite3/src/target
|
||||
config/external/nss/target: db/sqlite3/src/target
|
||||
endif
|
||||
endif
|
||||
ifeq ($(MOZ_REPLACE_MALLOC_LINKAGE),dummy library)
|
||||
|
@ -2,26 +2,26 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global AccessFu, Components, Utils, PrefCache, Logger, Services,
|
||||
PointerAdapter, dump, Presentation, Rect */
|
||||
/* exported AccessFu */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
const {utils: Cu, interfaces: Ci} = Components;
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['AccessFu'];
|
||||
this.EXPORTED_SYMBOLS = ['AccessFu']; // jshint ignore:line
|
||||
|
||||
Cu.import('resource://gre/modules/Services.jsm');
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
|
||||
const ACCESSFU_DISABLE = 0;
|
||||
const ACCESSFU_DISABLE = 0; // jshint ignore:line
|
||||
const ACCESSFU_ENABLE = 1;
|
||||
const ACCESSFU_AUTO = 2;
|
||||
|
||||
const SCREENREADER_SETTING = 'accessibility.screenreader';
|
||||
|
||||
this.AccessFu = {
|
||||
this.AccessFu = { // jshint ignore:line
|
||||
/**
|
||||
* Initialize chrome-layer accessibility functionality.
|
||||
* If accessibility is enabled on the platform, then a special accessibility
|
||||
@ -77,8 +77,9 @@ this.AccessFu = {
|
||||
* with arrow keys.
|
||||
*/
|
||||
_enable: function _enable() {
|
||||
if (this._enabled)
|
||||
if (this._enabled) {
|
||||
return;
|
||||
}
|
||||
this._enabled = true;
|
||||
|
||||
Cu.import('resource://gre/modules/accessibility/Utils.jsm');
|
||||
@ -87,7 +88,7 @@ this.AccessFu = {
|
||||
|
||||
Logger.info('Enabled');
|
||||
|
||||
for each (let mm in Utils.AllMessageManagers) {
|
||||
for (let mm of Utils.AllMessageManagers) {
|
||||
this._addMessageListeners(mm);
|
||||
this._loadFrameScript(mm);
|
||||
}
|
||||
@ -135,8 +136,7 @@ this.AccessFu = {
|
||||
}
|
||||
|
||||
if (Utils.MozBuildApp !== 'mobile/android') {
|
||||
this.announce(
|
||||
Utils.stringBundle.GetStringFromName('screenReaderStarted'));
|
||||
this.announce('screenReaderStarted');
|
||||
}
|
||||
},
|
||||
|
||||
@ -144,8 +144,9 @@ this.AccessFu = {
|
||||
* Disable AccessFu and return to default interaction mode.
|
||||
*/
|
||||
_disable: function _disable() {
|
||||
if (!this._enabled)
|
||||
if (!this._enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._enabled = false;
|
||||
|
||||
@ -154,11 +155,10 @@ this.AccessFu = {
|
||||
Utils.win.document.removeChild(this.stylesheet.get());
|
||||
|
||||
if (Utils.MozBuildApp !== 'mobile/android') {
|
||||
this.announce(
|
||||
Utils.stringBundle.GetStringFromName('screenReaderStopped'));
|
||||
this.announce('screenReaderStopped');
|
||||
}
|
||||
|
||||
for each (let mm in Utils.AllMessageManagers) {
|
||||
for (let mm of Utils.AllMessageManagers) {
|
||||
mm.sendAsyncMessage('AccessFu:Stop');
|
||||
this._removeMessageListeners(mm);
|
||||
}
|
||||
@ -196,10 +196,11 @@ this.AccessFu = {
|
||||
}
|
||||
let activatePref = this._activatePref.value;
|
||||
if (activatePref == ACCESSFU_ENABLE ||
|
||||
this._systemPref && activatePref == ACCESSFU_AUTO)
|
||||
this._systemPref && activatePref == ACCESSFU_AUTO) {
|
||||
this._enable();
|
||||
else
|
||||
} else {
|
||||
this._disable();
|
||||
}
|
||||
} catch (x) {
|
||||
dump('Error ' + x.message + ' ' + x.fileName + ':' + x.lineNumber);
|
||||
}
|
||||
@ -234,9 +235,10 @@ this.AccessFu = {
|
||||
},
|
||||
|
||||
_output: function _output(aPresentationData, aBrowser) {
|
||||
for each (let presenter in aPresentationData) {
|
||||
if (!presenter)
|
||||
for (let presenter of aPresentationData) {
|
||||
if (!presenter) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
Output[presenter.type](presenter.details, aBrowser);
|
||||
@ -392,8 +394,8 @@ this.AccessFu = {
|
||||
_processedMessageManagers: [],
|
||||
|
||||
/**
|
||||
* Adjusts the given bounds relative to the given browser. Converts from screen
|
||||
* or device pixels to either device or CSS pixels.
|
||||
* Adjusts the given bounds relative to the given browser. Converts from
|
||||
* screen or device pixels to either device or CSS pixels.
|
||||
* @param {Rect} aJsonBounds the bounds to adjust
|
||||
* @param {browser} aBrowser the browser we want the bounds relative to
|
||||
* @param {bool} aToCSSPixels whether to convert to CSS pixels (as opposed to
|
||||
@ -401,44 +403,46 @@ this.AccessFu = {
|
||||
* @param {bool} aFromDevicePixels whether to convert from device pixels (as
|
||||
* opposed to screen pixels)
|
||||
*/
|
||||
adjustContentBounds: function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) {
|
||||
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
||||
aJsonBounds.right - aJsonBounds.left,
|
||||
aJsonBounds.bottom - aJsonBounds.top);
|
||||
let win = Utils.win;
|
||||
let dpr = win.devicePixelRatio;
|
||||
let vp = Utils.getViewport(win);
|
||||
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
|
||||
adjustContentBounds:
|
||||
function(aJsonBounds, aBrowser, aToCSSPixels, aFromDevicePixels) {
|
||||
let bounds = new Rect(aJsonBounds.left, aJsonBounds.top,
|
||||
aJsonBounds.right - aJsonBounds.left,
|
||||
aJsonBounds.bottom - aJsonBounds.top);
|
||||
let win = Utils.win;
|
||||
let dpr = win.devicePixelRatio;
|
||||
let vp = Utils.getViewport(win);
|
||||
let offset = { left: -win.mozInnerScreenX, top: -win.mozInnerScreenY };
|
||||
|
||||
if (!aBrowser.contentWindow) {
|
||||
// OOP browser, add offset of browser.
|
||||
// The offset of the browser element in relation to its parent window.
|
||||
let clientRect = aBrowser.getBoundingClientRect();
|
||||
let win = aBrowser.ownerDocument.defaultView;
|
||||
offset.left += clientRect.left + win.mozInnerScreenX;
|
||||
offset.top += clientRect.top + win.mozInnerScreenY;
|
||||
if (!aBrowser.contentWindow) {
|
||||
// OOP browser, add offset of browser.
|
||||
// The offset of the browser element in relation to its parent window.
|
||||
let clientRect = aBrowser.getBoundingClientRect();
|
||||
let win = aBrowser.ownerDocument.defaultView;
|
||||
offset.left += clientRect.left + win.mozInnerScreenX;
|
||||
offset.top += clientRect.top + win.mozInnerScreenY;
|
||||
}
|
||||
|
||||
// Here we scale from screen pixels to layout device pixels by dividing by
|
||||
// the resolution (caused by pinch-zooming). The resolution is the
|
||||
// viewport zoom divided by the devicePixelRatio. If there's no viewport,
|
||||
// then we're on a platform without pinch-zooming and we can just ignore
|
||||
// this.
|
||||
if (!aFromDevicePixels && vp) {
|
||||
bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr);
|
||||
}
|
||||
|
||||
// Add the offset; the offset is in CSS pixels, so multiply the
|
||||
// devicePixelRatio back in before adding to preserve unit consistency.
|
||||
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
|
||||
|
||||
// If we want to get to CSS pixels from device pixels, this needs to be
|
||||
// further divided by the devicePixelRatio due to widget scaling.
|
||||
if (aToCSSPixels) {
|
||||
bounds = bounds.scale(1 / dpr, 1 / dpr);
|
||||
}
|
||||
|
||||
return bounds.expandToIntegers();
|
||||
}
|
||||
|
||||
// Here we scale from screen pixels to layout device pixels by dividing by
|
||||
// the resolution (caused by pinch-zooming). The resolution is the viewport
|
||||
// zoom divided by the devicePixelRatio. If there's no viewport, then we're
|
||||
// on a platform without pinch-zooming and we can just ignore this.
|
||||
if (!aFromDevicePixels && vp) {
|
||||
bounds = bounds.scale(vp.zoom / dpr, vp.zoom / dpr);
|
||||
}
|
||||
|
||||
// Add the offset; the offset is in CSS pixels, so multiply the
|
||||
// devicePixelRatio back in before adding to preserve unit consistency.
|
||||
bounds = bounds.translate(offset.left * dpr, offset.top * dpr);
|
||||
|
||||
// If we want to get to CSS pixels from device pixels, this needs to be
|
||||
// further divided by the devicePixelRatio due to widget scaling.
|
||||
if (aToCSSPixels) {
|
||||
bounds = bounds.scale(1 / dpr, 1 / dpr);
|
||||
}
|
||||
|
||||
return bounds.expandToIntegers();
|
||||
}
|
||||
};
|
||||
|
||||
var Output = {
|
||||
@ -453,8 +457,9 @@ var Output = {
|
||||
if (aOutput && 'output' in aOutput) {
|
||||
this.startOffset = aOutput.startOffset;
|
||||
this.endOffset = aOutput.endOffset;
|
||||
// We need to append a space at the end so that the routing key corresponding
|
||||
// to the end of the output (i.e. the space) can be hit to move the caret there.
|
||||
// We need to append a space at the end so that the routing key
|
||||
// corresponding to the end of the output (i.e. the space) can be hit to
|
||||
// move the caret there.
|
||||
this.text = aOutput.output + ' ';
|
||||
this.selectionStart = typeof aOutput.selectionStart === 'number' ?
|
||||
aOutput.selectionStart : this.selectionStart;
|
||||
@ -502,104 +507,17 @@ var Output = {
|
||||
braille.startOffset = this.startOffset;
|
||||
braille.endOffset = this.endOffset;
|
||||
braille.text = this.text;
|
||||
this.selectionStart = braille.selectionStart = aSelection.selectionStart + this.startOffset;
|
||||
this.selectionEnd = braille.selectionEnd = aSelection.selectionEnd + this.startOffset;
|
||||
this.selectionStart = braille.selectionStart =
|
||||
aSelection.selectionStart + this.startOffset;
|
||||
this.selectionEnd = braille.selectionEnd =
|
||||
aSelection.selectionEnd + this.startOffset;
|
||||
|
||||
return braille;
|
||||
}
|
||||
},
|
||||
|
||||
speechHelper: {
|
||||
EARCONS: ['virtual_cursor_move.ogg',
|
||||
'virtual_cursor_key.ogg',
|
||||
'clicked.ogg'],
|
||||
|
||||
earconBuffers: {},
|
||||
|
||||
inited: false,
|
||||
|
||||
webspeechEnabled: false,
|
||||
|
||||
deferredOutputs: [],
|
||||
|
||||
init: function init() {
|
||||
let window = Utils.win;
|
||||
this.webspeechEnabled = !!window.speechSynthesis &&
|
||||
!!window.SpeechSynthesisUtterance;
|
||||
|
||||
let settingsToGet = 2;
|
||||
let settingsCallback = (aName, aSetting) => {
|
||||
if (--settingsToGet > 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.inited = true;
|
||||
|
||||
for (let actions of this.deferredOutputs) {
|
||||
this.output(actions);
|
||||
}
|
||||
};
|
||||
|
||||
this._volumeSetting = new SettingCache(
|
||||
'accessibility.screenreader-volume', settingsCallback,
|
||||
{ defaultValue: 1, callbackNow: true, callbackOnce: true });
|
||||
this._rateSetting = new SettingCache(
|
||||
'accessibility.screenreader-rate', settingsCallback,
|
||||
{ defaultValue: 0, callbackNow: true, callbackOnce: true });
|
||||
|
||||
for (let earcon of this.EARCONS) {
|
||||
let earconName = /(^.*)\..*$/.exec(earcon)[1];
|
||||
this.earconBuffers[earconName] = new WeakMap();
|
||||
this.earconBuffers[earconName].set(
|
||||
window, new window.Audio('chrome://global/content/accessibility/' + earcon));
|
||||
}
|
||||
},
|
||||
|
||||
uninit: function uninit() {
|
||||
if (this.inited) {
|
||||
delete this._volumeSetting;
|
||||
delete this._rateSetting;
|
||||
}
|
||||
this.inited = false;
|
||||
},
|
||||
|
||||
output: function output(aActions) {
|
||||
if (!this.inited) {
|
||||
this.deferredOutputs.push(aActions);
|
||||
return;
|
||||
}
|
||||
|
||||
for (let action of aActions) {
|
||||
let window = Utils.win;
|
||||
Logger.debug('tts.' + action.method, '"' + action.data + '"',
|
||||
JSON.stringify(action.options));
|
||||
|
||||
if (!action.options.enqueue && this.webspeechEnabled) {
|
||||
window.speechSynthesis.cancel();
|
||||
}
|
||||
|
||||
if (action.method === 'speak' && this.webspeechEnabled) {
|
||||
let utterance = new window.SpeechSynthesisUtterance(action.data);
|
||||
let requestedRate = this._rateSetting.value;
|
||||
utterance.volume = this._volumeSetting.value;
|
||||
utterance.rate = requestedRate >= 0 ?
|
||||
requestedRate + 1 : 1 / (Math.abs(requestedRate) + 1);
|
||||
window.speechSynthesis.speak(utterance);
|
||||
} else if (action.method === 'playEarcon') {
|
||||
let audioBufferWeakMap = this.earconBuffers[action.data];
|
||||
if (audioBufferWeakMap) {
|
||||
let node = audioBufferWeakMap.get(window).cloneNode(false);
|
||||
node.volume = this._volumeSetting.value;
|
||||
node.play();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
start: function start() {
|
||||
Cu.import('resource://gre/modules/Geometry.jsm');
|
||||
this.speechHelper.init();
|
||||
},
|
||||
|
||||
stop: function stop() {
|
||||
@ -607,22 +525,32 @@ var Output = {
|
||||
Utils.win.document.documentElement.removeChild(this.highlightBox.get());
|
||||
delete this.highlightBox;
|
||||
}
|
||||
},
|
||||
|
||||
if (this.announceBox) {
|
||||
Utils.win.document.documentElement.removeChild(this.announceBox.get());
|
||||
delete this.announceBox;
|
||||
B2G: function B2G(aDetails) {
|
||||
let details = {
|
||||
type: 'accessfu-output',
|
||||
details: JSON.stringify(aDetails)
|
||||
};
|
||||
let window = Utils.win;
|
||||
if (window.shell) {
|
||||
// On B2G device.
|
||||
window.shell.sendChromeEvent(details);
|
||||
} else {
|
||||
// Dispatch custom event to have support for desktop and screen reader
|
||||
// emulator add-on.
|
||||
window.dispatchEvent(new window.CustomEvent(details.type, {
|
||||
bubbles: true,
|
||||
cancelable: true,
|
||||
detail: details
|
||||
}));
|
||||
}
|
||||
|
||||
this.speechHelper.uninit();
|
||||
},
|
||||
|
||||
Speech: function Speech(aDetails, aBrowser) {
|
||||
this.speechHelper.output(aDetails.actions);
|
||||
},
|
||||
|
||||
Visual: function Visual(aDetails, aBrowser) {
|
||||
switch (aDetails.method) {
|
||||
case 'showBounds':
|
||||
Visual: function Visual(aDetail, aBrowser) {
|
||||
switch (aDetail.eventType) {
|
||||
case 'viewport-change':
|
||||
case 'vc-change':
|
||||
{
|
||||
let highlightBox = null;
|
||||
if (!this.highlightBox) {
|
||||
@ -643,8 +571,8 @@ var Output = {
|
||||
highlightBox = this.highlightBox.get();
|
||||
}
|
||||
|
||||
let padding = aDetails.padding;
|
||||
let r = AccessFu.adjustContentBounds(aDetails.bounds, aBrowser, true);
|
||||
let padding = aDetail.padding;
|
||||
let r = AccessFu.adjustContentBounds(aDetail.bounds, aBrowser, true);
|
||||
|
||||
// First hide it to avoid flickering when changing the style.
|
||||
highlightBox.style.display = 'none';
|
||||
@ -656,43 +584,12 @@ var Output = {
|
||||
|
||||
break;
|
||||
}
|
||||
case 'hideBounds':
|
||||
case 'tabstate-change':
|
||||
{
|
||||
let highlightBox = this.highlightBox ? this.highlightBox.get() : null;
|
||||
if (highlightBox)
|
||||
if (highlightBox) {
|
||||
highlightBox.style.display = 'none';
|
||||
break;
|
||||
}
|
||||
case 'showAnnouncement':
|
||||
{
|
||||
let announceBox = this.announceBox ? this.announceBox.get() : null;
|
||||
if (!announceBox) {
|
||||
announceBox = Utils.win.document.
|
||||
createElementNS('http://www.w3.org/1999/xhtml', 'div');
|
||||
announceBox.id = 'announce-box';
|
||||
Utils.win.document.documentElement.appendChild(announceBox);
|
||||
this.announceBox = Cu.getWeakReference(announceBox);
|
||||
}
|
||||
|
||||
announceBox.innerHTML = '<div>' + aDetails.text + '</div>';
|
||||
announceBox.classList.add('showing');
|
||||
|
||||
if (this._announceHideTimeout)
|
||||
Utils.win.clearTimeout(this._announceHideTimeout);
|
||||
|
||||
if (aDetails.duration > 0)
|
||||
this._announceHideTimeout = Utils.win.setTimeout(
|
||||
function () {
|
||||
announceBox.classList.remove('showing');
|
||||
this._announceHideTimeout = 0;
|
||||
}.bind(this), aDetails.duration);
|
||||
break;
|
||||
}
|
||||
case 'hideAnnouncement':
|
||||
{
|
||||
let announceBox = this.announceBox ? this.announceBox.get() : null;
|
||||
if (announceBox)
|
||||
announceBox.classList.remove('showing');
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -716,32 +613,33 @@ var Output = {
|
||||
return;
|
||||
}
|
||||
|
||||
for each (let androidEvent in aDetails) {
|
||||
for (let androidEvent of aDetails) {
|
||||
androidEvent.type = 'Accessibility:Event';
|
||||
if (androidEvent.bounds)
|
||||
androidEvent.bounds = AccessFu.adjustContentBounds(androidEvent.bounds, aBrowser);
|
||||
if (androidEvent.bounds) {
|
||||
androidEvent.bounds = AccessFu.adjustContentBounds(
|
||||
androidEvent.bounds, aBrowser);
|
||||
}
|
||||
|
||||
switch(androidEvent.eventType) {
|
||||
case ANDROID_VIEW_TEXT_CHANGED:
|
||||
androidEvent.brailleOutput = this.brailleState.adjustText(androidEvent.text);
|
||||
androidEvent.brailleOutput = this.brailleState.adjustText(
|
||||
androidEvent.text);
|
||||
break;
|
||||
case ANDROID_VIEW_TEXT_SELECTION_CHANGED:
|
||||
androidEvent.brailleOutput = this.brailleState.adjustSelection(androidEvent.brailleOutput);
|
||||
androidEvent.brailleOutput = this.brailleState.adjustSelection(
|
||||
androidEvent.brailleOutput);
|
||||
break;
|
||||
default:
|
||||
androidEvent.brailleOutput = this.brailleState.init(androidEvent.brailleOutput);
|
||||
androidEvent.brailleOutput = this.brailleState.init(
|
||||
androidEvent.brailleOutput);
|
||||
break;
|
||||
}
|
||||
this.androidBridge.handleGeckoMessage(androidEvent);
|
||||
}
|
||||
},
|
||||
|
||||
Haptic: function Haptic(aDetails, aBrowser) {
|
||||
Utils.win.navigator.vibrate(aDetails.pattern);
|
||||
},
|
||||
|
||||
Braille: function Braille(aDetails, aBrowser) {
|
||||
Logger.debug('Braille output: ' + aDetails.text);
|
||||
Braille: function Braille(aDetails) {
|
||||
Logger.debug('Braille output: ' + aDetails.output);
|
||||
}
|
||||
};
|
||||
|
||||
@ -849,16 +747,18 @@ var Input = {
|
||||
let target = aEvent.target;
|
||||
|
||||
// Ignore keys with modifiers so the content could take advantage of them.
|
||||
if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey)
|
||||
if (aEvent.ctrlKey || aEvent.altKey || aEvent.metaKey) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (aEvent.keyCode) {
|
||||
case 0:
|
||||
// an alphanumeric key was pressed, handle it separately.
|
||||
// If it was pressed with either alt or ctrl, just pass through.
|
||||
// If it was pressed with meta, pass the key on without the meta.
|
||||
if (this.editState.editing)
|
||||
if (this.editState.editing) {
|
||||
return;
|
||||
}
|
||||
|
||||
let key = String.fromCharCode(aEvent.charCode);
|
||||
try {
|
||||
@ -870,43 +770,50 @@ var Input = {
|
||||
break;
|
||||
case aEvent.DOM_VK_RIGHT:
|
||||
if (this.editState.editing) {
|
||||
if (!this.editState.atEnd)
|
||||
if (!this.editState.atEnd) {
|
||||
// Don't move forward if caret is not at end of entry.
|
||||
// XXX: Fix for rtl
|
||||
return;
|
||||
else
|
||||
} else {
|
||||
target.blur();
|
||||
}
|
||||
}
|
||||
this.moveCursor(aEvent.shiftKey ? 'moveLast' : 'moveNext', 'Simple', 'keyboard');
|
||||
this.moveCursor(aEvent.shiftKey ?
|
||||
'moveLast' : 'moveNext', 'Simple', 'keyboard');
|
||||
break;
|
||||
case aEvent.DOM_VK_LEFT:
|
||||
if (this.editState.editing) {
|
||||
if (!this.editState.atStart)
|
||||
if (!this.editState.atStart) {
|
||||
// Don't move backward if caret is not at start of entry.
|
||||
// XXX: Fix for rtl
|
||||
return;
|
||||
else
|
||||
} else {
|
||||
target.blur();
|
||||
}
|
||||
}
|
||||
this.moveCursor(aEvent.shiftKey ? 'moveFirst' : 'movePrevious', 'Simple', 'keyboard');
|
||||
this.moveCursor(aEvent.shiftKey ?
|
||||
'moveFirst' : 'movePrevious', 'Simple', 'keyboard');
|
||||
break;
|
||||
case aEvent.DOM_VK_UP:
|
||||
if (this.editState.multiline) {
|
||||
if (!this.editState.atStart)
|
||||
if (!this.editState.atStart) {
|
||||
// Don't blur content if caret is not at start of text area.
|
||||
return;
|
||||
else
|
||||
} else {
|
||||
target.blur();
|
||||
}
|
||||
}
|
||||
|
||||
if (Utils.MozBuildApp == 'mobile/android')
|
||||
if (Utils.MozBuildApp == 'mobile/android') {
|
||||
// Return focus to native Android browser chrome.
|
||||
Services.androidBridge.handleGeckoMessage(
|
||||
{ type: 'ToggleChrome:Focus' });
|
||||
}
|
||||
break;
|
||||
case aEvent.DOM_VK_RETURN:
|
||||
if (this.editState.editing)
|
||||
if (this.editState.editing) {
|
||||
return;
|
||||
}
|
||||
this.activateCurrent();
|
||||
break;
|
||||
default:
|
||||
@ -980,7 +887,8 @@ var Input = {
|
||||
|
||||
activateContextMenu: function activateContextMenu(aDetails) {
|
||||
if (Utils.MozBuildApp === 'mobile/android') {
|
||||
let p = AccessFu.adjustContentBounds(aDetails.bounds, Utils.CurrentBrowser,
|
||||
let p = AccessFu.adjustContentBounds(aDetails.bounds,
|
||||
Utils.CurrentBrowser,
|
||||
true, true).center();
|
||||
Services.obs.notifyObservers(null, 'Gesture:LongPress',
|
||||
JSON.stringify({x: p.x, y: p.y}));
|
||||
@ -999,7 +907,8 @@ var Input = {
|
||||
|
||||
sendScrollMessage: function sendScrollMessage(aPage, aHorizontal) {
|
||||
let mm = Utils.getMessageManager(Utils.CurrentBrowser);
|
||||
mm.sendAsyncMessage('AccessFu:Scroll', {page: aPage, horizontal: aHorizontal, origin: 'top'});
|
||||
mm.sendAsyncMessage('AccessFu:Scroll',
|
||||
{page: aPage, horizontal: aHorizontal, origin: 'top'});
|
||||
},
|
||||
|
||||
doScroll: function doScroll(aDetails) {
|
||||
@ -1058,13 +967,15 @@ var Input = {
|
||||
},
|
||||
|
||||
previous: function quickNavMode_previous() {
|
||||
if (--this._currentIndex < 0)
|
||||
if (--this._currentIndex < 0) {
|
||||
this._currentIndex = this.modes.length - 1;
|
||||
}
|
||||
},
|
||||
|
||||
next: function quickNavMode_next() {
|
||||
if (++this._currentIndex >= this.modes.length)
|
||||
if (++this._currentIndex >= this.modes.length) {
|
||||
this._currentIndex = 0;
|
||||
}
|
||||
},
|
||||
|
||||
updateModes: function updateModes(aModes) {
|
||||
|
@ -2,17 +2,16 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global Components, XPCOMUtils, Utils, PrefCache, States, Roles, Logger */
|
||||
/* exported UtteranceGenerator, BrailleGenerator */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
const {utils: Cu, interfaces: Ci} = Components;
|
||||
|
||||
const INCLUDE_DESC = 0x01;
|
||||
const INCLUDE_NAME = 0x02;
|
||||
const INCLUDE_VALUE = 0x04;
|
||||
const INCLUDE_CUSTOM = 0x08;
|
||||
const NAME_FROM_SUBTREE_RULE = 0x10;
|
||||
const IGNORE_EXPLICIT_NAME = 0x20;
|
||||
|
||||
@ -20,22 +19,20 @@ const OUTPUT_DESC_FIRST = 0;
|
||||
const OUTPUT_DESC_LAST = 1;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrefCache',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PrefCache', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm',
|
||||
'resource://gre/modules/PluralForm.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator'];
|
||||
this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator']; // jshint ignore:line
|
||||
|
||||
this.OutputGenerator = {
|
||||
let OutputGenerator = {
|
||||
|
||||
defaultOutputOrder: OUTPUT_DESC_LAST,
|
||||
|
||||
@ -44,12 +41,9 @@ this.OutputGenerator = {
|
||||
* @param {PivotContext} aContext object that generates and caches
|
||||
* context information for a given accessible and its relationship with
|
||||
* another accessible.
|
||||
* @return {Object} An object that neccessarily has an output property which
|
||||
* is an array of strings. Depending on the utterance order,
|
||||
* the strings describe the context for an accessible object either
|
||||
* @return {Object} An array of speech data. Depending on the utterance order,
|
||||
* the data describes the context for an accessible object either
|
||||
* starting from the accessible's ancestry or accessible's subtree.
|
||||
* The object may also have properties specific to the type of output
|
||||
* generated.
|
||||
*/
|
||||
genForContext: function genForContext(aContext) {
|
||||
let output = [];
|
||||
@ -73,19 +67,16 @@ this.OutputGenerator = {
|
||||
if (this.outputOrder === OUTPUT_DESC_FIRST) {
|
||||
contextStart.forEach(addOutput);
|
||||
addOutput(aContext.accessible);
|
||||
[addOutput(node) for
|
||||
(node of aContext.subtreeGenerator(true, ignoreSubtree))];
|
||||
[addOutput(node) for // jshint ignore:line
|
||||
(node of aContext.subtreeGenerator(true, ignoreSubtree))]; // jshint ignore:line
|
||||
} else {
|
||||
[addOutput(node) for
|
||||
(node of aContext.subtreeGenerator(false, ignoreSubtree))];
|
||||
[addOutput(node) for // jshint ignore:line
|
||||
(node of aContext.subtreeGenerator(false, ignoreSubtree))]; // jshint ignore:line
|
||||
addOutput(aContext.accessible);
|
||||
contextStart.reverse().forEach(addOutput);
|
||||
}
|
||||
|
||||
// Clean up the white space.
|
||||
let trimmed;
|
||||
output = [trimmed for (word of output) if (trimmed = word.trim())];
|
||||
return {output: output};
|
||||
return output;
|
||||
},
|
||||
|
||||
|
||||
@ -96,10 +87,10 @@ this.OutputGenerator = {
|
||||
* @param {PivotContext} aContext object that generates and caches
|
||||
* context information for a given accessible and its relationship with
|
||||
* another accessible.
|
||||
* @return {Array} Two string array. The first string describes the object
|
||||
* and its state. The second string is the object's name. Whether the
|
||||
* object's description or it's role is included is determined by
|
||||
* {@link roleRuleMap}.
|
||||
* @return {Array} A 2 element array of speech data. The first element
|
||||
* describes the object and its state. The second element is the object's
|
||||
* name. Whether the object's description or it's role is included is
|
||||
* determined by {@link roleRuleMap}.
|
||||
*/
|
||||
genForObject: function genForObject(aAccessible, aContext) {
|
||||
let roleString = Utils.AccRetrieval.getStringRole(aAccessible.role);
|
||||
@ -109,8 +100,9 @@ this.OutputGenerator = {
|
||||
|
||||
let flags = this.roleRuleMap[roleString] || 0;
|
||||
|
||||
if (aAccessible.childCount == 0)
|
||||
if (aAccessible.childCount === 0) {
|
||||
flags |= INCLUDE_NAME;
|
||||
}
|
||||
|
||||
return func.apply(this, [aAccessible, roleString,
|
||||
Utils.getState(aAccessible), flags, aContext]);
|
||||
@ -122,17 +114,16 @@ this.OutputGenerator = {
|
||||
* invoked in.
|
||||
* @param {string} aActionName the name of the action, one of the keys in
|
||||
* {@link gActionMap}.
|
||||
* @return {Array} A one string array with the action.
|
||||
* @return {Array} A one element array with action data.
|
||||
*/
|
||||
genForAction: function genForAction(aObject, aActionName) {},
|
||||
genForAction: function genForAction(aObject, aActionName) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Generates output for an announcement. Basically attempts to localize
|
||||
* the announcement string.
|
||||
* Generates output for an announcement.
|
||||
* @param {string} aAnnouncement unlocalized announcement.
|
||||
* @return {Array} A one string array with the announcement.
|
||||
* @return {Array} An announcement speech data to be localized.
|
||||
*/
|
||||
genForAnnouncement: function genForAnnouncement(aAnnouncement) {},
|
||||
genForAnnouncement: function genForAnnouncement(aAnnouncement) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Generates output for a tab state change.
|
||||
@ -142,17 +133,23 @@ this.OutputGenerator = {
|
||||
* {@link Presenter.tabStateChanged}.
|
||||
* @return {Array} The tab state utterace.
|
||||
*/
|
||||
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {},
|
||||
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Generates output for announcing entering and leaving editing mode.
|
||||
* @param {aIsEditing} boolean true if we are in editing mode
|
||||
* @return {Array} The mode utterance
|
||||
*/
|
||||
genForEditingMode: function genForEditingMode(aIsEditing) {},
|
||||
genForEditingMode: function genForEditingMode(aIsEditing) {}, // jshint ignore:line
|
||||
|
||||
_getContextStart: function getContextStart(aContext) {},
|
||||
_getContextStart: function getContextStart(aContext) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Adds an accessible name and description to the output if available.
|
||||
* @param {Array} aOutput Output array.
|
||||
* @param {nsIAccessible} aAccessible current accessible object.
|
||||
* @param {Number} aFlags output flags.
|
||||
*/
|
||||
_addName: function _addName(aOutput, aAccessible, aFlags) {
|
||||
let name;
|
||||
if ((Utils.getAttributes(aAccessible)['explicit-name'] === 'true' &&
|
||||
@ -173,10 +170,10 @@ this.OutputGenerator = {
|
||||
}
|
||||
}
|
||||
|
||||
if (name) {
|
||||
aOutput[this.outputOrder === OUTPUT_DESC_FIRST ?
|
||||
'push' : 'unshift'](name);
|
||||
if (!name || !name.trim()) {
|
||||
return;
|
||||
}
|
||||
aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'](name);
|
||||
},
|
||||
|
||||
/**
|
||||
@ -189,23 +186,18 @@ this.OutputGenerator = {
|
||||
if (!landmarkName) {
|
||||
return;
|
||||
}
|
||||
|
||||
let landmark = Utils.stringBundle.GetStringFromName(landmarkName);
|
||||
if (!landmark) {
|
||||
return;
|
||||
}
|
||||
|
||||
aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push'](
|
||||
landmark);
|
||||
aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push']({
|
||||
string: landmarkName
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
* Adds an entry type attribute to the description if available.
|
||||
* @param {Array} aDesc Description array.
|
||||
* @param {Array} aOutput Output array.
|
||||
* @param {nsIAccessible} aAccessible current accessible object.
|
||||
* @param {String} aRoleStr aAccessible's role string.
|
||||
*/
|
||||
_addType: function _addType(aDesc, aAccessible, aRoleStr) {
|
||||
_addType: function _addType(aOutput, aAccessible, aRoleStr) {
|
||||
if (aRoleStr !== 'entry') {
|
||||
return;
|
||||
}
|
||||
@ -215,14 +207,13 @@ this.OutputGenerator = {
|
||||
if (!typeName || typeName === 'text') {
|
||||
return;
|
||||
}
|
||||
typeName = 'textInputType_' + typeName;
|
||||
try {
|
||||
aDesc.push(Utils.stringBundle.GetStringFromName(typeName));
|
||||
} catch (x) {
|
||||
Logger.warning('Failed to get a string from a bundle for', typeName);
|
||||
}
|
||||
aOutput.push({string: 'textInputType_' + typeName});
|
||||
},
|
||||
|
||||
_addState: function _addState(aOutput, aState) {}, // jshint ignore:line
|
||||
|
||||
_addRole: function _addRole(aOutput, aRoleStr) {}, // jshint ignore:line
|
||||
|
||||
get outputOrder() {
|
||||
if (!this._utteranceOrder) {
|
||||
this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance');
|
||||
@ -235,16 +226,6 @@ this.OutputGenerator = {
|
||||
return aName.replace(' ', '');
|
||||
},
|
||||
|
||||
_getLocalizedRole: function _getLocalizedRole(aRoleStr) {},
|
||||
|
||||
_getLocalizedState: function _getLocalizedState(aState) {},
|
||||
|
||||
_getPluralFormString: function _getPluralFormString(aString, aCount) {
|
||||
let str = Utils.stringBundle.GetStringFromName(this._getOutputName(aString));
|
||||
str = PluralForm.get(aCount, str);
|
||||
return str.replace('#1', aCount);
|
||||
},
|
||||
|
||||
roleRuleMap: {
|
||||
'menubar': INCLUDE_DESC,
|
||||
'scrollbar': INCLUDE_DESC,
|
||||
@ -322,32 +303,26 @@ this.OutputGenerator = {
|
||||
'app root': IGNORE_EXPLICIT_NAME },
|
||||
|
||||
objectOutputFunctions: {
|
||||
_generateBaseOutput: function _generateBaseOutput(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let output = [];
|
||||
_generateBaseOutput:
|
||||
function _generateBaseOutput(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let output = [];
|
||||
|
||||
if (aFlags & INCLUDE_DESC) {
|
||||
let desc = this._getLocalizedState(aState);
|
||||
let roleStr = this._getLocalizedRole(aRoleStr);
|
||||
if (roleStr) {
|
||||
this._addType(desc, aAccessible, aRoleStr);
|
||||
desc.push(roleStr);
|
||||
if (aFlags & INCLUDE_DESC) {
|
||||
this._addState(output, aState);
|
||||
this._addType(output, aAccessible, aRoleStr);
|
||||
this._addRole(output, aRoleStr);
|
||||
}
|
||||
output.push(desc.join(' '));
|
||||
}
|
||||
|
||||
if (aFlags & INCLUDE_VALUE) {
|
||||
let value = aAccessible.value;
|
||||
if (value) {
|
||||
output[this.outputOrder === OUTPUT_DESC_FIRST ?
|
||||
'push' : 'unshift'](value);
|
||||
if (aFlags & INCLUDE_VALUE && aAccessible.value.trim()) {
|
||||
output[this.outputOrder === OUTPUT_DESC_FIRST ? 'push' : 'unshift'](
|
||||
aAccessible.value);
|
||||
}
|
||||
}
|
||||
|
||||
this._addName(output, aAccessible, aFlags);
|
||||
this._addLandmark(output, aAccessible);
|
||||
this._addName(output, aAccessible, aFlags);
|
||||
this._addLandmark(output, aAccessible);
|
||||
|
||||
return output;
|
||||
},
|
||||
return output;
|
||||
},
|
||||
|
||||
label: function label(aAccessible, aRoleStr, aState, aFlags, aContext) {
|
||||
if (aContext.isNestedControl ||
|
||||
@ -367,16 +342,16 @@ this.OutputGenerator = {
|
||||
},
|
||||
|
||||
pagetab: function pagetab(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let localizedRole = this._getLocalizedRole(aRoleStr);
|
||||
let itemno = {};
|
||||
let itemof = {};
|
||||
aAccessible.groupPosition({}, itemof, itemno);
|
||||
let output = [];
|
||||
let desc = this._getLocalizedState(aState);
|
||||
desc.push(
|
||||
Utils.stringBundle.formatStringFromName(
|
||||
'objItemOf', [localizedRole, itemno.value, itemof.value], 3));
|
||||
output.push(desc.join(' '));
|
||||
this._addState(output, aState);
|
||||
this._addRole(output, aRoleStr);
|
||||
output.push({
|
||||
string: 'objItemOfN',
|
||||
args: [itemno.value, itemof.value]
|
||||
});
|
||||
|
||||
this._addName(output, aAccessible, aFlags);
|
||||
this._addLandmark(output, aAccessible);
|
||||
@ -398,13 +373,14 @@ this.OutputGenerator = {
|
||||
if (table.isProbablyForLayout()) {
|
||||
return output;
|
||||
}
|
||||
let tableColumnInfo = this._getPluralFormString('tableColumnInfo',
|
||||
table.columnCount);
|
||||
let tableRowInfo = this._getPluralFormString('tableRowInfo',
|
||||
table.rowCount);
|
||||
output.push(Utils.stringBundle.formatStringFromName(
|
||||
this._getOutputName('tableInfo'), [this._getLocalizedRole(aRoleStr),
|
||||
tableColumnInfo, tableRowInfo], 3));
|
||||
this._addRole(output, aRoleStr);
|
||||
output.push.call(output, {
|
||||
string: this._getOutputName('tblColumnInfo'),
|
||||
count: table.columnCount
|
||||
}, {
|
||||
string: this._getOutputName('tblRowInfo'),
|
||||
count: table.rowCount
|
||||
});
|
||||
this._addName(output, aAccessible, aFlags);
|
||||
this._addLandmark(output, aAccessible);
|
||||
return output;
|
||||
@ -415,7 +391,7 @@ this.OutputGenerator = {
|
||||
|
||||
/**
|
||||
* Generates speech utterances from objects, actions and state changes.
|
||||
* An utterance is an array of strings.
|
||||
* An utterance is an array of speech data.
|
||||
*
|
||||
* It should not be assumed that flattening an utterance array would create a
|
||||
* gramatically correct sentence. For example, {@link genForObject} might
|
||||
@ -429,7 +405,7 @@ this.OutputGenerator = {
|
||||
* clicked event. Speaking only 'clicked' makes sense. Speaking 'button' does
|
||||
* not.
|
||||
*/
|
||||
this.UtteranceGenerator = {
|
||||
this.UtteranceGenerator = { // jshint ignore:line
|
||||
__proto__: OutputGenerator,
|
||||
|
||||
gActionMap: {
|
||||
@ -451,63 +427,58 @@ this.UtteranceGenerator = {
|
||||
|
||||
//TODO: May become more verbose in the future.
|
||||
genForAction: function genForAction(aObject, aActionName) {
|
||||
return [Utils.stringBundle.GetStringFromName(this.gActionMap[aActionName])];
|
||||
return [{string: this.gActionMap[aActionName]}];
|
||||
},
|
||||
|
||||
genForLiveRegion: function genForLiveRegion(aContext, aIsHide, aModifiedText) {
|
||||
let utterance = [];
|
||||
if (aIsHide) {
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('hidden'));
|
||||
}
|
||||
return utterance.concat(
|
||||
aModifiedText || this.genForContext(aContext).output);
|
||||
},
|
||||
genForLiveRegion:
|
||||
function genForLiveRegion(aContext, aIsHide, aModifiedText) {
|
||||
let utterance = [];
|
||||
if (aIsHide) {
|
||||
utterance.push({string: 'hidden'});
|
||||
}
|
||||
return utterance.concat(aModifiedText || this.genForContext(aContext));
|
||||
},
|
||||
|
||||
genForAnnouncement: function genForAnnouncement(aAnnouncement) {
|
||||
try {
|
||||
return [Utils.stringBundle.GetStringFromName(aAnnouncement)];
|
||||
} catch (x) {
|
||||
return [aAnnouncement];
|
||||
}
|
||||
return [{
|
||||
string: aAnnouncement
|
||||
}];
|
||||
},
|
||||
|
||||
genForTabStateChange: function genForTabStateChange(aObject, aTabState) {
|
||||
switch (aTabState) {
|
||||
case 'newtab':
|
||||
return [Utils.stringBundle.GetStringFromName('tabNew')];
|
||||
return [{string: 'tabNew'}];
|
||||
case 'loading':
|
||||
return [Utils.stringBundle.GetStringFromName('tabLoading')];
|
||||
return [{string: 'tabLoading'}];
|
||||
case 'loaded':
|
||||
return [aObject.name || '',
|
||||
Utils.stringBundle.GetStringFromName('tabLoaded')];
|
||||
return [aObject.name, {string: 'tabLoaded'}];
|
||||
case 'loadstopped':
|
||||
return [Utils.stringBundle.GetStringFromName('tabLoadStopped')];
|
||||
return [{string: 'tabLoadStopped'}];
|
||||
case 'reload':
|
||||
return [Utils.stringBundle.GetStringFromName('tabReload')];
|
||||
return [{string: 'tabReload'}];
|
||||
default:
|
||||
return [];
|
||||
}
|
||||
},
|
||||
|
||||
genForEditingMode: function genForEditingMode(aIsEditing) {
|
||||
return [Utils.stringBundle.GetStringFromName(
|
||||
aIsEditing ? 'editingMode' : 'navigationMode')];
|
||||
return [{string: aIsEditing ? 'editingMode' : 'navigationMode'}];
|
||||
},
|
||||
|
||||
objectOutputFunctions: {
|
||||
|
||||
__proto__: OutputGenerator.objectOutputFunctions,
|
||||
|
||||
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) {
|
||||
return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
|
||||
defaultFunc: function defaultFunc() {
|
||||
return this.objectOutputFunctions._generateBaseOutput.apply(
|
||||
this, arguments);
|
||||
},
|
||||
|
||||
heading: function heading(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let level = {};
|
||||
aAccessible.groupPosition(level, {}, {});
|
||||
let utterance =
|
||||
[Utils.stringBundle.formatStringFromName(
|
||||
'headingLevel', [level.value], 1)];
|
||||
let utterance = [{string: 'headingLevel', args: [level.value]}];
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
@ -520,10 +491,14 @@ this.UtteranceGenerator = {
|
||||
let itemof = {};
|
||||
aAccessible.groupPosition({}, itemof, itemno);
|
||||
let utterance = [];
|
||||
if (itemno.value == 1) // Start of list
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('listStart'));
|
||||
else if (itemno.value == itemof.value) // last item
|
||||
utterance.push(Utils.stringBundle.GetStringFromName('listEnd'));
|
||||
if (itemno.value == 1) {
|
||||
// Start of list
|
||||
utterance.push({string: 'listStart'});
|
||||
}
|
||||
else if (itemno.value == itemof.value) {
|
||||
// last item
|
||||
utterance.push({string: 'listEnd'});
|
||||
}
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
@ -536,16 +511,18 @@ this.UtteranceGenerator = {
|
||||
(aAccessible, aRoleStr, aFlags, aAccessible.childCount);
|
||||
},
|
||||
|
||||
definitionlist: function definitionlist(aAccessible, aRoleStr, aState, aFlags) {
|
||||
return this._getListUtterance
|
||||
(aAccessible, aRoleStr, aFlags, aAccessible.childCount / 2);
|
||||
},
|
||||
definitionlist:
|
||||
function definitionlist(aAccessible, aRoleStr, aState, aFlags) {
|
||||
return this._getListUtterance
|
||||
(aAccessible, aRoleStr, aFlags, aAccessible.childCount / 2);
|
||||
},
|
||||
|
||||
application: function application(aAccessible, aRoleStr, aState, aFlags) {
|
||||
// Don't utter location of applications, it gets tiring.
|
||||
if (aAccessible.name != aAccessible.DOMNode.location)
|
||||
if (aAccessible.name != aAccessible.DOMNode.location) {
|
||||
return this.objectOutputFunctions.defaultFunc.apply(this,
|
||||
[aAccessible, aRoleStr, aState, aFlags]);
|
||||
}
|
||||
|
||||
return [];
|
||||
},
|
||||
@ -554,35 +531,32 @@ this.UtteranceGenerator = {
|
||||
let utterance = [];
|
||||
let cell = aContext.getCellInfo(aAccessible);
|
||||
if (cell) {
|
||||
let desc = [];
|
||||
let addCellChanged = function addCellChanged(aDesc, aChanged, aString, aIndex) {
|
||||
if (aChanged) {
|
||||
aDesc.push(Utils.stringBundle.formatStringFromName(aString,
|
||||
[aIndex + 1], 1));
|
||||
}
|
||||
};
|
||||
let addExtent = function addExtent(aDesc, aExtent, aString) {
|
||||
let addCellChanged =
|
||||
function addCellChanged(aUtterance, aChanged, aString, aIndex) {
|
||||
if (aChanged) {
|
||||
aUtterance.push({string: aString, args: [aIndex + 1]});
|
||||
}
|
||||
};
|
||||
let addExtent = function addExtent(aUtterance, aExtent, aString) {
|
||||
if (aExtent > 1) {
|
||||
aDesc.push(Utils.stringBundle.formatStringFromName(aString,
|
||||
[aExtent], 1));
|
||||
aUtterance.push({string: aString, args: [aExtent]});
|
||||
}
|
||||
};
|
||||
let addHeaders = function addHeaders(aDesc, aHeaders) {
|
||||
let addHeaders = function addHeaders(aUtterance, aHeaders) {
|
||||
if (aHeaders.length > 0) {
|
||||
aDesc.push.apply(aDesc, aHeaders);
|
||||
aUtterance.push.apply(aUtterance, aHeaders);
|
||||
}
|
||||
};
|
||||
|
||||
addCellChanged(desc, cell.columnChanged, 'columnInfo', cell.columnIndex);
|
||||
addCellChanged(desc, cell.rowChanged, 'rowInfo', cell.rowIndex);
|
||||
addCellChanged(utterance, cell.columnChanged, 'columnInfo',
|
||||
cell.columnIndex);
|
||||
addCellChanged(utterance, cell.rowChanged, 'rowInfo', cell.rowIndex);
|
||||
|
||||
addExtent(desc, cell.columnExtent, 'spansColumns');
|
||||
addExtent(desc, cell.rowExtent, 'spansRows');
|
||||
addExtent(utterance, cell.columnExtent, 'spansColumns');
|
||||
addExtent(utterance, cell.rowExtent, 'spansRows');
|
||||
|
||||
addHeaders(desc, cell.columnHeaders);
|
||||
addHeaders(desc, cell.rowHeaders);
|
||||
|
||||
utterance.push(desc.join(' '));
|
||||
addHeaders(utterance, cell.columnHeaders);
|
||||
addHeaders(utterance, cell.rowHeaders);
|
||||
}
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
@ -612,86 +586,71 @@ this.UtteranceGenerator = {
|
||||
return aContext.newAncestry;
|
||||
},
|
||||
|
||||
_getLocalizedRole: function _getLocalizedRole(aRoleStr) {
|
||||
try {
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
this._getOutputName(aRoleStr));
|
||||
} catch (x) {
|
||||
return '';
|
||||
}
|
||||
_addRole: function _addRole(aOutput, aRoleStr) {
|
||||
aOutput.push({string: this._getOutputName(aRoleStr)});
|
||||
},
|
||||
|
||||
_getLocalizedState: function _getLocalizedState(aState) {
|
||||
let stateUtterances = [];
|
||||
_addState: function _addState(aOutput, aState) {
|
||||
|
||||
if (aState.contains(States.UNAVAILABLE)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateUnavailable'));
|
||||
aOutput.push({string: 'stateUnavailable'});
|
||||
}
|
||||
|
||||
// Don't utter this in Jelly Bean, we let TalkBack do it for us there.
|
||||
// This is because we expose the checked information on the node itself.
|
||||
// XXX: this means the checked state is always appended to the end, regardless
|
||||
// of the utterance ordering preference.
|
||||
// XXX: this means the checked state is always appended to the end,
|
||||
// regardless of the utterance ordering preference.
|
||||
if ((Utils.AndroidSdkVersion < 16 || Utils.MozBuildApp === 'browser') &&
|
||||
aState.contains(States.CHECKABLE)) {
|
||||
let statetr = aState.contains(States.CHECKED) ?
|
||||
'stateChecked' : 'stateNotChecked';
|
||||
stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
|
||||
aOutput.push({string: statetr});
|
||||
}
|
||||
|
||||
if (aState.contains(States.PRESSED)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('statePressed'));
|
||||
aOutput.push({string: 'statePressed'});
|
||||
}
|
||||
|
||||
if (aState.contains(States.EXPANDABLE)) {
|
||||
let statetr = aState.contains(States.EXPANDED) ?
|
||||
'stateExpanded' : 'stateCollapsed';
|
||||
stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr));
|
||||
aOutput.push({string: statetr});
|
||||
}
|
||||
|
||||
if (aState.contains(States.REQUIRED)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateRequired'));
|
||||
aOutput.push({string: 'stateRequired'});
|
||||
}
|
||||
|
||||
if (aState.contains(States.TRAVERSED)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateTraversed'));
|
||||
aOutput.push({string: 'stateTraversed'});
|
||||
}
|
||||
|
||||
if (aState.contains(States.HASPOPUP)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateHasPopup'));
|
||||
aOutput.push({string: 'stateHasPopup'});
|
||||
}
|
||||
|
||||
if (aState.contains(States.SELECTED)) {
|
||||
stateUtterances.push(
|
||||
Utils.stringBundle.GetStringFromName('stateSelected'));
|
||||
aOutput.push({string: 'stateSelected'});
|
||||
}
|
||||
|
||||
return stateUtterances;
|
||||
},
|
||||
|
||||
_getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
|
||||
let desc = [];
|
||||
let roleStr = this._getLocalizedRole(aRoleStr);
|
||||
if (roleStr) {
|
||||
desc.push(roleStr);
|
||||
_getListUtterance:
|
||||
function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) {
|
||||
let utterance = [];
|
||||
this._addRole(utterance, aRoleStr);
|
||||
utterance.push({
|
||||
string: this._getOutputName('listItemsCount'),
|
||||
count: aItemCount
|
||||
});
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
|
||||
return utterance;
|
||||
}
|
||||
desc.push(this._getPluralFormString('listItemsCount', aItemCount));
|
||||
let utterance = [desc.join(' ')];
|
||||
|
||||
this._addName(utterance, aAccessible, aFlags);
|
||||
this._addLandmark(utterance, aAccessible);
|
||||
|
||||
return utterance;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
this.BrailleGenerator = {
|
||||
this.BrailleGenerator = { // jshint ignore:line
|
||||
__proto__: OutputGenerator,
|
||||
|
||||
genForContext: function genForContext(aContext) {
|
||||
@ -700,10 +659,10 @@ this.BrailleGenerator = {
|
||||
let acc = aContext.accessible;
|
||||
|
||||
// add the static text indicating a list item; do this for both listitems or
|
||||
// direct first children of listitems, because these are both common browsing
|
||||
// scenarios
|
||||
// direct first children of listitems, because these are both common
|
||||
// browsing scenarios
|
||||
let addListitemIndicator = function addListitemIndicator(indicator = '*') {
|
||||
output.output.unshift(indicator);
|
||||
output.unshift(indicator);
|
||||
};
|
||||
|
||||
if (acc.indexInParent === 1 &&
|
||||
@ -724,12 +683,6 @@ this.BrailleGenerator = {
|
||||
}
|
||||
}
|
||||
|
||||
if (acc instanceof Ci.nsIAccessibleText) {
|
||||
output.endOffset = this.outputOrder === OUTPUT_DESC_FIRST ?
|
||||
output.output.join(' ').length : acc.characterCount;
|
||||
output.startOffset = output.endOffset - acc.characterCount;
|
||||
}
|
||||
|
||||
return output;
|
||||
},
|
||||
|
||||
@ -737,8 +690,9 @@ this.BrailleGenerator = {
|
||||
|
||||
__proto__: OutputGenerator.objectOutputFunctions,
|
||||
|
||||
defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) {
|
||||
return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments);
|
||||
defaultFunc: function defaultFunc() {
|
||||
return this.objectOutputFunctions._generateBaseOutput.apply(
|
||||
this, arguments);
|
||||
},
|
||||
|
||||
listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) {
|
||||
@ -754,20 +708,19 @@ this.BrailleGenerator = {
|
||||
let braille = [];
|
||||
let cell = aContext.getCellInfo(aAccessible);
|
||||
if (cell) {
|
||||
let desc = [];
|
||||
let addHeaders = function addHeaders(aDesc, aHeaders) {
|
||||
let addHeaders = function addHeaders(aBraille, aHeaders) {
|
||||
if (aHeaders.length > 0) {
|
||||
aDesc.push.apply(aDesc, aHeaders);
|
||||
aBraille.push.apply(aBraille, aHeaders);
|
||||
}
|
||||
};
|
||||
|
||||
desc.push(Utils.stringBundle.formatStringFromName(
|
||||
this._getOutputName('cellInfo'), [cell.columnIndex + 1,
|
||||
cell.rowIndex + 1], 2));
|
||||
braille.push({
|
||||
string: this._getOutputName('cellInfo'),
|
||||
args: [cell.columnIndex + 1, cell.rowIndex + 1]
|
||||
});
|
||||
|
||||
addHeaders(desc, cell.columnHeaders);
|
||||
addHeaders(desc, cell.rowHeaders);
|
||||
braille.push(desc.join(' '));
|
||||
addHeaders(braille, cell.columnHeaders);
|
||||
addHeaders(braille, cell.rowHeaders);
|
||||
}
|
||||
|
||||
this._addName(braille, aAccessible, aFlags);
|
||||
@ -783,7 +736,7 @@ this.BrailleGenerator = {
|
||||
return this.objectOutputFunctions.cell.apply(this, arguments);
|
||||
},
|
||||
|
||||
statictext: function statictext(aAccessible, aRoleStr, aState, aFlags) {
|
||||
statictext: function statictext(aAccessible) {
|
||||
// Since we customize the list bullet's output, we add the static
|
||||
// text from the first node in each listitem, so skip it here.
|
||||
if (Utils.isListItemDecorator(aAccessible)) {
|
||||
@ -793,27 +746,25 @@ this.BrailleGenerator = {
|
||||
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
|
||||
},
|
||||
|
||||
_useStateNotRole: function _useStateNotRole(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let braille = [];
|
||||
_useStateNotRole:
|
||||
function _useStateNotRole(aAccessible, aRoleStr, aState, aFlags) {
|
||||
let braille = [];
|
||||
this._addState(braille, aState, aAccessible.role);
|
||||
this._addName(braille, aAccessible, aFlags);
|
||||
this._addLandmark(braille, aAccessible);
|
||||
|
||||
let desc = this._getLocalizedState(aState, aAccessible.role);
|
||||
braille.push(desc.join(' '));
|
||||
return braille;
|
||||
},
|
||||
|
||||
this._addName(braille, aAccessible, aFlags);
|
||||
this._addLandmark(braille, aAccessible);
|
||||
|
||||
return braille;
|
||||
},
|
||||
|
||||
checkbutton: function checkbutton(aAccessible, aRoleStr, aState, aFlags) {
|
||||
checkbutton: function checkbutton() {
|
||||
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
|
||||
},
|
||||
|
||||
radiobutton: function radiobutton(aAccessible, aRoleStr, aState, aFlags) {
|
||||
radiobutton: function radiobutton() {
|
||||
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
|
||||
},
|
||||
|
||||
togglebutton: function radiobutton(aAccessible, aRoleStr, aState, aFlags) {
|
||||
togglebutton: function togglebutton() {
|
||||
return this.objectOutputFunctions._useStateNotRole.apply(this, arguments);
|
||||
}
|
||||
},
|
||||
@ -830,42 +781,24 @@ this.BrailleGenerator = {
|
||||
return OutputGenerator._getOutputName(aName) + 'Abbr';
|
||||
},
|
||||
|
||||
_getLocalizedRole: function _getLocalizedRole(aRoleStr) {
|
||||
try {
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
this._getOutputName(aRoleStr));
|
||||
} catch (x) {
|
||||
try {
|
||||
return Utils.stringBundle.GetStringFromName(
|
||||
OutputGenerator._getOutputName(aRoleStr));
|
||||
} catch (y) {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
_addRole: function _addRole(aBraille, aRoleStr) {
|
||||
aBraille.push({string: this._getOutputName(aRoleStr)});
|
||||
},
|
||||
|
||||
_getLocalizedState: function _getLocalizedState(aState, aRole) {
|
||||
let stateBraille = [];
|
||||
|
||||
let getResultMarker = function getResultMarker(aMarker) {
|
||||
// aMarker is a simple boolean.
|
||||
let resultMarker = [];
|
||||
resultMarker.push('(');
|
||||
resultMarker.push(aMarker ? 'x' : ' ');
|
||||
resultMarker.push(')');
|
||||
|
||||
return resultMarker.join('');
|
||||
};
|
||||
|
||||
_addState: function _addState(aBraille, aState, aRole) {
|
||||
if (aState.contains(States.CHECKABLE)) {
|
||||
stateBraille.push(getResultMarker(aState.contains(States.CHECKED)));
|
||||
aBraille.push({
|
||||
string: aState.contains(States.CHECKED) ?
|
||||
this._getOutputName('stateChecked') :
|
||||
this._getOutputName('stateUnchecked')
|
||||
});
|
||||
}
|
||||
|
||||
if (aRole === Roles.TOGGLE_BUTTON) {
|
||||
stateBraille.push(getResultMarker(aState.contains(States.PRESSED)));
|
||||
aBraille.push({
|
||||
string: aState.contains(States.PRESSED) ?
|
||||
this._getOutputName('statePressed') :
|
||||
this._getOutputName('stateUnpressed')
|
||||
});
|
||||
}
|
||||
|
||||
return stateBraille;
|
||||
}
|
||||
|
||||
};
|
||||
|
@ -2,30 +2,31 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global Components, XPCOMUtils, Utils, Logger, BraillePresenter, Presentation,
|
||||
UtteranceGenerator, BrailleGenerator, States, Roles, PivotContext */
|
||||
/* exported Presentation */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results;
|
||||
const {utils: Cu, interfaces: Ci} = Components;
|
||||
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Utils',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Utils', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Logger',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Logger', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PivotContext',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PivotContext', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Utils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'UtteranceGenerator',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'UtteranceGenerator', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/OutputGenerator.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'BrailleGenerator',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'BrailleGenerator', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/OutputGenerator.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['Presentation'];
|
||||
this.EXPORTED_SYMBOLS = ['Presentation']; // jshint ignore:line
|
||||
|
||||
/**
|
||||
* The interface for all presenter classes. A presenter could be, for example,
|
||||
@ -46,38 +47,38 @@ Presenter.prototype = {
|
||||
* @param {int} aReason the reason for the pivot change.
|
||||
* See nsIAccessiblePivot.
|
||||
*/
|
||||
pivotChanged: function pivotChanged(aContext, aReason) {},
|
||||
pivotChanged: function pivotChanged(aContext, aReason) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* An object's action has been invoked.
|
||||
* @param {nsIAccessible} aObject the object that has been invoked.
|
||||
* @param {string} aActionName the name of the action.
|
||||
*/
|
||||
actionInvoked: function actionInvoked(aObject, aActionName) {},
|
||||
actionInvoked: function actionInvoked(aObject, aActionName) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Text has changed, either by the user or by the system. TODO.
|
||||
*/
|
||||
textChanged: function textChanged(aIsInserted, aStartOffset,
|
||||
aLength, aText,
|
||||
aModifiedText) {},
|
||||
textChanged: function textChanged(aIsInserted, aStartOffset, aLength, aText, // jshint ignore:line
|
||||
aModifiedText) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Text selection has changed. TODO.
|
||||
*/
|
||||
textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {},
|
||||
textSelectionChanged: function textSelectionChanged(
|
||||
aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Selection has changed. TODO.
|
||||
* @param {nsIAccessible} aObject the object that has been selected.
|
||||
*/
|
||||
selectionChanged: function selectionChanged(aObject) {},
|
||||
selectionChanged: function selectionChanged(aObject) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Value has changed.
|
||||
* @param {nsIAccessible} aAccessible the object whose value has changed.
|
||||
*/
|
||||
valueChanged: function valueChanged(aAccessible) {},
|
||||
valueChanged: function valueChanged(aAccessible) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* The tab, or the tab's document state has changed.
|
||||
@ -86,7 +87,7 @@ Presenter.prototype = {
|
||||
* @param {string} aPageState the state name for the tab, valid states are:
|
||||
* 'newtab', 'loading', 'newdoc', 'loaded', 'stopped', and 'reload'.
|
||||
*/
|
||||
tabStateChanged: function tabStateChanged(aDocObj, aPageState) {},
|
||||
tabStateChanged: function tabStateChanged(aDocObj, aPageState) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* The current tab has changed.
|
||||
@ -95,24 +96,24 @@ Presenter.prototype = {
|
||||
* @param {PivotContext} aVCContext context object for tab's current
|
||||
* virtual cursor position.
|
||||
*/
|
||||
tabSelected: function tabSelected(aDocContext, aVCContext) {},
|
||||
tabSelected: function tabSelected(aDocContext, aVCContext) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* The viewport has changed, either a scroll, pan, zoom, or
|
||||
* landscape/portrait toggle.
|
||||
* @param {Window} aWindow window of viewport that changed.
|
||||
*/
|
||||
viewportChanged: function viewportChanged(aWindow) {},
|
||||
viewportChanged: function viewportChanged(aWindow) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* We have entered or left text editing mode.
|
||||
*/
|
||||
editingModeChanged: function editingModeChanged(aIsEditing) {},
|
||||
editingModeChanged: function editingModeChanged(aIsEditing) {}, // jshint ignore:line
|
||||
|
||||
/**
|
||||
* Announce something. Typically an app state change.
|
||||
*/
|
||||
announce: function announce(aAnnouncement) {},
|
||||
announce: function announce(aAnnouncement) {}, // jshint ignore:line
|
||||
|
||||
|
||||
|
||||
@ -123,29 +124,28 @@ Presenter.prototype = {
|
||||
* @param {boolean} aIsHide An indicator of hide/remove event.
|
||||
* @param {string} aModifiedText Optional modified text.
|
||||
*/
|
||||
liveRegion: function liveRegionShown(aContext, aIsPolite, aIsHide,
|
||||
aModifiedText) {}
|
||||
liveRegion: function liveRegionShown(aContext, aIsPolite, aIsHide, // jshint ignore:line
|
||||
aModifiedText) {} // jshint ignore:line
|
||||
};
|
||||
|
||||
/**
|
||||
* Visual presenter. Draws a box around the virtual cursor's position.
|
||||
*/
|
||||
|
||||
this.VisualPresenter = function VisualPresenter() {
|
||||
function VisualPresenter() {
|
||||
this._displayedAccessibles = new WeakMap();
|
||||
};
|
||||
}
|
||||
|
||||
VisualPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
VisualPresenter.prototype = Object.create(Presenter.prototype);
|
||||
|
||||
type: 'Visual',
|
||||
VisualPresenter.prototype.type = 'Visual';
|
||||
|
||||
/**
|
||||
* The padding in pixels between the object and the highlight border.
|
||||
*/
|
||||
BORDER_PADDING: 2,
|
||||
/**
|
||||
* The padding in pixels between the object and the highlight border.
|
||||
*/
|
||||
VisualPresenter.prototype.BORDER_PADDING = 2;
|
||||
|
||||
viewportChanged: function VisualPresenter_viewportChanged(aWindow) {
|
||||
VisualPresenter.prototype.viewportChanged =
|
||||
function VisualPresenter_viewportChanged(aWindow) {
|
||||
let currentDisplay = this._displayedAccessibles.get(aWindow);
|
||||
if (!currentDisplay) {
|
||||
return null;
|
||||
@ -161,7 +161,7 @@ VisualPresenter.prototype = {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
method: 'showBounds',
|
||||
eventType: 'viewport-change',
|
||||
bounds: bounds,
|
||||
padding: this.BORDER_PADDING
|
||||
}
|
||||
@ -169,9 +169,10 @@ VisualPresenter.prototype = {
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
};
|
||||
|
||||
pivotChanged: function VisualPresenter_pivotChanged(aContext, aReason) {
|
||||
VisualPresenter.prototype.pivotChanged =
|
||||
function VisualPresenter_pivotChanged(aContext) {
|
||||
if (!aContext.accessible) {
|
||||
// XXX: Don't hide because another vc may be using the highlight.
|
||||
return null;
|
||||
@ -194,7 +195,7 @@ VisualPresenter.prototype = {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
method: 'showBounds',
|
||||
eventType: 'vc-change',
|
||||
bounds: bounds,
|
||||
padding: this.BORDER_PADDING
|
||||
}
|
||||
@ -203,61 +204,52 @@ VisualPresenter.prototype = {
|
||||
Logger.logException(e, 'Failed to get bounds');
|
||||
return null;
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
tabSelected: function VisualPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
VisualPresenter.prototype.tabSelected =
|
||||
function VisualPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
return this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
|
||||
},
|
||||
};
|
||||
|
||||
tabStateChanged: function VisualPresenter_tabStateChanged(aDocObj,
|
||||
aPageState) {
|
||||
if (aPageState == 'newdoc')
|
||||
return {type: this.type, details: {method: 'hideBounds'}};
|
||||
VisualPresenter.prototype.tabStateChanged =
|
||||
function VisualPresenter_tabStateChanged(aDocObj, aPageState) {
|
||||
if (aPageState == 'newdoc') {
|
||||
return {type: this.type, details: {eventType: 'tabstate-change'}};
|
||||
}
|
||||
|
||||
return null;
|
||||
},
|
||||
|
||||
announce: function VisualPresenter_announce(aAnnouncement) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
method: 'showAnnouncement',
|
||||
text: aAnnouncement,
|
||||
duration: 1000
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* Android presenter. Fires Android a11y events.
|
||||
*/
|
||||
function AndroidPresenter() {}
|
||||
|
||||
this.AndroidPresenter = function AndroidPresenter() {};
|
||||
AndroidPresenter.prototype = Object.create(Presenter.prototype);
|
||||
|
||||
AndroidPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
AndroidPresenter.prototype.type = 'Android';
|
||||
|
||||
type: 'Android',
|
||||
// Android AccessibilityEvent type constants.
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_CLICKED = 0x01;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_LONG_CLICKED = 0x02;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_SELECTED = 0x04;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_FOCUSED = 0x08;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_TEXT_CHANGED = 0x10;
|
||||
AndroidPresenter.prototype.ANDROID_WINDOW_STATE_CHANGED = 0x20;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_HOVER_ENTER = 0x80;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_HOVER_EXIT = 0x100;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_SCROLLED = 0x1000;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_TEXT_SELECTION_CHANGED = 0x2000;
|
||||
AndroidPresenter.prototype.ANDROID_ANNOUNCEMENT = 0x4000;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_ACCESSIBILITY_FOCUSED = 0x8000;
|
||||
AndroidPresenter.prototype.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY =
|
||||
0x20000;
|
||||
|
||||
// Android AccessibilityEvent type constants.
|
||||
ANDROID_VIEW_CLICKED: 0x01,
|
||||
ANDROID_VIEW_LONG_CLICKED: 0x02,
|
||||
ANDROID_VIEW_SELECTED: 0x04,
|
||||
ANDROID_VIEW_FOCUSED: 0x08,
|
||||
ANDROID_VIEW_TEXT_CHANGED: 0x10,
|
||||
ANDROID_WINDOW_STATE_CHANGED: 0x20,
|
||||
ANDROID_VIEW_HOVER_ENTER: 0x80,
|
||||
ANDROID_VIEW_HOVER_EXIT: 0x100,
|
||||
ANDROID_VIEW_SCROLLED: 0x1000,
|
||||
ANDROID_VIEW_TEXT_SELECTION_CHANGED: 0x2000,
|
||||
ANDROID_ANNOUNCEMENT: 0x4000,
|
||||
ANDROID_VIEW_ACCESSIBILITY_FOCUSED: 0x8000,
|
||||
ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY: 0x20000,
|
||||
|
||||
pivotChanged: function AndroidPresenter_pivotChanged(aContext, aReason) {
|
||||
if (!aContext.accessible)
|
||||
AndroidPresenter.prototype.pivotChanged =
|
||||
function AndroidPresenter_pivotChanged(aContext, aReason) {
|
||||
if (!aContext.accessible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let androidEvents = [];
|
||||
|
||||
@ -297,7 +289,8 @@ AndroidPresenter.prototype = {
|
||||
let state = Utils.getState(aContext.accessible);
|
||||
androidEvents.push({eventType: (isExploreByTouch) ?
|
||||
this.ANDROID_VIEW_HOVER_ENTER : focusEventType,
|
||||
text: UtteranceGenerator.genForContext(aContext).output,
|
||||
text: Utils.localize(UtteranceGenerator.genForContext(
|
||||
aContext)),
|
||||
bounds: aContext.bounds,
|
||||
clickable: aContext.accessible.actionCount > 0,
|
||||
checkable: state.contains(States.CHECKABLE),
|
||||
@ -310,39 +303,42 @@ AndroidPresenter.prototype = {
|
||||
type: this.type,
|
||||
details: androidEvents
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
actionInvoked: function AndroidPresenter_actionInvoked(aObject, aActionName) {
|
||||
AndroidPresenter.prototype.actionInvoked =
|
||||
function AndroidPresenter_actionInvoked(aObject, aActionName) {
|
||||
let state = Utils.getState(aObject);
|
||||
|
||||
// Checkable objects will have a state changed event we will use instead.
|
||||
if (state.contains(States.CHECKABLE))
|
||||
if (state.contains(States.CHECKABLE)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.type,
|
||||
details: [{
|
||||
eventType: this.ANDROID_VIEW_CLICKED,
|
||||
text: UtteranceGenerator.genForAction(aObject, aActionName),
|
||||
text: Utils.localize(UtteranceGenerator.genForAction(aObject,
|
||||
aActionName)),
|
||||
checked: state.contains(States.CHECKED)
|
||||
}]
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
tabSelected: function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
AndroidPresenter.prototype.tabSelected =
|
||||
function AndroidPresenter_tabSelected(aDocContext, aVCContext) {
|
||||
// Send a pivot change message with the full context utterance for this doc.
|
||||
return this.pivotChanged(aVCContext, Ci.nsIAccessiblePivot.REASON_NONE);
|
||||
},
|
||||
};
|
||||
|
||||
tabStateChanged: function AndroidPresenter_tabStateChanged(aDocObj,
|
||||
aPageState) {
|
||||
AndroidPresenter.prototype.tabStateChanged =
|
||||
function AndroidPresenter_tabStateChanged(aDocObj, aPageState) {
|
||||
return this.announce(
|
||||
UtteranceGenerator.genForTabStateChange(aDocObj, aPageState).join(' '));
|
||||
},
|
||||
UtteranceGenerator.genForTabStateChange(aDocObj, aPageState));
|
||||
};
|
||||
|
||||
textChanged: function AndroidPresenter_textChanged(aIsInserted, aStart,
|
||||
aLength, aText,
|
||||
aModifiedText) {
|
||||
AndroidPresenter.prototype.textChanged = function AndroidPresenter_textChanged(
|
||||
aIsInserted, aStart, aLength, aText, aModifiedText) {
|
||||
let eventDetails = {
|
||||
eventType: this.ANDROID_VIEW_TEXT_CHANGED,
|
||||
text: [aText],
|
||||
@ -362,20 +358,19 @@ AndroidPresenter.prototype = {
|
||||
}
|
||||
|
||||
return {type: this.type, details: [eventDetails]};
|
||||
},
|
||||
};
|
||||
|
||||
textSelectionChanged: function AndroidPresenter_textSelectionChanged(aText, aStart,
|
||||
aEnd, aOldStart,
|
||||
aOldEnd, aIsFromUser) {
|
||||
AndroidPresenter.prototype.textSelectionChanged =
|
||||
function AndroidPresenter_textSelectionChanged(aText, aStart, aEnd, aOldStart,
|
||||
aOldEnd, aIsFromUser) {
|
||||
let androidEvents = [];
|
||||
|
||||
if (Utils.AndroidSdkVersion >= 14 && !aIsFromUser) {
|
||||
if (!this._braillePresenter) {
|
||||
this._braillePresenter = new BraillePresenter();
|
||||
}
|
||||
let brailleOutput = this._braillePresenter.textSelectionChanged(aText, aStart, aEnd,
|
||||
aOldStart, aOldEnd,
|
||||
aIsFromUser).details;
|
||||
let brailleOutput = this._braillePresenter.textSelectionChanged(
|
||||
aText, aStart, aEnd, aOldStart, aOldEnd, aIsFromUser).details;
|
||||
|
||||
androidEvents.push({
|
||||
eventType: this.ANDROID_VIEW_TEXT_SELECTION_CHANGED,
|
||||
@ -388,7 +383,8 @@ AndroidPresenter.prototype = {
|
||||
}
|
||||
|
||||
if (Utils.AndroidSdkVersion >= 16 && aIsFromUser) {
|
||||
let [from, to] = aOldStart < aStart ? [aOldStart, aStart] : [aStart, aOldStart];
|
||||
let [from, to] = aOldStart < aStart ?
|
||||
[aOldStart, aStart] : [aStart, aOldStart];
|
||||
androidEvents.push({
|
||||
eventType: this.ANDROID_VIEW_TEXT_TRAVERSED_AT_MOVEMENT_GRANULARITY,
|
||||
text: [aText],
|
||||
@ -401,11 +397,13 @@ AndroidPresenter.prototype = {
|
||||
type: this.type,
|
||||
details: androidEvents
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
viewportChanged: function AndroidPresenter_viewportChanged(aWindow) {
|
||||
if (Utils.AndroidSdkVersion < 14)
|
||||
AndroidPresenter.prototype.viewportChanged =
|
||||
function AndroidPresenter_viewportChanged(aWindow) {
|
||||
if (Utils.AndroidSdkVersion < 14) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.type,
|
||||
@ -418,238 +416,221 @@ AndroidPresenter.prototype = {
|
||||
maxScrollY: aWindow.scrollMaxY
|
||||
}]
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
editingModeChanged: function AndroidPresenter_editingModeChanged(aIsEditing) {
|
||||
return this.announce(
|
||||
UtteranceGenerator.genForEditingMode(aIsEditing).join(' '));
|
||||
},
|
||||
AndroidPresenter.prototype.editingModeChanged =
|
||||
function AndroidPresenter_editingModeChanged(aIsEditing) {
|
||||
return this.announce(UtteranceGenerator.genForEditingMode(aIsEditing));
|
||||
};
|
||||
|
||||
announce: function AndroidPresenter_announce(aAnnouncement) {
|
||||
AndroidPresenter.prototype.announce =
|
||||
function AndroidPresenter_announce(aAnnouncement) {
|
||||
let localizedAnnouncement = Utils.localize(aAnnouncement).join(' ');
|
||||
return {
|
||||
type: this.type,
|
||||
details: [{
|
||||
eventType: (Utils.AndroidSdkVersion >= 16) ?
|
||||
this.ANDROID_ANNOUNCEMENT : this.ANDROID_VIEW_TEXT_CHANGED,
|
||||
text: [aAnnouncement],
|
||||
addedCount: aAnnouncement.length,
|
||||
text: [localizedAnnouncement],
|
||||
addedCount: localizedAnnouncement.length,
|
||||
removedCount: 0,
|
||||
fromIndex: 0
|
||||
}]
|
||||
};
|
||||
},
|
||||
};
|
||||
|
||||
liveRegion: function AndroidPresenter_liveRegion(aContext, aIsPolite,
|
||||
AndroidPresenter.prototype.liveRegion =
|
||||
function AndroidPresenter_liveRegion(aContext, aIsPolite,
|
||||
aIsHide, aModifiedText) {
|
||||
return this.announce(
|
||||
UtteranceGenerator.genForLiveRegion(aContext, aIsHide,
|
||||
aModifiedText).join(' '));
|
||||
}
|
||||
};
|
||||
UtteranceGenerator.genForLiveRegion(aContext, aIsHide, aModifiedText));
|
||||
};
|
||||
|
||||
/**
|
||||
* A speech presenter for direct TTS output
|
||||
* A B2G presenter for Gaia.
|
||||
*/
|
||||
function B2GPresenter() {}
|
||||
|
||||
this.SpeechPresenter = function SpeechPresenter() {};
|
||||
B2GPresenter.prototype = Object.create(Presenter.prototype);
|
||||
|
||||
SpeechPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
|
||||
type: 'Speech',
|
||||
|
||||
pivotChanged: function SpeechPresenter_pivotChanged(aContext, aReason) {
|
||||
if (!aContext.accessible)
|
||||
return null;
|
||||
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
actions: [
|
||||
{method: 'playEarcon',
|
||||
data: aContext.accessible.role === Roles.KEY ?
|
||||
'virtual_cursor_key' : 'virtual_cursor_move',
|
||||
options: {}},
|
||||
{method: 'speak',
|
||||
data: UtteranceGenerator.genForContext(aContext).output.join(' '),
|
||||
options: {enqueue: true}}
|
||||
]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
valueChanged: function SpeechPresenter_valueChanged(aAccessible) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
actions: [
|
||||
{ method: 'speak',
|
||||
data: aAccessible.value,
|
||||
options: { enqueue: false } }
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
actionInvoked: function SpeechPresenter_actionInvoked(aObject, aActionName) {
|
||||
let actions = [];
|
||||
if (aActionName === 'click') {
|
||||
actions.push({method: 'playEarcon',
|
||||
data: 'clicked',
|
||||
options: {}});
|
||||
} else {
|
||||
actions.push({method: 'speak',
|
||||
data: UtteranceGenerator.genForAction(aObject, aActionName).join(' '),
|
||||
options: {enqueue: false}});
|
||||
}
|
||||
return { type: this.type, details: { actions: actions } };
|
||||
},
|
||||
|
||||
liveRegion: function SpeechPresenter_liveRegion(aContext, aIsPolite, aIsHide,
|
||||
aModifiedText) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
actions: [{
|
||||
method: 'speak',
|
||||
data: UtteranceGenerator.genForLiveRegion(aContext, aIsHide,
|
||||
aModifiedText).join(' '),
|
||||
options: {enqueue: aIsPolite}
|
||||
}]
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
announce: function SpeechPresenter_announce(aAnnouncement) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
actions: [{
|
||||
method: 'speak', data: aAnnouncement, options: { enqueue: false }
|
||||
}]
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
B2GPresenter.prototype.type = 'B2G';
|
||||
|
||||
/**
|
||||
* A haptic presenter
|
||||
* A pattern used for haptic feedback.
|
||||
* @type {Array}
|
||||
*/
|
||||
|
||||
this.HapticPresenter = function HapticPresenter() {};
|
||||
|
||||
HapticPresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
|
||||
type: 'Haptic',
|
||||
|
||||
PIVOT_CHANGE_PATTERN: [40],
|
||||
|
||||
pivotChanged: function HapticPresenter_pivotChanged(aContext, aReason) {
|
||||
return { type: this.type, details: { pattern: this.PIVOT_CHANGE_PATTERN } };
|
||||
}
|
||||
};
|
||||
B2GPresenter.prototype.PIVOT_CHANGE_HAPTIC_PATTERN = [40];
|
||||
|
||||
/**
|
||||
* A braille presenter
|
||||
* Pivot move reasons.
|
||||
* @type {Array}
|
||||
*/
|
||||
B2GPresenter.prototype.pivotChangedReasons = ['none', 'next', 'prev', 'first',
|
||||
'last', 'text', 'point'];
|
||||
|
||||
this.BraillePresenter = function BraillePresenter() {};
|
||||
|
||||
BraillePresenter.prototype = {
|
||||
__proto__: Presenter.prototype,
|
||||
|
||||
type: 'Braille',
|
||||
|
||||
pivotChanged: function BraillePresenter_pivotChanged(aContext, aReason) {
|
||||
B2GPresenter.prototype.pivotChanged =
|
||||
function B2GPresenter_pivotChanged(aContext, aReason) {
|
||||
if (!aContext.accessible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let brailleOutput = BrailleGenerator.genForContext(aContext);
|
||||
brailleOutput.output = brailleOutput.output.join(' ');
|
||||
brailleOutput.selectionStart = 0;
|
||||
brailleOutput.selectionEnd = 0;
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
eventType: 'vc-change',
|
||||
data: UtteranceGenerator.genForContext(aContext),
|
||||
options: {
|
||||
pattern: this.PIVOT_CHANGE_HAPTIC_PATTERN,
|
||||
isKey: aContext.accessible.role === Roles.KEY,
|
||||
reason: this.pivotChangedReasons[aReason]
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
return { type: this.type, details: brailleOutput };
|
||||
},
|
||||
B2GPresenter.prototype.valueChanged =
|
||||
function B2GPresenter_valueChanged(aAccessible) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
eventType: 'value-change',
|
||||
data: aAccessible.value
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
textSelectionChanged: function BraillePresenter_textSelectionChanged(aText, aStart,
|
||||
aEnd, aOldStart,
|
||||
aOldEnd, aIsFromUser) {
|
||||
return { type: this.type,
|
||||
details: { selectionStart: aStart,
|
||||
selectionEnd: aEnd } };
|
||||
},
|
||||
B2GPresenter.prototype.actionInvoked =
|
||||
function B2GPresenter_actionInvoked(aObject, aActionName) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
eventType: 'action',
|
||||
data: UtteranceGenerator.genForAction(aObject, aActionName)
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
B2GPresenter.prototype.liveRegion = function B2GPresenter_liveRegion(aContext,
|
||||
aIsPolite, aIsHide, aModifiedText) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
eventType: 'liveregion-change',
|
||||
data: UtteranceGenerator.genForLiveRegion(aContext, aIsHide,
|
||||
aModifiedText),
|
||||
options: {enqueue: aIsPolite}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
B2GPresenter.prototype.announce =
|
||||
function B2GPresenter_announce(aAnnouncement) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
eventType: 'announcement',
|
||||
data: aAnnouncement
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.Presentation = {
|
||||
/**
|
||||
* A braille presenter
|
||||
*/
|
||||
function BraillePresenter() {}
|
||||
|
||||
BraillePresenter.prototype = Object.create(Presenter.prototype);
|
||||
|
||||
BraillePresenter.prototype.type = 'Braille';
|
||||
|
||||
BraillePresenter.prototype.pivotChanged =
|
||||
function BraillePresenter_pivotChanged(aContext) {
|
||||
if (!aContext.accessible) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
output: Utils.localize(BrailleGenerator.genForContext(aContext)).join(
|
||||
' '),
|
||||
selectionStart: 0,
|
||||
selectionEnd: 0
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
BraillePresenter.prototype.textSelectionChanged =
|
||||
function BraillePresenter_textSelectionChanged(aText, aStart, aEnd) {
|
||||
return {
|
||||
type: this.type,
|
||||
details: {
|
||||
selectionStart: aStart,
|
||||
selectionEnd: aEnd
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
this.Presentation = { // jshint ignore:line
|
||||
get presenters() {
|
||||
delete this.presenters;
|
||||
let presenterMap = {
|
||||
'mobile/android': [VisualPresenter, AndroidPresenter],
|
||||
'b2g': [VisualPresenter, SpeechPresenter, HapticPresenter],
|
||||
'browser': [VisualPresenter, SpeechPresenter, HapticPresenter,
|
||||
AndroidPresenter]
|
||||
'b2g': [VisualPresenter, B2GPresenter],
|
||||
'browser': [VisualPresenter, B2GPresenter, AndroidPresenter]
|
||||
};
|
||||
this.presenters = [new P() for (P of presenterMap[Utils.MozBuildApp])];
|
||||
this.presenters = [new P() for (P of presenterMap[Utils.MozBuildApp])]; // jshint ignore:line
|
||||
return this.presenters;
|
||||
},
|
||||
|
||||
pivotChanged: function Presentation_pivotChanged(aPosition, aOldPosition, aReason,
|
||||
aStartOffset, aEndOffset) {
|
||||
let context = new PivotContext(aPosition, aOldPosition, aStartOffset, aEndOffset);
|
||||
return [p.pivotChanged(context, aReason)
|
||||
for each (p in this.presenters)];
|
||||
pivotChanged: function Presentation_pivotChanged(
|
||||
aPosition, aOldPosition, aReason, aStartOffset, aEndOffset) {
|
||||
let context = new PivotContext(
|
||||
aPosition, aOldPosition, aStartOffset, aEndOffset);
|
||||
return [p.pivotChanged(context, aReason) for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
actionInvoked: function Presentation_actionInvoked(aObject, aActionName) {
|
||||
return [p.actionInvoked(aObject, aActionName)
|
||||
for each (p in this.presenters)];
|
||||
return [p.actionInvoked(aObject, aActionName) // jshint ignore:line
|
||||
for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
textChanged: function Presentation_textChanged(aIsInserted, aStartOffset,
|
||||
aLength, aText,
|
||||
aModifiedText) {
|
||||
return [p.textChanged(aIsInserted, aStartOffset, aLength,
|
||||
aText, aModifiedText)
|
||||
for each (p in this.presenters)];
|
||||
return [p.textChanged(aIsInserted, aStartOffset, aLength, aText, // jshint ignore:line
|
||||
aModifiedText) for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
textSelectionChanged: function textSelectionChanged(aText, aStart, aEnd,
|
||||
aOldStart, aOldEnd,
|
||||
aIsFromUser) {
|
||||
return [p.textSelectionChanged(aText, aStart, aEnd,
|
||||
aOldStart, aOldEnd, aIsFromUser)
|
||||
for each (p in this.presenters)];
|
||||
return [p.textSelectionChanged(aText, aStart, aEnd, aOldStart, aOldEnd, // jshint ignore:line
|
||||
aIsFromUser) for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
valueChanged: function valueChanged(aAccessible) {
|
||||
return [ p.valueChanged(aAccessible) for (p of this.presenters) ];
|
||||
return [ p.valueChanged(aAccessible) for (p of this.presenters) ]; // jshint ignore:line
|
||||
},
|
||||
|
||||
tabStateChanged: function Presentation_tabStateChanged(aDocObj, aPageState) {
|
||||
return [p.tabStateChanged(aDocObj, aPageState)
|
||||
for each (p in this.presenters)];
|
||||
return [p.tabStateChanged(aDocObj, aPageState) // jshint ignore:line
|
||||
for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
viewportChanged: function Presentation_viewportChanged(aWindow) {
|
||||
return [p.viewportChanged(aWindow)
|
||||
for each (p in this.presenters)];
|
||||
return [p.viewportChanged(aWindow) for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
editingModeChanged: function Presentation_editingModeChanged(aIsEditing) {
|
||||
return [p.editingModeChanged(aIsEditing)
|
||||
for each (p in this.presenters)];
|
||||
return [p.editingModeChanged(aIsEditing) for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
announce: function Presentation_announce(aAnnouncement) {
|
||||
// XXX: Typically each presenter uses the UtteranceGenerator,
|
||||
// but there really isn't a point here.
|
||||
return [p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)[0])
|
||||
for each (p in this.presenters)];
|
||||
return [p.announce(UtteranceGenerator.genForAnnouncement(aAnnouncement)) // jshint ignore:line
|
||||
for each (p in this.presenters)]; // jshint ignore:line
|
||||
},
|
||||
|
||||
liveRegion: function Presentation_liveRegion(aAccessible, aIsPolite, aIsHide,
|
||||
@ -659,7 +640,7 @@ this.Presentation = {
|
||||
context = new PivotContext(aAccessible, null, -1, -1, true,
|
||||
aIsHide ? true : false);
|
||||
}
|
||||
return [p.liveRegion(context, aIsPolite, aIsHide, aModifiedText) for (
|
||||
p of this.presenters)];
|
||||
return [p.liveRegion(context, aIsPolite, aIsHide, aModifiedText) // jshint ignore:line
|
||||
for (p of this.presenters)]; // jshint ignore:line
|
||||
}
|
||||
};
|
||||
|
@ -2,29 +2,34 @@
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
/* global Components, XPCOMUtils, Services, PluralForm, Logger, Rect, Utils,
|
||||
States, Relations, Roles, dump, Events, PivotContext, PrefCache */
|
||||
/* exported Utils, Logger, PivotContext, PrefCache, SettingCache */
|
||||
|
||||
'use strict';
|
||||
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const {classes: Cc, utils: Cu, interfaces: Ci} = Components;
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Services',
|
||||
Cu.import('resource://gre/modules/XPCOMUtils.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Services', // jshint ignore:line
|
||||
'resource://gre/modules/Services.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Rect',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Rect', // jshint ignore:line
|
||||
'resource://gre/modules/Geometry.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Roles', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Events',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Events', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Relations',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'Relations', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States',
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'States', // jshint ignore:line
|
||||
'resource://gre/modules/accessibility/Constants.jsm');
|
||||
XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm', // jshint ignore:line
|
||||
'resource://gre/modules/PluralForm.jsm');
|
||||
|
||||
this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache', 'SettingCache'];
|
||||
this.EXPORTED_SYMBOLS = ['Utils', 'Logger', 'PivotContext', 'PrefCache', // jshint ignore:line
|
||||
'SettingCache'];
|
||||
|
||||
this.Utils = {
|
||||
this.Utils = { // jshint ignore:line
|
||||
_buildAppMap: {
|
||||
'{3c2e2abc-06d4-11e1-ac3b-374f68613e61}': 'b2g',
|
||||
'{ec8030f7-c20a-464f-9b0e-13a3a9e97384}': 'browser',
|
||||
@ -33,10 +38,10 @@ this.Utils = {
|
||||
},
|
||||
|
||||
init: function Utils_init(aWindow) {
|
||||
if (this._win)
|
||||
if (this._win) {
|
||||
// XXX: only supports attaching to one window now.
|
||||
throw new Error('Only one top-level window could used with AccessFu');
|
||||
|
||||
}
|
||||
this._win = Cu.getWeakReference(aWindow);
|
||||
},
|
||||
|
||||
@ -77,34 +82,39 @@ this.Utils = {
|
||||
},
|
||||
|
||||
get MozBuildApp() {
|
||||
if (!this._buildApp)
|
||||
if (!this._buildApp) {
|
||||
this._buildApp = this._buildAppMap[Services.appinfo.ID];
|
||||
}
|
||||
return this._buildApp;
|
||||
},
|
||||
|
||||
get OS() {
|
||||
if (!this._OS)
|
||||
if (!this._OS) {
|
||||
this._OS = Services.appinfo.OS;
|
||||
}
|
||||
return this._OS;
|
||||
},
|
||||
|
||||
get widgetToolkit() {
|
||||
if (!this._widgetToolkit)
|
||||
if (!this._widgetToolkit) {
|
||||
this._widgetToolkit = Services.appinfo.widgetToolkit;
|
||||
}
|
||||
return this._widgetToolkit;
|
||||
},
|
||||
|
||||
get ScriptName() {
|
||||
if (!this._ScriptName)
|
||||
if (!this._ScriptName) {
|
||||
this._ScriptName =
|
||||
(Services.appinfo.processType == 2) ? 'AccessFuContent' : 'AccessFu';
|
||||
}
|
||||
return this._ScriptName;
|
||||
},
|
||||
|
||||
get AndroidSdkVersion() {
|
||||
if (!this._AndroidSdkVersion) {
|
||||
if (Services.appinfo.OS == 'Android') {
|
||||
this._AndroidSdkVersion = Services.sysinfo.getPropertyAsInt32('version');
|
||||
this._AndroidSdkVersion = Services.sysinfo.getPropertyAsInt32(
|
||||
'version');
|
||||
} else {
|
||||
// Most useful in desktop debugging.
|
||||
this._AndroidSdkVersion = 16;
|
||||
@ -138,8 +148,9 @@ this.Utils = {
|
||||
if (!this.BrowserApp) {
|
||||
return null;
|
||||
}
|
||||
if (this.MozBuildApp == 'b2g')
|
||||
if (this.MozBuildApp == 'b2g') {
|
||||
return this.BrowserApp.contentBrowser;
|
||||
}
|
||||
return this.BrowserApp.selectedBrowser;
|
||||
},
|
||||
|
||||
@ -155,7 +166,7 @@ this.Utils = {
|
||||
for (let i = 0; i < mm.childCount; i++) {
|
||||
let childMM = mm.getChildAt(i);
|
||||
|
||||
if ("sendAsyncMessage" in childMM) {
|
||||
if ('sendAsyncMessage' in childMM) {
|
||||
messageManagers.push(childMM);
|
||||
} else {
|
||||
collectLeafMessageManagers(childMM);
|
||||
@ -189,10 +200,49 @@ this.Utils = {
|
||||
return this.isContentProcess;
|
||||
},
|
||||
|
||||
localize: function localize(aOutput) {
|
||||
let outputArray = Array.isArray(aOutput) ? aOutput : [aOutput];
|
||||
let localized =
|
||||
[this.stringBundle.get(details) for (details of outputArray)]; // jshint ignore:line
|
||||
// Clean up the white space.
|
||||
let trimmed;
|
||||
return [trimmed for (word of localized) if (word && // jshint ignore:line
|
||||
(trimmed = word.trim()))]; // jshint ignore:line
|
||||
},
|
||||
|
||||
get stringBundle() {
|
||||
delete this.stringBundle;
|
||||
this.stringBundle = Services.strings.createBundle(
|
||||
let bundle = Services.strings.createBundle(
|
||||
'chrome://global/locale/AccessFu.properties');
|
||||
this.stringBundle = {
|
||||
get: function stringBundle_get(aDetails = {}) {
|
||||
if (!aDetails || typeof aDetails === 'string') {
|
||||
return aDetails;
|
||||
}
|
||||
let str = '';
|
||||
let string = aDetails.string;
|
||||
if (!string) {
|
||||
return str;
|
||||
}
|
||||
try {
|
||||
let args = aDetails.args;
|
||||
let count = aDetails.count;
|
||||
if (args) {
|
||||
str = bundle.formatStringFromName(string, args, args.length);
|
||||
} else {
|
||||
str = bundle.GetStringFromName(string);
|
||||
}
|
||||
if (count) {
|
||||
str = PluralForm.get(count, str);
|
||||
str = str.replace('#1', count);
|
||||
}
|
||||
} catch (e) {
|
||||
Logger.debug('Failed to get a string from a bundle for', string);
|
||||
} finally {
|
||||
return str;
|
||||
}
|
||||
}
|
||||
};
|
||||
return this.stringBundle;
|
||||
},
|
||||
|
||||
@ -262,7 +312,7 @@ this.Utils = {
|
||||
let accText = aAccessible.QueryInterface(Ci.nsIAccessibleText);
|
||||
let objX = {}, objY = {}, objW = {}, objH = {};
|
||||
accText.getRangeExtents(aStart, aEnd, objX, objY, objW, objH,
|
||||
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
|
||||
Ci.nsIAccessibleCoordinateType.COORDTYPE_SCREEN_RELATIVE);
|
||||
return new Rect(objX.value, objY.value, objW.value, objH.value);
|
||||
},
|
||||
|
||||
@ -400,7 +450,7 @@ State.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
this.Logger = {
|
||||
this.Logger = { // jshint ignore:line
|
||||
DEBUG: 0,
|
||||
INFO: 1,
|
||||
WARNING: 2,
|
||||
@ -412,8 +462,9 @@ this.Logger = {
|
||||
test: false,
|
||||
|
||||
log: function log(aLogLevel) {
|
||||
if (aLogLevel < this.logLevel)
|
||||
if (aLogLevel < this.logLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
let args = Array.prototype.slice.call(arguments, 1);
|
||||
let message = (typeof(args[0]) === 'function' ? args[0]() : args).join(' ');
|
||||
@ -467,7 +518,8 @@ this.Logger = {
|
||||
}
|
||||
stackMessage = stackLines.join('\n');
|
||||
} else {
|
||||
stackMessage = '(' + aException.fileName + ':' + aException.lineNumber + ')';
|
||||
stackMessage =
|
||||
'(' + aException.fileName + ':' + aException.lineNumber + ')';
|
||||
}
|
||||
this.error(aErrorMessage + ':\n ' +
|
||||
aException.message + '\n' +
|
||||
@ -515,21 +567,26 @@ this.Logger = {
|
||||
},
|
||||
|
||||
dumpTree: function dumpTree(aLogLevel, aRootAccessible) {
|
||||
if (aLogLevel < this.logLevel)
|
||||
if (aLogLevel < this.logLevel) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._dumpTreeInternal(aLogLevel, aRootAccessible, 0);
|
||||
},
|
||||
|
||||
_dumpTreeInternal: function _dumpTreeInternal(aLogLevel, aAccessible, aIndent) {
|
||||
let indentStr = '';
|
||||
for (var i=0; i < aIndent; i++)
|
||||
indentStr += ' ';
|
||||
this.log(aLogLevel, indentStr,
|
||||
this.accessibleToString(aAccessible),
|
||||
'(' + this.statesToString(aAccessible) + ')');
|
||||
for (var i=0; i < aAccessible.childCount; i++)
|
||||
this._dumpTreeInternal(aLogLevel, aAccessible.getChildAt(i), aIndent + 1);
|
||||
_dumpTreeInternal:
|
||||
function _dumpTreeInternal(aLogLevel, aAccessible, aIndent) {
|
||||
let indentStr = '';
|
||||
for (let i = 0; i < aIndent; i++) {
|
||||
indentStr += ' ';
|
||||
}
|
||||
this.log(aLogLevel, indentStr,
|
||||
this.accessibleToString(aAccessible),
|
||||
'(' + this.statesToString(aAccessible) + ')');
|
||||
for (let i = 0; i < aAccessible.childCount; i++) {
|
||||
this._dumpTreeInternal(aLogLevel, aAccessible.getChildAt(i),
|
||||
aIndent + 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@ -543,7 +600,7 @@ this.Logger = {
|
||||
* label. In this case the |accessible| field would be the embedded control,
|
||||
* and the |accessibleForBounds| field would be the label.
|
||||
*/
|
||||
this.PivotContext = function PivotContext(aAccessible, aOldAccessible,
|
||||
this.PivotContext = function PivotContext(aAccessible, aOldAccessible, // jshint ignore:line
|
||||
aStartOffset, aEndOffset, aIgnoreAncestry = false,
|
||||
aIncludeInvisible = false) {
|
||||
this._accessible = aAccessible;
|
||||
@ -554,7 +611,7 @@ this.PivotContext = function PivotContext(aAccessible, aOldAccessible,
|
||||
this.endOffset = aEndOffset;
|
||||
this._ignoreAncestry = aIgnoreAncestry;
|
||||
this._includeInvisible = aIncludeInvisible;
|
||||
}
|
||||
};
|
||||
|
||||
PivotContext.prototype = {
|
||||
get accessible() {
|
||||
@ -584,8 +641,10 @@ PivotContext.prototype = {
|
||||
let result = {startOffset: this.startOffset,
|
||||
endOffset: this.endOffset,
|
||||
text: this._accessible.QueryInterface(Ci.nsIAccessibleText).
|
||||
getText(0, Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT)};
|
||||
let hypertextAcc = this._accessible.QueryInterface(Ci.nsIAccessibleHyperText);
|
||||
getText(0,
|
||||
Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT)};
|
||||
let hypertextAcc = this._accessible.QueryInterface(
|
||||
Ci.nsIAccessibleHyperText);
|
||||
|
||||
// Iterate through the links in backwards order so text replacements don't
|
||||
// affect the offsets of links yet to be processed.
|
||||
@ -594,7 +653,8 @@ PivotContext.prototype = {
|
||||
let linkText = '';
|
||||
if (link instanceof Ci.nsIAccessibleText) {
|
||||
linkText = link.QueryInterface(Ci.nsIAccessibleText).
|
||||
getText(0, Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
|
||||
getText(0,
|
||||
Ci.nsIAccessibleText.TEXT_OFFSET_END_OF_TEXT);
|
||||
}
|
||||
|
||||
let start = link.startIndex;
|
||||
@ -666,9 +726,9 @@ PivotContext.prototype = {
|
||||
*/
|
||||
get newAncestry() {
|
||||
if (!this._newAncestry) {
|
||||
this._newAncestry = this._ignoreAncestry ? [] : [currentAncestor for (
|
||||
[index, currentAncestor] of Iterator(this.currentAncestry)) if (
|
||||
currentAncestor !== this.oldAncestry[index])];
|
||||
this._newAncestry = this._ignoreAncestry ? [] : [currentAncestor for ( // jshint ignore:line
|
||||
[index, currentAncestor] of Iterator(this.currentAncestry)) if ( // jshint ignore:line
|
||||
currentAncestor !== this.oldAncestry[index])]; // jshint ignore:line
|
||||
}
|
||||
return this._newAncestry;
|
||||
},
|
||||
@ -679,7 +739,7 @@ PivotContext.prototype = {
|
||||
* Note: needSubtree is a function argument that can be used to determine
|
||||
* whether aAccessible's subtree is required.
|
||||
*/
|
||||
_traverse: function _traverse(aAccessible, aPreorder, aStop) {
|
||||
_traverse: function* _traverse(aAccessible, aPreorder, aStop) {
|
||||
if (aStop && aStop(aAccessible)) {
|
||||
return;
|
||||
}
|
||||
@ -694,9 +754,9 @@ PivotContext.prototype = {
|
||||
if (include) {
|
||||
if (aPreorder) {
|
||||
yield child;
|
||||
[yield node for (node of this._traverse(child, aPreorder, aStop))];
|
||||
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
|
||||
} else {
|
||||
[yield node for (node of this._traverse(child, aPreorder, aStop))];
|
||||
[yield node for (node of this._traverse(child, aPreorder, aStop))]; // jshint ignore:line
|
||||
yield child;
|
||||
}
|
||||
}
|
||||
@ -743,7 +803,7 @@ PivotContext.prototype = {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
let getHeaders = function getHeaders(aHeaderCells) {
|
||||
let getHeaders = function* getHeaders(aHeaderCells) {
|
||||
let enumerator = aHeaderCells.enumerate();
|
||||
while (enumerator.hasMoreElements()) {
|
||||
yield enumerator.getNext().QueryInterface(Ci.nsIAccessible).name;
|
||||
@ -794,12 +854,12 @@ PivotContext.prototype = {
|
||||
cellInfo.columnHeaders = [];
|
||||
if (cellInfo.columnChanged && cellInfo.current.role !==
|
||||
Roles.COLUMNHEADER) {
|
||||
cellInfo.columnHeaders = [headers for (headers of getHeaders(
|
||||
cellInfo.columnHeaders = [headers for (headers of getHeaders( // jshint ignore:line
|
||||
cellInfo.current.columnHeaderCells))];
|
||||
}
|
||||
cellInfo.rowHeaders = [];
|
||||
if (cellInfo.rowChanged && cellInfo.current.role === Roles.CELL) {
|
||||
cellInfo.rowHeaders = [headers for (headers of getHeaders(
|
||||
cellInfo.rowHeaders = [headers for (headers of getHeaders( // jshint ignore:line
|
||||
cellInfo.current.rowHeaderCells))];
|
||||
}
|
||||
|
||||
@ -824,7 +884,7 @@ PivotContext.prototype = {
|
||||
}
|
||||
};
|
||||
|
||||
this.PrefCache = function PrefCache(aName, aCallback, aRunCallbackNow) {
|
||||
this.PrefCache = function PrefCache(aName, aCallback, aRunCallbackNow) { // jshint ignore:line
|
||||
this.name = aName;
|
||||
this.callback = aCallback;
|
||||
|
||||
@ -864,7 +924,7 @@ PrefCache.prototype = {
|
||||
}
|
||||
},
|
||||
|
||||
observe: function observe(aSubject, aTopic, aData) {
|
||||
observe: function observe(aSubject) {
|
||||
this.value = this._getValue(aSubject.QueryInterface(Ci.nsIPrefBranch));
|
||||
if (this.callback) {
|
||||
try {
|
||||
@ -879,7 +939,7 @@ PrefCache.prototype = {
|
||||
Ci.nsISupportsWeakReference])
|
||||
};
|
||||
|
||||
this.SettingCache = function SettingCache(aName, aCallback, aOptions = {}) {
|
||||
this.SettingCache = function SettingCache(aName, aCallback, aOptions = {}) { // jshint ignore:line
|
||||
this.value = aOptions.defaultValue;
|
||||
let runCallback = () => {
|
||||
if (aCallback) {
|
||||
@ -903,7 +963,8 @@ this.SettingCache = function SettingCache(aName, aCallback, aOptions = {}) {
|
||||
let req = lock.get(aName);
|
||||
|
||||
req.addEventListener('success', () => {
|
||||
this.value = req.result[aName] == undefined ? aOptions.defaultValue : req.result[aName];
|
||||
this.value = req.result[aName] === undefined ?
|
||||
aOptions.defaultValue : req.result[aName];
|
||||
if (aOptions.callbackNow) {
|
||||
runCallback();
|
||||
}
|
||||
|
@ -78,7 +78,7 @@ var AccessFuTest = {
|
||||
if (!data) {
|
||||
return;
|
||||
}
|
||||
isDeeply(data.details.actions, aWaitForData, "Data is correct");
|
||||
isDeeply(data.details, aWaitForData, "Data is correct");
|
||||
aListener.apply(listener);
|
||||
};
|
||||
Services.obs.addObserver(listener, 'accessfu-output', false);
|
||||
@ -288,8 +288,9 @@ AccessFuContentTest.prototype = {
|
||||
var android = this.extractAndroid(aMessage.json, expected.android);
|
||||
if ((speech && expected.speak) || (android && expected.android)) {
|
||||
if (expected.speak) {
|
||||
(SimpleTest[expected.speak_checkFunc] || is)(speech, expected.speak,
|
||||
'"' + speech + '" spoken');
|
||||
var checkFunc = SimpleTest[expected.speak_checkFunc] || isDeeply;
|
||||
checkFunc.apply(SimpleTest, [speech, expected.speak,
|
||||
'"' + JSON.stringify(speech) + '" spoken']);
|
||||
}
|
||||
|
||||
if (expected.android) {
|
||||
@ -332,11 +333,9 @@ AccessFuContentTest.prototype = {
|
||||
}
|
||||
|
||||
for (var output of aData) {
|
||||
if (output && output.type === 'Speech') {
|
||||
for (var action of output.details.actions) {
|
||||
if (action && action.method == 'speak') {
|
||||
return action.data;
|
||||
}
|
||||
if (output && output.type === 'B2G') {
|
||||
if (output.details && output.details.data[0].string !== 'clickAction') {
|
||||
return output.details.data;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -345,6 +344,10 @@ AccessFuContentTest.prototype = {
|
||||
},
|
||||
|
||||
extractAndroid: function(aData, aExpectedEvents) {
|
||||
if (!aData) {
|
||||
return null;
|
||||
}
|
||||
|
||||
for (var output of aData) {
|
||||
if (output && output.type === 'Android') {
|
||||
for (var i in output.details) {
|
||||
|
@ -22,7 +22,7 @@ function testContextOutput(expected, aAccOrElmOrID, aOldAccOrElmOrID, aGenerator
|
||||
var oldAccessible = aOldAccOrElmOrID !== null ?
|
||||
getAccessible(aOldAccOrElmOrID || 'root') : null;
|
||||
var context = new PivotContext(accessible, oldAccessible);
|
||||
var output = aGenerator.genForContext(context).output;
|
||||
var output = aGenerator.genForContext(context);
|
||||
|
||||
// Create a version of the output that has null members where we have
|
||||
// null members in the expected output. Those are indexes that are not testable
|
||||
@ -33,14 +33,15 @@ function testContextOutput(expected, aAccOrElmOrID, aOldAccOrElmOrID, aGenerator
|
||||
if (expected[i] === null) {
|
||||
masked_output.push(null);
|
||||
} else {
|
||||
masked_output[i] = output[i];
|
||||
masked_output[i] = typeof output[i] === "string" ? output[i].trim() :
|
||||
output[i];
|
||||
}
|
||||
}
|
||||
|
||||
isDeeply(masked_output, expected,
|
||||
"Context output is correct for " + aAccOrElmOrID +
|
||||
" (output: " + output.join(", ") + ") ==" +
|
||||
" (expected: " + expected.join(", ") + ")");
|
||||
" (output: " + JSON.stringify(output) + ") ==" +
|
||||
" (expected: " + JSON.stringify(expected) + ")");
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,6 +54,9 @@ function testContextOutput(expected, aAccOrElmOrID, aOldAccOrElmOrID, aGenerator
|
||||
*/
|
||||
function testObjectOutput(aAccOrElmOrID, aGenerator) {
|
||||
var accessible = getAccessible(aAccOrElmOrID);
|
||||
if (!accessible.name || !accessible.name.trim()) {
|
||||
return;
|
||||
}
|
||||
var context = new PivotContext(accessible);
|
||||
var output = aGenerator.genForObject(accessible, context);
|
||||
var outputOrder;
|
||||
|
@ -23,13 +23,10 @@
|
||||
function settingsStart() {
|
||||
ok(true, "EventManager was stopped.");
|
||||
isnot(AccessFu._enabled, true, "AccessFu was disabled.");
|
||||
AccessFuTest.once([{
|
||||
"method": "speak",
|
||||
"data": "Screen reader started",
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}], AccessFuTest.nextTest);
|
||||
AccessFuTest.once({
|
||||
"eventType": "announcement",
|
||||
"data": [{string: "screenReaderStarted"}]
|
||||
}, AccessFuTest.nextTest);
|
||||
// XXX: Bug 978076 - test start with SettingsManager.
|
||||
//navigator.mozSettings.createLock().set(
|
||||
// {'accessibility.screenreader': false});
|
||||
@ -39,13 +36,10 @@
|
||||
// Make sure EventManager is started again.
|
||||
function settingsStop() {
|
||||
ok(AccessFu._enabled, "AccessFu was enabled again.");
|
||||
AccessFuTest.once([{
|
||||
"method": "speak",
|
||||
"data": "Screen reader stopped",
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}], AccessFuTest.finish);
|
||||
AccessFuTest.once({
|
||||
"eventType": "announcement",
|
||||
"data": [{string: "screenReaderStopped"}]
|
||||
}, AccessFuTest.finish);
|
||||
// XXX: Bug 978076 - test stop with SettingsManager.
|
||||
//navigator.mozSettings.createLock().set(
|
||||
// {'accessibility.screenreader': false});
|
||||
|
@ -23,68 +23,72 @@
|
||||
<script type="application/javascript">
|
||||
function doTest() {
|
||||
var doc = currentTabDocument();
|
||||
var iframe = doc.createElement("iframe");
|
||||
var iframe = doc.createElement('iframe');
|
||||
iframe.mozbrowser = true;
|
||||
iframe.addEventListener("mozbrowserloadend", function () {
|
||||
iframe.addEventListener('mozbrowserloadend', function () {
|
||||
var contentTest = new AccessFuContentTest(
|
||||
[
|
||||
// Simple traversal forward
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]} ,'such app']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'many option not checked check button First item list 1 item'
|
||||
speak: ['many option', {'string': 'stateNotChecked'},
|
||||
{'string': 'checkbutton'}, {'string': 'listStart'},
|
||||
{'string': 'list'}, {'string': 'listItemsCount', 'count': 1}]
|
||||
}],
|
||||
// check checkbox
|
||||
[ContentMessages.activateCurrent(), {
|
||||
speak: 'checked'
|
||||
speak: [{'string': 'checkAction'}]
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'much range label'
|
||||
speak: ['much range', {'string': 'label'}]
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'much range 5 slider'
|
||||
speak: ['much range', '5', {'string': 'slider'}]
|
||||
}],
|
||||
[ContentMessages.adjustRangeUp,
|
||||
{ speak: '6'}],
|
||||
{ speak: ['6']}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Home button'
|
||||
speak: ['Home', {'string': 'pushbutton'}]
|
||||
}],
|
||||
|
||||
// Simple traversal backward
|
||||
[ContentMessages.simpleMovePrevious, {
|
||||
speak: 'much range 6 slider such app'
|
||||
speak: ['much range', '6', {'string': 'slider'}, 'such app']
|
||||
}],
|
||||
[ContentMessages.adjustRangeDown,
|
||||
{ speak: '5'}],
|
||||
{ speak: ['5']}],
|
||||
[ContentMessages.simpleMovePrevious, {
|
||||
speak: 'much range label'
|
||||
speak: ['much range', {'string': 'label'}]
|
||||
}],
|
||||
[ContentMessages.simpleMovePrevious, {
|
||||
speak: 'many option checked check button First item list 1 item'
|
||||
speak: ['many option', {'string': 'stateChecked'},
|
||||
{'string': 'checkbutton'}, {'string': 'listStart'},
|
||||
{'string': 'list'}, {'string': 'listItemsCount', 'count': 1}]
|
||||
}],
|
||||
// uncheck checkbox
|
||||
[ContentMessages.activateCurrent(), {
|
||||
speak: 'unchecked'
|
||||
speak: [{'string': 'uncheckAction'}]
|
||||
}],
|
||||
[ContentMessages.simpleMovePrevious, {
|
||||
speak: 'wow heading level 1'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}]
|
||||
}],
|
||||
[ContentMessages.simpleMovePrevious, {
|
||||
speak: 'Phone status bar'
|
||||
speak: ['Phone status bar']
|
||||
}],
|
||||
|
||||
// Moving to the absolute last item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
// Move from an inner frame to the last element in the parent doc
|
||||
[ContentMessages.simpleMoveLast, {
|
||||
speak: 'Home button',
|
||||
speak: ['Home', {'string': 'pushbutton'}],
|
||||
speak_checkFunc: 'todo_is'
|
||||
}],
|
||||
|
||||
@ -93,16 +97,18 @@
|
||||
// Moving to the absolute first item from an embedded document
|
||||
// fails. Bug 972035.
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'many option not checked check button First item list 1 item'
|
||||
speak: ['many option', {'string': 'stateNotChecked'},
|
||||
{'string': 'checkbutton'}, {'string': 'listStart'},
|
||||
{'string': 'list'}, {'string': 'listItemsCount', 'count': 1}]
|
||||
}],
|
||||
[ContentMessages.simpleMoveFirst, {
|
||||
speak: 'Phone status bar',
|
||||
speak: ['Phone status bar'],
|
||||
speak_checkFunc: 'todo_is'
|
||||
}],
|
||||
|
||||
@ -111,10 +117,10 @@
|
||||
|
||||
// Move cursor with focus in outside document
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[ContentMessages.focusSelector('button#home', false), {
|
||||
speak: 'Home button'
|
||||
speak: ['Home', {'string': 'pushbutton'}]
|
||||
}],
|
||||
|
||||
// Blur button and reset cursor
|
||||
@ -124,13 +130,13 @@
|
||||
// Set focus on element outside of embedded frame while
|
||||
// cursor is in frame
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
[ContentMessages.focusSelector('button#home', false), {
|
||||
speak: 'Home button'
|
||||
speak: ['Home button']
|
||||
}]
|
||||
|
||||
// Blur button and reset cursor
|
||||
@ -143,51 +149,52 @@
|
||||
|
||||
// Open dialog in outer doc, while cursor is also in outer doc
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: 'This is an alert! heading level 1 dialog'
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
}],
|
||||
|
||||
[function() {
|
||||
doc.defaultView.hideAlert()
|
||||
}, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
|
||||
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
|
||||
|
||||
// Open dialog in outer doc, while cursor is in inner frame
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'wow heading level 1 such app'
|
||||
speak: ['wow', {'string': 'headingLevel', 'args': [1]}, 'such app']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: 'This is an alert! heading level 1 dialog'
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
}],
|
||||
|
||||
// XXX: Place cursor back where it was.
|
||||
[doc.defaultView.hideAlert, {
|
||||
speak: 'many option not checked check button such app'
|
||||
speak: ['many option not checked check button such app']
|
||||
}],
|
||||
|
||||
[ContentMessages.clearCursor, 'AccessFu:CursorCleared'],
|
||||
|
||||
// Open dialog, then focus on something when closing
|
||||
[ContentMessages.simpleMoveNext, {
|
||||
speak: 'Phone status bar Traversal Rule test document'
|
||||
speak: ['Phone status bar', 'Traversal Rule test document']
|
||||
}],
|
||||
[doc.defaultView.showAlert, {
|
||||
speak: 'This is an alert! heading level 1 dialog'
|
||||
speak: ['This is an alert! heading level 1 dialog']
|
||||
}],
|
||||
|
||||
[function() {
|
||||
doc.defaultView.hideAlert();
|
||||
doc.querySelector('button#home').focus();
|
||||
}, {
|
||||
speak: 'Home button Traversal Rule test document'
|
||||
speak: ['Home', {'string': 'pushbutton'},
|
||||
'Traversal Rule test document']
|
||||
}]
|
||||
]);
|
||||
|
||||
@ -207,17 +214,17 @@
|
||||
openBrowserWindow(
|
||||
function () {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
'set': [
|
||||
// TODO: remove this as part of bug 820712
|
||||
["network.disable.ipc.security", true],
|
||||
['network.disable.ipc.security', true],
|
||||
|
||||
|
||||
["dom.ipc.browser_frames.oop_by_default", true],
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["browser.pagethumbnails.capturing_disabled", true]
|
||||
['dom.ipc.browser_frames.oop_by_default', true],
|
||||
['dom.mozBrowserFramesEnabled', true],
|
||||
['browser.pagethumbnails.capturing_disabled', true]
|
||||
]
|
||||
}, doTest) },
|
||||
getRootDirectory(window.location.href) + "doc_content_integration.html");
|
||||
getRootDirectory(window.location.href) + 'doc_content_integration.html');
|
||||
});
|
||||
</script>
|
||||
</head>
|
||||
|
@ -27,9 +27,9 @@
|
||||
[
|
||||
// Read-only text tests
|
||||
[ContentMessages.simpleMoveFirst, {
|
||||
speak: 'These are my awards, Mother. From Army. ' +
|
||||
speak: ['These are my awards, Mother. From Army. ' +
|
||||
'The seal is for marksmanship, and the gorilla is ' +
|
||||
'for sand racing. Text content test document'
|
||||
'for sand racing.', 'Text content test document']
|
||||
}],
|
||||
[ContentMessages.moveNextBy('word'), {
|
||||
speak: 'These',
|
||||
@ -142,8 +142,8 @@
|
||||
|
||||
// Editable text tests.
|
||||
[ContentMessages.focusSelector('textarea'), {
|
||||
speak: 'Please refrain from Mayoneggs during this ' +
|
||||
'salmonella scare. text area'
|
||||
speak: ['Please refrain from Mayoneggs during this ' +
|
||||
'salmonella scare.', {string: 'textarea'}]
|
||||
}],
|
||||
[null, { // When we first focus, caret is at 0.
|
||||
android: [{
|
||||
|
@ -16,80 +16,99 @@
|
||||
// Test the following accOrElmOrID.
|
||||
var tests = [{
|
||||
accOrElmOrID: "anchor1",
|
||||
expected: ["link", "title"]
|
||||
expected: [{"string": "link"}, "title"]
|
||||
}, {
|
||||
accOrElmOrID: "anchor2",
|
||||
expected: ["link", "This is a link"]
|
||||
expected: [{"string": "link"}, "This is a link"]
|
||||
}, {
|
||||
accOrElmOrID: "button1",
|
||||
expected: ["button", "Press me"]
|
||||
expected: [{"string": "pushbutton"}, "Press me"]
|
||||
}, {
|
||||
accOrElmOrID: "button2",
|
||||
expected: ["button", "Press me"]
|
||||
expected: [{"string": "pushbutton"}, "Press me"]
|
||||
}, {
|
||||
accOrElmOrID: "textarea1",
|
||||
expected: ["text area", "This is the text area text.", "Test Text Area"]
|
||||
expected: [{"string": "textarea"}, "This is the text area text.",
|
||||
"Test Text Area"]
|
||||
}, {
|
||||
accOrElmOrID: "textarea2",
|
||||
expected: ["text area", "This is the text area text."]
|
||||
expected: [{"string": "textarea"}, "This is the text area text."]
|
||||
}, {
|
||||
accOrElmOrID: "heading1",
|
||||
expected: ["heading level 1", "Test heading", "This is the heading."]
|
||||
expected: [{"string": "headingLevel", "args": [1]}, "Test heading",
|
||||
"This is the heading."]
|
||||
}, {
|
||||
accOrElmOrID: "heading1",
|
||||
oldAccOrElmOrID: null,
|
||||
expected: [null /* parent doc title */, document.title,
|
||||
"heading level 1", "Test heading", "This is the heading."]
|
||||
{"string": "headingLevel", "args": [1]}, "Test heading",
|
||||
"This is the heading."]
|
||||
}, {
|
||||
accOrElmOrID: "heading2",
|
||||
expected: ["heading level 1", "This is the heading."]
|
||||
expected: [{"string": "headingLevel", "args": [1]},
|
||||
"This is the heading."]
|
||||
}, {
|
||||
accOrElmOrID: "list",
|
||||
expected: ["list 2 items", "Test List", "First item", "Top of the list",
|
||||
"Last item", "2.", "list two"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 2},
|
||||
"Test List", {"string": "listStart"}, "Top of the list",
|
||||
{"string": "listEnd"}, "2.", "list two"]
|
||||
}, {
|
||||
accOrElmOrID: "dlist",
|
||||
expected: ["definition list 0.5 items", "Test Definition List",
|
||||
expected: [{"string": "definitionlist"},
|
||||
{"string": "listItemsCount", "count": 0.5}, "Test Definition List",
|
||||
"dd one"]
|
||||
}, {
|
||||
accOrElmOrID: "li_one",
|
||||
expected: ["list 2 items", "Test List", "First item", "Top of the list"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 2},
|
||||
"Test List", {"string": "listStart"}, "Top of the list"]
|
||||
}, {
|
||||
accOrElmOrID: "li_two",
|
||||
expected: ["list 2 items", "Test List", "Last item", "2.", "list two"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 2},
|
||||
"Test List", {"string": "listEnd"}, "2.", "list two"]
|
||||
}, {
|
||||
accOrElmOrID: "cell",
|
||||
expected: ["table with 1 column and 1 row", "Fruits and vegetables",
|
||||
"Column 1 Row 1", "List of Fruits", "list 4 items", "First item",
|
||||
"link", "Apples", "link", "Bananas", "link", "Peaches", "Last item",
|
||||
"link", "Plums"]
|
||||
expected: [{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 1}, "Fruits and vegetables",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "List of Fruits",
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 4},
|
||||
{"string": "listStart"}, {"string": "link"}, "Apples",
|
||||
{"string": "link"}, "Bananas",
|
||||
{"string": "link"}, "Peaches", {"string": "listEnd"},
|
||||
{"string": "link"}, "Plums"]
|
||||
}, {
|
||||
accOrElmOrID: "app.net",
|
||||
expected: ["list 2 items", "First item", "link", "star", "Last item",
|
||||
"link", "repost"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 2},
|
||||
{"string": "listStart"}, {"string": "link"}, "star",
|
||||
{"string": "listEnd"}, {"string": "link"}, "repost"]
|
||||
}, {
|
||||
// Test pivot to list from li_one.
|
||||
accOrElmOrID: "list",
|
||||
oldAccOrElmOrID: "li_one",
|
||||
expected: ["list 2 items", "Test List", "First item", "Top of the list",
|
||||
"Last item", "2.", "list two"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 2},
|
||||
"Test List", {"string": "listStart"}, "Top of the list",
|
||||
{"string": "listEnd"}, "2.", "list two"]
|
||||
}, {
|
||||
// Test pivot to li_one from list.
|
||||
accOrElmOrID: "li_one",
|
||||
oldAccOrElmOrID: "list",
|
||||
expected: ["First item", "Top of the list"]
|
||||
expected: [{"string": "listStart"}, "Top of the list"]
|
||||
}, {
|
||||
// Test pivot to "apples" link from the table cell.
|
||||
accOrElmOrID: "apples",
|
||||
oldAccOrElmOrID: "cell",
|
||||
expected: ["list 4 items", "First item", "link", "Apples"]
|
||||
expected: [{"string": "list"}, {"string": "listItemsCount", "count": 4},
|
||||
{"string": "listStart"}, {"string": "link"}, "Apples"]
|
||||
}, {
|
||||
// Test pivot to the table cell from the "apples" link.
|
||||
accOrElmOrID: "cell",
|
||||
oldAccOrElmOrID: "apples",
|
||||
expected: ["List of Fruits", "list 4 items", "First item", "link",
|
||||
"Apples", "link", "Bananas", "link", "Peaches", "Last item", "link",
|
||||
"Plums"]
|
||||
expected: ["List of Fruits", {"string": "list"},
|
||||
{"string": "listItemsCount", "count": 4}, {"string": "listStart"},
|
||||
{"string": "link"}, "Apples", {"string": "link"}, "Bananas",
|
||||
{"string": "link"}, "Peaches", {"string": "listEnd"},
|
||||
{"string": "link"}, "Plums"]
|
||||
}];
|
||||
|
||||
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, 0);
|
||||
|
@ -16,81 +16,104 @@
|
||||
// Test the following accOrElmOrID.
|
||||
var tests = [{
|
||||
accOrElmOrID: "nav",
|
||||
expectedUtterance: [["navigation", "a nav"], ["a nav", "navigation"]],
|
||||
expectedBraille: [["navigation", "a nav"], ["a nav", "navigation"]]
|
||||
expectedUtterance: [[{"string": "navigation"}, "a nav"],
|
||||
["a nav", {"string": "navigation"}]],
|
||||
expectedBraille: [[{"string": "navigation"}, "a nav"],
|
||||
["a nav", {"string": "navigation"}]]
|
||||
}, {
|
||||
accOrElmOrID: "main",
|
||||
expectedUtterance: [["main", "a main area"], ["a main area", "main"]],
|
||||
expectedBraille: [["main", "a main area"], ["a main area", "main"]]
|
||||
expectedUtterance: [[{"string": "main"}, "a main area"],
|
||||
["a main area", {"string": "main"}]],
|
||||
expectedBraille: [[{"string": "main"}, "a main area"],
|
||||
["a main area", {"string": "main"}]]
|
||||
}, {
|
||||
accOrElmOrID: "header",
|
||||
expectedUtterance: [["banner", "header", "a header"], ["a header",
|
||||
"header", "banner"]],
|
||||
expectedBraille: [["banner", "header", "a header"], ["a header",
|
||||
"header", "banner"]]
|
||||
expectedUtterance: [
|
||||
[{"string": "banner"}, {"string": "header"}, "a header"],
|
||||
["a header", {"string": "header"}, {"string": "banner"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "banner"}, {"string": "headerAbbr"}, "a header"],
|
||||
["a header", {"string": "headerAbbr"}, {"string": "banner"}]]
|
||||
}, {
|
||||
accOrElmOrID: "footer",
|
||||
expectedUtterance: [["content info", "footer", "a footer"], [
|
||||
"a footer", "footer", "content info"]],
|
||||
expectedBraille: [["content info", "footer", "a footer"], ["a footer",
|
||||
"footer", "content info"]]
|
||||
expectedUtterance: [
|
||||
[{"string": "contentinfo"}, {"string": "footer"}, "a footer"],
|
||||
["a footer", {"string": "footer"}, {"string": "contentinfo"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "contentinfo"}, {"string": "footerAbbr"}, "a footer"],
|
||||
["a footer", {"string": "footerAbbr"}, {"string": "contentinfo"}]]
|
||||
}, {
|
||||
accOrElmOrID: "article_header",
|
||||
expectedUtterance: [["header", "a header within an article"], [
|
||||
"a header within an article", "header"]],
|
||||
expectedBraille: [["header", "a header within an article"], [
|
||||
"a header within an article", "header"]],
|
||||
expectedUtterance: [
|
||||
[{"string": "header"}, "a header within an article"],
|
||||
["a header within an article", {"string": "header"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "headerAbbr"}, "a header within an article"],
|
||||
["a header within an article", {"string": "headerAbbr"}]],
|
||||
}, {
|
||||
accOrElmOrID: "article_footer",
|
||||
expectedUtterance: [["footer", "a footer within an article"], [
|
||||
"a footer within an article", "footer"]],
|
||||
expectedBraille: [["footer", "a footer within an article"], [
|
||||
"a footer within an article", "footer"]]
|
||||
expectedUtterance: [
|
||||
[{"string": "footer"}, "a footer within an article"],
|
||||
["a footer within an article", {"string": "footer"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "footerAbbr"}, "a footer within an article"],
|
||||
["a footer within an article", {"string": "footerAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "section_header",
|
||||
expectedUtterance: [["header", "a header within a section"], [
|
||||
"a header within a section", "header"]],
|
||||
expectedBraille: [["header", "a header within a section"], [
|
||||
"a header within a section", "header"]]
|
||||
expectedUtterance: [[{"string":"header"}, "a header within a section"],
|
||||
["a header within a section", {"string":"header"}]],
|
||||
expectedBraille: [
|
||||
[{"string":"headerAbbr"}, "a header within a section"],
|
||||
["a header within a section", {"string":"headerAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "section_footer",
|
||||
expectedUtterance: [["footer", "a footer within a section"], [
|
||||
"a footer within a section", "footer"]],
|
||||
expectedBraille: [["footer", "a footer within a section"], [
|
||||
"a footer within a section", "footer"]]
|
||||
expectedUtterance: [
|
||||
[{"string": "footer"}, "a footer within a section"],
|
||||
["a footer within a section", {"string": "footer"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "footerAbbr"}, "a footer within a section"],
|
||||
["a footer within a section", {"string": "footerAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "aside",
|
||||
expectedUtterance: [["complementary", "by the way I am an aside"], [
|
||||
"by the way I am an aside", "complementary"]],
|
||||
expectedBraille: [["complementary", "by the way I am an aside"], [
|
||||
"by the way I am an aside", "complementary"]]
|
||||
expectedUtterance: [
|
||||
[{"string": "complementary"}, "by the way I am an aside"],
|
||||
["by the way I am an aside", {"string": "complementary"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "complementary"}, "by the way I am an aside"],
|
||||
["by the way I am an aside", {"string": "complementary"}]]
|
||||
}, {
|
||||
accOrElmOrID: "main_element",
|
||||
expectedUtterance: [["main", "another main area"], [
|
||||
"another main area", "main"]],
|
||||
expectedBraille: [["main", "another main area"], ["another main area",
|
||||
"main"]]
|
||||
expectedUtterance: [[{"string": "main"}, "another main area"],
|
||||
["another main area", {"string": "main"}]],
|
||||
expectedBraille: [[{"string": "main"}, "another main area"],
|
||||
["another main area", {"string": "main"}]]
|
||||
}, {
|
||||
accOrElmOrID: "complementary",
|
||||
expectedUtterance: [["list 1 item", "complementary", "First item",
|
||||
"A complementary"], ["A complementary", "First item",
|
||||
"complementary", "list 1 item"]],
|
||||
expectedBraille: [["*", "complementary", "A complementary"], ["*",
|
||||
"A complementary", "complementary"]]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count": 1}, {"string": "complementary"},
|
||||
{"string": "listStart"}, "A complementary"], ["A complementary",
|
||||
{"string": "listStart"}, {"string": "complementary"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}]],
|
||||
expectedBraille: [["*", {"string": "complementary"}, "A complementary"],
|
||||
["*", "A complementary", {"string": "complementary"}]]
|
||||
}, {
|
||||
accOrElmOrID: "parent_main",
|
||||
expectedUtterance: [["main", "a parent main", "complementary",
|
||||
"a child complementary"], ["a parent main", "a child complementary",
|
||||
"complementary", "main"]],
|
||||
expectedBraille: [["main", "a parent main", "complementary",
|
||||
"a child complementary"], ["a parent main", "a child complementary",
|
||||
"complementary", "main"]]
|
||||
expectedUtterance: [[{"string": "main"}, "a parent main",
|
||||
{"string": "complementary"}, "a child complementary"],
|
||||
["a parent main", "a child complementary",
|
||||
{"string": "complementary"}, {"string": "main"}]],
|
||||
expectedBraille: [[{"string": "main"}, "a parent main",
|
||||
{"string": "complementary"}, "a child complementary"],
|
||||
["a parent main", "a child complementary",
|
||||
{"string": "complementary"}, {"string": "main"}]]
|
||||
}, {
|
||||
accOrElmOrID: "child_complementary",
|
||||
expectedUtterance: [["main", "complementary", "a child complementary"],
|
||||
["a child complementary", "complementary", "main"]],
|
||||
expectedBraille: [["complementary", "a child complementary"],
|
||||
["a child complementary", "complementary"]]
|
||||
expectedUtterance: [[{"string": "main"}, {"string": "complementary"},
|
||||
"a child complementary"], ["a child complementary",
|
||||
{"string": "complementary"}, {"string": "main"}]],
|
||||
expectedBraille: [[{"string": "complementary"},
|
||||
"a child complementary"], ["a child complementary",
|
||||
{"string": "complementary"}]]
|
||||
}];
|
||||
|
||||
// Test outputs (utterance and braille) for landmarks.
|
||||
|
@ -47,204 +47,204 @@
|
||||
}
|
||||
|
||||
var tests = [{
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden I will be hidden",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"}, "I will be hidden"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
[hide(id) for (id of ["to_hide1", "to_hide2", "to_hide3", "to_hide4"])];
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden I will be hidden",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"},"I will be hidden"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
[hide(id) for (id of ["to_hide_descendant1", "to_hide_descendant2",
|
||||
"to_hide_descendant3", "to_hide_descendant4"])];
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I will be shown",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I will be shown"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
[show(id) for (id of ["to_show1", "to_show2", "to_show3", "to_show4"])];
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I will be shown",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I will be shown"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
[show(id) for (id of ["to_show_descendant1", "to_show_descendant2",
|
||||
"to_show_descendant3", "to_show_descendant4"])];
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden I will be hidden",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"}, "I will be hidden"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
hide("to_hide_live_assertive");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I will be shown",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I will be shown"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
[show(id) for (id of ["to_show_live_off", "to_show_live_assertive"])];
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_add", "Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateHTML("text_add", "Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden Text Removed",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"}, "Text Removed"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_remove", "");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Descendant Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Descendant Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_add_descendant", "Descendant Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Descendant Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Descendant Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateHTML("text_add_descendant", "Descendant Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden Descendant Text Removed",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"}, "Descendant Text Removed"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_remove_descendant", "");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Descendant Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Descendant Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_add_descendant2", "Descendant Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "Descendant Text Added",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["Descendant Text Added"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateHTML("text_add_descendant2", "Descendant Text Added");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "hidden Descendant Text Removed",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": [{"string": "hidden"}, "Descendant Text Removed"],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("text_remove_descendant2", "");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I am replaced main",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I am replaced", {"string": "main"}],
|
||||
"options": {
|
||||
"enqueue": true
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
var region = document.getElementById("to_replace_region");
|
||||
var child = document.getElementById("to_replace");
|
||||
child.setAttribute("role", "main");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I am a replaced text",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I am a replaced text"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateText("to_replace_text", "I am a replaced text");
|
||||
}
|
||||
}, {
|
||||
expected: [{
|
||||
"method": "speak",
|
||||
"data": "I am a replaced text",
|
||||
expected: {
|
||||
"eventType": "liveregion-change",
|
||||
"data": ["I am a replaced text"],
|
||||
"options": {
|
||||
"enqueue": false
|
||||
}
|
||||
}],
|
||||
},
|
||||
action: function action() {
|
||||
updateHTML("to_replace_text", "I am a replaced text");
|
||||
}
|
||||
|
@ -22,340 +22,372 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||
// generator function within the UtteranceGenerator.
|
||||
var tests = [{
|
||||
accOrElmOrID: "anchor",
|
||||
expectedUtterance: [["link", "title"], ["title", "link"]],
|
||||
expectedBraille: [["lnk", "title"], ["title", "lnk"]]
|
||||
expectedUtterance: [[{"string": "link"}, "title"],
|
||||
["title", {"string": "link"}]],
|
||||
expectedBraille: [[{"string": "linkAbbr"}, "title"],
|
||||
["title", {"string": "linkAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_titleandtext",
|
||||
expectedUtterance: [["link", "goes to the tests -", "Tests"],
|
||||
["Tests", "- goes to the tests", "link"]],
|
||||
expectedBraille: [["lnk", "goes to the tests -", "Tests"],
|
||||
["Tests", "- goes to the tests", "lnk"]],
|
||||
expectedUtterance: [[{"string": "link"}, "goes to the tests -",
|
||||
"Tests"], ["Tests", "- goes to the tests", {"string": "link"}]],
|
||||
expectedBraille: [[{"string": "linkAbbr"}, "goes to the tests -",
|
||||
"Tests"], ["Tests", "- goes to the tests", {"string": "linkAbbr"}]],
|
||||
}, {
|
||||
accOrElmOrID: "anchor_duplicatedtitleandtext",
|
||||
expectedUtterance: [["link", "Tests"], ["Tests", "link"]],
|
||||
expectedBraille: [["lnk", "Tests"], ["Tests", "lnk"]]
|
||||
expectedUtterance: [[{"string": "link"}, "Tests"],
|
||||
["Tests", {"string": "link"}]],
|
||||
expectedBraille: [[{"string": "linkAbbr"}, "Tests"],
|
||||
["Tests", {"string": "linkAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "anchor_arialabelandtext",
|
||||
expectedUtterance: [["link", "goes to the tests - Tests"],
|
||||
["Tests - goes to the tests", "link"]],
|
||||
expectedBraille: [["lnk", "goes to the tests - Tests"],
|
||||
["Tests - goes to the tests", "lnk"]],
|
||||
expectedUtterance: [[{"string": "link"}, "goes to the tests - Tests"],
|
||||
["Tests - goes to the tests", {"string": "link"}]],
|
||||
expectedBraille: [[{"string": "linkAbbr"},
|
||||
"goes to the tests - Tests"], ["Tests - goes to the tests",
|
||||
{"string": "linkAbbr"}]],
|
||||
}, {
|
||||
accOrElmOrID: "textarea",
|
||||
expectedUtterance: [[
|
||||
"text area", "This is the text area text."
|
||||
], [
|
||||
"This is the text area text.", "text area"
|
||||
],],
|
||||
expectedBraille: [[
|
||||
"txtarea", "This is the text area text."
|
||||
], [
|
||||
"This is the text area text.", "txtarea"
|
||||
],],
|
||||
expectedUtterance: [[{"string": "textarea"},
|
||||
"This is the text area text."], ["This is the text area text.",
|
||||
{"string": "textarea"}]],
|
||||
expectedBraille: [[{"string": "textareaAbbr"},
|
||||
"This is the text area text."], ["This is the text area text.",
|
||||
{"string": "textareaAbbr"}]],
|
||||
}, {
|
||||
accOrElmOrID: "heading",
|
||||
expectedUtterance: [
|
||||
["heading level 1", "Test heading"],
|
||||
["Test heading", "heading level 1"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["heading", "Test heading"],
|
||||
["Test heading", "heading"]
|
||||
]
|
||||
expectedUtterance: [[{"string": "headingLevel", "args": [1]},
|
||||
"Test heading"], ["Test heading",
|
||||
{"string": "headingLevel", "args": [1]}]],
|
||||
expectedBraille: [[{"string": "headingAbbr"}, "Test heading"],
|
||||
["Test heading", {"string": "headingAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "list",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count":1}, {"string": "listStart"},
|
||||
"1.", "list one"], ["1.", "list one", {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count":1}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["list", "list one"],
|
||||
["list one", "list"]
|
||||
]
|
||||
expectedBraille: [[{"string": "listAbbr"}, "list one"],
|
||||
["list one", {"string": "listAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "dlist",
|
||||
expectedUtterance: [
|
||||
["definition list 0.5 items", "dd one"],
|
||||
["dd one", "definition list 0.5 items"]
|
||||
expectedUtterance: [[{"string": "definitionlist"},
|
||||
{"string": "listItemsCount", "count": 0.5}, "dd one"], ["dd one",
|
||||
{"string": "definitionlist"},
|
||||
{"string": "listItemsCount", "count": 0.5}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["definition list", "dd one"],
|
||||
["dd one", "definition list"]
|
||||
]
|
||||
expectedBraille: [[{"string": "definitionlistAbbr"}, "dd one"],
|
||||
["dd one", {"string": "definitionlistAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "li_one",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count": 1}, {"string": "listStart"},
|
||||
"1.", "list one"], ["1.", "list one", {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["1.", "list one"],
|
||||
["1.", "list one"]
|
||||
]
|
||||
expectedBraille: [["1.", "list one"], ["1.", "list one"]]
|
||||
},
|
||||
{
|
||||
accOrElmOrID: "li_two",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "list two"],
|
||||
["list two", "First item", "list 1 item"]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count": 1}, {"string": "listStart"},
|
||||
"list two"], ["list two", {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["*", "list two"],
|
||||
["*", "list two"]
|
||||
]
|
||||
expectedBraille: [["*", "list two"], ["*", "list two"]]
|
||||
}, {
|
||||
accOrElmOrID: "cell",
|
||||
expectedUtterance: [[
|
||||
"table with 1 column and 1 row", "Fruits and vegetables",
|
||||
"Column 1 Row 1", "list 4 items", "First item", "link", "Apples",
|
||||
"link", "Bananas", "link", "Peaches", "Last item", "link", "Plums"
|
||||
], [
|
||||
"Apples", "link", "First item", "Bananas", "link", "Peaches",
|
||||
"link", "Plums", "link", "Last item", "list 4 items",
|
||||
"Column 1 Row 1", "Fruits and vegetables",
|
||||
"table with 1 column and 1 row"
|
||||
]],
|
||||
expectedBraille: [[
|
||||
"c1r1", "list", "lnk", "Apples", "lnk", "Bananas", "lnk",
|
||||
"Peaches", "lnk", "Plums"
|
||||
], [
|
||||
"Apples", "lnk", "Bananas", "lnk", "Peaches", "lnk", "Plums",
|
||||
"lnk", "list", "c1r1"
|
||||
]]
|
||||
expectedUtterance: [[{"string":"table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 1}, "Fruits and vegetables",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, {"string": "list"},
|
||||
{"string": "listItemsCount", "count": 4}, {"string": "listStart"},
|
||||
{"string": "link"}, "Apples", {"string": "link"}, "Bananas",
|
||||
{"string": "link"}, "Peaches", {"string": "listEnd"},
|
||||
{"string": "link"}, "Plums"], ["Apples", {"string": "link"},
|
||||
{"string": "listStart"}, "Bananas", {"string": "link"}, "Peaches",
|
||||
{"string": "link"}, "Plums", {"string": "link"},
|
||||
{"string": "listEnd"}, {"string": "list"},
|
||||
{"string": "listItemsCount", "count": 4},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "Fruits and vegetables",
|
||||
{"string":"table"}, {"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 1}]],
|
||||
expectedBraille: [[{"string": "cellInfoAbbr", "args": [ 1, 1]},
|
||||
{"string": "listAbbr"}, {"string": "linkAbbr"}, "Apples",
|
||||
{"string": "linkAbbr"}, "Bananas", {"string": "linkAbbr"},
|
||||
"Peaches", {"string": "linkAbbr"}, "Plums"], ["Apples",
|
||||
{"string": "linkAbbr"}, "Bananas", {"string": "linkAbbr"},
|
||||
"Peaches", {"string": "linkAbbr"}, "Plums", {"string": "linkAbbr"},
|
||||
{"string": "listAbbr"},
|
||||
{"string": "cellInfoAbbr", "args": [ 1, 1]}]]
|
||||
}, {
|
||||
accOrElmOrID: "date",
|
||||
expectedUtterance: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]],
|
||||
expectedBraille: [["date entry", "2011-09-29"], ["2011-09-29", "date entry"]]
|
||||
expectedUtterance: [[{"string": "textInputType_date"},
|
||||
{"string": "entry"}, "2011-09-29"], ["2011-09-29",
|
||||
{"string": "textInputType_date"}, {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "textInputType_date"},
|
||||
{"string": "entryAbbr"}, "2011-09-29"], ["2011-09-29",
|
||||
{"string": "textInputType_date"}, {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "email",
|
||||
expectedUtterance: [
|
||||
["e-mail entry", "test@example.com"],
|
||||
["test@example.com", "e-mail entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["e-mail entry", "test@example.com"],
|
||||
["test@example.com", "e-mail entry"]
|
||||
]
|
||||
expectedUtterance: [[{"string": "textInputType_email"},
|
||||
{"string": "entry"}, "test@example.com"], ["test@example.com",
|
||||
{"string": "textInputType_email"}, {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "textInputType_email"},
|
||||
{"string": "entryAbbr"}, "test@example.com"], ["test@example.com",
|
||||
{"string": "textInputType_email"}, {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "search",
|
||||
expectedUtterance: [
|
||||
["search entry", "This is a search"],
|
||||
["This is a search", "search entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["search entry", "This is a search"],
|
||||
["This is a search", "search entry"]
|
||||
]
|
||||
expectedUtterance: [[{"string": "textInputType_search"},
|
||||
{"string": "entry"}, "This is a search"], ["This is a search",
|
||||
{"string": "textInputType_search"}, {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "textInputType_search"},
|
||||
{"string": "entryAbbr"}, "This is a search"], ["This is a search",
|
||||
{"string": "textInputType_search"}, {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "tel",
|
||||
expectedUtterance: [
|
||||
["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["telephone entry", "555-5555"], ["555-5555", "telephone entry"]
|
||||
]
|
||||
expectedUtterance: [[{"string": "textInputType_tel"},
|
||||
{"string": "entry"}, "555-5555"], ["555-5555",
|
||||
{"string": "textInputType_tel"}, {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "textInputType_tel"},
|
||||
{"string": "entryAbbr"}, "555-5555"], ["555-5555",
|
||||
{"string": "textInputType_tel"}, {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "url",
|
||||
expectedUtterance: [
|
||||
["URL entry", "http://example.com"],
|
||||
["http://example.com", "URL entry"]
|
||||
],
|
||||
expectedBraille: [
|
||||
["URL entry", "http://example.com"],
|
||||
["http://example.com", "URL entry"]
|
||||
]
|
||||
expectedUtterance: [[{"string": "textInputType_url"},
|
||||
{"string": "entry"}, "http://example.com"], ["http://example.com",
|
||||
{"string": "textInputType_url"}, {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "textInputType_url"},
|
||||
{"string": "entryAbbr"}, "http://example.com"],
|
||||
["http://example.com", {"string": "textInputType_url"},
|
||||
{"string": "entryAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "textInput",
|
||||
expectedUtterance: [["entry", "This is text."], ["This is text.", "entry"]],
|
||||
expectedBraille: [["entry", "This is text."], ["This is text.", "entry"]]
|
||||
expectedUtterance: [[{"string": "entry"}, "This is text."],
|
||||
["This is text.", {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "entryAbbr"}, "This is text."],
|
||||
["This is text.", {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
// Test pivot to list from li_one.
|
||||
accOrElmOrID: "list",
|
||||
oldAccOrElmOrID: "li_one",
|
||||
expectedUtterance: [
|
||||
["list 1 item", "First item", "1.", "list one"],
|
||||
["1.", "list one", "First item", "list 1 item"]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count": 1}, {"string": "listStart"},
|
||||
"1.", "list one"], ["1.", "list one", {"string": "listStart"},
|
||||
{"string": "list"}, {"string": "listItemsCount", "count": 1}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["list", "list one"],
|
||||
["list one", "list"]
|
||||
]
|
||||
expectedBraille: [[{"string": "listAbbr"}, "list one"],
|
||||
["list one", {"string": "listAbbr"}]]
|
||||
}, {
|
||||
// Test pivot to "apples" link from the table cell.
|
||||
accOrElmOrID: "apples",
|
||||
oldAccOrElmOrID: "cell",
|
||||
expectedUtterance: [
|
||||
["list 4 items", "First item", "link", "Apples"],
|
||||
["Apples", "link", "First item", "list 4 items"]
|
||||
expectedUtterance: [[{"string": "list"},
|
||||
{"string": "listItemsCount", "count": 4}, {"string": "listStart"},
|
||||
{"string": "link"}, "Apples"], ["Apples", {"string": "link"},
|
||||
{"string": "listStart"}, {"string": "list"},
|
||||
{"string": "listItemsCount", "count": 4}]
|
||||
],
|
||||
expectedBraille: [
|
||||
["*", "lnk", "Apples"],
|
||||
["*", "Apples", "lnk"]
|
||||
]
|
||||
expectedBraille: [["*", {"string": "linkAbbr"}, "Apples"],
|
||||
["*", "Apples", {"string": "linkAbbr"}]]
|
||||
}, {
|
||||
// Test pivot to 'bananas' link from 'apples' link.
|
||||
// Test pivot to "bananas" link from "apples" link.
|
||||
accOrElmOrID: "bananas",
|
||||
oldAccOrElmOrID: "apples",
|
||||
expectedUtterance: [["link", "Bananas"], ["Bananas", "link"]],
|
||||
expectedBraille: [["*", "lnk", "Bananas"], ["*", "Bananas", "lnk"]]
|
||||
expectedUtterance: [[{"string": "link"}, "Bananas"],
|
||||
["Bananas", {"string": "link"}]],
|
||||
expectedBraille: [["*", {"string": "linkAbbr"}, "Bananas"],
|
||||
["*", "Bananas", {"string": "linkAbbr"}]]
|
||||
}, {
|
||||
// test unavailable state utterance
|
||||
accOrElmOrID: 'unavailableButton',
|
||||
expectedUtterance: [["unavailable button", "I am unavailable"],
|
||||
["I am unavailable", "unavailable button"]],
|
||||
expectedBraille: [["btn", "I am unavailable"],
|
||||
["I am unavailable", "btn"]]
|
||||
accOrElmOrID: "unavailableButton",
|
||||
expectedUtterance: [[{"string": "stateUnavailable"},
|
||||
{"string": "pushbutton"}, "I am unavailable"], ["I am unavailable",
|
||||
{"string": "stateUnavailable"}, {"string": "pushbutton"}]],
|
||||
expectedBraille: [[{"string": "pushbuttonAbbr"}, "I am unavailable"],
|
||||
["I am unavailable", {"string": "pushbuttonAbbr"}]]
|
||||
}, {
|
||||
// test expanded state utterance
|
||||
accOrElmOrID: 'expandedButton',
|
||||
expectedUtterance: [["expanded button", "I am expanded"],
|
||||
["I am expanded", "expanded button"]],
|
||||
expectedBraille: [["btn", "I am expanded"],
|
||||
["I am expanded", "btn"]]
|
||||
accOrElmOrID: "expandedButton",
|
||||
expectedUtterance: [[{"string": "stateExpanded"},
|
||||
{"string": "pushbutton"}, "I am expanded"], ["I am expanded",
|
||||
{"string": "stateExpanded"}, {"string": "pushbutton"}]],
|
||||
expectedBraille: [[{"string": "pushbuttonAbbr"}, "I am expanded"],
|
||||
["I am expanded", {"string": "pushbuttonAbbr"}]]
|
||||
}, {
|
||||
// test collapsed state utterance
|
||||
accOrElmOrID: 'collapsedButton',
|
||||
expectedUtterance: [["collapsed button", "I am collapsed"],
|
||||
["I am collapsed", "collapsed button"]],
|
||||
expectedBraille: [["btn", "I am collapsed"],
|
||||
["I am collapsed", "btn"]]
|
||||
accOrElmOrID: "collapsedButton",
|
||||
expectedUtterance: [[{"string": "stateCollapsed"},
|
||||
{"string": "pushbutton"}, "I am collapsed"], ["I am collapsed",
|
||||
{"string": "stateCollapsed"}, {"string": "pushbutton"}]],
|
||||
expectedBraille: [[{"string": "pushbuttonAbbr"}, "I am collapsed"],
|
||||
["I am collapsed", {"string": "pushbuttonAbbr"}]]
|
||||
}, {
|
||||
// test required state utterance
|
||||
accOrElmOrID: 'requiredInput',
|
||||
expectedUtterance: [["required entry", "I am required"],
|
||||
["I am required", "required entry"]],
|
||||
expectedBraille: [["entry", "I am required"],
|
||||
["I am required", "entry"]]
|
||||
accOrElmOrID: "requiredInput",
|
||||
expectedUtterance: [[{"string": "stateRequired"}, {"string": "entry"},
|
||||
"I am required"], ["I am required", {"string": "stateRequired"},
|
||||
{"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "entryAbbr"}, "I am required"],
|
||||
["I am required", {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
// test has popup state utterance
|
||||
accOrElmOrID: 'hasPopupButton',
|
||||
expectedUtterance: [["has pop up button menu", "I have a popup"],
|
||||
["I have a popup", "has pop up button menu"]],
|
||||
expectedBraille: [["button menu", "I have a popup"],
|
||||
["I have a popup", "button menu"]]
|
||||
accOrElmOrID: "hasPopupButton",
|
||||
expectedUtterance: [[{"string": "stateHasPopup"},
|
||||
{"string": "buttonmenu"}, "I have a popup"], ["I have a popup",
|
||||
{"string": "stateHasPopup"}, {"string": "buttonmenu"}]],
|
||||
expectedBraille: [[{"string": "buttonmenuAbbr"}, "I have a popup"],
|
||||
["I have a popup", {"string": "buttonmenuAbbr"}]]
|
||||
}, {
|
||||
// Test selected tab
|
||||
accOrElmOrID: 'tab1',
|
||||
expectedUtterance: [['tab list', 'selected tab 1 of 2', 'Account'],
|
||||
['Account', 'selected tab 1 of 2', 'tab list']],
|
||||
expectedBraille: [['tab 1 of 2', 'Account'],
|
||||
['Account', 'tab 1 of 2']]
|
||||
accOrElmOrID: "tab1",
|
||||
expectedUtterance: [[{"string": "pagetablist"},
|
||||
{"string": "stateSelected"}, {"string": "pagetab"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account",
|
||||
{"string": "stateSelected"}, {"string": "pagetab"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, {"string": "pagetablist"}]
|
||||
],
|
||||
expectedBraille: [[{"string": "pagetabAbbr"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}, "Account"], ["Account",
|
||||
{"string": "pagetabAbbr"},
|
||||
{"string": "objItemOfN", "args": [1, 2]}]]
|
||||
}, {
|
||||
// Test unselected tab
|
||||
accOrElmOrID: 'tab2',
|
||||
expectedUtterance: [['tab list', 'tab 2 of 2', 'Advanced'],
|
||||
['Advanced', 'tab 2 of 2', 'tab list']],
|
||||
expectedBraille: [['tab 2 of 2', 'Advanced'],
|
||||
['Advanced', 'tab 2 of 2']]
|
||||
},
|
||||
|
||||
{
|
||||
accOrElmOrID: "tab2",
|
||||
expectedUtterance: [[{"string": "pagetablist"}, {"string": "pagetab"},
|
||||
{"string": "objItemOfN", "args": [2, 2]}, "Advanced"], ["Advanced",
|
||||
{"string": "pagetab"}, {"string": "objItemOfN", "args": [2, 2]},
|
||||
{"string": "pagetablist"}]],
|
||||
expectedBraille: [[{"string": "pagetabAbbr"},
|
||||
{"string": "objItemOfN", "args": [2, 2]}, "Advanced"], ["Advanced",
|
||||
{"string": "pagetabAbbr"},
|
||||
{"string": "objItemOfN", "args": [2, 2]}]]
|
||||
}, {
|
||||
// Landing on this label should mimic landing on the checkbox.
|
||||
accOrElmOrID: "label1",
|
||||
expectedUtterance: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Orange'],
|
||||
['Orange', '( )']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"],
|
||||
["Orange", {"string": "stateUncheckedAbbr"}]]
|
||||
}, {
|
||||
// Here we get a top-level view of the form.
|
||||
accOrElmOrID: "form1",
|
||||
expectedUtterance: [['label', 'not checked check button', 'Orange', 'Orange',
|
||||
'not checked check button', 'Blue', 'label', 'Blue'],
|
||||
['Orange', 'not checked check button', 'Orange', 'label',
|
||||
'Blue', 'not checked check button', 'Blue', 'label']],
|
||||
expectedBraille: [['label', '( )', 'Orange', 'Orange',
|
||||
'( )', 'Blue', 'label', 'Blue'],
|
||||
['Orange', '( )', 'Orange', 'label',
|
||||
'Blue', '( )', 'Blue', 'label']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "label"},
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange",
|
||||
"Orange", {"string": "stateNotChecked"}, {"string": "checkbutton"},
|
||||
"Blue", {"string": "label"}, "Blue"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}, "Orange",
|
||||
{"string": "label"}, "Blue", {"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Blue", {"string": "label"}]],
|
||||
expectedBraille: [[{"string": "labelAbbr"},
|
||||
{"string": "stateUncheckedAbbr"}, "Orange", "Orange",
|
||||
{"string": "stateUncheckedAbbr"}, "Blue", {"string": "labelAbbr"},
|
||||
"Blue"], ["Orange", {"string": "stateUncheckedAbbr"}, "Orange",
|
||||
{"string": "labelAbbr"}, "Blue", {"string": "stateUncheckedAbbr"},
|
||||
"Blue", {"string": "labelAbbr"}]]
|
||||
}, {
|
||||
// This is a non-nesting label.
|
||||
accOrElmOrID: "label2",
|
||||
expectedUtterance: [['label', 'Blue'], ['Blue', 'label']],
|
||||
expectedBraille: [['label', 'Blue'], ['Blue', 'label']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "label"}, "Blue"],
|
||||
["Blue", {"string": "label"}]],
|
||||
expectedBraille: [[{"string": "labelAbbr"}, "Blue"],
|
||||
["Blue", {"string": "labelAbbr"}]]
|
||||
}, {
|
||||
// This is a distinct control.
|
||||
accOrElmOrID: "input2",
|
||||
expectedUtterance: [['not checked check button', 'Blue'],
|
||||
['Blue', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Blue'],
|
||||
['Blue', '( )']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Blue"], ["Blue",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Blue"], ["Blue",
|
||||
{"string": "stateUncheckedAbbr"}]]
|
||||
}, {
|
||||
// This is a nested control.
|
||||
accOrElmOrID: "input1",
|
||||
expectedUtterance: [['not checked check button', 'Orange'],
|
||||
['Orange', 'not checked check button']],
|
||||
expectedBraille: [['( )', 'Orange'],
|
||||
['Orange', '( )']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "checkbutton"}, "Orange"], ["Orange",
|
||||
{"string": "stateNotChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateUncheckedAbbr"}, "Orange"],
|
||||
["Orange", {"string": "stateUncheckedAbbr"}]]
|
||||
}, {
|
||||
// Landing on this label should mimic landing on the entry.
|
||||
accOrElmOrID: "label3",
|
||||
expectedUtterance: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']],
|
||||
expectedBraille: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "entry"}, "Joe", "First name:"],
|
||||
["First name:", "Joe", {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "entryAbbr"}, "Joe", "First name:"],
|
||||
["First name:", "Joe", {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input3",
|
||||
expectedUtterance: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']],
|
||||
expectedBraille: [['entry', 'Joe', 'First name:'],
|
||||
['First name:', 'Joe', 'entry']]
|
||||
},
|
||||
{
|
||||
expectedUtterance: [[{"string": "entry"}, "Joe", "First name:"],
|
||||
["First name:", "Joe", {"string": "entry"}]],
|
||||
expectedBraille: [[{"string": "entryAbbr"}, "Joe", "First name:"],
|
||||
["First name:", "Joe", {"string": "entryAbbr"}]]
|
||||
}, {
|
||||
// This is a nested control with a value.
|
||||
accOrElmOrID: "input4",
|
||||
expectedUtterance: [['slider', '3', 'Points:'],
|
||||
['Points:', '3', 'slider']],
|
||||
expectedBraille: [['slider', '3', 'Points:'],
|
||||
['Points:', '3', 'slider']]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "slider"}, "3", "Points:"],
|
||||
["Points:", "3", {"string": "slider"}]],
|
||||
expectedBraille: [[{"string": "sliderAbbr"}, "3", "Points:"],
|
||||
["Points:", "3", {"string": "sliderAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "password",
|
||||
expectedUtterance: [["password text", "Secret Password"],
|
||||
["Secret Password", "password text"]],
|
||||
expectedBraille: [["passwdtxt", "Secret Password"],
|
||||
["Secret Password", "passwdtxt"]]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "passwordtext"}, "Secret Password"],
|
||||
["Secret Password", {"string": "passwordtext"}]],
|
||||
expectedBraille: [[{"string": "passwordtextAbbr"}, "Secret Password"],
|
||||
["Secret Password", {"string": "passwordtextAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "input5",
|
||||
expectedUtterance: [["checked check button", "Boring label"],
|
||||
["Boring label", "checked check button"]],
|
||||
expectedBraille: [["(x)", "Boring label"],
|
||||
["Boring label", "(x)"]]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "stateChecked"},
|
||||
{"string": "checkbutton"}, "Boring label"], ["Boring label",
|
||||
{"string": "stateChecked"}, {"string": "checkbutton"}]],
|
||||
expectedBraille: [[{"string": "stateCheckedAbbr"}, "Boring label"],
|
||||
["Boring label", {"string": "stateCheckedAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "radio_unselected",
|
||||
expectedUtterance: [["not checked radio button", "any old radio button"],
|
||||
["any old radio button", "not checked radio button"]],
|
||||
expectedBraille: [["( )", "any old radio button"],
|
||||
["any old radio button", "( )"]]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "stateNotChecked"},
|
||||
{"string": "radiobutton"}, "any old radio button"],
|
||||
["any old radio button", {"string": "stateNotChecked"},
|
||||
{"string": "radiobutton"}]
|
||||
],
|
||||
expectedBraille: [
|
||||
[{"string": "stateUncheckedAbbr"}, "any old radio button"],
|
||||
["any old radio button", {"string": "stateUncheckedAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "radio_selected",
|
||||
expectedUtterance: [["checked radio button", "a unique radio button"],
|
||||
["a unique radio button", "checked radio button"]],
|
||||
expectedBraille: [["(x)", "a unique radio button"],
|
||||
["a unique radio button", "(x)"]]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "stateChecked"},
|
||||
{"string": "radiobutton"}, "a unique radio button"],
|
||||
["a unique radio button", {"string": "stateChecked"},
|
||||
{"string": "radiobutton"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "stateCheckedAbbr"}, "a unique radio button"],
|
||||
["a unique radio button", {"string": "stateCheckedAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "togglebutton_notpressed",
|
||||
expectedUtterance: [["toggle button", "I ain't pressed"],
|
||||
["I ain't pressed", "toggle button"]],
|
||||
expectedBraille: [["( )", "I ain't pressed"],
|
||||
["I ain't pressed", "( )"]]
|
||||
},{
|
||||
expectedUtterance: [[{"string": "togglebutton"}, "I am not pressed"],
|
||||
["I am not pressed", {"string": "togglebutton"}]],
|
||||
expectedBraille: [
|
||||
[{"string": "stateUnpressedAbbr"}, "I am not pressed"],
|
||||
["I am not pressed", {"string": "stateUnpressedAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "togglebutton_pressed",
|
||||
expectedUtterance: [["pressed toggle button", "I am pressed!"],
|
||||
["I am pressed!", "pressed toggle button"]],
|
||||
expectedBraille: [["(x)", "I am pressed!"],
|
||||
["I am pressed!", "(x)"]]
|
||||
expectedUtterance: [[{"string": "statePressed"},
|
||||
{"string": "togglebutton"}, "I am pressed!"], ["I am pressed!",
|
||||
{"string": "statePressed"}, {"string": "togglebutton"}]],
|
||||
expectedBraille: [[{"string": "statePressedAbbr"}, "I am pressed!"],
|
||||
["I am pressed!", {"string": "statePressedAbbr"}]]
|
||||
}, {
|
||||
accOrElmOrID: "listbox-option",
|
||||
expectedUtterance: [["list box", "option", "Search suggestion"],
|
||||
["Search suggestion", "option", "list box"]],
|
||||
expectedBraille: [["option", "Search suggestion"],
|
||||
["Search suggestion", "option"]]
|
||||
expectedUtterance: [[{"string": "listbox"},
|
||||
{"string": "listboxoption"}, "Search suggestion"],
|
||||
["Search suggestion", {"string": "listboxoption"},
|
||||
{"string": "listbox"}]
|
||||
],
|
||||
expectedBraille: [
|
||||
[{"string": "listboxoptionAbbr"}, "Search suggestion"],
|
||||
["Search suggestion", {"string": "listboxoptionAbbr"}]]
|
||||
}];
|
||||
|
||||
// Test all possible utterance order preference values.
|
||||
@ -471,7 +503,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=753984
|
||||
<input id="url" type="url" value="http://example.com" />
|
||||
<input id="textInput" type="text" value="This is text." />
|
||||
<label>Points: <input id="range" type="range" name="points" min="1" max="10" value="3"></label>
|
||||
<div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I ain't pressed</div>
|
||||
<div id="togglebutton_notpressed" aria-pressed="false" role="button" tabindex="-1">I am not pressed</div>
|
||||
<div id="togglebutton_pressed" aria-pressed="true" role="button" tabindex="-1">I am pressed!</div>
|
||||
<ul role="listbox" style="list-style-type: none;">
|
||||
<li role="option" id="listbox-option">Search suggestion</li>
|
||||
|
@ -16,63 +16,219 @@
|
||||
// Test the following accOrElmOrID.
|
||||
var tests = [{
|
||||
accOrElmOrID: "table1",
|
||||
expectedUtterance: [["table with 2 columns and 2 rows",
|
||||
"Column 1 Row 1", "col1", "Column 2 Row 1", "col2",
|
||||
"Column 1 Row 2 col1", "cell1", "Column 2 Row 2 col2", "cell2"], [
|
||||
"col1", "Column 1 Row 1", "col2", "Column 2 Row 1", "cell1",
|
||||
"Column 1 Row 2 col1", "cell2", "Column 2 Row 2 col2",
|
||||
"table with 2 columns and 2 rows"]],
|
||||
expectedBraille: [["tbl 2c 2r", "c1r1", "col1", "c2r1", "col2",
|
||||
"c1r2 col1", "cell1", "c2r2 col2", "cell2"], ["col1", "c1r1", "col2",
|
||||
"c2r1", "cell1", "c1r2 col1", "cell2", "c2r2 col2", "tbl 2c 2r"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "col1", "cell1",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2", "cell2"], ["col1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "cell1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "col1", "cell2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2", {"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2}]],
|
||||
expectedBraille: [[
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 2},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col1",
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col1", "cell1",
|
||||
{"string": "cellInfoAbbr", "args": [2, 2]}, "col2", "cell2"], ["col1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col2",
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "cell1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col1", "cell2",
|
||||
{"string": "cellInfoAbbr", "args": [2, 2]}, "col2",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 2},
|
||||
{"string": "tblRowInfoAbbr", "count": 2}]]
|
||||
}, {
|
||||
accOrElmOrID: "table2",
|
||||
expectedUtterance: [["table with 2 columns and 2 rows",
|
||||
"Column 1 Row 1 col1", "cell1", "Column 2 Row 1 col2",
|
||||
"table with 1 column and 2 rows", "Column 1 Row 1", "colheader",
|
||||
"Column 1 Row 2 colheader", "bla", "Column 1 Row 2", "col1",
|
||||
"Column 2 Row 2", "col2"], ["cell1", "Column 1 Row 1 col1",
|
||||
"colheader", "Column 1 Row 1", "bla", "Column 1 Row 2 colheader",
|
||||
"table with 1 column and 2 rows", "Column 2 Row 1 col2", "col1",
|
||||
"Column 1 Row 2", "col2", "Column 2 Row 2",
|
||||
"table with 2 columns and 2 rows"]],
|
||||
expectedBraille: [["tbl 2c 2r", "c1r1 col1", "cell1", "c2r1 col2",
|
||||
"tbl 1c 2r", "c1r1", "colheader", "c1r2 colheader", "bla", "c1r2",
|
||||
"col1", "c2r2", "col2"], ["cell1", "c1r1 col1", "colheader", "c1r1",
|
||||
"bla", "c1r2 colheader", "tbl 1c 2r", "c2r1 col2", "col1", "c1r2",
|
||||
"col2", "c2r2", "tbl 2c 2r"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1", "cell1",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "col1",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2"], ["cell1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1", "colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2", "col1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, {"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2}]],
|
||||
expectedBraille: [[{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 2},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col1", "cell1",
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col1",
|
||||
{"string": "cellInfoAbbr", "args": [2, 2]}, "col2"], ["cell1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col1", "colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "bla",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2", "col1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col2",
|
||||
{"string": "cellInfoAbbr", "args": [2, 2]},
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 2},
|
||||
{"string": "tblRowInfoAbbr", "count": 2}]]
|
||||
}, {
|
||||
accOrElmOrID: "table3",
|
||||
expectedUtterance: [["table with 2 columns and 2 rows",
|
||||
"Column 2 Row 1 col2", "table with 1 column and 2 rows",
|
||||
"Column 1 Row 1", "colheader", "Column 1 Row 2 colheader", "bla"], [
|
||||
"colheader", "Column 1 Row 1", "bla", "Column 1 Row 2 colheader",
|
||||
"table with 1 column and 2 rows", "Column 2 Row 1 col2",
|
||||
"table with 2 columns and 2 rows"]],
|
||||
expectedBraille: [["tbl 1c 2r", "c1r1", "colheader", "c1r2 colheader",
|
||||
"bla"], ["colheader", "c1r1", "bla", "c1r2 colheader", "tbl 1c 2r"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla"], ["colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2}]],
|
||||
expectedBraille: [[
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla"],
|
||||
["colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "bla",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2}]]
|
||||
}, {
|
||||
accOrElmOrID: "table4",
|
||||
expectedUtterance: [["table with 4 columns and 3 rows",
|
||||
"Column 1 Row 1", "col1", "Column 2 Row 1", "col2", "Column 3 Row 1",
|
||||
"col3", "Column 1 Row 2 spans 2 columns col1", "row1",
|
||||
"Column 3 Row 2 col3 row1", "cell1",
|
||||
"Column 4 Row 2 spans 2 rows row1", "cell2", "Column 1 Row 3 col1",
|
||||
"row2", "Column 2 Row 3 col2 row2", "cell3",
|
||||
"Column 3 Row 3 col3 row2", "cell4"], ["col1", "Column 1 Row 1",
|
||||
"col2", "Column 2 Row 1", "col3", "Column 3 Row 1", "row1",
|
||||
"Column 1 Row 2 spans 2 columns col1", "cell1",
|
||||
"Column 3 Row 2 col3 row1", "cell2",
|
||||
"Column 4 Row 2 spans 2 rows row1", "row2", "Column 1 Row 3 col1",
|
||||
"cell3", "Column 2 Row 3 col2 row2", "cell4",
|
||||
"Column 3 Row 3 col3 row2", "table with 4 columns and 3 rows"]],
|
||||
expectedBraille: [["tbl 4c 3r", "c1r1", "col1", "c2r1", "col2", "c3r1",
|
||||
"col3", "c1r2 col1", "row1", "c3r2 col3 row1", "cell1", "c4r2 row1",
|
||||
"cell2", "c1r3 col1", "row2", "c2r3 col2 row2", "cell3",
|
||||
"c3r3 col3 row2", "cell4"], ["col1", "c1r1", "col2", "c2r1", "col3",
|
||||
"c3r1", "row1", "c1r2 col1", "cell1", "c3r2 col3 row1", "cell2",
|
||||
"c4r2 row1", "row2", "c1r3 col1", "cell3", "c2r3 col2 row2", "cell4",
|
||||
"c3r3 col3 row2", "tbl 4c 3r"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 4},
|
||||
{"string": "tblRowInfo", "count": 3},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [1]}, "col3",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansColumns", "args": [2]}, "col1", "row1",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [2]}, "col3", "row1", "cell1",
|
||||
{"string": "columnInfo", "args": [4]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansRows", "args": [2]}, "row1", "cell2",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [3]}, "col1", "row2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [3]}, "col2", "row2", "cell3",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [3]}, "col3", "row2", "cell4"], ["col1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col3",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [1]}, "row1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansColumns", "args": [2]}, "col1", "cell1",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [2]}, "col3", "row1", "cell2",
|
||||
{"string": "columnInfo", "args": [4]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansRows", "args": [2]}, "row1", "row2",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [3]}, "col1", "cell3",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [3]}, "col2", "row2", "cell4",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [3]}, "col3", "row2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 4},
|
||||
{"string": "tblRowInfo", "count": 3}]],
|
||||
expectedBraille: [[
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 4},
|
||||
{"string": "tblRowInfoAbbr", "count": 3},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col1",
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2",
|
||||
{"string": "cellInfoAbbr", "args": [3, 1]}, "col3",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col1", "row1",
|
||||
{"string": "cellInfoAbbr", "args": [3, 2]}, "col3", "row1", "cell1",
|
||||
{"string": "cellInfoAbbr", "args": [4, 2]}, "row1", "cell2",
|
||||
{"string": "cellInfoAbbr", "args": [1, 3]}, "col1", "row2",
|
||||
{"string": "cellInfoAbbr", "args": [2, 3]}, "col2", "row2", "cell3",
|
||||
{"string": "cellInfoAbbr", "args": [3, 3]}, "col3", "row2", "cell4"],
|
||||
["col1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col2",
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col3",
|
||||
{"string": "cellInfoAbbr", "args": [3, 1]}, "row1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "col1", "cell1",
|
||||
{"string": "cellInfoAbbr", "args": [3, 2]}, "col3", "row1", "cell2",
|
||||
{"string": "cellInfoAbbr", "args": [4, 2]}, "row1", "row2",
|
||||
{"string": "cellInfoAbbr", "args": [1, 3]}, "col1", "cell3",
|
||||
{"string": "cellInfoAbbr", "args": [2, 3]}, "col2", "row2", "cell4",
|
||||
{"string": "cellInfoAbbr", "args": [3, 3]}, "col3", "row2",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 4},
|
||||
{"string": "tblRowInfoAbbr", "count": 3}]]
|
||||
}, {
|
||||
accOrElmOrID: "table5",
|
||||
expectedUtterance: [["Row1", "Row2"], ["Row1", "Row2"]],
|
||||
@ -81,119 +237,239 @@
|
||||
// Test pivot to table1_th1 from table1.
|
||||
accOrElmOrID: "table1_th1",
|
||||
oldAccOrElmOrID: "table1",
|
||||
expectedUtterance: [["Column 1 Row 1", "col1"], ["col1",
|
||||
"Column 1 Row 1"]],
|
||||
expectedBraille: [["c1r1", "col1"], ["col1", "c1r1"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1"], ["col1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}]],
|
||||
expectedBraille: [[
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "col1"], ["col1",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}]]
|
||||
}, {
|
||||
// Test pivot to table1_td2 from table1.
|
||||
accOrElmOrID: "table1_td2",
|
||||
oldAccOrElmOrID: "table1",
|
||||
expectedUtterance: [["Column 2 Row 2 col2", "cell2"], ["cell2",
|
||||
"Column 2 Row 2 col2"]],
|
||||
expectedBraille: [["c2r2 col2", "cell2"], ["cell2", "c2r2 col2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2", "cell2"], ["cell2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [2, 2]}, "col2", "cell2"],
|
||||
["cell2", {"string": "cellInfoAbbr", "args": [2, 2]}, "col2"]]
|
||||
}, {
|
||||
// Test pivot to table1_td2 from table1_th1.
|
||||
accOrElmOrID: "table1_td2",
|
||||
oldAccOrElmOrID: "table1_th1",
|
||||
expectedUtterance: [["Column 2 Row 2 col2", "cell2"], ["cell2",
|
||||
"Column 2 Row 2 col2"]],
|
||||
expectedBraille: [["c2r2 col2", "cell2"], ["cell2", "c2r2 col2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2", "cell2"], ["cell2",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [2]}, "col2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [2, 2]}, "col2", "cell2"],
|
||||
["cell2", {"string": "cellInfoAbbr", "args": [2, 2]}, "col2"]]
|
||||
}, {
|
||||
// Test pivot to table1_td2 from table1_td1.
|
||||
accOrElmOrID: "table1_td2",
|
||||
oldAccOrElmOrID: "table1_td1",
|
||||
expectedUtterance: [["Column 2 col2", "cell2"], ["cell2",
|
||||
"Column 2 col2"]],
|
||||
expectedBraille: [["c2r2 col2", "cell2"], ["cell2", "c2r2 col2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]}, "col2", "cell2"], ["cell2",
|
||||
{"string": "columnInfo", "args": [2]}, "col2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [2, 2]}, "col2", "cell2"],
|
||||
["cell2", {"string": "cellInfoAbbr", "args": [2, 2]}, "col2"]]
|
||||
}, {
|
||||
// Test pivot to table2_cell_1 from table2.
|
||||
accOrElmOrID: "table2_cell_1",
|
||||
oldAccOrElmOrID: "table2",
|
||||
expectedUtterance: [["Column 1 Row 1 col1", "cell1"], ["cell1",
|
||||
"Column 1 Row 1 col1"]],
|
||||
expectedBraille: [["c1r1 col1", "cell1"], ["cell1", "c1r1 col1"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1", "cell1"], ["cell1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "col1"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 1]}, "col1", "cell1"],
|
||||
["cell1", {"string": "cellInfoAbbr", "args": [1, 1]}, "col1"]]
|
||||
}, {
|
||||
// Test pivot to table2_cell_2 from table2.
|
||||
accOrElmOrID: "table2_cell_2",
|
||||
oldAccOrElmOrID: "table2",
|
||||
expectedUtterance: [["Column 2 Row 1 col2",
|
||||
"table with 1 column and 2 rows", "Column 1 Row 1", "colheader",
|
||||
"Column 1 Row 2 colheader", "bla"], ["colheader", "Column 1 Row 1",
|
||||
"bla", "Column 1 Row 2 colheader", "table with 1 column and 2 rows",
|
||||
"Column 2 Row 1 col2"]],
|
||||
expectedBraille: [["c2r1 col2", "tbl 1c 2r", "c1r1", "colheader",
|
||||
"c1r2 colheader", "bla"], ["colheader", "c1r1", "bla",
|
||||
"c1r2 colheader", "tbl 1c 2r", "c2r1 col2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla"], ["colheader",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [1]}, "bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2"]],
|
||||
expectedBraille: [[
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla"],
|
||||
["colheader",
|
||||
{"string": "cellInfoAbbr", "args": [1, 1]}, "bla",
|
||||
{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader",
|
||||
{"string": "tableAbbr"},
|
||||
{"string": "tblColumnInfoAbbr", "count": 1},
|
||||
{"string": "tblRowInfoAbbr", "count": 2},
|
||||
{"string": "cellInfoAbbr", "args": [2, 1]}, "col2"]]
|
||||
}, {
|
||||
// Test pivot to table2_cell_1 from table2_cell_2.
|
||||
accOrElmOrID: "table2_cell_1",
|
||||
oldAccOrElmOrID: "table2_cell_2",
|
||||
expectedUtterance: [["Column 1 col1", "cell1"], ["cell1",
|
||||
"Column 1 col1"]],
|
||||
expectedBraille: [["c1r1 col1", "cell1"], ["cell1", "c1r1 col1"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [1]}, "col1", "cell1"], ["cell1",
|
||||
{"string": "columnInfo", "args": [1]}, "col1"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 1]}, "col1", "cell1"],
|
||||
["cell1", {"string": "cellInfoAbbr", "args": [1, 1]}, "col1"]]
|
||||
}, {
|
||||
// Test pivot to table3_cell from table2.
|
||||
accOrElmOrID: "table3_cell",
|
||||
oldAccOrElmOrID: "table2",
|
||||
expectedUtterance: [["Column 2 Row 1 col2",
|
||||
"table with 1 column and 2 rows", "Column 1 Row 2 colheader",
|
||||
"bla"], ["bla", "Column 1 Row 2 colheader",
|
||||
"table with 1 column and 2 rows", "Column 2 Row 1 col2"]],
|
||||
expectedBraille: [["c1r2 colheader", "bla"], ["bla", "c1r2 colheader"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla"], ["bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla"],
|
||||
["bla", {"string": "cellInfoAbbr", "args": [1, 2]}, "colheader"]]
|
||||
}, {
|
||||
// Test pivot to table3_cell from table2_cell_1.
|
||||
accOrElmOrID: "table3_cell",
|
||||
oldAccOrElmOrID: "table2_cell_1",
|
||||
expectedUtterance: [["Column 2 col2", "table with 1 column and 2 rows",
|
||||
"Column 1 Row 2 colheader", "bla"], ["bla",
|
||||
"Column 1 Row 2 colheader", "table with 1 column and 2 rows",
|
||||
"Column 2 Row 1 col2"]],
|
||||
expectedBraille: [["c1r2 colheader", "bla"], ["bla", "c1r2 colheader"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla"], ["bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla"],
|
||||
["bla", {"string": "cellInfoAbbr", "args": [1, 2]}, "colheader"]]
|
||||
}, {
|
||||
// Test pivot to table3_cell from table3_ch.
|
||||
accOrElmOrID: "table3_cell",
|
||||
oldAccOrElmOrID: "table3_ch",
|
||||
expectedUtterance: [["Row 2", "bla"], ["bla", "Row 2"]],
|
||||
expectedBraille: [["c1r2", "bla"], ["bla", "c1r2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "rowInfo", "args": [2]}, "bla"], ["bla",
|
||||
{"string": "rowInfo", "args": [2]}]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 2]}, "bla"],
|
||||
["bla", {"string": "cellInfoAbbr", "args": [1, 2]}]]
|
||||
}, {
|
||||
// Test pivot to table3_cell from table1_td1.
|
||||
accOrElmOrID: "table3_cell",
|
||||
oldAccOrElmOrID: "table1_td1",
|
||||
expectedUtterance: [["table with 2 columns and 2 rows",
|
||||
"Column 2 Row 1 col2", "table with 1 column and 2 rows",
|
||||
"Column 1 Row 2 colheader", "bla"], ["bla",
|
||||
"Column 1 Row 2 colheader", "table with 1 column and 2 rows",
|
||||
"Column 2 Row 1 col2", "table with 2 columns and 2 rows"]],
|
||||
expectedBraille: [["c1r2 colheader", "bla"], ["bla", "c1r2 colheader"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader", "bla"], ["bla",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]}, "colheader",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 1},
|
||||
{"string": "tblRowInfo", "count": 2},
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [1]}, "col2",
|
||||
{"string": "table"},
|
||||
{"string": "tblColumnInfo", "count": 2},
|
||||
{"string": "tblRowInfo", "count": 2}]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 2]}, "colheader", "bla"],
|
||||
["bla", {"string": "cellInfoAbbr", "args": [1, 2]}, "colheader"]]
|
||||
}, {
|
||||
// Test pivot to table4_ch_3 from table4.
|
||||
accOrElmOrID: "table4_ch_3",
|
||||
oldAccOrElmOrID: "table4",
|
||||
expectedUtterance: [["Column 3 Row 1", "col3"], ["col3",
|
||||
"Column 3 Row 1"]],
|
||||
expectedBraille: [["c3r1", "col3"], ["col3", "c3r1"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [1]}, "col3"], ["col3",
|
||||
{"string": "columnInfo", "args": [3]},
|
||||
{"string": "rowInfo", "args": [1]}]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [3, 1]}, "col3"],
|
||||
["col3", {"string": "cellInfoAbbr", "args": [3, 1]}]]
|
||||
}, {
|
||||
// Test pivot to table4_rh_1 from table4_ch_3.
|
||||
accOrElmOrID: "table4_rh_1",
|
||||
oldAccOrElmOrID: "table4_ch_3",
|
||||
expectedUtterance: [["Column 1 Row 2 spans 2 columns col1", "row1"], [
|
||||
"row1", "Column 1 Row 2 spans 2 columns col1"]],
|
||||
expectedBraille: [["c1r2 col1", "row1"], ["row1", "c1r2 col1"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansColumns", "args": [2]}, "col1", "row1"], ["row1",
|
||||
{"string": "columnInfo", "args": [1]},
|
||||
{"string": "rowInfo", "args": [2]},
|
||||
{"string": "spansColumns", "args": [2]}, "col1"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [1, 2]}, "col1", "row1"],
|
||||
["row1", {"string": "cellInfoAbbr", "args": [1, 2]}, "col1"]]
|
||||
}, {
|
||||
// Test pivot to table4_cell_3 from table4_rh_1.
|
||||
accOrElmOrID: "table4_cell_3",
|
||||
oldAccOrElmOrID: "table4_rh_1",
|
||||
expectedUtterance: [["Column 4 spans 2 rows", "cell2"], ["cell2",
|
||||
"Column 4 spans 2 rows"]],
|
||||
expectedBraille: [["c4r2", "cell2"], ["cell2", "c4r2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [4]},
|
||||
{"string": "spansRows", "args": [2]}, "cell2"], ["cell2",
|
||||
{"string": "columnInfo", "args": [4]},
|
||||
{"string": "spansRows", "args": [2]}]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [4, 2]}, "cell2"],
|
||||
["cell2", {"string": "cellInfoAbbr", "args": [4, 2]}]]
|
||||
}, {
|
||||
// Test pivot to table4_cell_5 from table4_cell_3.
|
||||
accOrElmOrID: "table4_cell_5",
|
||||
oldAccOrElmOrID: "table4_cell_3",
|
||||
expectedUtterance: [["Column 2 Row 3 col2 row2", "cell3"], ["cell3",
|
||||
"Column 2 Row 3 col2 row2"]],
|
||||
expectedBraille: [["c2r3 col2 row2", "cell3"], ["cell3",
|
||||
"c2r3 col2 row2"]]
|
||||
expectedUtterance: [[
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [3]}, "col2", "row2", "cell3"],
|
||||
["cell3",
|
||||
{"string": "columnInfo", "args": [2]},
|
||||
{"string": "rowInfo", "args": [3]}, "col2", "row2"]],
|
||||
expectedBraille: [
|
||||
[{"string": "cellInfoAbbr", "args": [2, 3]}, "col2", "row2", "cell3"],
|
||||
["cell3", {"string": "cellInfoAbbr", "args": [2, 3]}, "col2", "row2"]]
|
||||
}];
|
||||
|
||||
SpecialPowers.setIntPref(PREF_UTTERANCE_ORDER, 0);
|
||||
|
@ -4,9 +4,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['LIBXUL_SDK']:
|
||||
app_libxul_dirs = []
|
||||
app_libxul_static_dirs = []
|
||||
|
||||
include('/toolkit/toolkit.mozbuild')
|
||||
elif CONFIG['ENABLE_TESTS']:
|
||||
add_tier_dir('testharness', 'testing/mochitest')
|
||||
|
@ -4,8 +4,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['LIBXUL_SDK']:
|
||||
app_libxul_dirs = []
|
||||
app_libxul_static_dirs = []
|
||||
include('/toolkit/toolkit.mozbuild')
|
||||
|
||||
if CONFIG['MOZ_EXTENSIONS']:
|
||||
|
@ -11,7 +11,6 @@ MOZ_PKG_REMOVALS = $(srcdir)/removed-files.in
|
||||
MOZ_PKG_MANIFEST_P = $(srcdir)/package-manifest.in
|
||||
|
||||
DEFINES += \
|
||||
-DAB_CD=$(AB_CD) \
|
||||
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
|
||||
-DPREF_DIR=$(PREF_DIR) \
|
||||
$(NULL)
|
||||
|
@ -4,8 +4,6 @@
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
if not CONFIG['LIBXUL_SDK']:
|
||||
app_libxul_dirs = []
|
||||
app_libxul_static_dirs = []
|
||||
include('/toolkit/toolkit.mozbuild')
|
||||
|
||||
if CONFIG['MOZ_EXTENSIONS']:
|
||||
|
@ -11,7 +11,6 @@ PREF_JS_EXPORTS = $(srcdir)/profile/firefox.js \
|
||||
AB_CD = en-US
|
||||
|
||||
DEFINES += \
|
||||
-DAB_CD=$(AB_CD) \
|
||||
-DFIREFOX_ICO='"$(DIST)/branding/firefox.ico"' \
|
||||
-DDOCUMENT_ICO='"$(DIST)/branding/document.ico"' \
|
||||
-DNEWWINDOW_ICO='"$(DIST)/branding/newwindow.ico"' \
|
||||
|
@ -1,5 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
@ -1,5 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
@ -1,5 +1,4 @@
|
||||
[DEFAULT]
|
||||
skip-if = e10s # Bug ?????? - devtools tests disabled with e10s
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
cm_comment_test.js
|
||||
@ -19,6 +18,7 @@ support-files =
|
||||
css_autocompletion_tests.json
|
||||
vimemacs.html
|
||||
head.js
|
||||
helper_codemirror_runner.js
|
||||
|
||||
[browser_editor_autocomplete_basic.js]
|
||||
[browser_editor_autocomplete_js.js]
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
const HOST = 'mochi.test:8888';
|
||||
const URI = "http://" + HOST + "/browser/browser/devtools/sourceeditor/test/codemirror.html";
|
||||
loadHelperScript("helper_codemirror_runner.js");
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(3);
|
||||
@ -15,24 +16,10 @@ function test() {
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
runCodeMirrorTest(browser);
|
||||
}, true);
|
||||
|
||||
browser.loadURI(URI);
|
||||
|
||||
function check() {
|
||||
var win = browser.contentWindow.wrappedJSObject;
|
||||
var doc = win.document;
|
||||
var out = doc.getElementById("status");
|
||||
if (out && !win.mozilla_setStatus)
|
||||
win.mozilla_setStatus = codeMirror_setStatus;
|
||||
|
||||
if (!out || !out.classList.contains("done"))
|
||||
return void setTimeout(check, 100);
|
||||
|
||||
ok(!win.failed, "CodeMirror tests all passed");
|
||||
win.mozilla_setStatus = null;
|
||||
|
||||
while (gBrowser.tabs.length > 1) gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
setTimeout(check, 100);
|
||||
}
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
const HOST = 'mochi.test:8888';
|
||||
const URI = "http://" + HOST + "/browser/browser/devtools/sourceeditor/test/vimemacs.html";
|
||||
loadHelperScript("helper_codemirror_runner.js");
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(3);
|
||||
@ -14,24 +15,10 @@ function test() {
|
||||
gBrowser.selectedTab = tab;
|
||||
|
||||
let browser = gBrowser.getBrowserForTab(tab);
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
runCodeMirrorTest(browser);
|
||||
}, true);
|
||||
|
||||
browser.loadURI(URI);
|
||||
|
||||
function check() {
|
||||
var win = browser.contentWindow.wrappedJSObject;
|
||||
var doc = win.document;
|
||||
var out = doc.getElementById("status");
|
||||
if (out && !win.mozilla_setStatus)
|
||||
win.mozilla_setStatus = codeMirror_setStatus;
|
||||
|
||||
if (!out || !out.classList.contains("done"))
|
||||
return void setTimeout(check, 100);
|
||||
|
||||
ok(!win.failed, "CodeMirror tests all passed");
|
||||
win.mozilla_setStatus = null;
|
||||
|
||||
while (gBrowser.tabs.length > 1) gBrowser.removeCurrentTab();
|
||||
finish();
|
||||
}
|
||||
|
||||
setTimeout(check, 100);
|
||||
}
|
||||
|
@ -53,6 +53,22 @@ function teardown(ed, win) {
|
||||
finish();
|
||||
}
|
||||
|
||||
/**
|
||||
* Some tests may need to import one or more of the test helper scripts.
|
||||
* A test helper script is simply a js file that contains common test code that
|
||||
* is either not common-enough to be in head.js, or that is located in a separate
|
||||
* directory.
|
||||
* The script will be loaded synchronously and in the test's scope.
|
||||
* @param {String} filePath The file path, relative to the current directory.
|
||||
* Examples:
|
||||
* - "helper_attributes_test_runner.js"
|
||||
* - "../../../commandline/test/helpers.js"
|
||||
*/
|
||||
function loadHelperScript(filePath) {
|
||||
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
|
||||
Services.scriptloader.loadSubScript(testDir + "/" + filePath, this);
|
||||
}
|
||||
|
||||
/**
|
||||
* This method returns the portion of the input string `source` up to the
|
||||
* [line, ch] location.
|
||||
|
@ -0,0 +1,35 @@
|
||||
/* vim: set ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function runCodeMirrorTest(browser) {
|
||||
let mm = browser.messageManager;
|
||||
mm.addMessageListener('setStatus', function listener({data}) {
|
||||
let {statusMsg, type, customMsg} = data;
|
||||
codeMirror_setStatus(statusMsg, type, customMsg);
|
||||
});
|
||||
mm.addMessageListener('done', function listener({data}) {
|
||||
ok (!data.failed, "CodeMirror tests all passed");
|
||||
while (gBrowser.tabs.length > 1) gBrowser.removeCurrentTab();
|
||||
mm = null;
|
||||
finish();
|
||||
});
|
||||
|
||||
// Interact with the content iframe, giving it a function to
|
||||
// 1) Proxy CM test harness calls into ok() calls
|
||||
// 2) Detecting when it finishes by checking the DOM and
|
||||
// setting a timeout to check again if not.
|
||||
mm.loadFrameScript('data:,' +
|
||||
'content.wrappedJSObject.mozilla_setStatus = function(statusMsg, type, customMsg) {' +
|
||||
' sendSyncMessage("setStatus", {statusMsg: statusMsg, type: type, customMsg: customMsg});' +
|
||||
'};' +
|
||||
'function check() { ' +
|
||||
' var doc = content.document; var out = doc.getElementById("status"); ' +
|
||||
' if (!out || !out.classList.contains("done")) { return setTimeout(check, 100); }' +
|
||||
' sendSyncMessage("done", { failed: content.wrappedJSObject.failed });' +
|
||||
'}' +
|
||||
'check();'
|
||||
, true);
|
||||
}
|
@ -20,7 +20,7 @@ ifndef MOZ_MULET
|
||||
MOZ_PKG_FATAL_WARNINGS = 1
|
||||
endif
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD) -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
|
||||
DEFINES += -DMOZ_APP_NAME=$(MOZ_APP_NAME) -DPREF_DIR=$(PREF_DIR)
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
DEFINES += -DLIBXUL_SDK=1
|
||||
|
@ -38,7 +38,6 @@ BRANDING_FILES = \
|
||||
$(NULL)
|
||||
|
||||
DEFINES += \
|
||||
-DAB_CD=$(AB_CD) \
|
||||
-DMOZ_APP_NAME=$(MOZ_APP_NAME) \
|
||||
-DMOZ_APP_DISPLAYNAME='${MOZ_APP_DISPLAYNAME}' \
|
||||
-DMOZILLA_VERSION=${MOZILLA_VERSION} \
|
||||
|
@ -7,8 +7,6 @@ relativesrcdir = browser/metro/locales
|
||||
|
||||
include $(topsrcdir)/config/config.mk
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
#########################################
|
||||
|
@ -10,8 +10,6 @@ include $(topsrcdir)/config/config.mk
|
||||
#########################################
|
||||
# l10s prefs file
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
||||
|
||||
# copying firefox-l10n.js over from LOCALE_SRCDIR or browser
|
||||
PREF_JS_EXPORTS = $(firstword $(wildcard $(LOCALE_SRCDIR)/firefox-l10n.js) \
|
||||
$(topsrcdir)/$(relativesrcdir)/en-US/firefox-l10n.js )
|
||||
|
@ -55,12 +55,6 @@ rm -f conftest.out
|
||||
if test "`echo | $LD -v 2>&1 | grep -c GNU`" != "0"; then
|
||||
GNU_LD=1
|
||||
fi
|
||||
if test "$GNU_CC"; then
|
||||
if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
|
||||
GCC_USE_GNU_LD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
INTEL_CC=
|
||||
INTEL_CXX=
|
||||
if test "$compiler" = "icc"; then
|
||||
@ -81,6 +75,12 @@ if test "$compiler" = "clang-cl"; then
|
||||
CLANG_CL=1
|
||||
fi
|
||||
|
||||
if test "$GNU_CC"; then
|
||||
if `$CC -print-prog-name=ld` -v 2>&1 | grep -c GNU >/dev/null; then
|
||||
GCC_USE_GNU_LD=1
|
||||
fi
|
||||
fi
|
||||
|
||||
AC_SUBST(CLANG_CXX)
|
||||
AC_SUBST(CLANG_CL)
|
||||
])
|
||||
|
@ -667,7 +667,7 @@ else
|
||||
ifeq ($(HOST_OS_ARCH),WINNT)
|
||||
NSINSTALL = $(NSINSTALL_PY)
|
||||
else
|
||||
NSINSTALL = $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX)
|
||||
NSINSTALL = $(DEPTH)/config/nsinstall$(HOST_BIN_SUFFIX)
|
||||
endif # WINNT
|
||||
endif # NSINSTALL_BIN
|
||||
|
||||
@ -699,6 +699,8 @@ sysinstall_cmd = install_cmd
|
||||
# MOZ_UI_LOCALE directly, but use an intermediate variable that can be
|
||||
# overridden by the command line. (Besides, AB_CD is prettier).
|
||||
AB_CD = $(MOZ_UI_LOCALE)
|
||||
# Many locales directories want this definition.
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
||||
|
||||
ifndef L10NBASEDIR
|
||||
L10NBASEDIR = $(error L10NBASEDIR not defined by configure)
|
||||
|
@ -2,4 +2,5 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
||||
target::
|
||||
$(MAKE) -C $(DEPTH)/js/src/ctypes/libffi
|
@ -1,5 +1,5 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
@ -2,4 +2,5 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
||||
target::
|
||||
$(MAKE) -C $(DEPTH)/modules/freetype2
|
@ -1,5 +1,5 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
DEFINES += -DAB_CD=$(AB_CD)
|
@ -2,8 +2,6 @@
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
STANDALONE_MAKEFILE = 1
|
||||
|
||||
# Ensure that this happens before including rules.mk
|
||||
ifdef ENABLE_INTL_API
|
||||
ifndef MOZ_NATIVE_ICU
|
||||
@ -29,7 +27,7 @@ ifdef ENABLE_INTL_API
|
||||
ICU_DEST := $(DIST)/bin
|
||||
INSTALL_TARGETS += ICU
|
||||
$(ICU_FILES): buildicu
|
||||
ICU_TARGET := default
|
||||
ICU_TARGET := target
|
||||
endif
|
||||
else # !MOZ_SHARED_ICU
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
@ -44,7 +42,7 @@ include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef ENABLE_INTL_API
|
||||
ifndef MOZ_NATIVE_ICU
|
||||
default:: buildicu
|
||||
target:: buildicu
|
||||
|
||||
# - Force ICU to use the standard suffix for object files because expandlibs
|
||||
# will discard all files with a non-standard suffix (bug 857450).
|
||||
@ -54,16 +52,16 @@ buildicu::
|
||||
# Msys screws up GENRBOPTS when it contains spaces, so all genrb flags need
|
||||
# to be stuck together. See https://bugzilla.mozilla.org/show_bug.cgi?id=1034594#c34
|
||||
ifdef CROSS_COMPILE
|
||||
+$(MAKE) -j1 -C host STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kRC'
|
||||
+$(MAKE) -j1 -C $(DEPTH)/intl/icu/host STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kRC'
|
||||
endif
|
||||
+$(MAKE) -j1 -C target STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kR'
|
||||
+$(MAKE) -j1 -C $(DEPTH)/intl/icu/target STATIC_O=$(OBJ_SUFFIX) GENRBOPTS='-kR'
|
||||
$(ICU_LIB_RENAME)
|
||||
|
||||
distclean clean::
|
||||
ifdef CROSS_COMPILE
|
||||
+$(MAKE) -C host $@ STATIC_O=$(OBJ_SUFFIX)
|
||||
+$(MAKE) -C $(DEPTH)/intl/icu/host $@ STATIC_O=$(OBJ_SUFFIX)
|
||||
endif
|
||||
+$(MAKE) -C target $@ STATIC_O=$(OBJ_SUFFIX)
|
||||
+$(MAKE) -C $(DEPTH)/intl/icu/target $@ STATIC_O=$(OBJ_SUFFIX)
|
||||
|
||||
endif
|
||||
endif
|
5
config/external/icu/moz.build
vendored
Normal file
5
config/external/icu/moz.build
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
@ -6,10 +6,10 @@
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifdef LIBXUL_SDK
|
||||
$(error config/nspr/Makefile.in is not compatible with --enable-libxul-sdk=)
|
||||
$(error config/external/nspr/Makefile.in is not compatible with --enable-libxul-sdk=)
|
||||
endif
|
||||
ifdef MOZ_NATIVE_NSPR
|
||||
$(error config/nspr/Makefile.in is not compatible with MOZ_NATIVE_NSPR)
|
||||
$(error config/external/nspr/Makefile.in is not compatible with MOZ_NATIVE_NSPR)
|
||||
endif
|
||||
|
||||
# Copy NSPR to the SDK
|
@ -332,7 +332,7 @@ EXTRA_LIBS += $(DEPTH)/nsprpub/lib/ds/$(LIB_PREFIX)plds4$(SUFFIX)
|
||||
EXTRA_LIBS += $(DEPTH)/nsprpub/lib/libc/src/$(LIB_PREFIX)plc4$(SUFFIX)
|
||||
|
||||
# Add all static libraries for nss, smime, ssl and nssutil
|
||||
EXTRA_LIBS += $(addprefix ../,$(NSS_STATIC_LIBS))
|
||||
EXTRA_LIBS += $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
|
||||
|
||||
nss_def_file := $(srcdir)/nss.def
|
||||
|
||||
@ -368,7 +368,7 @@ ifdef MOZ_FOLD_LIBS
|
||||
# Force the linker to include everything from the static libraries.
|
||||
EXPAND_LIBS_EXEC += --extract
|
||||
|
||||
$(SHARED_LIBRARY): $(addprefix ../,$(NSS_STATIC_LIBS))
|
||||
$(SHARED_LIBRARY): $(addprefix $(DEPTH)/security/,$(NSS_STATIC_LIBS))
|
||||
|
||||
ifdef IMPORT_LIB_SUFFIX
|
||||
IMPORT_PREFIX = $(LIB_PREFIX)
|
||||
@ -389,7 +389,7 @@ $(DIST)/lib/$(DLL_PREFIX)freebl3$(DLL_SUFFIX): libs-nss/lib/freebl
|
||||
$(DIST)/lib/$(DLL_PREFIX)nssckbi$(DLL_SUFFIX): libs-nss/lib/ckfw
|
||||
$(DIST)/lib/$(DLL_PREFIX)softokn3$(DLL_SUFFIX): libs-nss/lib/softoken
|
||||
$(DIST)/lib/$(DLL_PREFIX)nssdbm3$(DLL_SUFFIX): libs-nss/lib/softoken
|
||||
$(foreach lib,$(NSS_STATIC_LIBS),$(eval ../$(lib): libs-$(patsubst %/,%,$(dir $(lib)))))
|
||||
$(foreach lib,$(NSS_STATIC_LIBS),$(eval $(DEPTH)/security/$(lib): libs-$(patsubst %/,%,$(dir $(lib)))))
|
||||
|
||||
# Create fake import libraries for the folded libraries, so that linking
|
||||
# against them works both for the NSS build system (see dependencies below)
|
||||
@ -427,7 +427,7 @@ DEFAULT_GMAKE_FLAGS += PYTHON='$(PYTHON)'
|
||||
DEFAULT_GMAKE_FLAGS += NSINSTALL_PY='$(abspath $(topsrcdir)/config/nsinstall.py)'
|
||||
DEFAULT_GMAKE_FLAGS += NSINSTALL='$$(PYTHON) $$(NSINSTALL_PY)'
|
||||
else
|
||||
DEFAULT_GMAKE_FLAGS += NSINSTALL='$(NSINSTALL)'
|
||||
DEFAULT_GMAKE_FLAGS += NSINSTALL='$(abspath $(NSINSTALL))'
|
||||
endif
|
||||
ifeq ($(OS_ARCH),WINNT)
|
||||
DEFAULT_GMAKE_FLAGS += INSTALL='$$(NSINSTALL) -t'
|
||||
@ -468,4 +468,4 @@ endif # MOZ_FOLD_LIBS
|
||||
|
||||
# Work around NSS build system race condition creating certdata.c in
|
||||
# security/nss/lib/ckfw/builtins. See bug #836220.
|
||||
libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,../nss/lib/ckfw/builtins)
|
||||
libs-nss/lib$(if $(MOZ_FOLD_LIBS),/ckfw): $(call mkdir_deps,$(DEPTH)/security/nss/lib/ckfw/builtins)
|
@ -29,7 +29,7 @@ echo-tiers:
|
||||
@echo $(TIERS)
|
||||
|
||||
echo-tier-dirs:
|
||||
@$(foreach tier,$(TIERS),echo '$(tier):'; echo ' dirs: $(tier_$(tier)_dirs)'; $(if $(tier_$(tier)_staticdirs),echo ' staticdirs: $(tier_$(tier)_staticdirs)';) )
|
||||
@$(foreach tier,$(TIERS),echo '$(tier):'; echo ' dirs: $(tier_$(tier)_dirs)')
|
||||
|
||||
echo-dirs:
|
||||
@echo $(call shell_quote,$(DIRS))
|
||||
|
@ -82,7 +82,7 @@ ifeq ($(CURRENT_TIER),compile)
|
||||
# https://savannah.gnu.org/bugs/index.php?42833
|
||||
.PHONY: $(compile_targets)
|
||||
$(compile_targets):
|
||||
$(call SUBMAKE,$(if $(filter $(@D),$(staticdirs)),,$(@F)),$(@D))
|
||||
$(call SUBMAKE,$(@F),$(@D))
|
||||
|
||||
else
|
||||
|
||||
@ -135,7 +135,6 @@ ifdef TIERS
|
||||
libs export tools::
|
||||
$(call BUILDSTATUS,TIER_START $@)
|
||||
$(foreach tier,$(TIERS), $(if $(filter-out libs_precompile tools_precompile,$@_$(tier)), \
|
||||
$(if $(filter libs,$@),$(foreach dir, $(tier_$(tier)_staticdirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),,1))) \
|
||||
$(foreach dir, $(tier_$(tier)_dirs), $(call TIER_DIR_SUBMAKE,$@,$(tier),$(dir),$@))))
|
||||
$(call BUILDSTATUS,TIER_FINISH $@)
|
||||
|
||||
|
@ -649,7 +649,7 @@ clean clobber realclean clobber_all::
|
||||
ifdef TIERS
|
||||
clean clobber realclean clobber_all distclean::
|
||||
$(foreach dir, \
|
||||
$(foreach tier, $(TIERS), $(tier_$(tier)_staticdirs) $(tier_$(tier)_dirs)), \
|
||||
$(foreach tier, $(TIERS), $(tier_$(tier)_dirs)), \
|
||||
-$(call SUBMAKE,$@,$(dir)))
|
||||
else
|
||||
clean clobber realclean clobber_all distclean::
|
||||
@ -1358,9 +1358,9 @@ $(error XPI_NAME must be set for INSTALL_EXTENSION_ID)
|
||||
endif
|
||||
|
||||
tools::
|
||||
$(RM) -r '$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)'
|
||||
$(NSINSTALL) -D '$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)'
|
||||
$(call copy_dir,$(FINAL_TARGET),$(DIST)/bin$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID))
|
||||
$(RM) -r '$(DIST)/bin/distribution$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)'
|
||||
$(NSINSTALL) -D '$(DIST)/bin/distribution$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID)'
|
||||
$(call copy_dir,$(FINAL_TARGET),$(DIST)/bin/distribution$(DIST_SUBDIR:%=/%)/extensions/$(INSTALL_EXTENSION_ID))
|
||||
|
||||
endif
|
||||
|
||||
@ -1433,9 +1433,9 @@ endif
|
||||
# file would be $(DIST)/include/bar/baz/qux.h instead of $(DIST)/include/qux.h
|
||||
|
||||
# If we're using binary nsinstall and it's not built yet, fallback to python nsinstall.
|
||||
ifneq (,$(filter $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX),$(install_cmd)))
|
||||
ifeq (,$(wildcard $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX)))
|
||||
nsinstall_is_usable = $(if $(wildcard $(DIST)/bin/nsinstall$(HOST_BIN_SUFFIX)),yes)
|
||||
ifneq (,$(filter $(DEPTH)/config/nsinstall$(HOST_BIN_SUFFIX),$(install_cmd)))
|
||||
ifeq (,$(wildcard $(DEPTH)/config/nsinstall$(HOST_BIN_SUFFIX)))
|
||||
nsinstall_is_usable = $(if $(wildcard $(DEPTH)/config/nsinstall$(HOST_BIN_SUFFIX)),yes)
|
||||
|
||||
define install_cmd_override
|
||||
$(1): install_cmd = $$(if $$(nsinstall_is_usable),$$(INSTALL),$$(NSINSTALL_PY) -t) $$(1)
|
||||
|
@ -2651,7 +2651,7 @@ if test "$ac_cv_sockaddr_sa_len" = true ; then
|
||||
AC_DEFINE(HAVE_SA_LEN)
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(dtrace,
|
||||
MOZ_ARG_ENABLE_BOOL(dtrace,
|
||||
[ --enable-dtrace build with dtrace support if available (default=no)],
|
||||
[enable_dtrace="yes"],)
|
||||
if test "x$enable_dtrace" = "xyes"; then
|
||||
|
@ -79,12 +79,20 @@ void WalkDescendantsSetDirAuto(mozilla::dom::Element* aElement,
|
||||
void WalkDescendantsClearAncestorDirAuto(mozilla::dom::Element* aElement);
|
||||
|
||||
/**
|
||||
* When the contents of a text node have changed, deal with any elements whose
|
||||
* directionality needs to change
|
||||
* When the contents of a text node are about to change, retrieve the current
|
||||
* directionality of the text
|
||||
*
|
||||
* @return whether the text node affects the directionality of any element
|
||||
*/
|
||||
void SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset,
|
||||
const char16_t* aBuffer, uint32_t aLength,
|
||||
bool aNotify);
|
||||
bool TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir,
|
||||
uint32_t aOffset);
|
||||
|
||||
/**
|
||||
* After the contents of a text node have changed, change the directionality
|
||||
* of any elements whose directionality is determined by that node
|
||||
*/
|
||||
void TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir,
|
||||
bool aNotify);
|
||||
|
||||
/**
|
||||
* When a text node is appended to an element, find any ancestors with dir=auto
|
||||
|
@ -1488,8 +1488,11 @@ NS_IMETHOD SetAttributeNode(nsIDOMAttr* newAttr, \
|
||||
if (!newAttr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(newAttr); \
|
||||
if (!attr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \
|
||||
*_retval = Element::SetAttributeNode(*attr, rv).take(); \
|
||||
return rv.ErrorCode(); \
|
||||
} \
|
||||
@ -1499,8 +1502,11 @@ NS_IMETHOD RemoveAttributeNode(nsIDOMAttr* oldAttr, \
|
||||
if (!oldAttr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(oldAttr); \
|
||||
if (!attr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(oldAttr); \
|
||||
*_retval = Element::RemoveAttributeNode(*attr, rv).take(); \
|
||||
return rv.ErrorCode(); \
|
||||
} \
|
||||
@ -1515,8 +1521,11 @@ NS_IMETHOD GetAttributeNodeNS(const nsAString& namespaceURI, \
|
||||
NS_IMETHOD SetAttributeNodeNS(nsIDOMAttr* newAttr, \
|
||||
nsIDOMAttr** _retval) MOZ_FINAL \
|
||||
{ \
|
||||
mozilla::dom::Attr* attr = mozilla::dom::Attr::FromDOMAttr(newAttr); \
|
||||
if (!attr) { \
|
||||
return NS_ERROR_INVALID_POINTER; \
|
||||
} \
|
||||
mozilla::ErrorResult rv; \
|
||||
mozilla::dom::Attr* attr = static_cast<mozilla::dom::Attr*>(newAttr); \
|
||||
*_retval = Element::SetAttributeNodeNS(*attr, rv).take(); \
|
||||
return rv.ErrorCode(); \
|
||||
} \
|
||||
|
@ -1520,6 +1520,13 @@ public:
|
||||
return sScriptBlockerCount == 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call this function if !IsSafeToRunScript() and we fail to run the script
|
||||
* (rather than using AddScriptRunner as we usually do). |aDocument| is
|
||||
* optional as it is only used for showing the URL in the console.
|
||||
*/
|
||||
static void WarnScriptWasIgnored(nsIDocument* aDocument);
|
||||
|
||||
/**
|
||||
* Retrieve information about the viewport as a data structure.
|
||||
* This will return information in the viewport META data section
|
||||
|
@ -80,6 +80,14 @@ public:
|
||||
|
||||
virtual nsIDOMNode* AsDOMNode() { return this; }
|
||||
|
||||
// This method should not do anything interesting, except possibly in the case of
|
||||
// external binary components.
|
||||
static Attr* FromDOMAttr(nsIDOMAttr* aDOMAttr)
|
||||
{
|
||||
nsCOMPtr<nsIAttribute> iattr = do_QueryInterface(aDOMAttr);
|
||||
return static_cast<mozilla::dom::Attr*>(iattr.get());
|
||||
}
|
||||
|
||||
// WebIDL
|
||||
virtual JSObject* WrapObject(JSContext* aCx) MOZ_OVERRIDE;
|
||||
|
||||
|
@ -317,6 +317,7 @@ GetDirectionFromText(const char16_t* aText, const uint32_t aLength,
|
||||
start < end &&
|
||||
NS_IS_LOW_SURROGATE(*start)) {
|
||||
ch = SURROGATE_TO_UCS4(ch, *start++);
|
||||
current++;
|
||||
}
|
||||
|
||||
Directionality dir = GetDirectionFromChar(ch);
|
||||
@ -823,26 +824,27 @@ void SetAncestorDirectionIfAuto(nsINode* aTextNode, Directionality aDir,
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
SetDirectionFromChangedTextNode(nsIContent* aTextNode, uint32_t aOffset,
|
||||
const char16_t* aBuffer, uint32_t aLength,
|
||||
bool aNotify)
|
||||
bool
|
||||
TextNodeWillChangeDirection(nsIContent* aTextNode, Directionality* aOldDir,
|
||||
uint32_t aOffset)
|
||||
{
|
||||
if (!NodeAffectsDirAutoAncestor(aTextNode)) {
|
||||
nsTextNodeDirectionalityMap::EnsureMapIsClearFor(aTextNode);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t firstStrong;
|
||||
Directionality oldDir = GetDirectionFromText(aTextNode->GetText(),
|
||||
&firstStrong);
|
||||
if (aOffset > firstStrong) {
|
||||
return;
|
||||
}
|
||||
*aOldDir = GetDirectionFromText(aTextNode->GetText(), &firstStrong);
|
||||
return (aOffset <= firstStrong);
|
||||
}
|
||||
|
||||
Directionality newDir = GetDirectionFromText(aBuffer, aLength);
|
||||
void
|
||||
TextNodeChangedDirection(nsIContent* aTextNode, Directionality aOldDir,
|
||||
bool aNotify)
|
||||
{
|
||||
Directionality newDir = GetDirectionFromText(aTextNode->GetText());
|
||||
if (newDir == eDir_NotSet) {
|
||||
if (oldDir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) {
|
||||
if (aOldDir != eDir_NotSet && aTextNode->HasTextNodeDirectionalityMap()) {
|
||||
// This node used to have a strong directional character but no
|
||||
// longer does. ResetTextNodeDirection() will re-resolve the
|
||||
// directionality of any elements whose directionality was
|
||||
|
@ -36,6 +36,7 @@
|
||||
#include "nsThreadUtils.h"
|
||||
#include "nsString.h"
|
||||
#include "prlog.h"
|
||||
#include "mozilla/dom/CSPReportBinding.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
@ -591,12 +592,10 @@ nsCSPContext::SendReports(nsISupports* aBlockedContentSource,
|
||||
}
|
||||
#endif
|
||||
|
||||
dom::CSPReport report;
|
||||
nsresult rv;
|
||||
nsString csp_report;
|
||||
csp_report.AppendASCII("{\"csp-report\": {");
|
||||
|
||||
// blocked-uri
|
||||
csp_report.AppendASCII("\"blocked-uri\": \"");
|
||||
if (aBlockedContentSource) {
|
||||
nsAutoCString reportBlockedURI;
|
||||
nsCOMPtr<nsIURI> uri = do_QueryInterface(aBlockedContentSource);
|
||||
@ -609,68 +608,59 @@ nsCSPContext::SendReports(nsISupports* aBlockedContentSource,
|
||||
cstr->GetData(reportBlockedURI);
|
||||
}
|
||||
}
|
||||
csp_report.AppendASCII(reportBlockedURI.get());
|
||||
if (reportBlockedURI.IsEmpty()) {
|
||||
// this can happen for frame-ancestors violation where the violating
|
||||
// ancestor is cross-origin.
|
||||
NS_WARNING("No blocked URI (null aBlockedContentSource) for CSP violation report.");
|
||||
}
|
||||
report.mCsp_report.mBlocked_uri = NS_ConvertUTF8toUTF16(reportBlockedURI);
|
||||
}
|
||||
else {
|
||||
// this can happen for frame-ancestors violation where the violating
|
||||
// ancestor is cross-origin.
|
||||
NS_WARNING("No blocked URI (null aBlockedContentSource) for CSP violation report.");
|
||||
}
|
||||
csp_report.AppendASCII("\", ");
|
||||
|
||||
// document-uri
|
||||
csp_report.AppendASCII("\"document-uri\": \"");
|
||||
if (aOriginalURI) {
|
||||
nsAutoCString reportDocumentURI;
|
||||
aOriginalURI->GetSpec(reportDocumentURI);
|
||||
csp_report.AppendASCII(reportDocumentURI.get());
|
||||
report.mCsp_report.mDocument_uri = NS_ConvertUTF8toUTF16(reportDocumentURI);
|
||||
}
|
||||
csp_report.AppendASCII("\", ");
|
||||
|
||||
// original-policy
|
||||
csp_report.AppendASCII("\"original-policy\": \"");
|
||||
nsAutoString originalPolicy;
|
||||
rv = this->GetPolicy(aViolatedPolicyIndex, originalPolicy);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
csp_report.Append(originalPolicy);
|
||||
csp_report.AppendASCII("\", ");
|
||||
report.mCsp_report.mOriginal_policy = originalPolicy;
|
||||
|
||||
// referrer
|
||||
csp_report.AppendASCII("\"referrer\": \"");
|
||||
if (mReferrer) {
|
||||
nsAutoCString referrerURI;
|
||||
mReferrer->GetSpec(referrerURI);
|
||||
csp_report.AppendASCII(referrerURI.get());
|
||||
report.mCsp_report.mReferrer = NS_ConvertUTF8toUTF16(referrerURI);
|
||||
}
|
||||
csp_report.AppendASCII("\", ");
|
||||
|
||||
// violated-directive
|
||||
csp_report.AppendASCII("\"violated-directive\": \"");
|
||||
csp_report.Append(aViolatedDirective);
|
||||
csp_report.AppendASCII("\"");
|
||||
report.mCsp_report.mViolated_directive = aViolatedDirective;
|
||||
|
||||
// source-file
|
||||
if (!aSourceFile.IsEmpty()) {
|
||||
csp_report.AppendASCII(", \"source-file\": \"");
|
||||
csp_report.Append(aSourceFile);
|
||||
csp_report.AppendASCII("\"");
|
||||
report.mCsp_report.mSource_file.Construct();
|
||||
report.mCsp_report.mSource_file.Value() = aSourceFile;
|
||||
}
|
||||
|
||||
// script-sample
|
||||
if (!aScriptSample.IsEmpty()) {
|
||||
csp_report.AppendASCII(", \"script-sample\": \"");
|
||||
csp_report.Append(aScriptSample);
|
||||
csp_report.AppendASCII("\"");
|
||||
report.mCsp_report.mScript_sample.Construct();
|
||||
report.mCsp_report.mScript_sample.Value() = aScriptSample;
|
||||
}
|
||||
|
||||
// line-number
|
||||
if (aLineNum != 0) {
|
||||
csp_report.AppendASCII(", \"line-number\": \"");
|
||||
csp_report.AppendInt(aLineNum);
|
||||
csp_report.AppendASCII("\"");
|
||||
report.mCsp_report.mLine_number.Construct();
|
||||
report.mCsp_report.mLine_number.Value() = aLineNum;
|
||||
}
|
||||
|
||||
csp_report.AppendASCII("}}\n\n");
|
||||
nsString csp_report;
|
||||
if (!report.ToJSON(csp_report)) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
// ---------- Assembled, now send it to all the report URIs ----------- //
|
||||
|
||||
|
@ -3961,6 +3961,7 @@ nsContentUtils::MaybeFireNodeRemoved(nsINode* aChild, nsINode* aParent,
|
||||
// than fire DOMNodeRemoved in all corner cases. We also rely on it for
|
||||
// nsAutoScriptBlockerSuppressNodeRemoved.
|
||||
if (!IsSafeToRunScript()) {
|
||||
WarnScriptWasIgnored(aOwnerDoc);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -5039,10 +5040,11 @@ nsContentUtils::GetAccessKeyCandidates(WidgetKeyboardEvent* aNativeKeyEvent,
|
||||
void
|
||||
nsContentUtils::AddScriptBlocker()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
if (!sScriptBlockerCount) {
|
||||
NS_ASSERTION(sRunnersCountAtFirstBlocker == 0,
|
||||
"Should not already have a count");
|
||||
sRunnersCountAtFirstBlocker = sBlockedScriptRunners->Length();
|
||||
MOZ_ASSERT(sRunnersCountAtFirstBlocker == 0,
|
||||
"Should not already have a count");
|
||||
sRunnersCountAtFirstBlocker = sBlockedScriptRunners ? sBlockedScriptRunners->Length() : 0;
|
||||
}
|
||||
++sScriptBlockerCount;
|
||||
}
|
||||
@ -5055,6 +5057,7 @@ static bool sRemovingScriptBlockers = false;
|
||||
void
|
||||
nsContentUtils::RemoveScriptBlocker()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!sRemovingScriptBlockers);
|
||||
NS_ASSERTION(sScriptBlockerCount != 0, "Negative script blockers");
|
||||
--sScriptBlockerCount;
|
||||
@ -5062,6 +5065,10 @@ nsContentUtils::RemoveScriptBlocker()
|
||||
return;
|
||||
}
|
||||
|
||||
if (!sBlockedScriptRunners) {
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t firstBlocker = sRunnersCountAtFirstBlocker;
|
||||
uint32_t lastBlocker = sBlockedScriptRunners->Length();
|
||||
uint32_t originalFirstBlocker = firstBlocker;
|
||||
@ -5091,6 +5098,25 @@ nsContentUtils::RemoveScriptBlocker()
|
||||
sBlockedScriptRunners->RemoveElementsAt(originalFirstBlocker, blockersCount);
|
||||
}
|
||||
|
||||
/* static */
|
||||
void
|
||||
nsContentUtils::WarnScriptWasIgnored(nsIDocument* aDocument)
|
||||
{
|
||||
nsAutoString msg;
|
||||
if (aDocument) {
|
||||
nsCOMPtr<nsIURI> uri = aDocument->GetDocumentURI();
|
||||
if (uri) {
|
||||
nsCString spec;
|
||||
uri->GetSpec(spec);
|
||||
msg.Append(NS_ConvertUTF8toUTF16(spec));
|
||||
msg.AppendLiteral(" : ");
|
||||
}
|
||||
}
|
||||
msg.AppendLiteral("Unable to run script because scripts are blocked internally.");
|
||||
|
||||
LogSimpleConsoleError(msg, "DOM");
|
||||
}
|
||||
|
||||
/* static */
|
||||
bool
|
||||
nsContentUtils::AddScriptRunner(nsIRunnable* aRunnable)
|
||||
|
@ -634,8 +634,10 @@ nsCopySupport::FireClipboardEvent(int32_t aType, int32_t aClipboardType, nsIPres
|
||||
}
|
||||
|
||||
// It seems to be unsafe to fire an event handler during reflow (bug 393696)
|
||||
if (!nsContentUtils::IsSafeToRunScript())
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
nsContentUtils::WarnScriptWasIgnored(doc);
|
||||
return false;
|
||||
}
|
||||
|
||||
nsCOMPtr<nsIDocShell> docShell = piWindow->GetDocShell();
|
||||
const bool chromeShell =
|
||||
|
@ -242,9 +242,9 @@ nsDOMAttributeMap::GetNamedItem(const nsAString& aAttrName,
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
|
||||
nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aDOMAttr, nsIDOMAttr** aReturn)
|
||||
{
|
||||
Attr* attribute = static_cast<Attr*>(aAttr);
|
||||
Attr* attribute = Attr::FromDOMAttr(aDOMAttr);
|
||||
NS_ENSURE_ARG(attribute);
|
||||
|
||||
ErrorResult rv;
|
||||
@ -253,9 +253,9 @@ nsDOMAttributeMap::SetNamedItem(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aAttr, nsIDOMAttr** aReturn)
|
||||
nsDOMAttributeMap::SetNamedItemNS(nsIDOMAttr* aDOMAttr, nsIDOMAttr** aReturn)
|
||||
{
|
||||
Attr* attribute = static_cast<Attr*>(aAttr);
|
||||
Attr* attribute = Attr::FromDOMAttr(aDOMAttr);
|
||||
NS_ENSURE_ARG(attribute);
|
||||
|
||||
ErrorResult rv;
|
||||
|
@ -322,9 +322,9 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount,
|
||||
nsNodeUtils::CharacterDataWillChange(this, &info);
|
||||
}
|
||||
|
||||
if (NodeType() == nsIDOMNode::TEXT_NODE) {
|
||||
SetDirectionFromChangedTextNode(this, aOffset, aBuffer, aLength, aNotify);
|
||||
}
|
||||
Directionality oldDir = eDir_NotSet;
|
||||
bool dirAffectsAncestor = (NodeType() == nsIDOMNode::TEXT_NODE &&
|
||||
TextNodeWillChangeDirection(this, &oldDir, aOffset));
|
||||
|
||||
if (aOffset == 0 && endOffset == textLength) {
|
||||
// Replacing whole text or old text was empty. Don't bother to check for
|
||||
@ -371,6 +371,10 @@ nsGenericDOMDataNode::SetTextInternal(uint32_t aOffset, uint32_t aCount,
|
||||
document->SetBidiEnabled();
|
||||
}
|
||||
|
||||
if (dirAffectsAncestor) {
|
||||
TextNodeChangedDirection(this, oldDir, aNotify);
|
||||
}
|
||||
|
||||
// Notify observers
|
||||
if (aNotify) {
|
||||
CharacterDataChangeInfo info = {
|
||||
|
@ -311,6 +311,7 @@ nsNodeUtils::CallUserDataHandlers(nsCOMArray<nsINode> &aNodesWithProperties,
|
||||
"cloned nodes.");
|
||||
|
||||
if (!nsContentUtils::IsSafeToRunScript()) {
|
||||
nsContentUtils::WarnScriptWasIgnored(aOwnerDocument);
|
||||
if (nsContentUtils::IsChromeDoc(aOwnerDocument)) {
|
||||
NS_WARNING("Fix the caller! Userdata callback disabled.");
|
||||
} else {
|
||||
|
@ -3,4 +3,5 @@
|
||||
[test_bug357450.js]
|
||||
[test_copypaste.xul]
|
||||
[test_messagemanager_principal.html]
|
||||
[test_messagemanager_send_principal.html]
|
||||
skip-if = buildapp == 'mulet'
|
||||
|
13
content/base/test/csp/file_csp_report.html
Normal file
13
content/base/test/csp/file_csp_report.html
Normal file
@ -0,0 +1,13 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Bug 1033424 - Test csp-report properties </title>
|
||||
</head>
|
||||
<body>
|
||||
<script type="text/javascript">
|
||||
var foo = "propEscFoo";
|
||||
var bar = "propEscBar";
|
||||
// just verifying that we properly escape newlines and quotes
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -1,25 +0,0 @@
|
||||
// SJS file for CSP violation report test
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=548193
|
||||
function handleRequest(request, response)
|
||||
{
|
||||
var query = {};
|
||||
request.queryString.split('&').forEach(function (val) {
|
||||
var [name, value] = val.split('=');
|
||||
query[name] = unescape(value);
|
||||
});
|
||||
|
||||
response.setHeader("Content-Type", "text/html", false);
|
||||
|
||||
// avoid confusing cache behaviors
|
||||
response.setHeader("Cache-Control", "no-cache", false);
|
||||
|
||||
// set CSP header
|
||||
response.setHeader("Content-Security-Policy",
|
||||
"default-src 'self'; report-uri http://mochi.test:8888/csp-report.cgi",
|
||||
false);
|
||||
|
||||
// content which will trigger a violation report
|
||||
response.write('<html><body>');
|
||||
response.write('<img src="http://example.org/tests/content/base/test/file_CSP.sjs?testid=img_bad&type=img/png"> </img>');
|
||||
response.write('</body></html>');
|
||||
}
|
@ -94,7 +94,7 @@ support-files =
|
||||
file_csp_regexp_parsing.js
|
||||
file_report_uri_missing_in_report_only_header.html
|
||||
file_report_uri_missing_in_report_only_header.html^headers^
|
||||
file_csp_report.sjs
|
||||
file_csp_report.html
|
||||
file_redirect_content.sjs
|
||||
file_redirect_report.sjs
|
||||
file_subframe_run_js_if_allowed.html
|
||||
|
@ -15,6 +15,49 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=548193
|
||||
|
||||
<iframe style="width:200px;height:200px;" id='cspframe'></iframe>
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/*
|
||||
* Description of the test:
|
||||
* We try to load an inline-src using a policy that constrains
|
||||
* all scripts from running (script-src 'none'). We verify that
|
||||
* the generated csp-report contains the expceted values. If any
|
||||
* of the JSON is not formatted properly (e.g. not properly escaped)
|
||||
* then JSON.parse will fail, which allows to pinpoint such errors
|
||||
* in the catch block, and the test will fail. Since we use an
|
||||
* observer, we can set the actual report-uri to a foo value.
|
||||
*/
|
||||
|
||||
const testfile = "tests/content/base/test/csp/file_csp_report.html";
|
||||
const reportURI = "http://mochi.test:8888/foo.sjs";
|
||||
const policy = "script-src 'none'; report-uri " + reportURI;
|
||||
const docUri = "http://mochi.test:8888/tests/content/base/test/csp/file_csp_testserver.sjs" +
|
||||
"?file=tests/content/base/test/csp/file_csp_report.html" +
|
||||
"&csp=script-src%20%27none%27%3B%20report-uri%20http%3A//mochi.test%3A8888/foo.sjs";
|
||||
|
||||
window.checkResults = function(reportObj) {
|
||||
var cspReport = reportObj["csp-report"];
|
||||
|
||||
is(cspReport["document-uri"], docUri, "Incorrect document-uri");
|
||||
|
||||
// we can not test for the whole referrer since it includes platform specific information
|
||||
ok(cspReport["referrer"].startsWith("http://mochi.test:8888/tests/content/base/test/csp/test_csp_report.html"),
|
||||
"Incorrect referrer");
|
||||
|
||||
is(cspReport["blocked-uri"], "self", "Incorrect blocked-uri");
|
||||
|
||||
is(cspReport["violated-directive"], "script-src 'none'", "Incorrect violated-directive");
|
||||
|
||||
is(cspReport["original-policy"], "script-src 'none'; report-uri http://mochi.test:8888/foo.sjs",
|
||||
"Incorrect original-policy");
|
||||
|
||||
is(cspReport["source-file"], docUri, "Incorrect source-file");
|
||||
|
||||
is(cspReport["script-sample"], "\n var foo = \"propEscFoo\";\n var bar...",
|
||||
"Incorrect script-sample");
|
||||
|
||||
is(cspReport["line-number"], "7", "Incorrect line-number");
|
||||
}
|
||||
|
||||
// This is used to watch requests go out so we can see if the report is
|
||||
// sent correctly
|
||||
function examiner() {
|
||||
@ -26,17 +69,15 @@ examiner.prototype = {
|
||||
if (!SpecialPowers.can_QI(subject))
|
||||
return;
|
||||
|
||||
const reportURI = "http://mochi.test:8888/csp-report.cgi";
|
||||
|
||||
if (topic === "http-on-opening-request") {
|
||||
var asciiSpec = SpecialPowers.getPrivilegedProps(SpecialPowers.do_QueryInterface(subject, "nsIHttpChannel"), "URI.asciiSpec");
|
||||
if (asciiSpec !== reportURI) return;
|
||||
|
||||
// Verify that the report was properly formatted.
|
||||
// We'll parse the report text as JSON and verify that the properties
|
||||
// have expected values.
|
||||
var reportText = "{}";
|
||||
try {
|
||||
// Verify that the report was properly formatted.
|
||||
// We'll parse the report text as JSON and verify that the properties
|
||||
// have expected values.
|
||||
var reportText = "{}";
|
||||
var uploadStream = SpecialPowers.wrap(SpecialPowers.do_QueryInterface(subject, "nsIUploadChannel")).uploadStream;
|
||||
|
||||
if (uploadStream) {
|
||||
@ -55,13 +96,18 @@ examiner.prototype = {
|
||||
// rewind stream as we are supposed to - there will be an assertion later if we don't.
|
||||
SpecialPowers.do_QueryInterface(uploadStream, "nsISeekableStream").seek(SpecialPowers.Ci.nsISeekableStream.NS_SEEK_SET, 0);
|
||||
}
|
||||
try {
|
||||
var reportObj = JSON.parse(reportText);
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "Could not parse JSON (exception: " + e + ")");
|
||||
}
|
||||
// test for the proper values in the report object
|
||||
window.checkResults(reportObj);
|
||||
}
|
||||
catch (e) {
|
||||
ok(false, "Could not query report (exception: " + e + ")");
|
||||
}
|
||||
catch(e) {}
|
||||
|
||||
var reportObj = JSON.parse(reportText);
|
||||
|
||||
// test for the proper values in the report object
|
||||
window.checkResults(reportObj);
|
||||
|
||||
// finish up
|
||||
window.examiner.remove();
|
||||
@ -74,35 +120,18 @@ examiner.prototype = {
|
||||
SpecialPowers.removeObserver(this, "http-on-opening-request");
|
||||
}
|
||||
}
|
||||
|
||||
// content file that triggers a violation report
|
||||
var testFile = "file_csp_report.sjs";
|
||||
|
||||
window.checkResults = function(reportObj) {
|
||||
var cspReport = reportObj["csp-report"];
|
||||
// correct violating request
|
||||
is(cspReport["document-uri"],
|
||||
"http://mochi.test:8888/tests/content/base/test/csp/" + testFile,
|
||||
"Incorrect violating request");
|
||||
// correct blocked-uri
|
||||
is(cspReport["blocked-uri"],
|
||||
"http://example.org/tests/content/base/test/file_CSP.sjs?testid=img_bad&type=img/png",
|
||||
"Incorrect blocked uri");
|
||||
// correct violated-directive
|
||||
is(cspReport["violated-directive"], "default-src http://mochi.test:8888",
|
||||
"Incorrect violated directive");
|
||||
// not practical to test request-headers as header names and values will
|
||||
// change with the trunk
|
||||
}
|
||||
|
||||
window.examiner = new examiner();
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
// load the resource which will generate a CSP violation report
|
||||
// save this for last so that our listeners are registered.
|
||||
// ... this loads the testbed of good and bad requests.
|
||||
document.getElementById("cspframe").src = testFile;
|
||||
var src = "file_csp_testserver.sjs";
|
||||
// append the file that should be served
|
||||
src += "?file=" + escape(testfile);
|
||||
// append the CSP that should be used to serve the file
|
||||
src += "&csp=" + escape(policy);
|
||||
document.getElementById("cspframe").src = src;
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
118
content/base/test/test_messagemanager_send_principal.html
Normal file
118
content/base/test/test_messagemanager_send_principal.html
Normal file
@ -0,0 +1,118 @@
|
||||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Principal in MessageManager</title>
|
||||
<script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript;version=1.7">
|
||||
"use strict";
|
||||
|
||||
const Ci = Components.interfaces;
|
||||
const Cc = Components.classes;
|
||||
const Cu = Components.utils;
|
||||
|
||||
var permManager = Cc["@mozilla.org/permissionmanager;1"]
|
||||
.getService(Ci.nsIPermissionManager);
|
||||
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
|
||||
const childFrameURL =
|
||||
"data:text/html,<!DOCTYPE HTML><html><body></body></html>";
|
||||
|
||||
function childFrameScript() {
|
||||
"use strict";
|
||||
|
||||
const secMan = Cc["@mozilla.org/scriptsecuritymanager;1"].
|
||||
getService(Ci.nsIScriptSecurityManager);
|
||||
|
||||
addMessageListener("test:content", function(message) {
|
||||
sendAsyncMessage("test:result", "is nsIPrincipal: " +
|
||||
(message.data instanceof Ci.nsIPrincipal ? "OK" : "KO"));
|
||||
|
||||
sendAsyncMessage("test:result", "principal.appId: " +
|
||||
("appId" in message.data ? "OK" : "KO"));
|
||||
|
||||
sendAsyncMessage("test:result", "principal.origin: " +
|
||||
("origin" in message.data ? "OK" : "KO"));
|
||||
|
||||
sendAsyncMessage("test:result", "principal.isInBrowserElement: " +
|
||||
("isInBrowserElement" in message.data ? "OK" : "KO"));
|
||||
});
|
||||
|
||||
addMessageListener("test:system", function(message) {
|
||||
sendAsyncMessage("test:result", "isSystemPrincipal: " +
|
||||
(secMan.isSystemPrincipal(message.data) ? "OK" : "KO"));
|
||||
});
|
||||
|
||||
addMessageListener("test:null", function(message) {
|
||||
sendAsyncMessage("test:result", "is nsIPrincipal: " +
|
||||
(message.data instanceof Ci.nsIPrincipal ? "OK" : "KO"));
|
||||
|
||||
sendAsyncMessage("test:result", "isNullPrincipal: " +
|
||||
(message.data.isNullPrincipal ? "OK" : "KO"));
|
||||
sendAsyncMessage("test:result", "DONE");
|
||||
});
|
||||
}
|
||||
|
||||
function runTests() {
|
||||
ok("Browser prefs set.");
|
||||
|
||||
let iframe = document.createElement("iframe");
|
||||
SpecialPowers.wrap(iframe).mozbrowser = true;
|
||||
iframe.id = "iframe";
|
||||
iframe.src = childFrameURL;
|
||||
|
||||
iframe.addEventListener("mozbrowserloadend", function() {
|
||||
ok(true, "Got iframe load event.");
|
||||
|
||||
let mm = SpecialPowers.getBrowserFrameMessageManager(iframe);
|
||||
mm.addMessageListener("test:result", function(message) {
|
||||
// We need to wrap to access message.json, and unwrap to do the
|
||||
// identity check.
|
||||
var msg = SpecialPowers.unwrap(SpecialPowers.wrap(message).data);
|
||||
if (/OK$/.exec(msg)) {
|
||||
ok(true, msg);
|
||||
} else if(/KO$/.exec(msg)) {
|
||||
ok(true, false);
|
||||
} else if (/DONE/.exec(msg)) {
|
||||
permManager.removeFromPrincipal(window.document.nodePrincipal, "browser",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
});
|
||||
mm.loadFrameScript("data:,(" + childFrameScript.toString() + ")();",
|
||||
false);
|
||||
|
||||
mm.sendAsyncMessage("test:content", window.document.nodePrincipal);
|
||||
|
||||
let system = Cc["@mozilla.org/systemprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
mm.sendAsyncMessage("test:system", system);
|
||||
|
||||
let nullP = Cc["@mozilla.org/nullprincipal;1"].
|
||||
createInstance(Ci.nsIPrincipal);
|
||||
mm.sendAsyncMessage("test:null", nullP);
|
||||
});
|
||||
|
||||
document.body.appendChild(iframe);
|
||||
}
|
||||
|
||||
addEventListener("load", function() {
|
||||
info("Got load event.");
|
||||
|
||||
permManager.addFromPrincipal(window.document.nodePrincipal, "browser",
|
||||
Ci.nsIPermissionManager.ALLOW_ACTION);
|
||||
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [
|
||||
["dom.mozBrowserFramesEnabled", true],
|
||||
["browser.pagethumbnails.capturing_disabled", true]
|
||||
]
|
||||
}, runTests);
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -139,8 +139,9 @@ MediaEngineWebRTCVideoSource::NotifyPull(MediaStreamGraph* aGraph,
|
||||
VideoSegment segment;
|
||||
|
||||
MonitorAutoLock lock(mMonitor);
|
||||
if (mState != kStarted)
|
||||
return;
|
||||
// B2G does AddTrack, but holds kStarted until the hardware changes state.
|
||||
// So mState could be kReleased here. We really don't care about the state,
|
||||
// though.
|
||||
|
||||
// Note: we're not giving up mImage here
|
||||
nsRefPtr<layers::Image> image = mImage;
|
||||
|
@ -97,7 +97,7 @@ public:
|
||||
return mList;
|
||||
}
|
||||
|
||||
nsISVGPoint* Clone() {
|
||||
virtual DOMSVGPoint* Copy() MOZ_OVERRIDE {
|
||||
return new DOMSVGPoint(this);
|
||||
}
|
||||
|
||||
|
@ -247,8 +247,9 @@ DOMSVGPointList::Initialize(nsISVGPoint& aNewItem, ErrorResult& aError)
|
||||
// from happening we have to do the clone here, if necessary.
|
||||
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
if (domItem->HasOwner() || domItem->IsReadonly() ||
|
||||
domItem->IsTranslatePoint()) {
|
||||
domItem = domItem->Copy(); // must do this before changing anything!
|
||||
}
|
||||
|
||||
ErrorResult rv;
|
||||
@ -298,8 +299,9 @@ DOMSVGPointList::InsertItemBefore(nsISVGPoint& aNewItem, uint32_t aIndex,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
if (domItem->HasOwner() || domItem->IsReadonly() ||
|
||||
domItem->IsTranslatePoint()) {
|
||||
domItem = domItem->Copy(); // must do this before changing anything!
|
||||
}
|
||||
|
||||
// Ensure we have enough memory so we can avoid complex error handling below:
|
||||
@ -341,8 +343,9 @@ DOMSVGPointList::ReplaceItem(nsISVGPoint& aNewItem, uint32_t aIndex,
|
||||
}
|
||||
|
||||
nsCOMPtr<nsISVGPoint> domItem = &aNewItem;
|
||||
if (domItem->HasOwner() || domItem->IsReadonly()) {
|
||||
domItem = domItem->Clone(); // must do this before changing anything!
|
||||
if (domItem->HasOwner() || domItem->IsReadonly() ||
|
||||
domItem->IsTranslatePoint()) {
|
||||
domItem = domItem->Copy(); // must do this before changing anything!
|
||||
}
|
||||
|
||||
AutoChangePointListNotifier notifier(this);
|
||||
|
@ -74,10 +74,10 @@ SVGSVGElement::~SVGSVGElement()
|
||||
{
|
||||
}
|
||||
|
||||
nsISVGPoint*
|
||||
DOMSVGTranslatePoint::Clone()
|
||||
DOMSVGPoint*
|
||||
DOMSVGTranslatePoint::Copy()
|
||||
{
|
||||
return new DOMSVGTranslatePoint(this);
|
||||
return new DOMSVGPoint(mPt.GetX(), mPt.GetY());
|
||||
}
|
||||
|
||||
nsISupports*
|
||||
|
@ -47,15 +47,15 @@ class SVGSVGElement;
|
||||
class DOMSVGTranslatePoint MOZ_FINAL : public nsISVGPoint {
|
||||
public:
|
||||
DOMSVGTranslatePoint(SVGPoint* aPt, SVGSVGElement *aElement)
|
||||
: nsISVGPoint(aPt), mElement(aElement) {}
|
||||
: nsISVGPoint(aPt, true), mElement(aElement) {}
|
||||
|
||||
DOMSVGTranslatePoint(DOMSVGTranslatePoint* aPt)
|
||||
: nsISVGPoint(&aPt->mPt), mElement(aPt->mElement) {}
|
||||
: nsISVGPoint(&aPt->mPt, true), mElement(aPt->mElement) {}
|
||||
|
||||
NS_DECL_ISUPPORTS_INHERITED
|
||||
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(DOMSVGTranslatePoint, nsISVGPoint)
|
||||
|
||||
virtual nsISVGPoint* Clone() MOZ_OVERRIDE;
|
||||
virtual DOMSVGPoint* Copy() MOZ_OVERRIDE;
|
||||
|
||||
// WebIDL
|
||||
virtual float X() MOZ_OVERRIDE { return mPt.GetX(); }
|
||||
|
@ -18,7 +18,7 @@ class nsSVGElement;
|
||||
{ 0xd6b6c440, 0xaf8d, 0x40ee, \
|
||||
{ 0x85, 0x6b, 0x02, 0xa3, 0x17, 0xca, 0xb2, 0x75 } }
|
||||
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 30
|
||||
#define MOZ_SVG_LIST_INDEX_BIT_COUNT 29
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
@ -48,15 +48,17 @@ public:
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
, mIsTranslatePoint(false)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
explicit nsISVGPoint(SVGPoint* aPt)
|
||||
explicit nsISVGPoint(SVGPoint* aPt, bool aIsTranslatePoint)
|
||||
: mList(nullptr)
|
||||
, mListIndex(0)
|
||||
, mIsReadonly(false)
|
||||
, mIsAnimValItem(false)
|
||||
, mIsTranslatePoint(aIsTranslatePoint)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mPt.mX = aPt->GetX();
|
||||
@ -76,10 +78,9 @@ protected:
|
||||
|
||||
public:
|
||||
/**
|
||||
* Create an unowned copy of this object. The caller is responsible for the
|
||||
* first AddRef()!
|
||||
* Creates an unowned copy of this object's point as a DOMSVGPoint.
|
||||
*/
|
||||
virtual nsISVGPoint* Clone() = 0;
|
||||
virtual DOMSVGPoint* Copy() = 0;
|
||||
|
||||
SVGPoint ToSVGPoint() const {
|
||||
return HasOwner() ? const_cast<nsISVGPoint*>(this)->InternalItem() : mPt;
|
||||
@ -99,6 +100,10 @@ public:
|
||||
return !!mList;
|
||||
}
|
||||
|
||||
bool IsTranslatePoint() const {
|
||||
return mIsTranslatePoint;
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is called to notify this DOM object that it is being inserted
|
||||
* into a list, and give it the information it needs as a result.
|
||||
@ -158,8 +163,9 @@ protected:
|
||||
// that if you change the capacity of any of the following.
|
||||
|
||||
uint32_t mListIndex:MOZ_SVG_LIST_INDEX_BIT_COUNT;
|
||||
uint32_t mIsReadonly:1; // uint32_t because MSVC won't pack otherwise
|
||||
uint32_t mIsAnimValItem:1; // uint32_t because MSVC won't pack otherwise
|
||||
uint32_t mIsReadonly:1; // These flags are uint32_t because MSVC won't
|
||||
uint32_t mIsAnimValItem:1; // pack otherwise.
|
||||
uint32_t mIsTranslatePoint:1;
|
||||
|
||||
/**
|
||||
* Get a reference to the internal SVGPoint list item that this DOM wrapper
|
||||
|
@ -14,6 +14,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=629200
|
||||
<div id="content" style="display:none;">
|
||||
<svg id="svg" xmlns="http://www.w3.org/2000/svg" width="100" height="100">
|
||||
<polyline id="polyline" points="50,375 150,380"/>
|
||||
<polyline id="polyline2" points="10,20"/>
|
||||
</svg>
|
||||
</div>
|
||||
<pre id="test">
|
||||
@ -63,6 +64,60 @@ function run_tests()
|
||||
polyline.removeAttributeNS(null, "points");
|
||||
eventChecker.finish();
|
||||
|
||||
// Test that the addition of an owned SVGPoint to an SVGPointList creates a
|
||||
// copy of the SVGPoint
|
||||
var polyline2 = document.getElementById("polyline2");
|
||||
var subtests = [
|
||||
function initialize(aItem) {
|
||||
polyline.removeAttribute("points");
|
||||
return points.initialize(aItem);
|
||||
},
|
||||
function insertItemBefore(aItem) {
|
||||
polyline.removeAttribute("points");
|
||||
return points.insertItemBefore(aItem, 0);
|
||||
},
|
||||
function replaceItem(aItem) {
|
||||
polyline.setAttribute("points", "10,20");
|
||||
return points.replaceItem(aItem, 0);
|
||||
},
|
||||
function appendItem(aItem) {
|
||||
polyline.removeAttribute("points");
|
||||
return points.appendItem(aItem);
|
||||
}
|
||||
];
|
||||
subtests.forEach(function(aFunction) {
|
||||
// -- Adding SVGSVGElement.currentTranslate, which is the only instance
|
||||
// of an owned, single SVGPoint
|
||||
var svg = document.getElementById("svg");
|
||||
var name = aFunction.name;
|
||||
var existingItem = svg.currentTranslate;
|
||||
var newItem = aFunction(existingItem);
|
||||
is(newItem, points.getItem(0), name + " return value is correct when passed currentTranslate");
|
||||
isnot(newItem, existingItem, name + " made a copy when passed currentTranslate");
|
||||
is(newItem.value, existingItem.value, name + " made a copy with the right values when passed currentTranslate");
|
||||
todo(svg.currentTranslate == existingItem, name + " left the original object alone when passed currentTranslate");
|
||||
});
|
||||
subtests.forEach(function(aFunction) {
|
||||
// -- Adding an SVGPoint that is in a baseVal list
|
||||
var name = aFunction.name;
|
||||
var existingItem = polyline2.points.getItem(0);
|
||||
var newItem = aFunction(existingItem);
|
||||
is(newItem, points.getItem(0), name + " return value is correct when passed a baseVal list item");
|
||||
isnot(newItem, existingItem, name + " made a copy when passed a baseVal list item");
|
||||
is(newItem.value, existingItem.value, name + " made a copy with the right values when passed a baseVal list item");
|
||||
is(polyline2.points.getItem(0), existingItem, name + " left the original object alone when passed a baseVal list item");
|
||||
});
|
||||
subtests.forEach(function(aFunction) {
|
||||
// -- Adding an SVGPoint that is in a animVal list
|
||||
var name = aFunction.name;
|
||||
var existingItem = polyline2.animatedPoints.getItem(0);
|
||||
var newItem = aFunction(existingItem);
|
||||
is(newItem, points.getItem(0), name + " return value is correct when passed a animVal list item");
|
||||
isnot(newItem, existingItem, name + " made a copy when passed a animVal list item");
|
||||
is(newItem.value, existingItem.value, name + " made a copy with the right values when passed a animVal list item");
|
||||
is(polyline2.animatedPoints.getItem(0), existingItem, name + " left the original object alone when passed a animVal list item");
|
||||
});
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
@ -11,21 +11,15 @@ ifeq ($(OS_ARCH),WINNT)
|
||||
DEFFILE = $(CURDIR)/sqlite-processed.def
|
||||
|
||||
GARBAGE += \
|
||||
sqlite-version.h \
|
||||
$(DEFFILE) \
|
||||
$(NULL)
|
||||
|
||||
# We generate the appropriate version header file with our python script.
|
||||
sqlite-version.h: sqlite-version.py sqlite3.h
|
||||
$(PYTHON) $^ > $@
|
||||
|
||||
# We have to preprocess our def file because we need different symbols in debug
|
||||
# builds exposed that are not built in non-debug builds.
|
||||
$(DEFFILE): sqlite.def
|
||||
@$(call py_action,preprocessor,$(DEFINES) $(XULPPFLAGS) \
|
||||
$(srcdir)/sqlite.def -o $(DEFFILE))
|
||||
|
||||
export:: sqlite-version.h
|
||||
else
|
||||
ifndef MOZ_FOLD_LIBS
|
||||
ifdef GCC_USE_GNU_LD
|
||||
|
@ -70,10 +70,6 @@ if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_MEMORY']:
|
||||
if CONFIG['SOLARIS_SUNPRO_CC']:
|
||||
NO_PGO = True
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'WINNT':
|
||||
RCFILE = 'sqlite.rc'
|
||||
RESFILE = 'sqlite.res'
|
||||
|
||||
if CONFIG['OS_ARCH'] == 'Linux' and \
|
||||
not CONFIG['MOZ_FOLD_LIBS'] and \
|
||||
CONFIG['GCC_USE_GNU_LD']:
|
||||
|
@ -1,25 +0,0 @@
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
# Define RegEx for finding and breaking apart SQLITE_VERSION string
|
||||
versionString = "^#define SQLITE_VERSION\D*(\d+)\.(\d+)\.(\d+)(?:\.(\d+))?\D*"
|
||||
|
||||
#Use command line argument pointing to sqlite3.h to open the file and use
|
||||
#the RegEx to search for the line #define SQLITE_VERSION. When the RegEx
|
||||
#matches and the line is found, print the version strings to the console
|
||||
#with #definey goodness.
|
||||
for line in open(sys.argv[1]):
|
||||
result = re.search(versionString, line)
|
||||
if result is not None: #If RegEx matches, print version numbers and stop
|
||||
splitVersion = list(result.groups())
|
||||
if splitVersion[3] is None: #Make 4th list element 0 if undefined
|
||||
splitVersion[3:] = ['0']
|
||||
print "#define SQLITE_VERSION_MAJOR " + splitVersion[0]
|
||||
print "#define SQLITE_VERSION_MINOR " + splitVersion[1]
|
||||
print "#define SQLITE_VERSION_PATCH " + splitVersion[2]
|
||||
print "#define SQLITE_VERSION_SUBPATCH " + splitVersion[3]
|
||||
break
|
@ -1,45 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "sqlite3.h"
|
||||
#include "sqlite-version.h"
|
||||
#include <winver.h>
|
||||
|
||||
#define SQLITE_COMPANY_NAME "sqlite.org"
|
||||
#define SQLITE_INTERNAL_NAME "sqlite3"
|
||||
#define SQLITE_FILEDESCRIPTION "SQLite Database Library"
|
||||
|
||||
#define MY_FILEOS VOS_NT_WINDOWS32
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Version-information resource
|
||||
//
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
|
||||
FILEVERSION SQLITE_VERSION_MAJOR,SQLITE_VERSION_MINOR,SQLITE_VERSION_PATCH,SQLITE_VERSION_SUBPATCH
|
||||
PRODUCTVERSION SQLITE_VERSION_MAJOR,SQLITE_VERSION_MINOR,SQLITE_VERSION_PATCH,SQLITE_VERSION_SUBPATCH
|
||||
FILEOS MY_FILEOS
|
||||
FILETYPE VFT_DLL
|
||||
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904B0" // Lang=US English, CharSet=Unicode
|
||||
BEGIN
|
||||
VALUE "CompanyName", SQLITE_COMPANY_NAME "\0"
|
||||
VALUE "FileDescription", SQLITE_FILEDESCRIPTION "\0"
|
||||
VALUE "FileVersion", SQLITE_VERSION "\0"
|
||||
VALUE "InternalName", SQLITE_INTERNAL_NAME "\0"
|
||||
VALUE "OriginalFilename", SQLITE_INTERNAL_NAME ".dll\0"
|
||||
VALUE "ProductName", SQLITE_FILEDESCRIPTION "\0"
|
||||
VALUE "ProductVersion", SQLITE_VERSION "\0"
|
||||
END
|
||||
END
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
VALUE "Translation", 0x409, 1200
|
||||
END
|
||||
END
|
@ -821,7 +821,7 @@ this.DOMApplicationRegistry = {
|
||||
root = aManifest.entry_points[aEntryPoint];
|
||||
}
|
||||
|
||||
if (!root.activities) {
|
||||
if (!root || !root.activities) {
|
||||
return activitiesToRegister;
|
||||
}
|
||||
|
||||
@ -2908,6 +2908,10 @@ this.DOMApplicationRegistry = {
|
||||
});
|
||||
|
||||
let zipFile = yield this._getPackage(requestChannel, aId, aOldApp, aNewApp);
|
||||
|
||||
// After this point, it's too late to cancel the download.
|
||||
AppDownloadManager.remove(aNewApp.manifestURL);
|
||||
|
||||
let hash = yield this._computeFileHash(zipFile.path);
|
||||
|
||||
let responseStatus = requestChannel.responseStatus;
|
||||
@ -2926,8 +2930,6 @@ this.DOMApplicationRegistry = {
|
||||
let newManifest = yield this._openAndReadPackage(zipFile, aOldApp, aNewApp,
|
||||
isLocalFileInstall, aIsUpdate, aManifest, requestChannel, hash);
|
||||
|
||||
AppDownloadManager.remove(aNewApp.manifestURL);
|
||||
|
||||
return [aOldApp.id, newManifest];
|
||||
|
||||
}),
|
||||
|
@ -106,7 +106,7 @@ function handleRequest(request, response) {
|
||||
response.write(resource);
|
||||
aTimer.cancel();
|
||||
response.finish();
|
||||
}, 1000, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
}, 15000, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
} else {
|
||||
response.write(resource);
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ var steps = [
|
||||
PackagedTestHelper.gApp.cancelDownload();
|
||||
// And only do this once.
|
||||
PackagedTestHelper.gApp.onprogress = null;
|
||||
}, 40);
|
||||
}, 10);
|
||||
};
|
||||
|
||||
var alreadyCanceled = false;
|
||||
@ -261,18 +261,24 @@ var steps = [
|
||||
|
||||
PackagedTestHelper.gApp.ondownloadsuccess = function() {
|
||||
info("App downloaded");
|
||||
// We could try also applying the download we just made.
|
||||
|
||||
// Sometimes we can't cancel in time (since setting a high timer on the
|
||||
// sjs just doesn't work). Let's fail gracefully in that case, and just
|
||||
// give a warning here.
|
||||
if (!alreadyCanceled) {
|
||||
todo(alreadyCanceled, "The app download wasn't cancelled in time!");
|
||||
}
|
||||
var expected = {
|
||||
name: PackagedTestHelper.gAppName,
|
||||
manifestURL: miniManifestURL,
|
||||
installOrigin: PackagedTestHelper.gInstallOrigin,
|
||||
progress: 0,
|
||||
installState: "pending",
|
||||
installState: alreadyCanceled?"pending":"installed",
|
||||
downloadAvailable: false,
|
||||
downloading: false,
|
||||
downloadSize: 0,
|
||||
size: 0,
|
||||
readyToApplyDownload: true
|
||||
readyToApplyDownload: alreadyCanceled
|
||||
};
|
||||
PackagedTestHelper.checkAppState(PackagedTestHelper.gApp, 3, expected,
|
||||
true, false, function() {});
|
||||
|
@ -35,6 +35,10 @@ enum StructuredCloneTags {
|
||||
// This tag is for WebCrypto keys
|
||||
SCTAG_DOM_WEBCRYPTO_KEY,
|
||||
|
||||
SCTAG_DOM_NULL_PRINCIPAL,
|
||||
SCTAG_DOM_SYSTEM_PRINCIPAL,
|
||||
SCTAG_DOM_CONTENT_PRINCIPAL,
|
||||
|
||||
SCTAG_DOM_MAX
|
||||
};
|
||||
|
||||
|
@ -60,6 +60,8 @@
|
||||
#include "mozilla/dom/ImageData.h"
|
||||
#include "mozilla/dom/StructuredClone.h"
|
||||
#include "mozilla/dom/SubtleCryptoBinding.h"
|
||||
#include "mozilla/ipc/BackgroundUtils.h"
|
||||
#include "mozilla/ipc/PBackgroundSharedTypes.h"
|
||||
#include "nsAXPCNativeCallContext.h"
|
||||
#include "mozilla/CycleCollectedJSRuntime.h"
|
||||
|
||||
@ -2830,6 +2832,46 @@ NS_DOMReadStructuredClone(JSContext* cx,
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else if (tag == SCTAG_DOM_NULL_PRINCIPAL ||
|
||||
tag == SCTAG_DOM_SYSTEM_PRINCIPAL ||
|
||||
tag == SCTAG_DOM_CONTENT_PRINCIPAL) {
|
||||
mozilla::ipc::PrincipalInfo info;
|
||||
if (tag == SCTAG_DOM_SYSTEM_PRINCIPAL) {
|
||||
info = mozilla::ipc::SystemPrincipalInfo();
|
||||
} else if (tag == SCTAG_DOM_NULL_PRINCIPAL) {
|
||||
info = mozilla::ipc::NullPrincipalInfo();
|
||||
} else {
|
||||
uint32_t appId = data;
|
||||
|
||||
uint32_t isInBrowserElement, specLength;
|
||||
if (!JS_ReadUint32Pair(reader, &isInBrowserElement, &specLength)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsAutoCString spec;
|
||||
spec.SetLength(specLength);
|
||||
if (!JS_ReadBytes(reader, spec.BeginWriting(), specLength)) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
info = mozilla::ipc::ContentPrincipalInfo(appId, isInBrowserElement, spec);
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIPrincipal> principal = PrincipalInfoToPrincipal(info, &rv);
|
||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
JS::RootedValue result(cx);
|
||||
rv = nsContentUtils::WrapNative(cx, principal, &NS_GET_IID(nsIPrincipal), &result);
|
||||
if (NS_FAILED(rv)) {
|
||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
return result.toObjectOrNull();
|
||||
}
|
||||
|
||||
// Don't know what this is. Bail.
|
||||
@ -2856,6 +2898,31 @@ NS_DOMWriteStructuredClone(JSContext* cx,
|
||||
key->WriteStructuredClone(writer);
|
||||
}
|
||||
|
||||
if (xpc::IsReflector(obj)) {
|
||||
nsCOMPtr<nsISupports> base = xpc::UnwrapReflectorToISupports(obj);
|
||||
nsCOMPtr<nsIPrincipal> principal = do_QueryInterface(base);
|
||||
if (principal) {
|
||||
mozilla::ipc::PrincipalInfo info;
|
||||
if (NS_WARN_IF(NS_FAILED(PrincipalToPrincipalInfo(principal, &info)))) {
|
||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (info.type() == mozilla::ipc::PrincipalInfo::TNullPrincipalInfo) {
|
||||
return JS_WriteUint32Pair(writer, SCTAG_DOM_NULL_PRINCIPAL, 0);
|
||||
}
|
||||
if (info.type() == mozilla::ipc::PrincipalInfo::TSystemPrincipalInfo) {
|
||||
return JS_WriteUint32Pair(writer, SCTAG_DOM_SYSTEM_PRINCIPAL, 0);
|
||||
}
|
||||
|
||||
MOZ_ASSERT(info.type() == mozilla::ipc::PrincipalInfo::TContentPrincipalInfo);
|
||||
const mozilla::ipc::ContentPrincipalInfo& cInfo = info;
|
||||
return JS_WriteUint32Pair(writer, SCTAG_DOM_CONTENT_PRINCIPAL, cInfo.appId()) &&
|
||||
JS_WriteUint32Pair(writer, cInfo.isInBrowserElement(), cInfo.spec().Length()) &&
|
||||
JS_WriteBytes(writer, cInfo.spec().get(), cInfo.spec().Length());
|
||||
}
|
||||
}
|
||||
|
||||
// Don't know what this is
|
||||
xpc::Throw(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
|
||||
return false;
|
||||
|
@ -11167,7 +11167,7 @@ class CGDictionary(CGThing):
|
||||
|
||||
@staticmethod
|
||||
def makeMemberName(name):
|
||||
return "m" + name[0].upper() + name[1:]
|
||||
return "m" + name[0].upper() + name[1:].replace("-", "_")
|
||||
|
||||
def getMemberType(self, memberInfo):
|
||||
_, conversionInfo = memberInfo
|
||||
@ -11351,7 +11351,7 @@ class CGDictionary(CGThing):
|
||||
|
||||
@staticmethod
|
||||
def makeIdName(name):
|
||||
return name + "_id"
|
||||
return name.replace("-", "_") + "_id"
|
||||
|
||||
@staticmethod
|
||||
def getDictionaryDependenciesFromType(type):
|
||||
|
@ -4059,7 +4059,7 @@ class Tokenizer(object):
|
||||
return t
|
||||
|
||||
def t_IDENTIFIER(self, t):
|
||||
r'[A-Z_a-z][0-9A-Z_a-z]*'
|
||||
r'[A-Z_a-z][0-9A-Z_a-z-]*'
|
||||
t.type = self.keywords.get(t.value, 'IDENTIFIER')
|
||||
return t
|
||||
|
||||
|
@ -921,6 +921,8 @@ dictionary Dict : ParentDict {
|
||||
sequence<long>? seq3;
|
||||
sequence<long>? seq4 = null;
|
||||
sequence<long>? seq5 = [];
|
||||
|
||||
long dashed-name;
|
||||
};
|
||||
|
||||
dictionary ParentDict : GrandparentDict {
|
||||
|
@ -9,8 +9,6 @@
|
||||
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsMathUtils.h"
|
||||
#include "SVGPreserveAspectRatio.h"
|
||||
#include "SVGImageContext.h"
|
||||
|
||||
#include "nsContentUtils.h"
|
||||
|
||||
@ -3434,7 +3432,7 @@ CanvasRenderingContext2D::DrawImage(const HTMLImageOrCanvasOrVideoElement& image
|
||||
DrawOptions(CurrentState().globalAlpha, UsedOperation()));
|
||||
} else {
|
||||
DrawDirectlyToCanvas(drawInfo, &bounds, dx, dy, dw, dh,
|
||||
sx, sy, sw, sh, imgSize, CurrentState().globalAlpha);
|
||||
sx, sy, sw, sh, imgSize);
|
||||
}
|
||||
|
||||
RedrawUser(gfxRect(dx, dy, dw, dh));
|
||||
@ -3445,8 +3443,7 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
||||
const nsLayoutUtils::DirectDrawInfo& image,
|
||||
mgfx::Rect* bounds, double dx, double dy,
|
||||
double dw, double dh, double sx, double sy,
|
||||
double sw, double sh, gfxIntSize imgSize,
|
||||
gfxFloat opacity)
|
||||
double sw, double sh, gfxIntSize imgSize)
|
||||
{
|
||||
gfxMatrix contextMatrix;
|
||||
|
||||
@ -3472,14 +3469,12 @@ CanvasRenderingContext2D::DrawDirectlyToCanvas(
|
||||
// FLAG_CLAMP is added for increased performance
|
||||
uint32_t modifiedFlags = image.mDrawingFlags | imgIContainer::FLAG_CLAMP;
|
||||
|
||||
SVGImageContext svgContext(SVGPreserveAspectRatio(), opacity);
|
||||
|
||||
nsresult rv = image.mImgContainer->
|
||||
Draw(context, GraphicsFilter::FILTER_GOOD, transformMatrix,
|
||||
gfxRect(gfxPoint(dx, dy), gfxIntSize(dw, dh)),
|
||||
nsIntRect(nsIntPoint(0, 0), gfxIntSize(imgSize.width, imgSize.height)),
|
||||
gfxIntSize(imgSize.width, imgSize.height),
|
||||
&svgContext, image.mWhichFrame, modifiedFlags);
|
||||
gfxIntSize(imgSize.width, imgSize.height), nullptr, image.mWhichFrame,
|
||||
modifiedFlags);
|
||||
|
||||
NS_ENSURE_SUCCESS_VOID(rv);
|
||||
}
|
||||
|
@ -667,8 +667,7 @@ protected:
|
||||
void DrawDirectlyToCanvas(const nsLayoutUtils::DirectDrawInfo& image,
|
||||
mozilla::gfx::Rect* bounds, double dx, double dy,
|
||||
double dw, double dh, double sx, double sy,
|
||||
double sw, double sh, gfxIntSize imgSize,
|
||||
gfxFloat opacity);
|
||||
double sw, double sh, gfxIntSize imgSize);
|
||||
|
||||
nsString& GetFont()
|
||||
{
|
||||
|
27
dom/canvas/WebGLBindableName.cpp
Normal file
27
dom/canvas/WebGLBindableName.cpp
Normal file
@ -0,0 +1,27 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "WebGLBindableName.h"
|
||||
#include "GLConsts.h"
|
||||
#include "mozilla/Assertions.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLBindableName::WebGLBindableName()
|
||||
: mGLName(LOCAL_GL_NONE)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
{ }
|
||||
|
||||
void
|
||||
WebGLBindableName::BindTo(GLenum target)
|
||||
{
|
||||
MOZ_ASSERT(target != LOCAL_GL_NONE, "Can't bind to GL_NONE.");
|
||||
MOZ_ASSERT(mTarget == LOCAL_GL_NONE || mTarget == target, "Rebinding is illegal.");
|
||||
|
||||
bool targetChanged = (target != mTarget);
|
||||
mTarget = target;
|
||||
if (targetChanged)
|
||||
OnTargetChanged();
|
||||
}
|
36
dom/canvas/WebGLBindableName.h
Normal file
36
dom/canvas/WebGLBindableName.h
Normal file
@ -0,0 +1,36 @@
|
||||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef WEBGLBINDABLENAME_H_
|
||||
#define WEBGLBINDABLENAME_H_
|
||||
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
/** Represents a GL name that can be bound to a target.
|
||||
*/
|
||||
class WebGLBindableName
|
||||
{
|
||||
public:
|
||||
WebGLBindableName();
|
||||
void BindTo(GLenum target);
|
||||
|
||||
bool HasEverBeenBound() const { return mTarget != 0; }
|
||||
GLuint GLName() const { return mGLName; }
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
protected:
|
||||
|
||||
//! Called after mTarget has been changed by BindTo(target).
|
||||
virtual void OnTargetChanged() {}
|
||||
|
||||
GLuint mGLName;
|
||||
GLenum mTarget;
|
||||
};
|
||||
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // !WEBGLBINDABLENAME_H_
|
@ -13,10 +13,9 @@
|
||||
using namespace mozilla;
|
||||
|
||||
WebGLBuffer::WebGLBuffer(WebGLContext *context)
|
||||
: WebGLContextBoundObject(context)
|
||||
, mHasEverBeenBound(false)
|
||||
: WebGLBindableName()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mByteLength(0)
|
||||
, mTarget(LOCAL_GL_NONE)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
mContext->MakeContextCurrent();
|
||||
@ -38,8 +37,7 @@ WebGLBuffer::Delete() {
|
||||
}
|
||||
|
||||
void
|
||||
WebGLBuffer::SetTarget(GLenum target) {
|
||||
mTarget = target;
|
||||
WebGLBuffer::OnTargetChanged() {
|
||||
if (!mCache && mTarget == LOCAL_GL_ELEMENT_ARRAY_BUFFER)
|
||||
mCache = new WebGLElementArrayCache;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "mozilla/LinkedList.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "nsWrapperCache.h"
|
||||
#include "WebGLBindableName.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLTypes.h"
|
||||
|
||||
@ -19,6 +20,7 @@ class WebGLElementArrayCache;
|
||||
|
||||
class WebGLBuffer MOZ_FINAL
|
||||
: public nsWrapperCache
|
||||
, public WebGLBindableName
|
||||
, public WebGLRefCountedObject<WebGLBuffer>
|
||||
, public LinkedListElement<WebGLBuffer>
|
||||
, public WebGLContextBoundObject
|
||||
@ -30,16 +32,10 @@ public:
|
||||
|
||||
size_t SizeOfIncludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
GLuint GLName() const { return mGLName; }
|
||||
WebGLsizeiptr ByteLength() const { return mByteLength; }
|
||||
GLenum Target() const { return mTarget; }
|
||||
|
||||
void SetByteLength(WebGLsizeiptr byteLength) { mByteLength = byteLength; }
|
||||
|
||||
void SetTarget(GLenum target);
|
||||
|
||||
bool ElementArrayCacheBufferData(const void* ptr, size_t buffer_size_in_bytes);
|
||||
|
||||
void ElementArrayCacheBufferSubData(size_t pos, const void* ptr, size_t update_size_in_bytes);
|
||||
@ -61,10 +57,9 @@ public:
|
||||
protected:
|
||||
~WebGLBuffer();
|
||||
|
||||
GLuint mGLName;
|
||||
bool mHasEverBeenBound;
|
||||
virtual void OnTargetChanged() MOZ_OVERRIDE;
|
||||
|
||||
WebGLsizeiptr mByteLength;
|
||||
GLenum mTarget;
|
||||
|
||||
nsAutoPtr<WebGLElementArrayCache> mCache;
|
||||
};
|
||||
|
@ -31,9 +31,8 @@ WebGLContext::BindBuffer(GLenum target, WebGLBuffer *buffer)
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->Target()) {
|
||||
buffer->SetTarget(target);
|
||||
buffer->SetHasEverBeenBound(true);
|
||||
if (!buffer->HasEverBeenBound()) {
|
||||
buffer->BindTo(target);
|
||||
} else if (target != buffer->Target()) {
|
||||
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
|
||||
}
|
||||
@ -67,12 +66,11 @@ WebGLContext::BindBufferBase(GLenum target, GLuint index, WebGLBuffer* buffer)
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->Target()) {
|
||||
buffer->SetTarget(target);
|
||||
buffer->SetHasEverBeenBound(true);
|
||||
} else if (target != buffer->Target()) {
|
||||
if (!buffer->HasEverBeenBound())
|
||||
buffer->BindTo(target);
|
||||
|
||||
if (target != buffer->Target())
|
||||
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
|
||||
}
|
||||
}
|
||||
|
||||
WebGLRefPtr<WebGLBuffer>* bufferSlot = GetBufferSlotByTarget(target, "bindBuffer");
|
||||
@ -108,12 +106,12 @@ WebGLContext::BindBufferRange(GLenum target, GLuint index, WebGLBuffer* buffer,
|
||||
}
|
||||
|
||||
if (buffer) {
|
||||
if (!buffer->Target()) {
|
||||
buffer->SetTarget(target);
|
||||
buffer->SetHasEverBeenBound(true);
|
||||
} else if (target != buffer->Target()) {
|
||||
if (!buffer->HasEverBeenBound())
|
||||
buffer->BindTo(target);
|
||||
|
||||
if (target != buffer->Target())
|
||||
return ErrorInvalidOperation("bindBuffer: buffer already bound to a different target");
|
||||
}
|
||||
|
||||
CheckedInt<WebGLsizeiptr> checked_neededByteLength = CheckedInt<WebGLsizeiptr>(offset) + size;
|
||||
if (!checked_neededByteLength.isValid() ||
|
||||
checked_neededByteLength.value() > buffer->ByteLength())
|
||||
|
@ -174,9 +174,9 @@ WebGLContext::BindFramebuffer(GLenum target, WebGLFramebuffer *wfb)
|
||||
if (!wfb) {
|
||||
gl->fBindFramebuffer(target, 0);
|
||||
} else {
|
||||
wfb->BindTo(target);
|
||||
GLuint framebuffername = wfb->GLName();
|
||||
gl->fBindFramebuffer(target, framebuffername);
|
||||
wfb->SetHasEverBeenBound(true);
|
||||
}
|
||||
|
||||
mBoundFramebuffer = wfb;
|
||||
@ -199,7 +199,7 @@ WebGLContext::BindRenderbuffer(GLenum target, WebGLRenderbuffer *wrb)
|
||||
return;
|
||||
|
||||
if (wrb)
|
||||
wrb->SetHasEverBeenBound(true);
|
||||
wrb->BindTo(target);
|
||||
|
||||
MakeContextCurrent();
|
||||
|
||||
|
@ -89,5 +89,3 @@ WebGLContext::IsVertexArray(WebGLVertexArray *array)
|
||||
!array->IsDeleted() &&
|
||||
array->HasEverBeenBound();
|
||||
}
|
||||
|
||||
|
||||
|
@ -24,9 +24,9 @@ WebGLFramebuffer::WrapObject(JSContext* cx)
|
||||
}
|
||||
|
||||
WebGLFramebuffer::WebGLFramebuffer(WebGLContext* context)
|
||||
: WebGLContextBoundObject(context)
|
||||
: WebGLBindableName()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mStatus(0)
|
||||
, mHasEverBeenBound(false)
|
||||
, mDepthAttachment(LOCAL_GL_DEPTH_ATTACHMENT)
|
||||
, mStencilAttachment(LOCAL_GL_STENCIL_ATTACHMENT)
|
||||
, mDepthStencilAttachment(LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
|
||||
@ -79,8 +79,9 @@ WebGLFramebuffer::Attachment::HasAlpha() const
|
||||
bool
|
||||
WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||
{
|
||||
if (Texture() && Texture()->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
||||
GLenum type = Texture()->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType();
|
||||
const WebGLTexture* tex = Texture();
|
||||
if (tex && tex->HasImageInfoAt(mTexImageTarget, mTexImageLevel)) {
|
||||
GLenum type = tex->ImageInfoAt(mTexImageTarget, mTexImageLevel).WebGLType();
|
||||
switch (type) {
|
||||
case LOCAL_GL_FLOAT:
|
||||
case LOCAL_GL_HALF_FLOAT_OES:
|
||||
@ -89,8 +90,9 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||
return false;
|
||||
}
|
||||
|
||||
if (Renderbuffer()) {
|
||||
GLenum format = Renderbuffer()->InternalFormat();
|
||||
const WebGLRenderbuffer* rb = Renderbuffer();
|
||||
if (rb) {
|
||||
GLenum format = rb->InternalFormat();
|
||||
switch (format) {
|
||||
case LOCAL_GL_RGB16F:
|
||||
case LOCAL_GL_RGBA16F:
|
||||
@ -101,6 +103,8 @@ WebGLFramebuffer::Attachment::IsReadableFloat() const
|
||||
return false;
|
||||
}
|
||||
|
||||
// If we arrive here Attachment isn't correct setup because it has
|
||||
// no texture nor render buffer pointer.
|
||||
MOZ_ASSERT(false, "Should not get here.");
|
||||
return false;
|
||||
}
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef WEBGLFRAMEBUFFER_H_
|
||||
#define WEBGLFRAMEBUFFER_H_
|
||||
|
||||
#include "WebGLBindableName.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
|
||||
#include "nsWrapperCache.h"
|
||||
@ -23,6 +24,7 @@ namespace gl {
|
||||
|
||||
class WebGLFramebuffer MOZ_FINAL
|
||||
: public nsWrapperCache
|
||||
, public WebGLBindableName
|
||||
, public WebGLRefCountedObject<WebGLFramebuffer>
|
||||
, public LinkedListElement<WebGLFramebuffer>
|
||||
, public WebGLContextBoundObject
|
||||
@ -92,10 +94,6 @@ public:
|
||||
|
||||
void Delete();
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
GLuint GLName() { return mGLName; }
|
||||
|
||||
void FramebufferRenderbuffer(GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum rbtarget,
|
||||
@ -183,9 +181,6 @@ private:
|
||||
|
||||
mutable GLenum mStatus;
|
||||
|
||||
GLuint mGLName;
|
||||
bool mHasEverBeenBound;
|
||||
|
||||
// we only store pointers to attached renderbuffers, not to attached textures, because
|
||||
// we will only need to initialize renderbuffers. Textures are already initialized.
|
||||
nsTArray<Attachment> mColorAttachments;
|
||||
|
@ -43,12 +43,12 @@ WebGLRenderbuffer::WrapObject(JSContext *cx) {
|
||||
}
|
||||
|
||||
WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext *context)
|
||||
: WebGLContextBoundObject(context)
|
||||
: WebGLBindableName()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mPrimaryRB(0)
|
||||
, mSecondaryRB(0)
|
||||
, mInternalFormat(0)
|
||||
, mInternalFormatForGL(0)
|
||||
, mHasEverBeenBound(false)
|
||||
, mImageDataStatus(WebGLImageDataStatus::NoImageData)
|
||||
{
|
||||
SetIsDOMBinding();
|
||||
|
@ -6,6 +6,7 @@
|
||||
#ifndef WEBGLRENDERBUFFER_H_
|
||||
#define WEBGLRENDERBUFFER_H_
|
||||
|
||||
#include "WebGLBindableName.h"
|
||||
#include "WebGLObjectModel.h"
|
||||
#include "WebGLFramebufferAttachable.h"
|
||||
|
||||
@ -17,6 +18,7 @@ namespace mozilla {
|
||||
|
||||
class WebGLRenderbuffer MOZ_FINAL
|
||||
: public nsWrapperCache
|
||||
, public WebGLBindableName
|
||||
, public WebGLRefCountedObject<WebGLRenderbuffer>
|
||||
, public LinkedListElement<WebGLRenderbuffer>
|
||||
, public WebGLRectangleObject
|
||||
@ -28,9 +30,6 @@ public:
|
||||
|
||||
void Delete();
|
||||
|
||||
bool HasEverBeenBound() { return mHasEverBeenBound; }
|
||||
void SetHasEverBeenBound(bool x) { mHasEverBeenBound = x; }
|
||||
|
||||
bool HasUninitializedImageData() const { return mImageDataStatus == WebGLImageDataStatus::UninitializedImageData; }
|
||||
void SetImageDataStatus(WebGLImageDataStatus x) {
|
||||
// there is no way to go from having image data to not having any
|
||||
@ -71,7 +70,6 @@ protected:
|
||||
GLuint mSecondaryRB;
|
||||
GLenum mInternalFormat;
|
||||
GLenum mInternalFormatForGL;
|
||||
bool mHasEverBeenBound;
|
||||
WebGLImageDataStatus mImageDataStatus;
|
||||
|
||||
friend class WebGLFramebuffer;
|
||||
|
@ -23,9 +23,8 @@ WebGLTexture::WrapObject(JSContext *cx) {
|
||||
}
|
||||
|
||||
WebGLTexture::WebGLTexture(WebGLContext *context)
|
||||
: WebGLContextBoundObject(context)
|
||||
, mHasEverBeenBound(false)
|
||||
, mTarget(0)
|
||||
: WebGLBindableName()
|
||||
, WebGLContextBoundObject(context)
|
||||
, mMinFilter(LOCAL_GL_NEAREST_MIPMAP_LINEAR)
|
||||
, mMagFilter(LOCAL_GL_LINEAR)
|
||||
, mWrapS(LOCAL_GL_REPEAT)
|
||||
@ -108,18 +107,21 @@ WebGLTexture::Bind(GLenum aTarget) {
|
||||
// this function should only be called by bindTexture().
|
||||
// it assumes that the GL context is already current.
|
||||
|
||||
bool firstTimeThisTextureIsBound = !mHasEverBeenBound;
|
||||
bool firstTimeThisTextureIsBound = !HasEverBeenBound();
|
||||
|
||||
if (!firstTimeThisTextureIsBound && aTarget != mTarget) {
|
||||
if (firstTimeThisTextureIsBound) {
|
||||
BindTo(aTarget);
|
||||
} else if (aTarget != Target()) {
|
||||
mContext->ErrorInvalidOperation("bindTexture: this texture has already been bound to a different target");
|
||||
// very important to return here before modifying texture state! This was the place when I lost a whole day figuring
|
||||
// very strange 'invalid write' crashes.
|
||||
return;
|
||||
}
|
||||
|
||||
mTarget = aTarget;
|
||||
GLuint name = GLName();
|
||||
GLenum target = Target();
|
||||
|
||||
mContext->gl->fBindTexture(mTarget, mGLName);
|
||||
mContext->gl->fBindTexture(target, name);
|
||||
|
||||
if (firstTimeThisTextureIsBound) {
|
||||
mFacesCount = (mTarget == LOCAL_GL_TEXTURE_2D) ? 1 : 6;
|
||||
@ -132,8 +134,6 @@ WebGLTexture::Bind(GLenum aTarget) {
|
||||
if (mTarget == LOCAL_GL_TEXTURE_CUBE_MAP && !mContext->gl->IsGLES())
|
||||
mContext->gl->fTexParameteri(mTarget, LOCAL_GL_TEXTURE_WRAP_R, LOCAL_GL_CLAMP_TO_EDGE);
|
||||
}
|
||||
|
||||
mHasEverBeenBound = true;
|
||||
}
|
||||
|
||||
void
|
||||
@ -141,8 +141,14 @@ WebGLTexture::SetImageInfo(GLenum aTarget, GLint aLevel,
|
||||
GLsizei aWidth, GLsizei aHeight,
|
||||
GLenum aFormat, GLenum aType, WebGLImageDataStatus aStatus)
|
||||
{
|
||||
if ( (aTarget == LOCAL_GL_TEXTURE_2D) != (mTarget == LOCAL_GL_TEXTURE_2D) )
|
||||
// TODO(djg): I suspected the following ASSERT and check are
|
||||
// trying to express more than they're saying, probably
|
||||
// to do with cubemap targets. We should do this
|
||||
// properly. https://bugzilla.mozilla.org/show_bug.cgi?id=1006908
|
||||
MOZ_ASSERT((aTarget == LOCAL_GL_TEXTURE_2D) == (mTarget == LOCAL_GL_TEXTURE_2D));
|
||||
if ((aTarget == LOCAL_GL_TEXTURE_2D) != (mTarget == LOCAL_GL_TEXTURE_2D)) {
|
||||
return;
|
||||
}
|
||||
|
||||
EnsureMaxLevelWithCustomImagesAtLeast(aLevel);
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user