author | Ryan VanderMeulen <ryanvm@gmail.com> |
Tue, 04 Mar 2014 17:12:58 -0500 | |
changeset 171831 | e5b09585215f0c8e066a6255bed90918a1439e70 |
parent 171767 | 46c3b9de467a52ad99e761aa09191b4515bc49c6 (current diff) |
parent 171830 | c0805ed62585e519412fddcf5f35d623b05702b9 (diff) |
child 171844 | a9780d2f2b86f8aac4dc83409ddef76d070fb73c |
child 171951 | 1fba6d21db7176579c34ea7ad3636f8bba25dbb0 |
push id | 26340 |
push user | ryanvm@gmail.com |
push date | Tue, 04 Mar 2014 22:12:36 +0000 |
treeherder | mozilla-central@e5b09585215f [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
milestone | 30.0a1 |
first release with | nightly linux32
e5b09585215f
/
30.0a1
/
20140305030201
/
files
nightly linux64
e5b09585215f
/
30.0a1
/
20140305030201
/
files
nightly mac
e5b09585215f
/
30.0a1
/
20140305030201
/
files
nightly win32
e5b09585215f
/
30.0a1
/
20140305030201
/
files
nightly win64
e5b09585215f
/
30.0a1
/
20140305030201
/
files
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
releases | nightly linux32
30.0a1
/
20140305030201
/
pushlog to previous
nightly linux64
30.0a1
/
20140305030201
/
pushlog to previous
nightly mac
30.0a1
/
20140305030201
/
pushlog to previous
nightly win32
30.0a1
/
20140305030201
/
pushlog to previous
nightly win64
30.0a1
/
20140305030201
/
pushlog to previous
|
--- a/CLOBBER +++ b/CLOBBER @@ -17,9 +17,9 @@ # # Modifying this file will now automatically clobber the buildbot machines \o/ # # Are you updating CLOBBER because you think it's needed for your WebIDL # changes to stick? As of bug 928195, this shouldn't be necessary! Please # don't change CLOBBER for WebIDL changes any more. -Update CLOBBER for bug 939672 moves file location and requires clobber build. +Update CLOBBER for bug 978784 because it touches the ICU build system.
--- a/accessible/src/jsat/AccessFu.css +++ b/accessible/src/jsat/AccessFu.css @@ -33,17 +33,16 @@ font-weight: 700; color: orange; background-color: black; border-radius: 0.25em; } #announce-box:not(.showing) { opacity: 0.0; - margin: 0.1em; -moz-transition: opacity 0.4s linear; } #announce-box.showing { opacity: 1.0; -moz-transition: opacity 0.2s linear; }
--- a/accessible/src/jsat/AccessFu.jsm +++ b/accessible/src/jsat/AccessFu.jsm @@ -129,31 +129,41 @@ this.AccessFu = { Utils.win.addEventListener('TabOpen', this); Utils.win.addEventListener('TabClose', this); Utils.win.addEventListener('TabSelect', this); if (this.readyCallback) { this.readyCallback(); delete this.readyCallback; } + + if (Utils.MozBuildApp !== 'mobile/android') { + this.announce( + Utils.stringBundle.GetStringFromName('screenReaderStarted')); + } }, /** * Disable AccessFu and return to default interaction mode. */ _disable: function _disable() { if (!this._enabled) return; this._enabled = false; Logger.info('Disabled'); Utils.win.document.removeChild(this.stylesheet.get()); + if (Utils.MozBuildApp !== 'mobile/android') { + this.announce( + Utils.stringBundle.GetStringFromName('screenReaderStopped')); + } + for each (let mm in Utils.AllMessageManagers) { mm.sendAsyncMessage('AccessFu:Stop'); this._removeMessageListeners(mm); } this.Input.stop(); Output.stop(); TouchAdapter.stop(); @@ -363,18 +373,17 @@ this.AccessFu = { }, showCurrent: function showCurrent(aMove) { let mm = Utils.getMessageManager(Utils.CurrentBrowser); mm.sendAsyncMessage('AccessFu:ShowCurrent', { move: aMove }); }, announce: function announce(aAnnouncement) { - this._output(Presentation.announce(aAnnouncement), - Utils.CurrentBrowser); + this._output(Presentation.announce(aAnnouncement), Utils.CurrentBrowser); }, // So we don't enable/disable twice _enabled: false, // Layerview is focused _focused: false, @@ -510,17 +519,18 @@ var Output = { inited: false, webspeechEnabled: false, deferredOutputs: [], init: function init() { let window = Utils.win; - this.webspeechEnabled = !!window.speechSynthesis; + this.webspeechEnabled = !!window.speechSynthesis && + !!window.SpeechSynthesisUtterance; let settingsToGet = 2; let settingsCallback = (aName, aSetting) => { if (--settingsToGet > 0) { return; } this.inited = true;
--- a/accessible/src/jsat/OutputGenerator.jsm +++ b/accessible/src/jsat/OutputGenerator.jsm @@ -28,20 +28,16 @@ XPCOMUtils.defineLazyModuleGetter(this, 'resource://gre/modules/accessibility/Utils.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'PluralForm', 'resource://gre/modules/PluralForm.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'Roles', 'resource://gre/modules/accessibility/Constants.jsm'); XPCOMUtils.defineLazyModuleGetter(this, 'States', 'resource://gre/modules/accessibility/Constants.jsm'); -var gStringBundle = Cc['@mozilla.org/intl/stringbundle;1']. - getService(Ci.nsIStringBundleService). - createBundle('chrome://global/locale/AccessFu.properties'); - this.EXPORTED_SYMBOLS = ['UtteranceGenerator', 'BrailleGenerator']; this.OutputGenerator = { defaultOutputOrder: OUTPUT_DESC_LAST, /** * Generates output for a PivotContext. @@ -189,17 +185,17 @@ this.OutputGenerator = { * @param {nsIAccessible} aAccessible current accessible object. */ _addLandmark: function _addLandmark(aOutput, aAccessible) { let landmarkName = Utils.getLandmarkName(aAccessible); if (!landmarkName) { return; } - let landmark = gStringBundle.GetStringFromName(landmarkName); + let landmark = Utils.stringBundle.GetStringFromName(landmarkName); if (!landmark) { return; } aOutput[this.outputOrder === OUTPUT_DESC_FIRST ? 'unshift' : 'push']( landmark); }, @@ -216,17 +212,17 @@ this.OutputGenerator = { let typeName = Utils.getAttributes(aAccessible)['text-input-type']; // Ignore the the input type="text" case. if (!typeName || typeName === 'text') { return; } typeName = 'textInputType_' + typeName; try { - aDesc.push(gStringBundle.GetStringFromName(typeName)); + aDesc.push(Utils.stringBundle.GetStringFromName(typeName)); } catch (x) { Logger.warning('Failed to get a string from a bundle for', typeName); } }, get outputOrder() { if (!this._utteranceOrder) { this._utteranceOrder = new PrefCache('accessibility.accessfu.utterance'); @@ -239,17 +235,17 @@ this.OutputGenerator = { return aName.replace(' ', ''); }, _getLocalizedRole: function _getLocalizedRole(aRoleStr) {}, _getLocalizedState: function _getLocalizedState(aState) {}, _getPluralFormString: function _getPluralFormString(aString, aCount) { - let str = gStringBundle.GetStringFromName(this._getOutputName(aString)); + 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, 'grip': INCLUDE_DESC, @@ -373,17 +369,17 @@ 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( - gStringBundle.formatStringFromName( + Utils.stringBundle.formatStringFromName( 'objItemOf', [localizedRole, itemno.value, itemof.value], 3)); output.push(desc.join(' ')); this._addName(output, aAccessible, aFlags); this._addLandmark(output, aAccessible); return output; }, @@ -401,17 +397,17 @@ this.OutputGenerator = { // We don't want to speak any table information for layout tables. if (table.isProbablyForLayout()) { return output; } let tableColumnInfo = this._getPluralFormString('tableColumnInfo', table.columnCount); let tableRowInfo = this._getPluralFormString('tableRowInfo', table.rowCount); - output.push(gStringBundle.formatStringFromName( + output.push(Utils.stringBundle.formatStringFromName( this._getOutputName('tableInfo'), [this._getLocalizedRole(aRoleStr), tableColumnInfo, tableRowInfo], 3)); this._addName(output, aAccessible, aFlags); this._addLandmark(output, aAccessible); return output; } } } @@ -450,88 +446,89 @@ this.UtteranceGenerator = { collapse: 'collapseAction', expand: 'expandAction', activate: 'activateAction', cycle: 'cycleAction' }, //TODO: May become more verbose in the future. genForAction: function genForAction(aObject, aActionName) { - return [gStringBundle.GetStringFromName(this.gActionMap[aActionName])]; + return [Utils.stringBundle.GetStringFromName(this.gActionMap[aActionName])]; }, genForLiveRegion: function genForLiveRegion(aContext, aIsHide, aModifiedText) { let utterance = []; if (aIsHide) { - utterance.push(gStringBundle.GetStringFromName('hidden')); + utterance.push(Utils.stringBundle.GetStringFromName('hidden')); } return utterance.concat( aModifiedText || this.genForContext(aContext).output); }, genForAnnouncement: function genForAnnouncement(aAnnouncement) { try { - return [gStringBundle.GetStringFromName(aAnnouncement)]; + return [Utils.stringBundle.GetStringFromName(aAnnouncement)]; } catch (x) { return [aAnnouncement]; } }, genForTabStateChange: function genForTabStateChange(aObject, aTabState) { switch (aTabState) { case 'newtab': - return [gStringBundle.GetStringFromName('tabNew')]; + return [Utils.stringBundle.GetStringFromName('tabNew')]; case 'loading': - return [gStringBundle.GetStringFromName('tabLoading')]; + return [Utils.stringBundle.GetStringFromName('tabLoading')]; case 'loaded': return [aObject.name || '', - gStringBundle.GetStringFromName('tabLoaded')]; + Utils.stringBundle.GetStringFromName('tabLoaded')]; case 'loadstopped': - return [gStringBundle.GetStringFromName('tabLoadStopped')]; + return [Utils.stringBundle.GetStringFromName('tabLoadStopped')]; case 'reload': - return [gStringBundle.GetStringFromName('tabReload')]; + return [Utils.stringBundle.GetStringFromName('tabReload')]; default: return []; } }, genForEditingMode: function genForEditingMode(aIsEditing) { - return [gStringBundle.GetStringFromName( - aIsEditing ? 'editingMode' : 'navigationMode')]; + return [Utils.stringBundle.GetStringFromName( + aIsEditing ? 'editingMode' : 'navigationMode')]; }, objectOutputFunctions: { __proto__: OutputGenerator.objectOutputFunctions, defaultFunc: function defaultFunc(aAccessible, aRoleStr, aState, aFlags) { return this.objectOutputFunctions._generateBaseOutput.apply(this, arguments); }, heading: function heading(aAccessible, aRoleStr, aState, aFlags) { let level = {}; aAccessible.groupPosition(level, {}, {}); let utterance = - [gStringBundle.formatStringFromName('headingLevel', [level.value], 1)]; + [Utils.stringBundle.formatStringFromName( + 'headingLevel', [level.value], 1)]; this._addName(utterance, aAccessible, aFlags); this._addLandmark(utterance, aAccessible); return utterance; }, listitem: function listitem(aAccessible, aRoleStr, aState, aFlags) { let itemno = {}; let itemof = {}; aAccessible.groupPosition({}, itemof, itemno); let utterance = []; if (itemno.value == 1) // Start of list - utterance.push(gStringBundle.GetStringFromName('listStart')); + utterance.push(Utils.stringBundle.GetStringFromName('listStart')); else if (itemno.value == itemof.value) // last item - utterance.push(gStringBundle.GetStringFromName('listEnd')); + utterance.push(Utils.stringBundle.GetStringFromName('listEnd')); this._addName(utterance, aAccessible, aFlags); this._addLandmark(utterance, aAccessible); return utterance; }, list: function list(aAccessible, aRoleStr, aState, aFlags) { @@ -555,23 +552,23 @@ this.UtteranceGenerator = { cell: function cell(aAccessible, aRoleStr, aState, aFlags, aContext) { let utterance = []; let cell = aContext.getCellInfo(aAccessible); if (cell) { let desc = []; let addCellChanged = function addCellChanged(aDesc, aChanged, aString, aIndex) { if (aChanged) { - aDesc.push(gStringBundle.formatStringFromName(aString, + aDesc.push(Utils.stringBundle.formatStringFromName(aString, [aIndex + 1], 1)); } }; let addExtent = function addExtent(aDesc, aExtent, aString) { if (aExtent > 1) { - aDesc.push(gStringBundle.formatStringFromName(aString, + aDesc.push(Utils.stringBundle.formatStringFromName(aString, [aExtent], 1)); } }; let addHeaders = function addHeaders(aDesc, aHeaders) { if (aHeaders.length > 0) { aDesc.push.apply(aDesc, aHeaders); } }; @@ -604,59 +601,65 @@ this.UtteranceGenerator = { }, _getContextStart: function _getContextStart(aContext) { return aContext.newAncestry; }, _getLocalizedRole: function _getLocalizedRole(aRoleStr) { try { - return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr)); + return Utils.stringBundle.GetStringFromName( + this._getOutputName(aRoleStr)); } catch (x) { return ''; } }, _getLocalizedState: function _getLocalizedState(aState) { let stateUtterances = []; if (aState.contains(States.UNAVAILABLE)) { - stateUtterances.push(gStringBundle.GetStringFromName('stateUnavailable')); + stateUtterances.push( + Utils.stringBundle.GetStringFromName('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. if (Utils.AndroidSdkVersion < 16 && aState.contains(States.CHECKABLE)) { let statetr = aState.contains(States.CHECKED) ? 'stateChecked' : 'stateNotChecked'; - stateUtterances.push(gStringBundle.GetStringFromName(statetr)); + stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr)); } if (aState.contains(States.EXPANDABLE)) { let statetr = aState.contains(States.EXPANDED) ? 'stateExpanded' : 'stateCollapsed'; - stateUtterances.push(gStringBundle.GetStringFromName(statetr)); + stateUtterances.push(Utils.stringBundle.GetStringFromName(statetr)); } if (aState.contains(States.REQUIRED)) { - stateUtterances.push(gStringBundle.GetStringFromName('stateRequired')); + stateUtterances.push( + Utils.stringBundle.GetStringFromName('stateRequired')); } if (aState.contains(States.TRAVERSED)) { - stateUtterances.push(gStringBundle.GetStringFromName('stateTraversed')); + stateUtterances.push( + Utils.stringBundle.GetStringFromName('stateTraversed')); } if (aState.contains(States.HASPOPUP)) { - stateUtterances.push(gStringBundle.GetStringFromName('stateHasPopup')); + stateUtterances.push( + Utils.stringBundle.GetStringFromName('stateHasPopup')); } if (aState.contains(States.SELECTED)) { - stateUtterances.push(gStringBundle.GetStringFromName('stateSelected')); + stateUtterances.push( + Utils.stringBundle.GetStringFromName('stateSelected')); } return stateUtterances; }, _getListUtterance: function _getListUtterance(aAccessible, aRoleStr, aFlags, aItemCount) { let desc = []; let roleStr = this._getLocalizedRole(aRoleStr); @@ -739,17 +742,17 @@ this.BrailleGenerator = { if (cell) { let desc = []; let addHeaders = function addHeaders(aDesc, aHeaders) { if (aHeaders.length > 0) { aDesc.push.apply(aDesc, aHeaders); } }; - desc.push(gStringBundle.formatStringFromName( + desc.push(Utils.stringBundle.formatStringFromName( this._getOutputName('cellInfo'), [cell.columnIndex + 1, cell.rowIndex + 1], 2)); addHeaders(desc, cell.columnHeaders); addHeaders(desc, cell.rowHeaders); braille.push(desc.join(' ')); } @@ -810,20 +813,21 @@ this.BrailleGenerator = { }, _getOutputName: function _getOutputName(aName) { return OutputGenerator._getOutputName(aName) + 'Abbr'; }, _getLocalizedRole: function _getLocalizedRole(aRoleStr) { try { - return gStringBundle.GetStringFromName(this._getOutputName(aRoleStr)); + return Utils.stringBundle.GetStringFromName( + this._getOutputName(aRoleStr)); } catch (x) { try { - return gStringBundle.GetStringFromName( + return Utils.stringBundle.GetStringFromName( OutputGenerator._getOutputName(aRoleStr)); } catch (y) { return ''; } } }, _getLocalizedState: function _getLocalizedState(aState) {
--- a/accessible/src/jsat/Presentation.jsm +++ b/accessible/src/jsat/Presentation.jsm @@ -494,34 +494,45 @@ SpeechPresenter.prototype = { 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 } + }] + } + }; } }; /** * A haptic presenter */ this.HapticPresenter = function HapticPresenter() {}; HapticPresenter.prototype = { __proto__: Presenter.prototype, type: 'Haptic', - PIVOT_CHANGE_PATTHERN: [20], + PIVOT_CHANGE_PATTERN: [40], pivotChanged: function HapticPresenter_pivotChanged(aContext, aReason) { - return { type: this.type, details: { pattern: this.PIVOT_CHANGE_PATTHERN } }; + return { type: this.type, details: { pattern: this.PIVOT_CHANGE_PATTERN } }; } }; /** * A braille presenter */ this.BraillePresenter = function BraillePresenter() {};
--- a/accessible/src/jsat/Utils.jsm +++ b/accessible/src/jsat/Utils.jsm @@ -164,16 +164,23 @@ this.Utils = { get isContentProcess() { delete this.isContentProcess; this.isContentProcess = Services.appinfo.processType == Services.appinfo.PROCESS_TYPE_CONTENT; return this.isContentProcess; }, + get stringBundle() { + delete this.stringBundle; + this.stringBundle = Services.strings.createBundle( + 'chrome://global/locale/AccessFu.properties'); + return this.stringBundle; + }, + getMessageManager: function getMessageManager(aBrowser) { try { return aBrowser.QueryInterface(Ci.nsIFrameLoaderOwner). frameLoader.messageManager; } catch (x) { Logger.logException(x); return null; } @@ -770,28 +777,33 @@ this.PrefCache = function PrefCache(aNam } } branch.addObserver(aName, this, true); }; PrefCache.prototype = { _getValue: function _getValue(aBranch) { - if (!this.type) { - this.type = aBranch.getPrefType(this.name); - } - switch (this.type) { - case Ci.nsIPrefBranch.PREF_STRING: - return aBranch.getCharPref(this.name); - case Ci.nsIPrefBranch.PREF_INT: - return aBranch.getIntPref(this.name); - case Ci.nsIPrefBranch.PREF_BOOL: - return aBranch.getBoolPref(this.name); - default: - return null; + try { + if (!this.type) { + this.type = aBranch.getPrefType(this.name); + } + switch (this.type) { + case Ci.nsIPrefBranch.PREF_STRING: + return aBranch.getCharPref(this.name); + case Ci.nsIPrefBranch.PREF_INT: + return aBranch.getIntPref(this.name); + case Ci.nsIPrefBranch.PREF_BOOL: + return aBranch.getBoolPref(this.name); + default: + return null; + } + } catch (x) { + // Pref does not exist. + return null; } }, observe: function observe(aSubject, aTopic, aData) { this.value = this._getValue(aSubject.QueryInterface(Ci.nsIPrefBranch)); if (this.callback) { try { this.callback(this.name, this.value);
--- a/accessible/tests/mochitest/hittest/a11y.ini +++ b/accessible/tests/mochitest/hittest/a11y.ini @@ -1,9 +1,11 @@ [DEFAULT] support-files = zoom_tree.xul [test_browser.html] +[text_canvas_hitregion.html] +skip-if = os == "android" || appname == "b2g" [test_general.html] [test_menu.xul] [test_zoom.html] [test_zoom_text.html] [test_zoom_tree.xul]
new file mode 100644 --- /dev/null +++ b/accessible/tests/mochitest/hittest/test_canvas_hitregion.html @@ -0,0 +1,88 @@ +<!DOCTYPE html> +<html> +<head> + <title>nsIAccessible::childAtPoint() for canvas from browser tests</title> + <link rel="stylesheet" type="text/css" href="chrome://mochikit/content/tests/SimpleTest/test.css" /> + + <script type="application/javascript" + src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> + + <script type="application/javascript" + src="../common.js"></script> + <script type="application/javascript" + src="../layout.js"></script> + + <script type="application/javascript"> + SpecialPowers.setBoolPref("canvas.hitregions.enabled", true); + + function redrawCheckbox(context, element, x, y) + { + context.save(); + context.font = '10px sans-serif'; + context.textAlign = 'left'; + context.textBaseline = 'middle'; + var metrics = context.measureText(element.parentNode.textContent); + context.beginPath(); + context.strokeStyle = 'black'; + context.rect(x-5, y-5, 10, 10); + context.stroke(); + if (element.checked) { + context.fillStyle = 'black'; + context.fill(); + } + context.fillText(element.parentNode.textContent, x+5, y); + + context.beginPath(); + context.rect(x-7, y-7, 12 + metrics.width+2, 14); + + if (document.activeElement == element) + context.drawFocusIfNeeded(element); + context.addHitRegion({control: element}); + context.restore(); + } + + function doTest() + { + getNode("hittest").scrollIntoView(true); + + var context = document.getElementById("hitcanvas").getContext('2d'); + redrawCheckbox(context, document.getElementById('hitcheck'), 20, 40); + + var hitcanvas = getAccessible("hitcanvas"); + var hitcheck = getAccessible("hitcheck"); + + var [hitX, hitY, hitWidth, hitHeight] = getBounds(hitcanvas); + + var docAcc = getAccessible(document); + var tgtX = hitX+25; + var tgtY = hitY+45; + hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY); + // test if we hit the region associated with the shadow dom checkbox + is(hitAcc, hitcheck, "Hit match at " + tgtX + "," + tgtY + + ". Found: " + prettyName(hitAcc)); + + tgtY = hitY+75; + hitAcc = docAcc.getDeepestChildAtPoint(tgtX, tgtY); + // test that we don't hit the region associated with the shadow dom checkbox + is(hitAcc, hitcanvas, "Hit match at " + tgtX + "," + tgtY + + ". Found: " + prettyName(hitAcc)); + + SpecialPowers.setBoolPref("canvas.hitregions.enabled", false); + SimpleTest.finish(); + } + + SimpleTest.waitForExplicitFinish(); + addA11yLoadEvent(doTest); + </script> +</head> +<body> + + <a target="_blank" + href="https://bugzilla.mozilla.org/show_bug.cgi?id=966591" + title="nsIAccessible::childAtPoint() for canvas hit regions from browser tests">Mozilla Bug 966591</a> + + <canvas id="hitcanvas"> + <input id="hitcheck" type="checkbox"><label for="showA"> Show A </label> + </canvas> +</body> +</html>
--- a/accessible/tests/mochitest/jsat/jsatcommon.js +++ b/accessible/tests/mochitest/jsat/jsatcommon.js @@ -88,26 +88,21 @@ var AccessFuTest = { waitForExplicitFinish: function AccessFuTest_waitForExplicitFinish() { this._waitForExplicitFinish = true; }, finish: function AccessFuTest_finish() { // Disable the console service logging. Logger.test = false; Logger.logLevel = Logger.INFO; - AccessFu.doneCallback = function doneCallback() { - // This is being called once AccessFu has been shut down. - // Detach AccessFu from everything it attached itself to. + // Finish through idle callback to let AccessFu._disable complete. + SimpleTest.executeSoon(function () { AccessFu.detach(); - // and finish the test run. SimpleTest.finish(); - }; - // Tear down accessibility and make AccessFu stop. - SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 0); - SpecialPowers.setIntPref("accessibility.accessfu.activate", 0); + }); }, nextTest: function AccessFuTest_nextTest() { var testFunc; try { // Get the next test function from the iterator. If none left, // StopIteration exception is thrown. testFunc = gIterator.next()[1]; @@ -133,31 +128,31 @@ var AccessFuTest = { Components.utils.import("resource://gre/modules/accessibility/AccessFu.jsm"); AccessFu.attach(getMainChromeWindow(window)); AccessFu.readyCallback = function readyCallback() { // Enable logging to the console service. Logger.test = true; Logger.logLevel = Logger.DEBUG; - // This is being called once accessibility has been turned on. + }; + SpecialPowers.pushPrefEnv({ + 'set': [['accessibility.accessfu.notify_output', 1], + ['dom.mozSettings.enabled', true]] + }, function () { if (AccessFuTest._waitForExplicitFinish) { // Run all test functions asynchronously. AccessFuTest.nextTest(); } else { // Run all test functions synchronously. [testFunc() for (testFunc of gTestFuncs)]; AccessFuTest.finish(); } - }; - - // Invoke the whole thing. - SpecialPowers.setIntPref("accessibility.accessfu.activate", 1); - SpecialPowers.setIntPref("accessibility.accessfu.notify_output", 1); + }); } }; function AccessFuContentTest(aFuncResultPairs) { this.queue = aFuncResultPairs; } AccessFuContentTest.prototype = {
--- a/accessible/tests/mochitest/jsat/test_alive.html +++ b/accessible/tests/mochitest/jsat/test_alive.html @@ -8,53 +8,67 @@ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="../common.js"></script> <script type="application/javascript" src="./jsatcommon.js"></script> <script type="application/javascript"> - function confirmAccessFuStart() { - ok(AccessFu._enabled, "AccessFu was started and enabled."); - AccessFuTest.nextTest(); + function prefStart() { + // Start AccessFu via pref. + SpecialPowers.setIntPref("accessibility.accessfu.activate", 1); + AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest); } // Listen for 'EventManager.stop' and enable AccessFu again. - function onStop() { + function settingsStart() { ok(true, "EventManager was stopped."); isnot(AccessFu._enabled, true, "AccessFu was disabled."); - AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest); - AccessFu._enable(); + AccessFuTest.once([{ + "method": "speak", + "data": "Screen reader started", + "options": { + "enqueue": false + } + }], AccessFuTest.nextTest); + // XXX: Bug 978076 - test start with SettingsManager. + //navigator.mozSettings.createLock().set( + // {'accessibility.screenreader': false}); + AccessFu._enable() } // Make sure EventManager is started again. - function onFinalStart() { - ok(true, "EventManager was started again."); + function settingsStop() { ok(AccessFu._enabled, "AccessFu was enabled again."); - AccessFuTest.finish(); + AccessFuTest.once([{ + "method": "speak", + "data": "Screen reader stopped", + "options": { + "enqueue": false + } + }], AccessFuTest.finish); + // XXX: Bug 978076 - test stop with SettingsManager. + //navigator.mozSettings.createLock().set( + // {'accessibility.screenreader': false}); + AccessFu._disable(); } // Listen for initial 'EventManager.start' and disable AccessFu. - function onInitialStart() { - ok(true, "EventManager was started."); + function prefStop() { + ok(AccessFu._enabled, "AccessFu was started via preference."); AccessFuTest.once_log("EventManager.stop", AccessFuTest.nextTest); - AccessFu._disable(); - } - - function init() { - AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest); + SpecialPowers.setIntPref("accessibility.accessfu.activate", 0); } function doTest() { - AccessFuTest.addFunc(confirmAccessFuStart); - AccessFuTest.addFunc(init); - AccessFuTest.addFunc(onInitialStart); - AccessFuTest.addFunc(onStop); - AccessFuTest.addFunc(onFinalStart); + AccessFuTest.addFunc(prefStart); + AccessFuTest.addFunc(prefStop); + AccessFuTest.addFunc(settingsStart); + AccessFuTest.addFunc(settingsStop); AccessFuTest.waitForExplicitFinish(); AccessFuTest.runTests(); // Will call SimpleTest.finish(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script>
--- a/accessible/tests/mochitest/jsat/test_live_regions.html +++ b/accessible/tests/mochitest/jsat/test_live_regions.html @@ -8,20 +8,26 @@ <script type="application/javascript" src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script> <script type="application/javascript" src="../common.js"></script> <script type="application/javascript" src="./jsatcommon.js"></script> <script type="application/javascript"> - function EventManagerStarted() { + function startAccessFu() { + SpecialPowers.setIntPref("accessibility.accessfu.activate", 1); AccessFuTest.once_log("EventManager.start", AccessFuTest.nextTest); } + function stopAccessFu() { + SpecialPowers.setIntPref("accessibility.accessfu.activate", 0); + AccessFuTest.once_log("EventManager.stop", AccessFuTest.finish); + } + function hide(id) { var element = document.getElementById(id); element.style.display = "none"; } function show(id) { var element = document.getElementById(id); element.style.display = "block"; @@ -240,24 +246,24 @@ } }], action: function action() { updateHTML("to_replace_text", "I am a replaced text"); } }]; function doTest() { - AccessFuTest.addFunc(EventManagerStarted); + AccessFuTest.addFunc(startAccessFu); tests.forEach(function addTest(test) { AccessFuTest.addFunc(function () { AccessFuTest.once(test.expected, AccessFuTest.nextTest); test.action(); }); }); - AccessFuTest.addFunc(AccessFuTest.finish); + AccessFuTest.addFunc(stopAccessFu); AccessFuTest.waitForExplicitFinish(); AccessFuTest.runTests(); } SimpleTest.waitForExplicitFinish(); addA11yLoadEvent(doTest); </script>
--- a/browser/base/content/browser-plugins.js +++ b/browser/base/content/browser-plugins.js @@ -125,17 +125,17 @@ var gPluginHandler = { [right, top], [right, bottom], [centerX, centerY]]; if (right <= 0 || top <= 0) { return false; } - let contentWindow = plugin.ownerDocument.defaultView.top; + let contentWindow = plugin.ownerDocument.defaultView; let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); for (let [x, y] of points) { let el = cwu.elementFromPoint(x, y, true, true); if (el !== plugin) { return false; }
--- a/browser/base/content/test/general/browser.ini +++ b/browser/base/content/test/general/browser.ini @@ -1,25 +1,19 @@ [DEFAULT] support-files = POSTSearchEngine.xml accounts_testRemoteCommands.html alltabslistener.html app_bug575561.html app_subframe_bug575561.html authenticate.sjs - blockNoPlugins.xml - blockPluginHard.xml - blockPluginVulnerableNoUpdate.xml - blockPluginVulnerableUpdatable.xml browser_bug479408_sample.html browser_bug678392-1.html browser_bug678392-2.html - browser_clearplugindata.html - browser_clearplugindata_noage.html browser_registerProtocolHandler_notification.html browser_star_hsts.sjs browser_tab_dragdrop2_frame1.xul bug564387.html bug564387_video1.ogv bug564387_video1.ogv^headers^ bug592338.html bug792517-2.html @@ -60,42 +54,16 @@ support-files = file_fullscreen-window-open.html get_user_media.html head.js healthreport_testRemoteCommands.html moz.png offlineQuotaNotification.cacheManifest offlineQuotaNotification.html page_style_sample.html - plugin_add_dynamically.html - plugin_alternate_content.html - plugin_big.html - plugin_both.html - plugin_both2.html - plugin_bug744745.html - plugin_bug749455.html - plugin_bug752516.html - plugin_bug787619.html - plugin_bug797677.html - plugin_bug820497.html - plugin_clickToPlayAllow.html - plugin_clickToPlayDeny.html - plugin_data_url.html - plugin_hidden_to_visible.html - plugin_outsideScrollArea.html - plugin_overlayed.html - plugin_positioned.html - plugin_small.html - plugin_syncRemoved.html - plugin_test.html - plugin_test2.html - plugin_test3.html - plugin_two_types.html - plugin_unknown.html - pluginCrashCommentAndURL.html print_postdata.sjs redirect_bug623155.sjs test-mixedcontent-securityerrors.html test_bug435035.html test_bug462673.html test_bug628179.html test_bug839103.html test_bug959531.html @@ -106,29 +74,18 @@ support-files = test_no_mcb_on_http_site_img.html test_no_mcb_on_http_site_img.css test_no_mcb_on_http_site_font.html test_no_mcb_on_http_site_font.css test_no_mcb_on_http_site_font2.html test_no_mcb_on_http_site_font2.css xul_tooltiptext.xhtml -[browser_CTP_context_menu.js] -skip-if = toolkit == "gtk2" || toolkit == "gtk3" # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342) -[browser_CTP_crashreporting.js] -run-if = crashreporter -[browser_CTP_data_urls.js] -[browser_CTP_drag_drop.js] -[browser_CTP_hide_overlay.js] -[browser_CTP_multi_allow.js] -[browser_CTP_nonplugins.js] -[browser_CTP_notificationBar.js] -[browser_CTP_outsideScrollArea.js] -[browser_CTP_resize.js] [browser_URLBarSetURI.js] +skip-if = (os == "linux" || os == "mac") && debug # bug 970052, bug 970053 [browser_aboutAccounts.js] skip-if = os == "linux" # Bug 958026 [browser_aboutHealthReport.js] skip-if = os == "linux" # Bug 924307 [browser_aboutHome.js] [browser_aboutSyncProgress.js] [browser_addKeywordSearch.js] [browser_alltabslistener.js] @@ -224,40 +181,31 @@ run-if = toolkit == "cocoa" [browser_bug676619.js] skip-if = os == "mac" # Intermittent failures, bug 925225 [browser_bug678392.js] [browser_bug710878.js] [browser_bug719271.js] [browser_bug724239.js] [browser_bug734076.js] [browser_bug735471.js] -[browser_bug743421.js] -[browser_bug744745.js] [browser_bug749738.js] -[browser_bug752516.js] [browser_bug763468_perwindowpb.js] [browser_bug767836_perwindowpb.js] [browser_bug771331.js] [browser_bug783614.js] -[browser_bug787619.js] -[browser_bug797677.js] -[browser_bug812562.js] [browser_bug816527.js] [browser_bug817947.js] -[browser_bug818118.js] -[browser_bug820497.js] [browser_bug822367.js] [browser_bug832435.js] [browser_bug839103.js] [browser_bug880101.js] [browser_bug882977.js] [browser_bug902156.js] [browser_bug906190.js] [browser_canonizeURL.js] -[browser_clearplugindata.js] [browser_contentAreaClick.js] [browser_contextSearchTabPosition.js] skip-if = os == "mac" # bug 967013, bug 926729 [browser_ctrlTab.js] [browser_customize_popupNotification.js] [browser_datareporting_notification.js] run-if = datareporting [browser_discovery.js] @@ -283,26 +231,19 @@ skip-if = os == "linux" # Intermittent f skip-if = os != "win" # The Fitts Law menu button is only supported on Windows (bug 969376) [browser_middleMouse_inherit.js] [browser_minimize.js] [browser_mixedcontent_securityflags.js] [browser_notification_tab_switching.js] [browser_offlineQuotaNotification.js] [browser_overflowScroll.js] [browser_pageInfo.js] -[browser_pageInfo_plugins.js] [browser_page_style_menu.js] [browser_pinnedTabs.js] [browser_plainTextLinks.js] -[browser_pluginnotification.js] -[browser_pluginplaypreview.js] -[browser_pluginplaypreview2.js] -[browser_pluginCrashCommentAndURL.js] -run-if = crashreporter -[browser_plugins_added_dynamically.js] [browser_popupNotification.js] skip-if = toolkit == "windows" # Disabled on Windows due to frequent failures (bugs 825739, 841341) [browser_popupUI.js] [browser_printpreview.js] [browser_private_browsing_window.js] [browser_private_no_prompt.js] [browser_relatedTabs.js] [browser_removeTabsToTheEnd.js]
deleted file mode 100644 --- a/browser/base/content/test/general/browser_bug752516.js +++ /dev/null @@ -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/. */ - -Components.utils.import("resource://gre/modules/Services.jsm"); - -var gTestBrowser = null; - -function test() { - waitForExplicitFinish(); - registerCleanupFunction(function() { - Services.prefs.clearUserPref("plugins.click_to_play"); - gBrowser.removeCurrentTab(); - window.focus(); - }); - - Services.prefs.setBoolPref("plugins.click_to_play", true); - setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); - - gBrowser.selectedTab = gBrowser.addTab(); - gTestBrowser = gBrowser.selectedBrowser; - let gHttpTestRoot = getRootDirectory(gTestPath).replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); - gTestBrowser.contentWindow.location = gHttpTestRoot + "plugin_bug752516.html"; - - gTestBrowser.addEventListener("load", tabLoad, true); -} - -function tabLoad() { - // Due to layout being async, "PluginBindAttached" may trigger later. - // This forces a layout flush, thus triggering it, and schedules the - // test so it is definitely executed afterwards. - gTestBrowser.contentDocument.getElementById('test').clientTop; - executeSoon(actualTest); -} - -function actualTest() { - let doc = gTestBrowser.contentDocument; - let plugin = doc.getElementById("test"); - ok(!plugin.activated, "Plugin should not be activated"); - ok(PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed, "Doorhanger should not be open"); - - EventUtils.synthesizeMouseAtCenter(plugin, {}, gTestBrowser.contentWindow); - let condition = function() !PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser).dismissed; - waitForCondition(condition, finish, "Waited too long for plugin doorhanger to activate"); -}
deleted file mode 100644 --- a/browser/base/content/test/general/plugin_bug752516.html +++ /dev/null @@ -1,24 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf-8"/> - <style type="text/css"> - div { - padding: 2%; - position: absolute; - top: 0; bottom: 0; - left: 0; right: 0; - text-align: center; - border: 4px solid red; - } - </style> -</head> -<body> - <div id="container"> - <object id="test" type="application/x-test" width="159" height="91"></object> - </div> - <div id="overlay"> - <h1>overlay</h1> - </div> -</body> -</html>
rename from browser/base/content/test/general/blockNoPlugins.xml rename to browser/base/content/test/plugins/blockNoPlugins.xml
rename from browser/base/content/test/general/blockPluginHard.xml rename to browser/base/content/test/plugins/blockPluginHard.xml
rename from browser/base/content/test/general/blockPluginVulnerableNoUpdate.xml rename to browser/base/content/test/plugins/blockPluginVulnerableNoUpdate.xml
rename from browser/base/content/test/general/blockPluginVulnerableUpdatable.xml rename to browser/base/content/test/plugins/blockPluginVulnerableUpdatable.xml
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/plugins/browser.ini @@ -0,0 +1,64 @@ +[DEFAULT] +support-files = + blockNoPlugins.xml + blockPluginHard.xml + blockPluginVulnerableNoUpdate.xml + blockPluginVulnerableUpdatable.xml + browser_clearplugindata.html + browser_clearplugindata_noage.html + head.js + plugin_add_dynamically.html + plugin_alternate_content.html + plugin_big.html + plugin_both.html + plugin_both2.html + plugin_bug744745.html + plugin_bug749455.html + plugin_bug787619.html + plugin_bug797677.html + plugin_bug820497.html + plugin_clickToPlayAllow.html + plugin_clickToPlayDeny.html + plugin_data_url.html + plugin_hidden_to_visible.html + plugin_iframe.html + plugin_outsideScrollArea.html + plugin_overlayed.html + plugin_positioned.html + plugin_small.html + plugin_syncRemoved.html + plugin_test.html + plugin_test2.html + plugin_test3.html + plugin_two_types.html + plugin_unknown.html + plugin_crashCommentAndURL.html + +[browser_bug743421.js] +[browser_bug744745.js] +[browser_bug787619.js] +[browser_bug797677.js] +[browser_bug812562.js] +[browser_bug818118.js] +[browser_bug820497.js] +[browser_clearplugindata.js] +[browser_CTP_context_menu.js] +skip-if = toolkit == "gtk2" || toolkit == "gtk3" # browser_CTP_context_menu.js fails intermittently on Linux (bug 909342) +[browser_CTP_crashreporting.js] +run-if = crashreporter +[browser_CTP_data_urls.js] +[browser_CTP_drag_drop.js] +[browser_CTP_hide_overlay.js] +[browser_CTP_iframe.js] +[browser_CTP_multi_allow.js] +[browser_CTP_nonplugins.js] +[browser_CTP_notificationBar.js] +[browser_CTP_outsideScrollArea.js] +[browser_CTP_resize.js] +[browser_pageInfo_plugins.js] +[browser_pluginnotification.js] +[browser_pluginplaypreview.js] +[browser_pluginplaypreview2.js] +[browser_pluginCrashCommentAndURL.js] +run-if = crashreporter +[browser_plugins_added_dynamically.js]
rename from browser/base/content/test/general/browser_CTP_context_menu.js rename to browser/base/content/test/plugins/browser_CTP_context_menu.js
rename from browser/base/content/test/general/browser_CTP_crashreporting.js rename to browser/base/content/test/plugins/browser_CTP_crashreporting.js
rename from browser/base/content/test/general/browser_CTP_data_urls.js rename to browser/base/content/test/plugins/browser_CTP_data_urls.js
rename from browser/base/content/test/general/browser_CTP_drag_drop.js rename to browser/base/content/test/plugins/browser_CTP_drag_drop.js
rename from browser/base/content/test/general/browser_CTP_hide_overlay.js rename to browser/base/content/test/plugins/browser_CTP_hide_overlay.js
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/plugins/browser_CTP_iframe.js @@ -0,0 +1,102 @@ +let rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir; +const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/"); + +let gTestBrowser = null; +let gNextTest = null; + +Components.utils.import("resource://gre/modules/Services.jsm"); + +function test() { + waitForExplicitFinish(); + registerCleanupFunction(function() { + clearAllPluginPermissions(); + Services.prefs.clearUserPref("extensions.blocklist.suppressUI"); + }); + Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true); + + let newTab = gBrowser.addTab(); + gBrowser.selectedTab = newTab; + gTestBrowser = gBrowser.selectedBrowser; + gTestBrowser.addEventListener("load", pageLoad, true); + + Services.prefs.setBoolPref("plugins.click_to_play", true); + setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY); + + prepareTest(delayTest(runAfterPluginBindingAttached(test1)), gHttpTestRoot + "plugin_iframe.html"); +} + +function finishTest() { + clearAllPluginPermissions(); + gTestBrowser.removeEventListener("load", pageLoad, true); + gBrowser.removeCurrentTab(); + window.focus(); + finish(); +} + +function pageLoad() { + gNextTest(); +} + +function prepareTest(nextTest, url) { + gNextTest = nextTest; + gTestBrowser.contentWindow.location = url; +} + +// Delay executing a test for one load event to wait for frame loads. +function delayTest(nextTest) { + return () => { + gNextTest = nextTest; + } +} + +// Due to layout being async, "PluginBindAttached" may trigger later. +// This wraps a function to force a layout flush, thus triggering it, +// and schedules the function execution so they're definitely executed +// afterwards. +function runAfterPluginBindingAttached(func) { + return () => { + let frame = gTestBrowser.contentDocument.getElementById("frame"); + let doc = frame.contentDocument; + let elems = doc.getElementsByTagName('embed'); + if (elems.length < 1) { + elems = doc.getElementsByTagName('object'); + } + elems[0].clientTop; + executeSoon(func); + }; +} + +// Tests that the overlays are visible and actionable if the plugin is in an iframe. +function test1() { + let frame = gTestBrowser.contentDocument.getElementById("frame"); + let doc = frame.contentDocument; + let plugin = doc.getElementById("test"); + ok(plugin, "Test 1, Found plugin in page"); + + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + ok(overlay.classList.contains("visible"), "Test 1, Plugin overlay should exist, not be hidden"); + let closeIcon = doc.getAnonymousElementByAttribute(plugin, "anonid", "closeIcon") + + EventUtils.synthesizeMouseAtCenter(closeIcon, {}, frame.contentWindow); + let condition = () => !overlay.classList.contains("visible"); + waitForCondition(condition, test2, "Test 1, Waited too long for the overlay to become invisible."); +} + +function test2() { + prepareTest(delayTest(runAfterPluginBindingAttached(test3)), gHttpTestRoot + "plugin_iframe.html"); +} + +function test3() { + let frame = gTestBrowser.contentDocument.getElementById("frame"); + let doc = frame.contentDocument; + let plugin = doc.getElementById("test"); + ok(plugin, "Test 3, Found plugin in page"); + + let overlay = doc.getAnonymousElementByAttribute(plugin, "anonid", "main"); + ok(overlay.classList.contains("visible"), "Test 3, Plugin overlay should exist, not be hidden"); + + EventUtils.synthesizeMouseAtCenter(plugin, {}, frame.contentWindow); + let condition = () => PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser); + waitForCondition(condition, finishTest, "Test 3, Waited too long for the doorhanger to pop up."); +}
rename from browser/base/content/test/general/browser_CTP_multi_allow.js rename to browser/base/content/test/plugins/browser_CTP_multi_allow.js
rename from browser/base/content/test/general/browser_CTP_nonplugins.js rename to browser/base/content/test/plugins/browser_CTP_nonplugins.js
rename from browser/base/content/test/general/browser_CTP_notificationBar.js rename to browser/base/content/test/plugins/browser_CTP_notificationBar.js
rename from browser/base/content/test/general/browser_CTP_outsideScrollArea.js rename to browser/base/content/test/plugins/browser_CTP_outsideScrollArea.js
rename from browser/base/content/test/general/browser_CTP_resize.js rename to browser/base/content/test/plugins/browser_CTP_resize.js
rename from browser/base/content/test/general/browser_bug743421.js rename to browser/base/content/test/plugins/browser_bug743421.js --- a/browser/base/content/test/general/browser_bug743421.js +++ b/browser/base/content/test/plugins/browser_bug743421.js @@ -1,9 +1,10 @@ -const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/general/"; +var rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); var gTestBrowser = null; var gNextTest = null; Components.utils.import("resource://gre/modules/Services.jsm"); function test() { waitForExplicitFinish();
rename from browser/base/content/test/general/browser_bug744745.js rename to browser/base/content/test/plugins/browser_bug744745.js
rename from browser/base/content/test/general/browser_bug787619.js rename to browser/base/content/test/plugins/browser_bug787619.js
rename from browser/base/content/test/general/browser_bug797677.js rename to browser/base/content/test/plugins/browser_bug797677.js
rename from browser/base/content/test/general/browser_bug812562.js rename to browser/base/content/test/plugins/browser_bug812562.js
rename from browser/base/content/test/general/browser_bug818118.js rename to browser/base/content/test/plugins/browser_bug818118.js
rename from browser/base/content/test/general/browser_bug820497.js rename to browser/base/content/test/plugins/browser_bug820497.js
rename from browser/base/content/test/general/browser_clearplugindata.html rename to browser/base/content/test/plugins/browser_clearplugindata.html
rename from browser/base/content/test/general/browser_clearplugindata.js rename to browser/base/content/test/plugins/browser_clearplugindata.js --- a/browser/base/content/test/general/browser_clearplugindata.js +++ b/browser/base/content/test/plugins/browser_clearplugindata.js @@ -1,16 +1,19 @@ /** * Any copyright is dedicated to the Public Domain. * http://creativecommons.org/publicdomain/zero/1.0/ */ +var rootDir = getRootDirectory(gTestPath); +const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); + // Test clearing plugin data using sanitize.js. -const testURL1 = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_clearplugindata.html"; -const testURL2 = "http://mochi.test:8888/browser/browser/base/content/test/general/browser_clearplugindata_noage.html"; +const testURL1 = gHttpTestRoot + "browser_clearplugindata.html"; +const testURL2 = gHttpTestRoot + "browser_clearplugindata_noage.html"; let tempScope = {}; Cc["@mozilla.org/moz/jssubscript-loader;1"].getService(Ci.mozIJSSubScriptLoader) .loadSubScript("chrome://browser/content/sanitize.js", tempScope); let Sanitizer = tempScope.Sanitizer; const pluginHostIface = Ci.nsIPluginHost; var pluginHost = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost);
rename from browser/base/content/test/general/browser_clearplugindata_noage.html rename to browser/base/content/test/plugins/browser_clearplugindata_noage.html
rename from browser/base/content/test/general/browser_pageInfo_plugins.js rename to browser/base/content/test/plugins/browser_pageInfo_plugins.js
rename from browser/base/content/test/general/browser_pluginCrashCommentAndURL.js rename to browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js --- a/browser/base/content/test/general/browser_pluginCrashCommentAndURL.js +++ b/browser/base/content/test/plugins/browser_pluginCrashCommentAndURL.js @@ -1,15 +1,15 @@ /* 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/. */ Cu.import("resource://gre/modules/Services.jsm"); -const CRASH_URL = "http://example.com/browser/browser/base/content/test/general/pluginCrashCommentAndURL.html"; +const CRASH_URL = "http://example.com/browser/browser/base/content/test/plugins/plugin_crashCommentAndURL.html"; const SERVER_URL = "http://example.com/browser/toolkit/crashreporter/test/browser/crashreport.sjs"; function test() { // Crashing the plugin takes up a lot of time, so extend the test timeout. requestLongerTimeout(runs.length); waitForExplicitFinish(); setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
rename from browser/base/content/test/general/browser_pluginnotification.js rename to browser/base/content/test/plugins/browser_pluginnotification.js
rename from browser/base/content/test/general/browser_pluginplaypreview.js rename to browser/base/content/test/plugins/browser_pluginplaypreview.js
rename from browser/base/content/test/general/browser_pluginplaypreview2.js rename to browser/base/content/test/plugins/browser_pluginplaypreview2.js
rename from browser/base/content/test/general/browser_plugins_added_dynamically.js rename to browser/base/content/test/plugins/browser_plugins_added_dynamically.js --- a/browser/base/content/test/general/browser_plugins_added_dynamically.js +++ b/browser/base/content/test/plugins/browser_plugins_added_dynamically.js @@ -1,9 +1,10 @@ -const gTestRoot = "http://mochi.test:8888/browser/browser/base/content/test/general/"; +var rootDir = getRootDirectory(gTestPath); +const gTestRoot = rootDir.replace("chrome://mochitests/content/", "http://mochi.test:8888/"); let gTestBrowser = null; let gNextTest = null; let gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost); Components.utils.import("resource://gre/modules/Services.jsm"); // Let's do the XPCNativeWrapper dance!
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/plugins/head.js @@ -0,0 +1,110 @@ +Components.utils.import("resource://gre/modules/XPCOMUtils.jsm"); + +XPCOMUtils.defineLazyModuleGetter(this, "Promise", + "resource://gre/modules/commonjs/sdk/core/promise.js"); +XPCOMUtils.defineLazyModuleGetter(this, "Task", + "resource://gre/modules/Task.jsm"); +XPCOMUtils.defineLazyModuleGetter(this, "PlacesUtils", + "resource://gre/modules/PlacesUtils.jsm"); + +function whenDelayedStartupFinished(aWindow, aCallback) { + Services.obs.addObserver(function observer(aSubject, aTopic) { + if (aWindow == aSubject) { + Services.obs.removeObserver(observer, aTopic); + executeSoon(aCallback); + } + }, "browser-delayed-startup-finished", false); +} + +function findChromeWindowByURI(aURI) { + let windows = Services.wm.getEnumerator(null); + while (windows.hasMoreElements()) { + let win = windows.getNext(); + if (win.location.href == aURI) + return win; + } + return null; +} + +function waitForCondition(condition, nextTest, errorMsg) { + var tries = 0; + var interval = setInterval(function() { + if (tries >= 30) { + ok(false, errorMsg); + moveOn(); + } + var conditionPassed; + try { + conditionPassed = condition(); + } catch (e) { + ok(false, e + "\n" + e.stack); + conditionPassed = false; + } + if (conditionPassed) { + moveOn(); + } + tries++; + }, 100); + var moveOn = function() { clearInterval(interval); nextTest(); }; +} + +function getTestPlugin(aName) { + var pluginName = aName || "Test Plug-in"; + var ph = Cc["@mozilla.org/plugin/host;1"].getService(Ci.nsIPluginHost); + var tags = ph.getPluginTags(); + + // Find the test plugin + for (var i = 0; i < tags.length; i++) { + if (tags[i].name == pluginName) + return tags[i]; + } + ok(false, "Unable to find plugin"); + return null; +} + +// call this to set the test plugin(s) initially expected enabled state. +// it will automatically be reset to it's previous value after the test +// ends +function setTestPluginEnabledState(newEnabledState, pluginName) { + var plugin = getTestPlugin(pluginName); + var oldEnabledState = plugin.enabledState; + plugin.enabledState = newEnabledState; + SimpleTest.registerCleanupFunction(function() { + getTestPlugin(pluginName).enabledState = oldEnabledState; + }); +} + +// after a test is done using the plugin doorhanger, we should just clear +// any permissions that may have crept in +function clearAllPluginPermissions() { + let perms = Services.perms.enumerator; + while (perms.hasMoreElements()) { + let perm = perms.getNext(); + if (perm.type.startsWith('plugin')) { + Services.perms.remove(perm.host, perm.type); + } + } +} + +function updateBlocklist(aCallback) { + var blocklistNotifier = Cc["@mozilla.org/extensions/blocklist;1"] + .getService(Ci.nsITimerCallback); + var observer = function() { + Services.obs.removeObserver(observer, "blocklist-updated"); + SimpleTest.executeSoon(aCallback); + }; + Services.obs.addObserver(observer, "blocklist-updated", false); + blocklistNotifier.notify(null); +} + +var _originalTestBlocklistURL = null; +function setAndUpdateBlocklist(aURL, aCallback) { + if (!_originalTestBlocklistURL) + _originalTestBlocklistURL = Services.prefs.getCharPref("extensions.blocklist.url"); + Services.prefs.setCharPref("extensions.blocklist.url", aURL); + updateBlocklist(aCallback); +} + +function resetBlocklist() { + Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL); +}
rename from browser/base/content/test/general/plugin_add_dynamically.html rename to browser/base/content/test/plugins/plugin_add_dynamically.html
rename from browser/base/content/test/general/plugin_alternate_content.html rename to browser/base/content/test/plugins/plugin_alternate_content.html
rename from browser/base/content/test/general/plugin_big.html rename to browser/base/content/test/plugins/plugin_big.html
rename from browser/base/content/test/general/plugin_both.html rename to browser/base/content/test/plugins/plugin_both.html
rename from browser/base/content/test/general/plugin_both2.html rename to browser/base/content/test/plugins/plugin_both2.html
rename from browser/base/content/test/general/plugin_bug744745.html rename to browser/base/content/test/plugins/plugin_bug744745.html
rename from browser/base/content/test/general/plugin_bug749455.html rename to browser/base/content/test/plugins/plugin_bug749455.html
rename from browser/base/content/test/general/plugin_bug787619.html rename to browser/base/content/test/plugins/plugin_bug787619.html
rename from browser/base/content/test/general/plugin_bug797677.html rename to browser/base/content/test/plugins/plugin_bug797677.html
rename from browser/base/content/test/general/plugin_bug820497.html rename to browser/base/content/test/plugins/plugin_bug820497.html
rename from browser/base/content/test/general/plugin_clickToPlayAllow.html rename to browser/base/content/test/plugins/plugin_clickToPlayAllow.html
rename from browser/base/content/test/general/plugin_clickToPlayDeny.html rename to browser/base/content/test/plugins/plugin_clickToPlayDeny.html
rename from browser/base/content/test/general/pluginCrashCommentAndURL.html rename to browser/base/content/test/plugins/plugin_crashCommentAndURL.html
rename from browser/base/content/test/general/plugin_data_url.html rename to browser/base/content/test/plugins/plugin_data_url.html
rename from browser/base/content/test/general/plugin_hidden_to_visible.html rename to browser/base/content/test/plugins/plugin_hidden_to_visible.html
new file mode 100644 --- /dev/null +++ b/browser/base/content/test/plugins/plugin_iframe.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> +<head> +<meta charset="utf-8"> +</head> +<body> +<iframe id="frame" with="400" height="400" src="plugin_test.html"> +</body> +</html>
rename from browser/base/content/test/general/plugin_outsideScrollArea.html rename to browser/base/content/test/plugins/plugin_outsideScrollArea.html
rename from browser/base/content/test/general/plugin_overlayed.html rename to browser/base/content/test/plugins/plugin_overlayed.html
rename from browser/base/content/test/general/plugin_positioned.html rename to browser/base/content/test/plugins/plugin_positioned.html
rename from browser/base/content/test/general/plugin_small.html rename to browser/base/content/test/plugins/plugin_small.html
rename from browser/base/content/test/general/plugin_syncRemoved.html rename to browser/base/content/test/plugins/plugin_syncRemoved.html
rename from browser/base/content/test/general/plugin_test.html rename to browser/base/content/test/plugins/plugin_test.html
rename from browser/base/content/test/general/plugin_test2.html rename to browser/base/content/test/plugins/plugin_test2.html
rename from browser/base/content/test/general/plugin_test3.html rename to browser/base/content/test/plugins/plugin_test3.html
rename from browser/base/content/test/general/plugin_two_types.html rename to browser/base/content/test/plugins/plugin_two_types.html
rename from browser/base/content/test/general/plugin_unknown.html rename to browser/base/content/test/plugins/plugin_unknown.html
--- a/browser/base/content/test/social/head.js +++ b/browser/base/content/test/social/head.js @@ -320,17 +320,17 @@ function setAndUpdateBlocklist(aURL, aCa Services.prefs.setCharPref("extensions.blocklist.url", aURL); updateBlocklist(aCallback); } function resetBlocklist(aCallback) { // XXX - this has "forked" from the head.js helpers in our parent directory :( // But let's reuse their blockNoPlugins.xml. Later, we should arrange to // use their head.js helpers directly - let noBlockedURL = "http://example.com/browser/browser/base/content/test/general/blockNoPlugins.xml"; + let noBlockedURL = "http://example.com/browser/browser/base/content/test/plugins/blockNoPlugins.xml"; setAndUpdateBlocklist(noBlockedURL, function() { Services.prefs.setCharPref("extensions.blocklist.url", _originalTestBlocklistURL); if (aCallback) aCallback(); }); } function setManifestPref(name, manifest) {
--- a/browser/base/moz.build +++ b/browser/base/moz.build @@ -10,16 +10,17 @@ MOCHITEST_MANIFESTS += [ MOCHITEST_CHROME_MANIFESTS += [ 'content/test/chrome/chrome.ini', ] BROWSER_CHROME_MANIFESTS += [ 'content/test/general/browser.ini', 'content/test/newtab/browser.ini', + 'content/test/plugins/browser.ini', 'content/test/social/browser.ini', ] DEFINES['MOZ_APP_VERSION'] = CONFIG['MOZ_APP_VERSION'] DEFINES['APP_LICENSE_BLOCK'] = '%s/content/overrides/app-license.html' % SRCDIR if CONFIG['MOZ_WIDGET_TOOLKIT'] in ('windows', 'gtk2', 'gtk3', 'cocoa'): DEFINES['HAVE_SHELL_SERVICE'] = 1
--- a/browser/branding/aurora/pref/firefox-branding.js +++ b/browser/branding/aurora/pref/firefox-branding.js @@ -23,11 +23,12 @@ pref("app.update.url.details", "https:// // The number of days a binary is permitted to be old // without checking for an update. This assumes that // app.update.checkInstallTime is true. pref("app.update.checkInstallTime.days", 2); // Search codes belong only in builds with official branding pref("browser.search.param.yahoo-fr", ""); +pref("browser.search.param.yahoo-fr-metro", ""); pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused pref("browser.search.param.yahoo-fr-ja", ""); pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/branding/nightly/pref/firefox-branding.js +++ b/browser/branding/nightly/pref/firefox-branding.js @@ -20,11 +20,12 @@ pref("app.update.url.details", "https:// // The number of days a binary is permitted to be old // without checking for an update. This assumes that // app.update.checkInstallTime is true. pref("app.update.checkInstallTime.days", 2); // Search codes belong only in builds with official branding pref("browser.search.param.yahoo-fr", ""); +pref("browser.search.param.yahoo-fr-metro", ""); pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused pref("browser.search.param.yahoo-fr-ja", ""); pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/branding/official/pref/firefox-branding.js +++ b/browser/branding/official/pref/firefox-branding.js @@ -19,11 +19,13 @@ pref("app.update.url.manual", "https://w pref("app.update.url.details", "https://www.mozilla.org/%LOCALE%/firefox/notes"); // The number of days a binary is permitted to be old // without checking for an update. This assumes that // app.update.checkInstallTime is true. pref("app.update.checkInstallTime.days", 63); pref("browser.search.param.ms-pc", "MOZI"); +pref("browser.search.param.ms-pc-metro", "MOZW"); pref("browser.search.param.yahoo-fr", "moz35"); +pref("browser.search.param.yahoo-fr-metro", "mozilla_metro_search"); pref("browser.search.param.yahoo-fr-cjkt", "moz35"); // now unused pref("browser.search.param.yahoo-fr-ja", "mozff");
--- a/browser/branding/unofficial/pref/firefox-branding.js +++ b/browser/branding/unofficial/pref/firefox-branding.js @@ -20,11 +20,12 @@ pref("app.update.url.details", "https:// // The number of days a binary is permitted to be old // without checking for an update. This assumes that // app.update.checkInstallTime is true. pref("app.update.checkInstallTime.days", 2); // Search codes belong only in builds with official branding pref("browser.search.param.yahoo-fr", ""); +pref("browser.search.param.yahoo-fr-metro", ""); pref("browser.search.param.yahoo-fr-cjkt", ""); // now unused pref("browser.search.param.yahoo-fr-ja", ""); pref("browser.search.param.yahoo-f-CN", "");
--- a/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js +++ b/browser/devtools/debugger/test/browser_dbg_chrome-debugging.js @@ -7,16 +7,22 @@ const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html"; let gClient, gThreadClient; let gAttached = promise.defer(); let gNewGlobal = promise.defer() let gNewChromeSource = promise.defer() +let { DevToolsLoader } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +let loader = new DevToolsLoader(); +loader.invisibleToDebugger = true; +loader.main("devtools/server/main"); +let DebuggerServer = loader.DebuggerServer; + function test() { if (!DebuggerServer.initialized) { DebuggerServer.init(() => true); DebuggerServer.addBrowserActors(); } let transport = DebuggerServer.connectPipe(); gClient = new DebuggerClient(transport); @@ -84,9 +90,12 @@ function resumeAndCloseConnection() { registerCleanupFunction(function() { removeTab(gBrowser.selectedTab); gClient = null; gThreadClient = null; gAttached = null; gNewGlobal = null; gNewChromeSource = null; + + loader = null; + DebuggerServer = null; });
--- a/browser/locales/en-US/searchplugins/bingmetrofx.xml +++ b/browser/locales/en-US/searchplugins/bingmetrofx.xml @@ -5,18 +5,18 @@ <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> <ShortName>Bing</ShortName> <Description>Bing. Search by Microsoft.</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16">data:image/x-icon;base64,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</Image> <Image width="74" height="74">data:image/png;base64,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</Image> <Url type="application/x-suggestions+json" template="http://api.bing.com/osjson.aspx"> <Param name="query" value="{searchTerms}"/> - <Param name="form" value="MOZW"/> + <Param name="form" value="OSDJAS"/> <Param name="language" value="{moz:locale}"/> </Url> <Url type="text/html" method="GET" template="http://www.bing.com/search"> <Param name="q" value="{searchTerms}"/> - <MozParam name="pc" condition="pref" pref="ms-pc"/> - <Param name="form" value="MOZW"/> + <MozParam name="pc" condition="pref" pref="ms-pc-metro"/> + <Param name="form" value="MOZWSB"/> </Url> <SearchForm>http://www.bing.com/search</SearchForm> </SearchPlugin>
--- a/browser/locales/en-US/searchplugins/googlemetrofx.xml +++ b/browser/locales/en-US/searchplugins/googlemetrofx.xml @@ -2,17 +2,17 @@ - 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/. --> <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> <ShortName>Google</ShortName> <Description>Google Search</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAB9AQAAJgAAACAgAAAAAAAA8gIAAKMBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAFESURBVDjLpZNJSwNBEIXnt4lE4kHxovgT9BDwJHqPy0HEEOJBiAuCRg+KUdC4QS4KrpC4gCBGE3NQ48JsnZ6eZ3UOM6gjaePhQU93v6+qq2q0pqgeJj2S8EdJT1hr0OxBtKCD5iEd8QxDYpvhvOBAuMDKURX9C9aPu4GA1GEVkzvMg10UBfYveWAWgYAP00V01fa+R9M2bA51wJvhIn3qR+ybt3D3JNQBE5sMjCIOLFpoHzOwdsLRO22qA6R6kiZiWwxUvy/PUQZIhYZ1vFM9cvcOOsYNdcBgysISdSJBnZjJMlR0Fw8vAp0xoz5gao/h+NZBy4i/10XGwrPA+hmvDyhVRG2Avu/LwcrkFADZa16L1h330w1RNgc3DiJzCpPYRm1bpveXX11clQR28xwblHpk1vq1iP/5mcoS0CoXDZiL0vsJ+dzfl+3T/VYAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAK5SURBVFjDxVfrSxRRFJ9/Jta/oyWjF5XQm6D6EkHRgygIIgjUTcueVgqVWSRRkppEUQYWWB8ye1iGWilWlo/Ude489s7M6Zw7D9dlt53dmd29cFiWvXvO77x+51xpaaUsoSxBaUWZQ4ECy5xji2xKZDyCMlMEw6lCNiOSgwZKJK1SkcKeSealfP64t0mBjl4Ow39MkDUL0p2RSROOtqhZdeUEYM1pBl39XCg/fEeFtWcY7G9W4csvUxjlBkCsQ4Nt9QyWVfvT6RsAKXw3aoDGATZeYIt+W1kjw7cJG0RctWDTRebbKd8A6h5pwsDb70ba3w/eUr3wt/cmwgfw6Yft4TNMQaY7o1P2ncm4FT4ANQH/jQBJ2xv7kqIXEADDql8eS3+n8bku7oxNm+EDIM/dU92upb3T/NJGeaNbDx/AsbsLRUY5Xn92caWXY5d8RV6gWllxSg4fAEnTC90DQW13BLlgXR2D3dcUeDVkwOthA1bXspxILWcm3HdThcfvufB26LcJpkOEAz9NKI/lzqpSEC7feol5EWnpSeSlIxCALUkApmULdjUqxQVAQnl3D/X/yQda4QBEq2TYc12By091MQ17Bg3R88nHKlQbVmHvj89awNBLYrwT9zXY2aBAxTkGFdiSxP/Jp6FLDw+AS7GfsdJTJ2EqSO5khD43nGfBARy/ZxOQgZHe7GPM1jzUvChUtmnBAXQPcKGMJp3fdFGq6NByEhiAO4b/YptFfQJwNyQ/bZkVQGcf90Ja25ndIyrKBOa/f8wIpwi3X1G8UcxNu7ozUS7tiH0jBswwS3RIaF1w6LYKU/ML2+8sGnjygQswtKrVIy/Qd9qQP6LnO64q4fPAKpxyZIymHo1jWk6p1ag2BsdNwQMHcC+M5kHFJX+YlPxpVlbCx2mZ5DzPI04k4kUwHHdskU3pH76iftG8yWlkAAAAAElFTkSuQmCC</Image> -<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpBN0E5NEYwRUYzMDQxMUUyQjUzMEMyNEUyNjY3NEQyNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpBN0E5NEYwRkYzMDQxMUUyQjUzMEMyNEUyNjY3NEQyNyI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkE3QTk0RjBDRjMwNDExRTJCNTMwQzI0RTI2Njc0RDI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkE3QTk0RjBERjMwNDExRTJCNTMwQzI0RTI2Njc0RDI3Ii8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2BTc4b7gAAA3xJREFUeNrs2WtIU1EcAPBz7r17XKdrEVNpc4qGsqz5IFOhUMikB2JIEvQUoi%2BRHzT6sIiiIrOIiIK%2B9PhSSZAVEfUlUb9VYhphqDOdZpqv%2BWxzj3t2OjclyUcQeefuOOfDOGyw7Xf%2F5%2FzP%2F38v3FQ6AUJ3MCCkB%2BVRHuVRHuVRHuVRHuVRHuVRHuVRHuVRnix5eLn%2FGA4qHlxuHgwSHpZyceEV58Fg3ntcYH4m0cTszFClJTAxaxgt%2F8cVsfWja888zTZBimsnOS9MBcuL1WYjc%2BWp5%2B4rZIpmy4tUqXGsTwBnHk232AXHOEZ%2BeR4MLAMqj%2FH5aYrS265PHYLTjVu7hRO3nG19SMEBa7EaISCdTXLe9s2K7ESuqVMYnZxLEh4fqHziIRNdGDyQp5Txsb4nS%2Fz3w5PzE%2BDnLqFjAJFJnkXOPLOBJa967SIZ4m2bmEu0vPyLMkssy7Hz3xwYE0M6OOGXMa%2FZLoYogodbUxTzPuKVYkhfNPhkzHtY652ZlBWqIzRzS5RjwLYU7kMXqq7zSpu612Zapfv2%2FhG%2FC%2BGsRI4EMNPM2YfwDzc2RDKn9vFOD7DemfZIGzwAA%2FDwOSmWK8xWJJsYPwZmI8tCsmjR8ZtOAYVEUdbeI1ztETehXgdfX4ggk%2Fc2IQC2QLezv4%2B%2FomxlTBQTaryRcVzbIoYxUgsfnNRsWZBO5bc4IQTxBsYSz5n0bJQOxuln86dGDa8f5W%2B8hFVvvHLl5aYrSgvUqzXg%2BTtvQ7vQO4QmXZis0ZIdykM5KgItK1B7faC6XiqhhJmztEh1OFfVZEfWe67RBWUnkVcc5EnfQDqj3eemxqawnPZeZjJHbCQ9nr6%2FiI2M%2Bibf2appMiFCyzpOZqllV4aYNuzDyDGxZFhqGn1fHXimLZQZL0rH%2FOromL%2FfThidEkvqjm9IZjxbv3%2BmFcrLWDL7a8PheiPb%2BEXoHfTLjFdV63GJHTk4v5%2Ffm6tc2BCRg%2BHiEX5yGl967JZlzbkhgbtcwkevEpenYwrXtQid3xEpqdVKmGRg81O5tn5UUeXuG%2FbLkkcGkeSmczkbFclGVhcOOQjGXXhgzP%2BxW6hpRq1dgqT3gAPUMfxflQpXdu%2FhIL46wX4THq44bzaGcJlNQfYADC%2FrhgueB2AgtPce5VEe5VEe5VEe5VEe5VEe5VEe5VEe5VHeP4yfAgwAufYl8QJfZAAAAAAASUVORK5CYII%3D</Image> +<Image width="74" height="74">data:image/png;base64,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</Image> <Url type="application/x-suggestions+json" method="GET" template="https://www.google.com/complete/search?client=metrofirefox&q={searchTerms}"/> <Url type="text/html" method="GET" template="https://www.google.com/search"> <Param name="q" value="{searchTerms}"/> <Param name="ie" value="utf-8"/> <Param name="oe" value="utf-8"/> <Param name="client" value="metrofirefox"/> </Url> <SearchForm>https://www.google.com/</SearchForm>
--- a/browser/locales/en-US/searchplugins/wikipediametrofx.xml +++ b/browser/locales/en-US/searchplugins/wikipediametrofx.xml @@ -2,17 +2,17 @@ - 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/. --> <SearchPlugin xmlns="http://www.mozilla.org/2006/browser/search/"> <ShortName>Wikipedia (en)</ShortName> <Description>Wikipedia, the free encyclopedia</Description> <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16">data:image/x-icon;base64,AAABAAIAEBAAAAAAAAA4AQAAJgAAACAgAAAAAAAAJAMAAGQBAACJUE5HDQoaCgAAAA1JSERSAAAAEAAAABAIBgAAAB/z/2EAAAEFSURBVDjLxZPRDYJAEESJoQjpgBoM/9IBtoAl4KcUQQlSAjYgJWAH0gPmyNtkzEEuxkQTPzawc3Ozc3MQTc/JfVPR/wW6a+eKQ+Hyfe54B2wvrfXVqXLDfTCMd3j0VHksrTcH9bl2aZq+BCgEwCCPj9E4TdPYGj0C9CYAKdkmBrIIxiIYbvpbb2sSl8AiA+ywAbJE5YLpCImLU/WRDyIAWRgu4k1s4v50ODru4haYSCk4ntkuM0wcMAINXiPKTJQ9CfgB40phBr8DyFjGKkKEhYhCY4iCDgpAYAM2EZBlhJnsZxQUYBNkSkfBvjDd0ttPeR0mxREQ+OhfYOJ6EmL+l/qzn2kGli9cAF3BOfkAAAAASUVORK5CYIKJUE5HDQoaCgAAAA1JSERSAAAAIAAAACAIBgAAAHN6evQAAAIKSURBVFjD7ZdBSgNRDIYLguAB7FLwAkXwBl0JgiDYjQcY8ARduBJKu3I5C0EoWDxAT9AL9AK9QBeCIHQlCM/3DZOSmeZNZ2r1bQyEGV7yXv7kJZlJq6XIOXfs+crzwPPTnvnR863n05ZFufDD/T595Q4eauM37u/pWYwfeX53cegcABcuHg0AkEQE8AKAu4gAXv8BrAEMh0PXbrddt9t1vV4v406nk62laeqm02n2LjKYIuK5WCyyfeiLDF32yLn6TJ5mBFarlev3+9nBMMqsabkYhmezWcEd2ctTE/tYBwhgt14BhtmAV2VaLpdrAHioCW+VdwWy9IMAUBQjJcQFTwGqvcTD+Xy+oc8askZJyAYrnKEokCeWLpQkSSZvBIANYgSDVVEQQJaeyHQu1QIgiQNb6AmrTtaQ9+RFSLa1D4iXgfsrVITloeSFFZlaAEjAUMaXo2DJWQtVRe1OKF5aJUkf0NdglXO5VzQGoI2USwwD3LEl590CtdO3QBoT5WSFV+Q63Oha17ITgMlkslGSGBWPdeNiDR2SL1B6zQFINmOAkFOW5eTSURCdvX6OdUlapaWjsKX0dgOg26/VWHSUKhrPz35ISKwq76R9Wx+kKgC1f0o5mISsypUG3kPj2L/lDzKYvEUwzoh2JtPRdQQAo1jD6afne88H1oTMeH6ZK+x7PB/lQ/CJtvkNEgDh1dr/bVYAAAAASUVORK5CYII=</Image> -<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw%2FeHBhY2tldCBiZWdpbj0i77u%2FIiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8%2BIDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFOUFERjZERUY0MkExMUUyQjUzMEMyNEUyNjY3NEQyNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFOUFERjZERkY0MkExMUUyQjUzMEMyNEUyNjY3NEQyNyI%2BIDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU5QURGNkRDRjQyQTExRTJCNTMwQzI0RTI2Njc0RDI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU5QURGNkRERjQyQTExRTJCNTMwQzI0RTI2Njc0RDI3Ii8%2BIDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY%2BIDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8%2B0WY7JQAAAuJJREFUeNrs2j1IamEYB3BTTLAQ%2BqKhgkgJbSilhqAGlyYzUiRqKSmCcKwlnFqkIXERggSjkGgMpxoikNAlcwpSCJIoKroJFZWCt3P%2FdOAgd%2Fa9F%2BP%2FDHJ8zgf8fN7zPs9gnSRJqp8batWPDvLII4888sgjjzzyyCOPPPLII4888sgjjzzyyCOPvP%2FK29zcHBkZsdlsQ0NDDofj8PBQTprN5sHBwdHR0YODg3K5vLGxgWt6e3tdLtev71hYWOjv7%2B%2Fr6xseHsb1VfZJVYrX19ejoyOdTodn7u%2FvF4tFJF9eXpaXl5Fxu90fHx%2FIvL29gWGxWG5ubn5%2FR6FQALirqyubzeKsVNVQVfdxXq8XmJWVla%2BvLznz%2BPjY3d3d1NR0dnaGr%2Bl0uqOj4%2BTkRLnl%2Bvq6s7Nze3tbEhBV5iUSifr6egCurq6UZCgUgnlpaQnHs7OzY2NjlbcEg0H4Ufwa4CEmJiaACQQCSub%2B%2Fh6rsbGxcXd312QyJZNJ5RRW78DAwPr6uiQmqs%2FDG4gCGo3Gp6cnJRkOh2HW6%2FV%2Bv19Zt4h4PN7T04P1WTO89%2Fd3u90OTCQSUZKgooBIHh8fV17sdDp9Pp8kLFQiHhqLxSCxWq2VO6HH45F3HSWTyWSwqWCzqTEeuhlaGTBwyhkY5N2%2Fra3t4uJCTs7Pz09OTkoiQ8jU0tLSMjMzg4O9vb3Pz08cRKPRqamp1dVVrNKdnR1kbm9vT09P5%2BbmxI4tgn62h4cH1Eqj0aRSqVwuB3A%2Bn0cPbG5ubm1tfX5%2B3trawnxTKpWEVk%2BztrYm4ldDG8A4gjaI6uEToxk6fkNDAzZJFA0qtAeUDsKarB7i8vKyvb1dq9UaDIbz83M5CRW%2BqtVqDKLwS4JDJfTpi4uLyrwiB5oemgGSGFYk8SGWh6KNj4%2Fj3atMYuCcnp6%2Bu7v7B7w6%2FmWOPPLII4888sgjjzzyyCOPPPLII4888sgjjzzyyCPv7%2FgjwAC5b9U654qBRwAAAABJRU5ErkJggg%3D%3D</Image> +<Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA3NpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDIxIDc5LjE1NDkxMSwgMjAxMy8xMC8yOS0xMTo0NzoxNiAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDo5ZWJkNTlmMy02ZDIzLTRjZWUtOWQyOS01OWY4ODY2OTRmNzMiIHhtcE1NOkRvY3VtZW50SUQ9InhtcC5kaWQ6NTA2MTE5RkU5QjQwMTFFM0IwODREMENBREVCMTMxOUIiIHhtcE1NOkluc3RhbmNlSUQ9InhtcC5paWQ6NTA2MTE5RkQ5QjQwMTFFM0IwODREMENBREVCMTMxOUIiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENDIChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6MGIwYjJiY2EtNDlhOS00ZTNmLThiMzAtYTViMGFjZTQ3OTVjIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjllYmQ1OWYzLTZkMjMtNGNlZS05ZDI5LTU5Zjg4NjY5NGY3MyIvPiA8L3JkZjpEZXNjcmlwdGlvbj4gPC9yZGY6UkRGPiA8L3g6eG1wbWV0YT4gPD94cGFja2V0IGVuZD0iciI/PpbYde4AAATqSURBVHja7JpZKG1fHMeveYhMIXPodAxRElFmXlAyTw+eSBGivBiSPFCmPDhekJDiAZEiUaIQh8wiccpM5lm43+6u9d+dc/a5HMf/urf1e1p7re9e+/ux9t6/39qH0tvb249/N5R//NNB8SgexaN4FI/iUTyKR/EoHsWjeBSP4lE8ikfxKN47Q/X9Uk9Pz+fnZx6PZ2VlZWBgoKmp+fj4eHNzc3d3d3V1tb6+fnZ2trCw0NfXV1hYaGdn5+zsbGRkBBnOury8PDk52djY2NvbGxoagj4uLs7W1tbBwQFT6erqYqr9/f3Nzc2dnZ3+/v6Hh4fY2Fh7e3s+n49JtLW1b29vce7i4qKSktL09PR7Tb+9O3A9gHHNo6KiEhAQAJcjIyMeHh5SNUD18fERiUQrKytoSAqA4efnt7u7yyUwMzNLTEx8v+cP4DGxvLwcGBgodtXMzEwxGVYyJCSErcnIyBDTYFXZmo6ODjEB/lj+/v7MqIaGxuDg4EfdfhiPCdxUxJaamtrT05OkBub09PSIrKWlRVLT3t7OjHZ1dUm9EBEMDAzI4VNOPKFQ+N/bSVl5bW1NqkwgEBAZ7lhJQXp6OoZSUlK4LlRRUQFBaGiofD7lxEOw76usrCwumaWlJZGNjo6yhy4uLlR+xfX1NdfpTk5OOHF+fv7/xhsbGyO+8WDgFSpV1tTUxLWAzNJVVlZyXWJychICd3d3uU3Kjyf2BFZVVUnVvLy8GBsbE9nExATTjzSAQ0NDQxnz456U+6lTAB57ZSwsLLhk1dXVRIbXPdMZExODw7a2Nq6zGH4TE5PPOPwUHt6NSMrEemdnp1TZ/f09+xUK3+hBA2ldxuT5+fnQ1NfX/zE8REFBAfHt5ubGJSstLSWyhISE+Ph4NIaHh7n0SImoAVRVVVG+/Em8w8NDdu5GuSRVhioMdtlKX19fGdM2NzdDk5eX90l7n8VjijViOioqikuWm5vLruBQo8qY08bGBrKDg4M/jzczM8NeFtTEUmXHx8eob0ihg+qZa8KpqSlowsPDP+9NAXgIdg2dk5PDJSsuLiaysLAw2QUDNh/fBa+7u5u9LeBK8bW1tex1XlpaktRgu4AhV1dXhRhTDB7C1NSU+AaGpABbPuzr2HgRERGSsuzsbAxhy/e98MrLy4lvbAslBWlpaRhCNkOlQpSrq6tsDXYeKND19fUV5UpheOfn5+rq6sR3T08Pe/To6Aidjo6OaCclJXG9aRsbG9FZU1Pz7fAQqampXNVzdHQ0yYpzc3PsW3RjY4PIzM3N0YNi6DviIZWxfc/OzjL9W1tbOAwICCBKtNlFDNM5Pj4udVP/XfAQ5NsBAumeDbO9vU1k2DdIpkrm48rnU/kX4g0ODop9pzo9PUUjOTlZTOnl5UVkhYWFuCHRCA4OVqwfBeMh7O3tie+ysrLIyEg0kBXEZKiniQyPHMDQEAqF3x2voaFB7DtaSUmJVKWLiwtb5u3trXAzisfDXk5HR4eYRpZ7fX39ba2D6O3t/QvwENjIENOtra0ylDwej5FZW1t/hZMvwROJRIxpPp8vWwl4RllXV/fX4CGCgoJgemRk5PcOfsXd3d1X2FD9op9mioqKUIIxkLJDIBBgy6+lpfUVNpTe6L+KUzyKR/EoHsWjeBSP4lE8ikfxKB7Fo3gUj+JRvHfFTwEGAAgMbrUkfQalAAAAAElFTkSuQmCC</Image> <Url type="application/x-suggestions+json" method="GET" template="http://en.wikipedia.org/w/api.php"> <Param name="action" value="opensearch"/> <Param name="search" value="{searchTerms}"/> </Url> <Url type="text/html" method="GET" template="http://en.wikipedia.org/wiki/Special:Search"> <Param name="search" value="{searchTerms}"/> <Param name="sourceid" value="Mozilla-search"/> </Url>
--- a/browser/locales/en-US/searchplugins/yahoometrofx.xml +++ b/browser/locales/en-US/searchplugins/yahoometrofx.xml @@ -8,12 +8,12 @@ <InputEncoding>UTF-8</InputEncoding> <Image width="16" height="16">data:image/x-icon;base64,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</Image> <Image width="74" height="74">data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEoAAABKCAIAAACTslUmAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAA2xpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuNS1jMDE0IDc5LjE1MTQ4MSwgMjAxMy8wMy8xMy0xMjowOToxNSAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wTU09Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9tbS8iIHhtbG5zOnN0UmVmPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvc1R5cGUvUmVzb3VyY2VSZWYjIiB4bWxuczp4bXA9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC8iIHhtcE1NOk9yaWdpbmFsRG9jdW1lbnRJRD0ieG1wLmRpZDpGMkQ1NjY1OTQzMjA2ODExOEFCM0NBQTM2NzFDMUYwRiIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDoyNTI5NTE2NzcwQ0IxMUUzQUZGRUQxNzZFRDEwMkU1NiIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDoyNTI5NTE2NjcwQ0IxMUUzQUZGRUQxNzZFRDEwMkU1NiIgeG1wOkNyZWF0b3JUb29sPSJBZG9iZSBQaG90b3Nob3AgQ1M2IChNYWNpbnRvc2gpIj4gPHhtcE1NOkRlcml2ZWRGcm9tIHN0UmVmOmluc3RhbmNlSUQ9InhtcC5paWQ6NDY2MGVjYzAtNDBiNy00NzFlLTg0NTgtOTQzNTNmOWM4YzYyIiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOjkzMUIyODkyMTQ5QjExRTM5QkRGOUUwM0ZBM0MwMDNBIi8+IDwvcmRmOkRl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</Image> <Url type="application/x-suggestions+json" method="GET" template="http://ff.search.yahoo.com/gossip?output=fxjson&command={searchTerms}" /> <Url type="text/html" method="GET" template="http://search.yahoo.com/search"> <Param name="p" value="{searchTerms}"/> <Param name="ei" value="UTF-8"/> - <MozParam name="fr" condition="pref" pref="yahoo-fr" /> + <MozParam name="fr" condition="pref" pref="yahoo-fr-metro" /> </Url> <SearchForm>http://search.yahoo.com/</SearchForm> </SearchPlugin>
--- a/build/autoconf/icu.m4 +++ b/build/autoconf/icu.m4 @@ -117,18 +117,16 @@ AC_SUBST(DBG_SUFFIX) AC_SUBST(ENABLE_INTL_API) AC_SUBST(ICU_LIB_NAMES) AC_SUBST(MOZ_ICU_LIBS) if test -n "$ENABLE_INTL_API" -a -z "$MOZ_NATIVE_ICU"; then dnl We build ICU as a static library for non-shared js builds and as a shared library for shared js builds. if test -z "$MOZ_SHARED_ICU"; then AC_DEFINE(U_STATIC_IMPLEMENTATION) - else - AC_DEFINE(U_COMBINED_IMPLEMENTATION) fi dnl Source files that use ICU should have control over which parts of the ICU dnl namespace they want to use. AC_DEFINE(U_USING_ICU_NAMESPACE,0) fi ])
--- a/build/automationutils.py +++ b/build/automationutils.py @@ -451,18 +451,18 @@ def environment(xrePath, env=None, crash if crashreporter and not debugger: env['MOZ_CRASHREPORTER_NO_REPORT'] = '1' env['MOZ_CRASHREPORTER'] = '1' else: env['MOZ_CRASHREPORTER_DISABLE'] = '1' # Set WebRTC logging in case it is not set yet - env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:3') - env.setdefault('R_LOG_LEVEL', '5') + env.setdefault('NSPR_LOG_MODULES', 'signaling:5,mtransport:5,datachannel:5') + env.setdefault('R_LOG_LEVEL', '6') env.setdefault('R_LOG_DESTINATION', 'stderr') env.setdefault('R_LOG_VERBOSE', '1') # ASan specific environment stuff asan = bool(mozinfo.info.get("asan")) if asan and (mozinfo.isLinux or mozinfo.isMac): try: # Symbolizer support
--- a/build/unix/elfhack/Makefile.in +++ b/build/unix/elfhack/Makefile.in @@ -44,10 +44,8 @@ dummy: dummy.$(OBJ_SUFFIX) libs:: dummy # Will either crash or return exit code 1 if elfhack is broken LD_PRELOAD=$(CURDIR)/test-array$(DLL_SUFFIX) $(CURDIR)/dummy LD_PRELOAD=$(CURDIR)/test-ctors$(DLL_SUFFIX) $(CURDIR)/dummy GARBAGE += dummy endif endif - -test.$(OBJ_SUFFIX): CFLAGS := -O0
--- a/config/rules.mk +++ b/config/rules.mk @@ -967,17 +967,17 @@ endef $(HOST_CMMOBJS): $(REPORT_BUILD) $(ELOG) $(HOST_CXX) $(HOST_OUTOPTION)$@ -c $(HOST_CXXFLAGS) $(HOST_CMMFLAGS) $(INCLUDES) $(NSPR_CFLAGS) $(_VPATH_SRCS) $(COBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) - $(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(ELOG) $(CC) $(OUTOPTION)$@ -c $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) # DEFINES and ACDEFINES are needed here to enable conditional compilation of Q_OBJECTs: # 'moc' only knows about #defines it gets on the command line (-D...), not in # included headers like mozilla-config.h $(filter moc_%.cpp,$(CPPSRCS)): moc_%.cpp: %.h $(REPORT_BUILD) $(ELOG) $(MOC) $(DEFINES) $(ACDEFINES) $< $(OUTOPTION)$@ @@ -989,65 +989,65 @@ endef $(REPORT_BUILD) $(ELOG) $(RCC) -name $* $< $(OUTOPTION)$@ ifdef ASFILES # The AS_DASH_C_FLAG is needed cause not all assemblers (Solaris) accept # a '-c' flag. $(ASOBJS): $(REPORT_BUILD) - $(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS) + $(AS) $(ASOUTOPTION)$@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(AS_DASH_C_FLAG) $(_VPATH_SRCS) endif $(SOBJS): $(REPORT_BUILD) - $(AS) -o $@ $(ASFLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $< + $(AS) -o $@ $(ASFLAGS) $($(notdir $<)_FLAGS) $(LOCAL_INCLUDES) $(TARGET_LOCAL_INCLUDES) -c $< $(CPPOBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CXX) - $(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(ELOG) $(CCC) $(OUTOPTION)$@ -c $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(CMMOBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CXX) - $(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(ELOG) $(CCC) -o $@ -c $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(CMOBJS): $(REPORT_BUILD) @$(MAKE_DEPS_AUTO_CC) - $(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(ELOG) $(CC) -o $@ -c $(COMPILE_CFLAGS) $(COMPILE_CMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.s,$(CPPSRCS:%.cpp=%.s)): %.s: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CCC) -S $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.s,$(CPPSRCS:%.cc=%.s)): %.s: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CCC) -S $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CCC) -S $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.s,$(CSRCS:%.c=%.s)): %.s: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CC) -S $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CC) -S $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.i,$(CPPSRCS:%.cpp=%.i)): %.i: %.cpp $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.i,$(CPPSRCS:%.cc=%.i)): %.i: %.cc $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.i,$(CSRCS:%.c=%.i)): %.i: %.c $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(filter %.i,$(CMMSRCS:%.mm=%.i)): %.i: %.mm $(call mkdir_deps,$(MDDEPDIR)) $(REPORT_BUILD) - $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) + $(CCC) -C $(PREPROCESS_OPTION)$@ $(COMPILE_CXXFLAGS) $(COMPILE_CMMFLAGS) $($(notdir $<)_FLAGS) $(TARGET_LOCAL_INCLUDES) $(_VPATH_SRCS) $(RESFILE): %.res: %.rc $(REPORT_BUILD) @echo Creating Resource file: $@ ifdef GNU_CC $(RC) $(RCFLAGS) $(filter-out -U%,$(DEFINES)) $(INCLUDES:-I%=--include-dir %) $(OUTOPTION)$@ $(_VPATH_SRCS) else $(RC) $(RCFLAGS) -r $(DEFINES) $(INCLUDES) $(OUTOPTION)$@ $(_VPATH_SRCS)
--- a/configure.in +++ b/configure.in @@ -947,17 +947,17 @@ IMPORT_LIB_SUFFIX= TARGET_MD_ARCH=unix DIRENT_INO=d_ino MOZ_USER_DIR=".mozilla" MOZ_JPEG_CFLAGS= MOZ_JPEG_LIBS='$(call EXPAND_LIBNAME_PATH,mozjpeg,$(DEPTH)/media/libjpeg)' MOZ_BZ2_CFLAGS= MOZ_BZ2_LIBS='$(call EXPAND_LIBNAME_PATH,bz2,$(DEPTH)/modules/libbz2/src)' -MOZ_PNG_CFLAGS= +MOZ_PNG_CFLAGS="-I$_objdir/dist/include" # needed for freetype compilation MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/media/libpng)' MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)' MOZ_JS_SHARED_LIBS='$(call EXPAND_LIBNAME_PATH,mozjs,$(LIBXUL_DIST)/lib)' MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(prefix)/lib' XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/bin)' LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS)' XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)' @@ -8670,29 +8670,17 @@ AC_SUBST(MOZ_ENABLE_SZIP) AC_SUBST(MOZ_SZIP_FLAGS) if test "$MOZ_DEBUG"; then MOZ_EM_DEBUG=1 fi AC_SUBST(MOZ_EM_DEBUG) if test -n "$COMPILE_ENVIRONMENT"; then -AC_MSG_CHECKING([for posix_fallocate]) -AC_TRY_LINK([#define _XOPEN_SOURCE 600 - #include <fcntl.h>], - [posix_fallocate(0, 0, 0);], - [ac_cv___posix_fallocate=true], - [ac_cv___posix_fallocate=false]) - -if test "$ac_cv___posix_fallocate" = true ; then - AC_DEFINE(HAVE_POSIX_FALLOCATE) - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi +AC_CHECK_FUNCS(posix_fadvise posix_fallocate) dnl Check for missing components if test "$MOZ_X11"; then if test "$WITHOUT_X11"; then AC_MSG_ERROR([--without-x specified and MOZ_X11 still defined]) fi dnl ==================================================== dnl = Check if X headers exist @@ -8922,18 +8910,20 @@ fi # Run freetype configure script if test "$MOZ_TREE_FREETYPE"; then export CFLAGS="$CFLAGS $MOZ_DEBUG_FLAGS -std=c99" export CPPFLAGS="$CPPFLAGS $MOZ_DEBUG_FLAGS" export CXXFLAGS="$CXXFLAGS $MOZ_DEBUG_FLAGS" export LDFLAGS="$LDFLAGS $MOZ_DEBUG_LDFLAGS" + export LIBPNG_CFLAGS="$MOZ_PNG_CFLAGS" + export LIBPNG_LDFLAGS="$MOZ_PNG_LIBS" export CONFIG_FILES="unix-cc.mk:unix-cc.in unix-def.mk:unix-def.in freetype-config freetype2.pc:freetype2.in" - ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes --without-png" + ac_configure_args="$ac_configure_args --host=$target --disable-shared --with-pic=yes" if ! test -e modules; then mkdir modules fi AC_OUTPUT_SUBDIRS(modules/freetype2) fi
deleted file mode 100644 --- a/content/base/src/Makefile.in +++ /dev/null @@ -1,18 +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 $(topsrcdir)/config/rules.mk - -# gcc requires -msse2 for this file since it uses SSE2 intrinsics. (See bug -# 585538 comment 12.) -ifneq (,$(INTEL_ARCHITECTURE)) -ifdef GNU_CC -nsTextFragmentSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -endif - -ifdef SOLARIS_SUNPRO_CXX -nsTextFragmentSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-xarch=sse2 -xO4 -endif -endif
--- a/content/base/src/moz.build +++ b/content/base/src/moz.build @@ -45,19 +45,23 @@ if CONFIG['MOZ_WEBRTC']: ] LOCAL_INCLUDES += [ '/netwerk/sctp/datachannel', ] # Are we targeting x86-32 or x86-64? If so, we want to include SSE2 code for # nsTextFragment.cpp if CONFIG['INTEL_ARCHITECTURE']: - SOURCES += [ - 'nsTextFragmentSSE2.cpp', - ] + SOURCES += ['nsTextFragmentSSE2.cpp'] + if CONFIG['GNU_CC']: + # gcc requires -msse2 for this file since it uses SSE2 intrinsics. (See bug + # 585538 comment 12.) + SOURCES['nsTextFragmentSSE2.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['nsTextFragmentSSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] EXPORTS.mozilla.dom += [ 'Attr.h', 'Comment.h', 'DocumentFragment.h', 'DocumentType.h', 'DOMImplementation.h', 'DOMParser.h',
--- a/content/canvas/test/webgl/conformance/extensions/00_test_list.txt +++ b/content/canvas/test/webgl/conformance/extensions/00_test_list.txt @@ -1,9 +1,9 @@ oes-standard-derivatives.html ext-texture-filter-anisotropic.html oes-texture-float.html oes-vertex-array-object.html webgl-debug-renderer-info.html webgl-debug-shaders.html ---min-version 1.0.2 webgl-compressed-texture-s3tc.html +webgl-compressed-texture-s3tc.html --min-version 1.0.2 webgl-depth-texture.html ext-sRGB.html
--- a/content/canvas/test/webgl/non-conf-tests/mochitest.ini +++ b/content/canvas/test/webgl/non-conf-tests/mochitest.ini @@ -6,8 +6,9 @@ support-files = [test_depth_readpixels.html] [test_highp_fs.html] [test_no_arr_points.html] [test_privileged_exts.html] [test_webgl_available.html] [test_webgl_conformance.html] [test_webgl_request_context.html] [test_webgl_request_mismatch.html] +[test_webgl2_not_exposed.html]
new file mode 100644 --- /dev/null +++ b/content/canvas/test/webgl/non-conf-tests/test_webgl2_not_exposed.html @@ -0,0 +1,22 @@ +<!DOCTYPE HTML> +<html> +<head> +<title>WebGL test: WebGL2RenderingContext not exposed</title> +<script src="/MochiKit/MochiKit.js"></script> +<script src="/tests/SimpleTest/SimpleTest.js"></script> +<link rel="stylesheet" href="/tests/SimpleTest/test.css"> +</head> +<body> +<script> + +var exposed = false; +try { + null instanceof WebGL2RenderingContext; + exposed = true; +} catch (e) {} + +ok(!exposed, 'WebGL2RenderingContext should not be exposed.'); + +</script> +</body> +</html>
--- a/content/html/content/src/HTMLMediaElement.cpp +++ b/content/html/content/src/HTMLMediaElement.cpp @@ -612,17 +612,17 @@ void HTMLMediaElement::AbortExistingLoad mAudioStream = nullptr; } mLoadingSrc = nullptr; if (mNetworkState == nsIDOMHTMLMediaElement::NETWORK_LOADING || mNetworkState == nsIDOMHTMLMediaElement::NETWORK_IDLE) { - DispatchEvent(NS_LITERAL_STRING("abort")); + DispatchAsyncEvent(NS_LITERAL_STRING("abort")); } mError = nullptr; mLoadedFirstFrame = false; mAutoplaying = true; mIsLoadingFromSourceChildren = false; mSuspendedAfterFirstFrame = false; mAllowSuspendAfterFirstFrame = true; @@ -643,17 +643,17 @@ void HTMLMediaElement::AbortExistingLoad if (fireTimeUpdate) { // Since we destroyed the decoder above, the current playback position // will now be reported as 0. The playback position was non-zero when // we destroyed the decoder, so fire a timeupdate event so that the // change will be reflected in the controls. FireTimeUpdate(false); } - DispatchEvent(NS_LITERAL_STRING("emptied")); + DispatchAsyncEvent(NS_LITERAL_STRING("emptied")); } // We may have changed mPaused, mAutoplaying, mNetworkState and other // things which can affect AddRemoveSelfReference AddRemoveSelfReference(); mIsRunningSelectResource = false; }
--- a/content/media/Makefile.in +++ b/content/media/Makefile.in @@ -1,10 +1,8 @@ # 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 $(topsrcdir)/config/rules.mk CFLAGS += $(GSTREAMER_CFLAGS) CXXFLAGS += $(GSTREAMER_CFLAGS) - -AudioNodeEngineNEON.$(OBJ_SUFFIX): CXXFLAGS += -mfpu=neon
--- a/content/media/moz.build +++ b/content/media/moz.build @@ -159,19 +159,18 @@ UNIFIED_SOURCES += [ SOURCES += [ 'DecoderTraits.cpp', 'Latency.cpp', ] FAIL_ON_WARNINGS = True if CONFIG['CPU_ARCH'] == 'arm' and CONFIG['BUILD_ARM_NEON']: - SOURCES += [ - 'AudioNodeEngineNEON.cpp', - ] + SOURCES += ['AudioNodeEngineNEON.cpp'] + SOURCES['AudioNodeEngineNEON.cpp'].flags += ['-mfpu=neon'] MSVC_ENABLE_PGO = True include('/ipc/chromium/chromium-config.mozbuild') FINAL_LIBRARY = 'gklayout' LOCAL_INCLUDES += [ '/content/base/src',
--- a/content/media/test/mochitest.ini +++ b/content/media/test/mochitest.ini @@ -351,16 +351,17 @@ support-files = [test_playback_errors.html] [test_seekable1.html] [test_preload_actions.html] [test_preload_attribute.html] [test_progress.html] [test_reactivate.html] [test_readyState.html] [test_referer.html] +[test_reset_events_async.html] [test_replay_metadata.html] [test_seek2.html] [test_seek_out_of_range.html] [test_seekable2.html] [test_seekable3.html] [test_source.html] [test_source_write.html] [test_source_null.html]
--- a/content/media/test/test_bug654550.html +++ b/content/media/test/test_bug654550.html @@ -57,16 +57,19 @@ https://bugzilla.mozilla.org/show_bug.cg removeNodeAndSource(v); manager.finished(v.token); } function startTest(test, token) { var v = document.createElement('video'); v.token = token; v.src = test.name; + // playback may reach the end before pref is changed for the duration is short + // set 'loop' to true to keep playing so that we won't miss 'timeupdate' events + v.loop = true; manager.started(token); SpecialPowers.pushPrefEnv({"set": [["media.video_stats.enabled", true]]}, function() { v.play(); v.addEventListener("timeupdate", ontimeupdate_statsEnabled); }); }
new file mode 100644 --- /dev/null +++ b/content/media/test/test_reset_events_async.html @@ -0,0 +1,58 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=975270 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug </title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> + <script type="application/javascript" src="manifest.js"></script> + <script type="application/javascript"> + + /** Test for Bug 975270 **/ + // Test that 'emptied' and 'abort' events are fired asynchronously when re-starting + // media load. + SimpleTest.waitForExplicitFinish(); + + var a = document.createElement("audio"); + a._abort = 0; + a._emptied = 0; + a.preload = "metadata"; // On B2G we default to preload:none. + + is(a.networkState, HTMLMediaElement.NETWORK_EMPTY, "Shouldn't be loading"); + + a.addEventListener("abort", function(e) { a._abort++; }); + a.addEventListener("emptied", function(e) { a._emptied++; }); + a.addEventListener("loadedmetadata", + function(e) { + is(a._abort, 0, "Should not have received 'abort' before 'loadedmetadata"); + is(a._emptied, 0, "Should not have received 'emptied' before 'loadedmetadata"); + + a.addEventListener("loadstart", + function(e) { + is(a._abort, 1, "Should have received 'abort' before 'loadstart"); + is(a._emptied, 1, "Should have received 'emptied' before 'loadstart"); + SimpleTest.finish(); + }); + + a.src = ""; + is(a._abort, 0, "Should not have received 'abort' during setting a.src=''"); + is(a._emptied, 0, "Should not have received 'emptied' during setting a.src=''"); + }); + + a.src = getPlayableAudio(gSmallTests).name; + + </script> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug </a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +</pre> +</body> +</html>
--- a/dom/base/CompositionStringSynthesizer.cpp +++ b/dom/base/CompositionStringSynthesizer.cpp @@ -18,28 +18,29 @@ namespace dom { NS_IMPL_ISUPPORTS1(CompositionStringSynthesizer, nsICompositionStringSynthesizer) CompositionStringSynthesizer::CompositionStringSynthesizer( nsPIDOMWindow* aWindow) { mWindow = do_GetWeakReference(aWindow); + mClauses = new TextRangeArray(); ClearInternal(); } CompositionStringSynthesizer::~CompositionStringSynthesizer() { } void CompositionStringSynthesizer::ClearInternal() { mString.Truncate(); - mClauses.Clear(); + mClauses->Clear(); mCaret.mRangeType = 0; } nsIWidget* CompositionStringSynthesizer::GetWidget() { nsCOMPtr<nsPIDOMWindow> window = do_QueryReferent(mWindow); if (!window) { @@ -79,20 +80,20 @@ CompositionStringSynthesizer::AppendClau switch (aAttribute) { case ATTR_RAWINPUT: case ATTR_SELECTEDRAWTEXT: case ATTR_CONVERTEDTEXT: case ATTR_SELECTEDCONVERTEDTEXT: { TextRange textRange; textRange.mStartOffset = - mClauses.IsEmpty() ? 0 : mClauses[mClauses.Length() - 1].mEndOffset; + mClauses->IsEmpty() ? 0 : mClauses->LastElement().mEndOffset; textRange.mEndOffset = textRange.mStartOffset + aLength; textRange.mRangeType = aAttribute; - mClauses.AppendElement(textRange); + mClauses->AppendElement(textRange); return NS_OK; } default: return NS_ERROR_INVALID_ARG; } } NS_IMETHODIMP @@ -113,37 +114,38 @@ CompositionStringSynthesizer::DispatchEv NS_ENSURE_ARG_POINTER(aDefaultPrevented); nsCOMPtr<nsIWidget> widget = GetWidget(); NS_ENSURE_TRUE(widget && !widget->Destroyed(), NS_ERROR_NOT_AVAILABLE); if (!nsContentUtils::IsCallerChrome()) { return NS_ERROR_DOM_SECURITY_ERR; } - if (!mClauses.IsEmpty() && - mClauses[mClauses.Length()-1].mEndOffset != mString.Length()) { + if (!mClauses->IsEmpty() && + mClauses->LastElement().mEndOffset != mString.Length()) { NS_WARNING("Sum of length of the all clauses must be same as the string " "length"); ClearInternal(); return NS_ERROR_ILLEGAL_VALUE; } if (mCaret.mRangeType == NS_TEXTRANGE_CARETPOSITION) { if (mCaret.mEndOffset > mString.Length()) { NS_WARNING("Caret position is out of the composition string"); ClearInternal(); return NS_ERROR_ILLEGAL_VALUE; } - mClauses.AppendElement(mCaret); + mClauses->AppendElement(mCaret); } WidgetTextEvent textEvent(true, NS_TEXT_TEXT, widget); textEvent.time = PR_IntervalNow(); textEvent.theText = mString; - textEvent.rangeCount = mClauses.Length(); - textEvent.rangeArray = mClauses.Elements(); + if (!mClauses->IsEmpty()) { + textEvent.mRanges = mClauses; + } // XXX How should we set false for this on b2g? textEvent.mFlags.mIsSynthesizedForTests = true; nsEventStatus status = nsEventStatus_eIgnore; nsresult rv = widget->DispatchEvent(&textEvent, status); *aDefaultPrevented = (status == nsEventStatus_eConsumeNoDefault);
--- a/dom/base/CompositionStringSynthesizer.h +++ b/dom/base/CompositionStringSynthesizer.h @@ -3,17 +3,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/. */ #ifndef mozilla_dom_compositionstringsynthesizer_h__ #define mozilla_dom_compositionstringsynthesizer_h__ #include "nsICompositionStringSynthesizer.h" #include "nsString.h" -#include "nsTArray.h" #include "nsWeakReference.h" #include "mozilla/Attributes.h" #include "mozilla/TextRange.h" class nsIWidget; class nsPIDOMWindow; namespace mozilla { @@ -27,17 +26,17 @@ public: ~CompositionStringSynthesizer(); NS_DECL_ISUPPORTS NS_DECL_NSICOMPOSITIONSTRINGSYNTHESIZER private: nsWeakPtr mWindow; // refers an instance of nsPIDOMWindow nsString mString; - nsAutoTArray<TextRange, 10> mClauses; + nsRefPtr<TextRangeArray> mClauses; TextRange mCaret; nsIWidget* GetWidget(); void ClearInternal(); }; } // namespace dom } // namespace mozilla
--- a/dom/bindings/BindingUtils.cpp +++ b/dom/bindings/BindingUtils.cpp @@ -963,30 +963,29 @@ XrayResolveAttribute(JSContext* cx, JS:: for ( ; attributeIds[i] != JSID_VOID; ++i) { if (id == attributeIds[i]) { const JSPropertySpec& attrSpec = attributeSpecs[i]; // Because of centralization, we need to make sure we fault in the // JitInfos as well. At present, until the JSAPI changes, the easiest // way to do this is wrap them up as functions ourselves. desc.setAttributes(attrSpec.flags & ~JSPROP_NATIVE_ACCESSORS); // They all have getters, so we can just make it. - JS::Rooted<JSObject*> global(cx, JS_GetGlobalForObject(cx, wrapper)); JS::Rooted<JSFunction*> fun(cx, JS_NewFunctionById(cx, (JSNative)attrSpec.getter.propertyOp.op, - 0, 0, global, id)); + 0, 0, wrapper, id)); if (!fun) return false; SET_JITINFO(fun, attrSpec.getter.propertyOp.info); JSObject *funobj = JS_GetFunctionObject(fun); desc.setGetterObject(funobj); desc.attributesRef() |= JSPROP_GETTER; if (attrSpec.setter.propertyOp.op) { // We have a setter! Make it. fun = JS_NewFunctionById(cx, (JSNative)attrSpec.setter.propertyOp.op, 1, 0, - global, id); + wrapper, id); if (!fun) return false; SET_JITINFO(fun, attrSpec.setter.propertyOp.info); funobj = JS_GetFunctionObject(fun); desc.setSetterObject(funobj); desc.attributesRef() |= JSPROP_SETTER; } else { desc.setSetter(nullptr);
--- a/dom/bindings/Codegen.py +++ b/dom/bindings/Codegen.py @@ -1172,21 +1172,28 @@ class CGClassConstructor(CGAbstractStati def definition_body(self): return self.generate_code() def generate_code(self): preamble = """ JS::CallArgs args = JS::CallArgsFromVp(argc, vp); JS::Rooted<JSObject*> obj(cx, &args.callee()); """ + # [ChromeOnly] interfaces may only be constructed by chrome. + # Additionally, we want to throw if a non-chrome caller does a bareword invocation of a + # constructor without |new|. We don't enforce this for chrome to avoid the addon compat + # fallout of making that change. See bug 916644. if isChromeOnly(self._ctor): - preamble += """ if (!nsContentUtils::ThreadsafeIsCallerChrome()) { + mayInvokeCtor = "nsContentUtils::ThreadsafeIsCallerChrome()" + else: + mayInvokeCtor = "(args.isConstructing() || nsContentUtils::ThreadsafeIsCallerChrome())" + preamble += """ if (!%s) { return ThrowingConstructor(cx, argc, vp); } -""" +""" % mayInvokeCtor name = self._ctor.identifier.name nativeName = MakeNativeName(self.descriptor.binaryNames.get(name, name)) callGenerator = CGMethodCall(nativeName, True, self.descriptor, self._ctor, isConstructor=True) return preamble + callGenerator.define(); # Encapsulate the constructor in a helper method to share genConstructorBody with CGJSImplMethod. class CGConstructNavigatorObjectHelper(CGAbstractStaticMethod):
--- a/dom/browser-element/BrowserElementChildPreload.js +++ b/dom/browser-element/BrowserElementChildPreload.js @@ -68,33 +68,31 @@ function NS_ERROR_GET_CODE(err) { } let SEC_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SEC_ERROR_BASE; let SEC_ERROR_UNKNOWN_ISSUER = (SEC_ERROR_BASE + 13); let SEC_ERROR_CA_CERT_INVALID = (SEC_ERROR_BASE + 36); let SEC_ERROR_UNTRUSTED_ISSUER = (SEC_ERROR_BASE + 20); let SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE = (SEC_ERROR_BASE + 30); let SEC_ERROR_UNTRUSTED_CERT = (SEC_ERROR_BASE + 21); -let SEC_ERROR_INADEQUATE_KEY_USAGE = (SEC_ERROR_BASE + 90); let SEC_ERROR_EXPIRED_CERTIFICATE = (SEC_ERROR_BASE + 11); let SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED = (SEC_ERROR_BASE + 176); let SSL_ERROR_BASE = Ci.nsINSSErrorsService.NSS_SSL_ERROR_BASE; let SSL_ERROR_BAD_CERT_DOMAIN = (SSL_ERROR_BASE + 12); function getErrorClass(errorCode) { let NSPRCode = -1 * NS_ERROR_GET_CODE(errorCode); switch (NSPRCode) { case SEC_ERROR_UNKNOWN_ISSUER: case SEC_ERROR_CA_CERT_INVALID: case SEC_ERROR_UNTRUSTED_ISSUER: case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_INADEQUATE_KEY_USAGE: case SSL_ERROR_BAD_CERT_DOMAIN: case SEC_ERROR_EXPIRED_CERTIFICATE: case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: return Ci.nsINSSErrorsService.ERROR_CLASS_BAD_CERT; default: return Ci.nsINSSErrorsService.ERROR_CLASS_SSL_PROTOCOL; }
--- a/dom/datastore/DataStore.jsm +++ b/dom/datastore/DataStore.jsm @@ -74,16 +74,17 @@ this.DataStore.prototype = { _window: null, _name: null, _owner: null, _readOnly: null, _revisionId: null, _exposedObject: null, _cursor: null, + _shuttingdown: false, init: function(aWindow, aName, aOwner, aReadOnly) { debug("DataStore init"); this._window = aWindow; this._name = aName; this._owner = aOwner; this._readOnly = aReadOnly; @@ -91,16 +92,18 @@ this.DataStore.prototype = { this._db = new DataStoreDB(); this._db.init(aOwner, aName); let self = this; Services.obs.addObserver(function(aSubject, aTopic, aData) { let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data; if (wId == self._innerWindowID) { cpmm.removeMessageListener("DataStore:Changed:Return:OK", self); + cpmm.sendAsyncMessage("DataStore:UnregisterForMessages"); + self._shuttingdown = true; self._db.close(); } }, "inner-window-destroyed", false); let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindowUtils); this._innerWindowID = util.currentInnerWindowID; @@ -315,16 +318,21 @@ this.DataStore.prototype = { aMessage.data.store != this._name) { return; } let self = this; this.retrieveRevisionId( function() { + // If the window has been destroyed we don't emit the events. + if (self._shuttingdown) { + return; + } + // If we have an active cursor we don't emit events. if (self._cursor) { return; } let event = new self._window.DataStoreChangeEvent('change', aMessage.data.message); self.__DOM_IMPL__.dispatchEvent(event);
--- a/dom/datastore/DataStoreChangeNotifier.jsm +++ b/dom/datastore/DataStoreChangeNotifier.jsm @@ -20,16 +20,17 @@ Cu.import("resource://gre/modules/Servic XPCOMUtils.defineLazyServiceGetter(this, "ppmm", "@mozilla.org/parentprocessmessagemanager;1", "nsIMessageBroadcaster"); this.DataStoreChangeNotifier = { children: [], messages: [ "DataStore:Changed", "DataStore:RegisterForMessages", + "DataStore:UnregisterForMessages", "child-process-shutdown" ], init: function() { debug("init"); this.messages.forEach((function(msgName) { ppmm.addMessageListener(msgName, this); }).bind(this)); @@ -89,16 +90,17 @@ this.DataStoreChangeNotifier = { } this.children.push({ mm: aMessage.target, store: aMessage.data.store, owner: aMessage.data.owner }); break; case "child-process-shutdown": + case "DataStore:UnregisterForMessages": debug("Unregister"); for (let i = 0; i < this.children.length;) { if (this.children[i].mm == aMessage.target) { debug("Unregister index: " + i); this.children.splice(i, 1); } else { ++i;
--- a/dom/events/TextComposition.cpp +++ b/dom/events/TextComposition.cpp @@ -108,27 +108,18 @@ TextComposition::NotityUpdateComposition // Unknown offset NS_WARNING("Cannot get start offset of IME composition"); mCompositionStartOffset = 0; } mCompositionTargetOffset = mCompositionStartOffset; } else if (aEvent->eventStructType != NS_TEXT_EVENT) { return; } else { - WidgetTextEvent* textEvent = aEvent->AsTextEvent(); - mCompositionTargetOffset = mCompositionStartOffset; - - for (uint32_t i = 0; i < textEvent->rangeCount; i++) { - TextRange& range = textEvent->rangeArray[i]; - if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT || - range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) { - mCompositionTargetOffset += range.mStartOffset; - break; - } - } + mCompositionTargetOffset = + mCompositionStartOffset + aEvent->AsTextEvent()->TargetClauseOffset(); } NotifyIME(NOTIFY_IME_OF_COMPOSITION_UPDATE); } void TextComposition::DispatchCompositionEventRunnable(uint32_t aEventMessage, const nsAString& aData) @@ -156,16 +147,17 @@ TextComposition::NotifyIME(IMEMessage aM NS_ENSURE_TRUE(mPresContext, NS_ERROR_NOT_AVAILABLE); return nsIMEStateManager::NotifyIME(aMessage, mPresContext); } void TextComposition::EditorWillHandleTextEvent(const WidgetTextEvent* aTextEvent) { mIsComposing = aTextEvent->IsComposing(); + mRanges = aTextEvent->mRanges; mIsEditorHandlingEvent = true; MOZ_ASSERT(mLastData == aTextEvent->theText, "The text of a text event must be same as previous data attribute value " "of the latest compositionupdate event"); } void
--- a/dom/events/TextComposition.h +++ b/dom/events/TextComposition.h @@ -11,16 +11,17 @@ #include "nsINode.h" #include "nsIWeakReference.h" #include "nsIWidget.h" #include "nsTArray.h" #include "nsThreadUtils.h" #include "nsPresContext.h" #include "mozilla/Attributes.h" #include "mozilla/EventForwards.h" +#include "mozilla/TextRange.h" class nsDispatchingCallback; class nsIEditor; class nsIMEStateManager; namespace mozilla { /** @@ -52,16 +53,22 @@ public: // This value is modified at dispatching compositionupdate. const nsString& LastData() const { return mLastData; } // The composition string which is already handled by the focused editor. // I.e., this value must be same as the composition string on the focused // editor. This value is modified at a call of EditorDidHandleTextEvent(). // Note that mString and mLastData are different between dispatcing // compositionupdate and text event handled by focused editor. const nsString& String() const { return mString; } + // Returns the clauses and/or caret range of the composition string. + // This is modified at a call of EditorWillHandleTextEvent(). + // This may return null if there is no clauses and caret. + // XXX We should return |const TextRangeArray*| here, but it causes compile + // error due to inaccessible Release() method. + TextRangeArray* GetRanges() const { return mRanges; } // Returns true if the composition is started with synthesized event which // came from nsDOMWindowUtils. bool IsSynthesizedForTests() const { return mIsSynthesizedForTests; } bool MatchesNativeContext(nsIWidget* aWidget) const; /** * This is called when nsIMEStateManager stops managing the instance. @@ -138,16 +145,20 @@ public: private: // This class holds nsPresContext weak. This instance shouldn't block // destroying it. When the presContext is being destroyed, it's notified to // nsIMEStateManager::OnDestroyPresContext(), and then, it destroy // this instance. nsPresContext* mPresContext; nsCOMPtr<nsINode> mNode; + // This is the clause and caret range information which is managed by + // the focused editor. This may be null if there is no clauses or caret. + nsRefPtr<TextRangeArray> mRanges; + // mNativeContext stores a opaque pointer. This works as the "ID" for this // composition. Don't access the instance, it may not be available. void* mNativeContext; // mEditorWeak is a weak reference to the focused editor handling composition. nsWeakPtr mEditorWeak; // mLastData stores the data attribute of the latest composition event (except
--- a/dom/events/moz.build +++ b/dom/events/moz.build @@ -19,18 +19,16 @@ EXPORTS += [ 'nsDOMEventTargetHelper.h', 'nsDOMKeyNameList.h', 'nsEventDispatcher.h', 'nsEventListenerManager.h', 'nsEventNameList.h', 'nsEventStateManager.h', 'nsEventStates.h', 'nsIJSEventListener.h', - 'nsIPrivateTextEvent.h', - 'nsIPrivateTextRange.h', 'nsVKList.h', ] EXPORTS.mozilla += [ 'InternalMutationEvent.h', ] EXPORTS.mozilla.dom += [ @@ -84,24 +82,22 @@ UNIFIED_SOURCES += [ 'MouseScrollEvent.cpp', 'MutationEvent.cpp', 'NotifyAudioAvailableEvent.cpp', 'NotifyPaintEvent.cpp', 'nsAsyncDOMEvent.cpp', 'nsContentEventHandler.cpp', 'nsDOMEvent.cpp', 'nsDOMEventTargetHelper.cpp', - 'nsDOMTextEvent.cpp', 'nsEventDispatcher.cpp', 'nsEventListenerManager.cpp', 'nsEventListenerService.cpp', 'nsIMEStateManager.cpp', 'nsJSEventListener.cpp', 'nsPaintRequest.cpp', - 'nsPrivateTextRange.cpp', 'PointerEvent.cpp', 'ScrollAreaEvent.cpp', 'SimpleGestureEvent.cpp', 'TextComposition.cpp', 'Touch.cpp', 'TouchEvent.cpp', 'TransitionEvent.cpp', 'UIEvent.cpp',
deleted file mode 100644 --- a/dom/events/nsDOMTextEvent.cpp +++ /dev/null @@ -1,86 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 sw=2 et tw=78: */ -/* 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 "nsDOMTextEvent.h" -#include "nsPrivateTextRange.h" -#include "prtime.h" -#include "mozilla/TextEvents.h" - -using namespace mozilla; -using namespace mozilla::dom; - -nsDOMTextEvent::nsDOMTextEvent(mozilla::dom::EventTarget* aOwner, - nsPresContext* aPresContext, - WidgetTextEvent* aEvent) - : UIEvent(aOwner, aPresContext, - aEvent ? aEvent : new WidgetTextEvent(false, 0, nullptr)) -{ - NS_ASSERTION(mEvent->eventStructType == NS_TEXT_EVENT, "event type mismatch"); - - if (aEvent) { - mEventIsInternal = false; - } - else { - mEventIsInternal = true; - mEvent->time = PR_Now(); - } - - // - // extract the IME composition string - // - WidgetTextEvent* te = mEvent->AsTextEvent(); - mText = te->theText; - - // - // build the range list -- ranges need to be DOM-ified since the - // IME transaction will hold a ref, the widget representation - // isn't persistent - // - mTextRange = new nsPrivateTextRangeList(te->rangeCount); - if (mTextRange) { - uint16_t i; - - for(i = 0; i < te->rangeCount; i++) { - nsRefPtr<nsPrivateTextRange> tempPrivateTextRange = new - nsPrivateTextRange(te->rangeArray[i]); - - if (tempPrivateTextRange) { - mTextRange->AppendTextRange(tempPrivateTextRange); - } - } - } -} - -NS_IMPL_ADDREF_INHERITED(nsDOMTextEvent, UIEvent) -NS_IMPL_RELEASE_INHERITED(nsDOMTextEvent, UIEvent) - -NS_INTERFACE_MAP_BEGIN(nsDOMTextEvent) - NS_INTERFACE_MAP_ENTRY(nsIPrivateTextEvent) -NS_INTERFACE_MAP_END_INHERITING(UIEvent) - -NS_METHOD nsDOMTextEvent::GetText(nsString& aText) -{ - aText = mText; - return NS_OK; -} - -NS_METHOD_(already_AddRefed<nsIPrivateTextRangeList>) nsDOMTextEvent::GetInputRange() -{ - if (mEvent->message == NS_TEXT_TEXT) { - nsRefPtr<nsPrivateTextRangeList> textRange = mTextRange; - return textRange.forget(); - } - return nullptr; -} - -nsresult NS_NewDOMTextEvent(nsIDOMEvent** aInstancePtrResult, - mozilla::dom::EventTarget* aOwner, - nsPresContext* aPresContext, - WidgetTextEvent* aEvent) -{ - nsDOMTextEvent* it = new nsDOMTextEvent(aOwner, aPresContext, aEvent); - return CallQueryInterface(it, aInstancePtrResult); -}
deleted file mode 100644 --- a/dom/events/nsDOMTextEvent.h +++ /dev/null @@ -1,39 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 nsDOMTextEvent_h__ -#define nsDOMTextEvent_h__ - -#include "mozilla/dom/UIEvent.h" -#include "mozilla/Attributes.h" -#include "mozilla/EventForwards.h" -#include "nsIPrivateTextEvent.h" -#include "nsPrivateTextRange.h" - -class nsDOMTextEvent : public mozilla::dom::UIEvent, - public nsIPrivateTextEvent -{ - typedef mozilla::dom::UIEvent UIEvent; - -public: - nsDOMTextEvent(mozilla::dom::EventTarget* aOwner, - nsPresContext* aPresContext, - mozilla::WidgetTextEvent* aEvent); - - NS_DECL_ISUPPORTS_INHERITED - - // Forward to base class - NS_FORWARD_TO_UIEVENT - - // nsIPrivateTextEvent interface - NS_IMETHOD GetText(nsString& aText) MOZ_OVERRIDE; - NS_IMETHOD_(already_AddRefed<nsIPrivateTextRangeList>) GetInputRange() MOZ_OVERRIDE; - -protected: - nsString mText; - nsRefPtr<nsPrivateTextRangeList> mTextRange; -}; - -#endif // nsDOMTextEvent_h__
--- a/dom/events/nsEventDispatcher.cpp +++ b/dom/events/nsEventDispatcher.cpp @@ -703,18 +703,18 @@ nsEventDispatcher::CreateEvent(mozilla:: aEvent->AsMouseScrollEvent()); case NS_WHEEL_EVENT: return NS_NewDOMWheelEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsWheelEvent()); case NS_DRAG_EVENT: return NS_NewDOMDragEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsDragEvent()); case NS_TEXT_EVENT: - return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext, - aEvent->AsTextEvent()); + return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, + aEvent->AsTextEvent()); case NS_CLIPBOARD_EVENT: return NS_NewDOMClipboardEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsClipboardEvent()); case NS_SVGZOOM_EVENT: return NS_NewDOMSVGZoomEvent(aDOMEvent, aOwner, aPresContext, aEvent->AsGUIEvent()); case NS_SMIL_TIME_EVENT: return NS_NewDOMTimeEvent(aDOMEvent, aOwner, aPresContext, aEvent); @@ -759,17 +759,17 @@ nsEventDispatcher::CreateEvent(mozilla:: return NS_NewDOMKeyboardEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("compositionevent")) return NS_NewDOMCompositionEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("mutationevent") || aEventType.LowerCaseEqualsLiteral("mutationevents")) return NS_NewDOMMutationEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("textevent") || aEventType.LowerCaseEqualsLiteral("textevents")) - return NS_NewDOMTextEvent(aDOMEvent, aOwner, aPresContext, nullptr); + return NS_NewDOMUIEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("popupblockedevents")) return NS_NewDOMPopupBlockedEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("deviceorientationevent")) return NS_NewDOMDeviceOrientationEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("devicemotionevent")) return NS_NewDOMDeviceMotionEvent(aDOMEvent, aOwner, aPresContext, nullptr); if (aEventType.LowerCaseEqualsLiteral("uievent") || aEventType.LowerCaseEqualsLiteral("uievents"))
--- a/dom/events/nsEventNameList.h +++ b/dom/events/nsEventNameList.h @@ -654,17 +654,17 @@ NON_IDL_EVENT(speakerforcedchange, NS_SPEAKERMANAGER_SPEAKERFORCEDCHANGE, EventNameType_None, NS_EVENT) // Events that only have on* attributes on XUL elements NON_IDL_EVENT(text, NS_TEXT_TEXT, EventNameType_XUL, - NS_EVENT) + NS_TEXT_EVENT) NON_IDL_EVENT(compositionstart, NS_COMPOSITION_START, EventNameType_XUL, NS_COMPOSITION_EVENT) NON_IDL_EVENT(compositionupdate, NS_COMPOSITION_UPDATE, EventNameType_XUL, NS_COMPOSITION_EVENT)
deleted file mode 100644 --- a/dom/events/nsIPrivateTextEvent.h +++ /dev/null @@ -1,28 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 nsIPrivateTextEvent_h__ -#define nsIPrivateTextEvent_h__ - -#include "nsISupports.h" -#include "nsIPrivateTextRange.h" - -#define NS_IPRIVATETEXTEVENT_IID \ -{ 0xb6840e02, 0x9e56, 0x49d8, \ - { 0x84, 0xd, 0x5f, 0xc1, 0xcb, 0x6c, 0xff, 0xb3 } } - -class nsIPrivateTextEvent : public nsISupports { - -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTEVENT_IID) - - NS_IMETHOD GetText(nsString& aText) = 0; - NS_IMETHOD_(already_AddRefed<nsIPrivateTextRangeList>) GetInputRange() = 0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextEvent, NS_IPRIVATETEXTEVENT_IID) - -#endif // nsIPrivateTextEvent_h__ -
deleted file mode 100644 --- a/dom/events/nsIPrivateTextRange.h +++ /dev/null @@ -1,55 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 nsIPrivateTextRange_h__ -#define nsIPrivateTextRange_h__ - -#include "nsISupports.h" -#include "nsString.h" -#include "nsCOMPtr.h" -#include "mozilla/EventForwards.h" - -#define NS_IPRIVATETEXTRANGE_IID \ -{ 0xf795a44d, 0x413a, 0x4c63, \ - { 0xa6, 0xb0, 0x7a, 0xa3, 0x0c, 0xf5, 0xe9, 0xe0 } } - -class nsIPrivateTextRange : public nsISupports { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGE_IID) - - // Note that the range array may not specify a caret position; in that - // case there will be no range of type TEXTRANGE_CARETPOSITION in the array. - enum { - TEXTRANGE_CARETPOSITION = 1, - TEXTRANGE_RAWINPUT = 2, - TEXTRANGE_SELECTEDRAWTEXT = 3, - TEXTRANGE_CONVERTEDTEXT = 4, - TEXTRANGE_SELECTEDCONVERTEDTEXT = 5 - }; - - NS_IMETHOD GetRangeStart(uint16_t* aRangeStart)=0; - NS_IMETHOD GetRangeEnd(uint16_t* aRangeEnd)=0; - NS_IMETHOD GetRangeType(uint16_t* aRangeType)=0; - NS_IMETHOD GetRangeStyle(mozilla::TextRangeStyle* aTextRangeStyle)=0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRange, NS_IPRIVATETEXTRANGE_IID) - -#define NS_IPRIVATETEXTRANGELIST_IID \ -{0xb5a04b19, 0xed33, 0x4cd0, \ -{0x82, 0xa8, 0xb7, 0x00, 0x83, 0xef, 0xc4, 0x91}} - -class nsIPrivateTextRangeList : public nsISupports { -public: - NS_DECLARE_STATIC_IID_ACCESSOR(NS_IPRIVATETEXTRANGELIST_IID) - - NS_IMETHOD_(uint16_t) GetLength()=0; - NS_IMETHOD_(already_AddRefed<nsIPrivateTextRange>) Item(uint16_t aIndex)=0; -}; - -NS_DEFINE_STATIC_IID_ACCESSOR(nsIPrivateTextRangeList, - NS_IPRIVATETEXTRANGELIST_IID) - -#endif // nsIPrivateTextRange_h__
deleted file mode 100644 --- a/dom/events/nsPrivateTextRange.cpp +++ /dev/null @@ -1,67 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 "nsPrivateTextRange.h" -#include "mozilla/TextEvents.h" - -using namespace mozilla; - -nsPrivateTextRange::nsPrivateTextRange(const TextRange &aTextRange) - : mRangeStart(uint16_t(aTextRange.mStartOffset)), - mRangeEnd(uint16_t(aTextRange.mEndOffset)), - mRangeType(uint16_t(aTextRange.mRangeType)), - mRangeStyle(aTextRange.mRangeStyle) -{ -} - -nsPrivateTextRange::~nsPrivateTextRange(void) -{ -} - -NS_IMPL_ISUPPORTS1(nsPrivateTextRange, nsIPrivateTextRange) - -NS_METHOD nsPrivateTextRange::GetRangeStart(uint16_t* aRangeStart) -{ - *aRangeStart = mRangeStart; - return NS_OK; -} - -NS_METHOD nsPrivateTextRange::GetRangeEnd(uint16_t* aRangeEnd) -{ - *aRangeEnd = mRangeEnd; - return NS_OK; -} - -NS_METHOD nsPrivateTextRange::GetRangeType(uint16_t* aRangeType) -{ - *aRangeType = mRangeType; - return NS_OK; -} - -NS_METHOD nsPrivateTextRange::GetRangeStyle(TextRangeStyle* aTextRangeStyle) -{ - NS_ENSURE_ARG_POINTER(aTextRangeStyle); - *aTextRangeStyle = mRangeStyle; - return NS_OK; -} - -NS_IMPL_ISUPPORTS1(nsPrivateTextRangeList, nsIPrivateTextRangeList) - -void nsPrivateTextRangeList::AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange) -{ - mList.AppendElement(aRange); -} - -NS_METHOD_(uint16_t) nsPrivateTextRangeList::GetLength() -{ - return static_cast<uint16_t>(mList.Length()); -} - -NS_METHOD_(already_AddRefed<nsIPrivateTextRange>) nsPrivateTextRangeList::Item(uint16_t aIndex) -{ - nsRefPtr<nsPrivateTextRange> ret = mList.ElementAt(aIndex); - return ret.forget(); -} -
deleted file mode 100644 --- a/dom/events/nsPrivateTextRange.h +++ /dev/null @@ -1,52 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* 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 nsPrivateTextRange_h__ -#define nsPrivateTextRange_h__ - -#include "nsIPrivateTextRange.h" -#include "nsTArray.h" -#include "nsAutoPtr.h" -#include "mozilla/Attributes.h" -#include "mozilla/TextRange.h" - -class nsPrivateTextRange MOZ_FINAL : public nsIPrivateTextRange -{ - NS_DECL_ISUPPORTS -public: - - nsPrivateTextRange(const mozilla::TextRange &aTextRange); - virtual ~nsPrivateTextRange(void); - - NS_IMETHOD GetRangeStart(uint16_t* aRangeStart) MOZ_OVERRIDE; - NS_IMETHOD GetRangeEnd(uint16_t* aRangeEnd) MOZ_OVERRIDE; - NS_IMETHOD GetRangeType(uint16_t* aRangeType) MOZ_OVERRIDE; - NS_IMETHOD GetRangeStyle(mozilla::TextRangeStyle* aRangeStyle) MOZ_OVERRIDE; - -protected: - - uint16_t mRangeStart; - uint16_t mRangeEnd; - uint16_t mRangeType; - mozilla::TextRangeStyle mRangeStyle; -}; - -class nsPrivateTextRangeList MOZ_FINAL : public nsIPrivateTextRangeList -{ - NS_DECL_ISUPPORTS -public: - nsPrivateTextRangeList(uint16_t aLength) : mList(aLength) {} - - void AppendTextRange(nsRefPtr<nsPrivateTextRange>& aRange); - - NS_IMETHOD_(uint16_t) GetLength() MOZ_OVERRIDE; - - NS_IMETHOD_(already_AddRefed<nsIPrivateTextRange>) Item(uint16_t aIndex) MOZ_OVERRIDE; -protected: - nsTArray<nsRefPtr<nsPrivateTextRange> > mList; -}; - - -#endif
--- a/dom/ipc/TabChild.cpp +++ b/dom/ipc/TabChild.cpp @@ -2034,17 +2034,16 @@ TabChild::RecvCompositionEvent(const Wid return true; } bool TabChild::RecvTextEvent(const WidgetTextEvent& event) { WidgetTextEvent localEvent(event); DispatchWidgetEvent(localEvent); - IPC::ParamTraits<WidgetTextEvent>::Free(event); return true; } bool TabChild::RecvSelectionEvent(const WidgetSelectionEvent& event) { WidgetSelectionEvent localEvent(event); DispatchWidgetEvent(localEvent);
--- a/dom/locales/en-US/chrome/accessibility/AccessFu.properties +++ b/dom/locales/en-US/chrome/accessibility/AccessFu.properties @@ -1,12 +1,17 @@ # 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/. +# Screen reader started/stopped +screenReaderStarted = Screen reader started +screenReaderStopped = Screen reader stopped + +# Roles menubar = menu bar scrollbar = scroll bar grip = grip alert = alert menupopup = menu popup document = document pane = pane dialog = dialog
--- a/dom/media/tests/mochitest/pc.js +++ b/dom/media/tests/mochitest/pc.js @@ -1444,42 +1444,53 @@ PeerConnectionWrapper.prototype = { info(self + ": As expected, failed to add an ICE candidate"); onFailure(err); }) ; }, /** * Returns if the ICE the connection state is "connected". * - * @returns {boolean} True is the connection state is "connected", otherwise false. + * @returns {boolean} True if the connection state is "connected", otherwise false. */ isIceConnected : function PCW_isIceConnected() { info("iceConnectionState: " + this.iceConnectionState); return this.iceConnectionState === "connected"; }, /** * Returns if the ICE the connection state is "checking". * - * @returns {boolean} True is the connection state is "checking", otherwise false. + * @returns {boolean} True if the connection state is "checking", otherwise false. */ isIceChecking : function PCW_isIceChecking() { return this.iceConnectionState === "checking"; }, /** * Returns if the ICE the connection state is "new". * - * @returns {boolean} True is the connection state is "new", otherwise false. + * @returns {boolean} True if the connection state is "new", otherwise false. */ isIceNew : function PCW_isIceNew() { return this.iceConnectionState === "new"; }, /** + * Checks if the ICE connection state still waits for a connection to get + * established. + * + * @returns {boolean} True if the connection state is "checking" or "new", + * otherwise false. + */ + isIceConnectionPending : function PCW_isIceConnectionPending() { + return (this.isIceChecking() || this.isIceNew()); + }, + + /** * Registers a callback for the ICE connection state change and * reports success (=connected) or failure via the callbacks. * States "new" and "checking" are ignored. * * @param {function} onSuccess * Callback if ICE connection status is "connected". * @param {function} onFailure * Callback if ICE connection reaches a different state than @@ -1489,17 +1500,17 @@ PeerConnectionWrapper.prototype = { var self = this; var mySuccess = onSuccess; var myFailure = onFailure; function iceConnectedChanged () { if (self.isIceConnected()) { delete self.ice_connection_callbacks["waitForIceConnected"]; mySuccess(); - } else if (! (self.isIceChecking() || self.isIceNew())) { + } else if (! self.isIceConnectionPending()) { delete self.ice_connection_callbacks["waitForIceConnected"]; myFailure(); } }; self.ice_connection_callbacks["waitForIceConnected"] = (function() {iceConnectedChanged()}); },
--- a/dom/media/tests/mochitest/templates.js +++ b/dom/media/tests/mochitest/templates.js @@ -138,52 +138,58 @@ var commandsPeerConnection = [ ], [ 'PC_LOCAL_WAIT_FOR_ICE_CONNECTED', function (test) { var myTest = test; var myPc = myTest.pcLocal; function onIceConnectedSuccess () { - ok(true, "pc_local: ICE switched to connected state"); + ok(true, "pc_local: ICE switched to 'connected' state"); myTest.next(); }; function onIceConnectedFailed () { - ok(false, "pc_local: ICE failed to switch to connected"); + ok(false, "pc_local: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState()); myTest.next(); }; if (myPc.isIceConnected()) { ok(true, "pc_local: ICE is in connected state"); myTest.next(); + } else if (myPc.isIceConnectionPending()) { + myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed); } else { - myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed); + ok(false, "pc_local: ICE is already in bad state: " + myPc.iceConnectionState()); + myTest.next(); } } ], [ 'PC_REMOTE_WAIT_FOR_ICE_CONNECTED', function (test) { var myTest = test; var myPc = myTest.pcRemote; function onIceConnectedSuccess () { - ok(true, "pc_remote: ICE switched to connected state"); + ok(true, "pc_remote: ICE switched to 'connected' state"); myTest.next(); }; function onIceConnectedFailed () { - ok(false, "pc_remote: ICE failed to switch to connected"); + ok(false, "pc_remote: ICE failed to switch to 'connected' state: " + myPc.iceConnectionState()); myTest.next(); }; if (myPc.isIceConnected()) { ok(true, "pc_remote: ICE is in connected state"); myTest.next(); + } else if (myPc.isIceConnectionPending()) { + myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed); } else { - myPc.waitForIceConnected(onIceConnectedSuccess, onIceConnectedFailed); + ok(false, "pc_remote: ICE is already in bad state: " + myPc.iceConnectionState()); + myTest.next(); } } ], [ 'PC_LOCAL_CHECK_MEDIA_STREAMS', function (test) { test.pcLocal.checkMediaStreams(test._remote_constraints); test.next();
--- a/dom/plugins/base/nsPluginTags.cpp +++ b/dom/plugins/base/nsPluginTags.cpp @@ -562,15 +562,15 @@ nsPluginTag::GetBlocklistState() } void nsPluginTag::InvalidateBlocklistState() { mCachedBlocklistStateValid = false; } -nsresult +NS_IMETHODIMP nsPluginTag::GetLastModifiedTime(PRTime* aLastModifiedTime) { MOZ_ASSERT(aLastModifiedTime); *aLastModifiedTime = mLastModifiedTime; return NS_OK; }
--- a/dom/promise/Promise.cpp +++ b/dom/promise/Promise.cpp @@ -4,16 +4,17 @@ * 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 "mozilla/dom/Promise.h" #include "jsfriendapi.h" #include "mozilla/dom/OwningNonNull.h" #include "mozilla/dom/PromiseBinding.h" +#include "mozilla/CycleCollectedJSRuntime.h" #include "mozilla/Preferences.h" #include "PromiseCallback.h" #include "PromiseNativeHandler.h" #include "nsContentUtils.h" #include "WorkerPrivate.h" #include "WorkerRunnable.h" #include "nsJSPrincipals.h" #include "nsJSUtils.h" @@ -93,38 +94,34 @@ public: : mPromise(aPromise) , mValue(aValue) , mState(aState) { MOZ_ASSERT(aPromise); MOZ_ASSERT(mState != Promise::Pending); MOZ_COUNT_CTOR(PromiseResolverMixin); - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - /* It's safe to use unsafeGet() here: the unsafeness comes from the * possibility of updating the value of mJSObject without triggering the * barriers. However if the value will always be marked, post barriers * unnecessary. */ - JS_AddNamedValueRootRT(JS_GetRuntime(cx), mValue.unsafeGet(), + JS_AddNamedValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet(), "PromiseResolverMixin.mValue"); } virtual ~PromiseResolverMixin() { NS_ASSERT_OWNINGTHREAD(PromiseResolverMixin); MOZ_COUNT_DTOR(PromiseResolverMixin); - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - /* It's safe to use unsafeGet() here: the unsafeness comes from the * possibility of updating the value of mJSObject without triggering the * barriers. However if the value will always be marked, post barriers * unnecessary. */ - JS_RemoveValueRootRT(JS_GetRuntime(cx), mValue.unsafeGet()); + JS_RemoveValueRootRT(CycleCollectedJSRuntime::Get()->Runtime(), mValue.unsafeGet()); } protected: void RunInternal() { NS_ASSERT_OWNINGTHREAD(PromiseResolverMixin); mPromise->RunResolveTask( @@ -626,17 +623,17 @@ public: { mozilla::DropJSObjects(this); } void SetValue(uint32_t index, const JS::Handle<JS::Value> aValue) { MOZ_ASSERT(mCountdown > 0); - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); + ThreadsafeAutoSafeJSContext cx; JSAutoCompartment ac(cx, mValues); { AutoDontReportUncaught silenceReporting(cx); if (!JS_DefineElement(cx, mValues, index, aValue, nullptr, nullptr, JSPROP_ENUMERATE)) { MOZ_ASSERT(JS_IsExceptionPending(cx)); JS::Rooted<JS::Value> exn(cx); JS_GetPendingException(cx, &exn); @@ -850,39 +847,35 @@ Promise::RunTask() MOZ_ASSERT(mState != Pending); nsTArray<nsRefPtr<PromiseCallback>> callbacks; callbacks.SwapElements(mState == Resolved ? mResolveCallbacks : mRejectCallbacks); mResolveCallbacks.Clear(); mRejectCallbacks.Clear(); - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - JSAutoRequest ar(cx); + ThreadsafeAutoJSContext cx; // Just for rooting. JS::Rooted<JS::Value> value(cx, mResult); for (uint32_t i = 0; i < callbacks.Length(); ++i) { callbacks[i]->Call(value); } } void Promise::MaybeReportRejected() { if (mState != Rejected || mHadRejectCallback || mResult.isUndefined()) { return; } - // Technically we should push this JSContext, but in reality the JS engine - // just uses it for string allocation here, so we can get away without it. if (!mResult.isObject()) { return; } - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - JSAutoRequest ar(cx); + ThreadsafeAutoJSContext cx; JS::Rooted<JSObject*> obj(cx, &mResult.toObject()); JSAutoCompartment ac(cx, obj); JSErrorReport* report = JS_ErrorFromException(cx, obj); if (!report) { return; } // Remains null in case of worker.
--- a/dom/promise/PromiseCallback.cpp +++ b/dom/promise/PromiseCallback.cpp @@ -72,22 +72,17 @@ ResolvePromiseCallback::~ResolvePromiseC { MOZ_COUNT_DTOR(ResolvePromiseCallback); } void ResolvePromiseCallback::Call(JS::Handle<JS::Value> aValue) { // Run resolver's algorithm with value and the synchronous flag set. - JSContext *cx = nsContentUtils::GetDefaultJSContextForThread(); - - Maybe<AutoCxPusher> pusher; - if (NS_IsMainThread()) { - pusher.construct(cx); - } + ThreadsafeAutoSafeJSContext cx; Maybe<JSAutoCompartment> ac; EnterCompartment(ac, cx, aValue); mPromise->ResolveInternal(cx, aValue, Promise::SyncTask); } // RejectPromiseCallback @@ -113,22 +108,17 @@ RejectPromiseCallback::~RejectPromiseCal { MOZ_COUNT_DTOR(RejectPromiseCallback); } void RejectPromiseCallback::Call(JS::Handle<JS::Value> aValue) { // Run resolver's algorithm with value and the synchronous flag set. - JSContext *cx = nsContentUtils::GetDefaultJSContextForThread(); - - Maybe<AutoCxPusher> pusher; - if (NS_IsMainThread()) { - pusher.construct(cx); - } + ThreadsafeAutoSafeJSContext cx; Maybe<JSAutoCompartment> ac; EnterCompartment(ac, cx, aValue); mPromise->RejectInternal(cx, aValue, Promise::SyncTask); } // WrapperPromiseCallback @@ -155,26 +145,17 @@ WrapperPromiseCallback::WrapperPromiseCa WrapperPromiseCallback::~WrapperPromiseCallback() { MOZ_COUNT_DTOR(WrapperPromiseCallback); } void WrapperPromiseCallback::Call(JS::Handle<JS::Value> aValue) { - // AutoCxPusher and co. interact with xpconnect, which crashes on - // workers. On workers we'll get the right context from - // GetDefaultJSContextForThread(), and since there is only one context, we - // don't need to push or pop it from the stack. - JSContext* cx = nsContentUtils::GetDefaultJSContextForThread(); - - Maybe<AutoCxPusher> pusher; - if (NS_IsMainThread()) { - pusher.construct(cx); - } + ThreadsafeAutoSafeJSContext cx; Maybe<JSAutoCompartment> ac; EnterCompartment(ac, cx, aValue); ErrorResult rv; // If invoking callback threw an exception, run resolver's reject with the // thrown exception as argument and the synchronous flag set.
--- a/dom/tests/mochitest/bugs/test_bug370098.html +++ b/dom/tests/mochitest/bugs/test_bug370098.html @@ -19,20 +19,19 @@ https://bugzilla.mozilla.org/show_bug.cg /** Test for Bug 370098 **/ function test_constructor(dom_proto, shouldthrow) { var threw = false; try { window[dom_proto](); } catch (e) { threw = true; } - if (shouldthrow) - ok(threw, "Calling |" + dom_proto + "()| should throw"); - else - todo(threw, "Calling |" + dom_proto + "()| should throw"); + // XSLTProcessor is still on the old bindings. + if (dom_proto != 'XSLTProcessor') + ok(threw, "Calling |" + dom_proto + "()| should always throw"); threw = false; try { new window[dom_proto](); } catch (e) { threw = true; } is(threw, shouldthrow, "Calling |new " + dom_proto + "()| should" + (shouldthrow ? " " : " not ") + "throw");
--- a/dom/xbl/nsXBLBinding.h +++ b/dom/xbl/nsXBLBinding.h @@ -32,17 +32,17 @@ class XBLChildrenElement; } // namespace dom } // namespace mozilla class nsAnonymousContentList; // *********************************************************************/ // The XBLBinding class -class nsXBLBinding +class nsXBLBinding MOZ_FINAL { public: nsXBLBinding(nsXBLPrototypeBinding* aProtoBinding); nsXBLBinding(mozilla::dom::ShadowRoot* aShadowRoot, nsXBLPrototypeBinding* aProtoBinding); ~nsXBLBinding(); /** * XBLBindings are refcounted. They are held onto in 3 ways:
--- a/dom/xbl/nsXBLDocumentInfo.h +++ b/dom/xbl/nsXBLDocumentInfo.h @@ -10,17 +10,17 @@ #include "nsAutoPtr.h" #include "nsWeakReference.h" #include "nsIDocument.h" #include "nsCycleCollectionParticipant.h" class nsXBLPrototypeBinding; class nsXBLDocGlobalObject; -class nsXBLDocumentInfo : public nsSupportsWeakReference +class nsXBLDocumentInfo MOZ_FINAL : public nsSupportsWeakReference { public: NS_DECL_CYCLE_COLLECTING_ISUPPORTS nsXBLDocumentInfo(nsIDocument* aDocument); virtual ~nsXBLDocumentInfo(); already_AddRefed<nsIDocument> GetDocument()
--- a/dom/xbl/nsXBLProtoImpl.h +++ b/dom/xbl/nsXBLProtoImpl.h @@ -10,17 +10,17 @@ #include "nsXBLPrototypeHandler.h" #include "nsXBLProtoImplMember.h" #include "nsXBLProtoImplField.h" #include "nsXBLBinding.h" class nsXBLPrototypeBinding; class nsXBLProtoImplAnonymousMethod; -class nsXBLProtoImpl +class nsXBLProtoImpl MOZ_FINAL { public: nsXBLProtoImpl() : mClassObject(nullptr), mMembers(nullptr), mFields(nullptr), mConstructor(nullptr), mDestructor(nullptr)
--- a/dom/xbl/nsXBLPrototypeBinding.h +++ b/dom/xbl/nsXBLPrototypeBinding.h @@ -26,17 +26,17 @@ class nsXBLBinding; class nsXBLProtoImplField; // *********************************************************************/ // The XBLPrototypeBinding class // Instances of this class are owned by the nsXBLDocumentInfo object returned // by XBLDocumentInfo(). Consumers who want to refcount things should refcount // that. -class nsXBLPrototypeBinding +class nsXBLPrototypeBinding MOZ_FINAL { public: nsIContent* GetBindingElement() const { return mBinding; } void SetBindingElement(nsIContent* aElement); nsIURI* BindingURI() const { return mBindingURI; } nsIURI* AlternateBindingURI() const { return mAlternateBindingURI; } nsIURI* DocURI() const { return mXBLDocInfoWeak->DocumentURI(); }
--- a/dom/xbl/nsXBLService.h +++ b/dom/xbl/nsXBLService.h @@ -27,18 +27,18 @@ class nsIPrincipal; class nsHashtable; namespace mozilla { namespace dom { class EventTarget; } } -class nsXBLService : public nsIObserver, - public nsSupportsWeakReference +class nsXBLService MOZ_FINAL : public nsIObserver, + public nsSupportsWeakReference { NS_DECL_ISUPPORTS static nsXBLService* gInstance; static void Init(); static void Shutdown() {
--- a/editor/libeditor/base/IMETextTxn.cpp +++ b/editor/libeditor/base/IMETextTxn.cpp @@ -10,17 +10,16 @@ #include "nsAutoPtr.h" // for nsRefPtr #include "nsDebug.h" // for NS_ASSERTION, etc #include "nsError.h" // for NS_SUCCEEDED, NS_FAILED, etc #include "nsIDOMCharacterData.h" // for nsIDOMCharacterData #include "nsIDOMRange.h" // for nsRange::SetEnd, etc #include "nsIContent.h" // for nsIContent #include "nsIEditor.h" // for nsIEditor #include "nsIPresShell.h" // for SelectionType -#include "nsIPrivateTextRange.h" // for nsIPrivateTextRange, etc #include "nsISelection.h" // for nsISelection #include "nsISelectionController.h" // for nsISelectionController, etc #include "nsISelectionPrivate.h" // for nsISelectionPrivate #include "nsISupportsImpl.h" // for nsRange::AddRef, etc #include "nsISupportsUtils.h" // for NS_ADDREF_THIS, NS_RELEASE #include "nsITransaction.h" // for nsITransaction #include "nsRange.h" // for nsRange #include "nsString.h" // for nsString @@ -44,29 +43,27 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION( NS_ADDREF_THIS(); return NS_OK; } else NS_INTERFACE_MAP_END_INHERITING(EditTxn) NS_IMETHODIMP IMETextTxn::Init(nsIDOMCharacterData *aElement, uint32_t aOffset, uint32_t aReplaceLength, - nsIPrivateTextRangeList *aTextRangeList, + TextRangeArray *aTextRangeArray, const nsAString &aStringToInsert, nsIEditor *aEditor) { - NS_ASSERTION(aElement, "illegal value- null ptr- aElement"); - NS_ASSERTION(aTextRangeList, "illegal value- null ptr - aTextRangeList"); - NS_ENSURE_TRUE(aElement && aTextRangeList, NS_ERROR_NULL_POINTER); - mElement = do_QueryInterface(aElement); + NS_ENSURE_ARG_POINTER(aElement); + mElement = aElement; mOffset = aOffset; mReplaceLength = aReplaceLength; mStringToInsert = aStringToInsert; mEditor = aEditor; - mRangeList = do_QueryInterface(aTextRangeList); + mRanges = aTextRangeArray; mFixed = false; return NS_OK; } NS_IMETHODIMP IMETextTxn::DoTransaction(void) { #ifdef DEBUG_IMETXN @@ -80,17 +77,17 @@ NS_IMETHODIMP IMETextTxn::DoTransaction( // advance caret: This requires the presentation shell to get the selection. nsresult result; if (mReplaceLength == 0) { result = mElement->InsertData(mOffset, mStringToInsert); } else { result = mElement->ReplaceData(mOffset, mReplaceLength, mStringToInsert); } if (NS_SUCCEEDED(result)) { - result = CollapseTextSelection(); + result = SetSelectionForRanges(); } return result; } NS_IMETHODIMP IMETextTxn::UndoTransaction(void) { #ifdef DEBUG_IMETXN @@ -137,19 +134,18 @@ NS_IMETHODIMP IMETextTxn::Merge(nsITrans // IMETextTxn* otherTxn = nullptr; nsresult result = aTransaction->QueryInterface(IMETextTxn::GetCID(),(void**)&otherTxn); if (otherTxn && NS_SUCCEEDED(result)) { // // we absorb the next IME transaction by adopting its insert string as our own // - nsIPrivateTextRangeList* newTextRangeList; - otherTxn->GetData(mStringToInsert,&newTextRangeList); - mRangeList = do_QueryInterface(newTextRangeList); + mStringToInsert = otherTxn->mStringToInsert; + mRanges = otherTxn->mRanges; *aDidMerge = true; #ifdef DEBUG_IMETXN printf("IMETextTxn assimilated IMETextTxn:%p\n", aTransaction); #endif NS_RELEASE(otherTxn); return NS_OK; } @@ -166,201 +162,139 @@ NS_IMETHODIMP IMETextTxn::MarkFixed(void NS_IMETHODIMP IMETextTxn::GetTxnDescription(nsAString& aString) { aString.AssignLiteral("IMETextTxn: "); aString += mStringToInsert; return NS_OK; } /* ============ protected methods ================== */ -static SelectionType TextRangeToSelection(int aTextRangeType) +static SelectionType +ToSelectionType(uint32_t aTextRangeType) { - switch(aTextRangeType) - { - case nsIPrivateTextRange::TEXTRANGE_RAWINPUT: - return nsISelectionController::SELECTION_IME_RAWINPUT; - case nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT: - return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT; - case nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT: - return nsISelectionController::SELECTION_IME_CONVERTEDTEXT; - case nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT: - return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT; - case nsIPrivateTextRange::TEXTRANGE_CARETPOSITION: - default: - return nsISelectionController::SELECTION_NORMAL; - }; -} - -NS_IMETHODIMP IMETextTxn::GetData(nsString& aResult,nsIPrivateTextRangeList** aTextRangeList) -{ - NS_ASSERTION(aTextRangeList, "illegal value- null ptr- aTextRangeList"); - NS_ENSURE_TRUE(aTextRangeList, NS_ERROR_NULL_POINTER); - aResult = mStringToInsert; - *aTextRangeList = mRangeList; - return NS_OK; + switch(aTextRangeType) { + case NS_TEXTRANGE_RAWINPUT: + return nsISelectionController::SELECTION_IME_RAWINPUT; + case NS_TEXTRANGE_SELECTEDRAWTEXT: + return nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT; + case NS_TEXTRANGE_CONVERTEDTEXT: + return nsISelectionController::SELECTION_IME_CONVERTEDTEXT; + case NS_TEXTRANGE_SELECTEDCONVERTEDTEXT: + return nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT; + default: + MOZ_CRASH("Selection type is invalid"); + return nsISelectionController::SELECTION_NORMAL; + } } -static SelectionType sel[4]= +nsresult +IMETextTxn::SetSelectionForRanges() { - nsISelectionController::SELECTION_IME_RAWINPUT, - nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT, - nsISelectionController::SELECTION_IME_CONVERTEDTEXT, - nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT -}; + nsCOMPtr<nsISelectionController> selCon; + mEditor->GetSelectionController(getter_AddRefs(selCon)); + NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); -NS_IMETHODIMP IMETextTxn::CollapseTextSelection(void) -{ - nsresult result; - uint16_t i; + nsCOMPtr<nsISelection> selection; + nsresult rv = + selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, + getter_AddRefs(selection)); + NS_ENSURE_SUCCESS(rv, rv); -#ifdef DEBUG_IMETXN - uint16_t listlen,start,stop,type; - result = mRangeList->GetLength(&listlen); - printf("nsIPrivateTextRangeList[%p]\n",mRangeList); - nsIPrivateTextRange* rangePtr; - for (i=0;i<listlen;i++) { - (void)mRangeList->Item(i,&rangePtr); - rangePtr->GetRangeStart(&start); - rangePtr->GetRangeEnd(&stop); - rangePtr->GetRangeType(&type); - printf("range[%d] start=%d end=%d type=",i,start,stop,type); - if (type==nsIPrivateTextRange::TEXTRANGE_RAWINPUT) - printf("TEXTRANGE_RAWINPUT\n"); - else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDRAWTEXT) - printf("TEXTRANGE_SELECTEDRAWTEXT\n"); - else if (type==nsIPrivateTextRange::TEXTRANGE_CONVERTEDTEXT) - printf("TEXTRANGE_CONVERTEDTEXT\n"); - else if (type==nsIPrivateTextRange::TEXTRANGE_SELECTEDCONVERTEDTEXT) - printf("TEXTRANGE_SELECTEDCONVERTEDTEXT\n"); - else if (type==nsIPrivateTextRange::TEXTRANGE_CARETPOSITION) - printf("TEXTRANGE_CARETPOSITION\n"); - else printf("unknown constant\n"); + nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection)); + rv = selPriv->StartBatchChanges(); + NS_ENSURE_SUCCESS(rv, rv); + + // First, remove all selections of IME composition. + static const SelectionType kIMESelections[] = { + nsISelectionController::SELECTION_IME_RAWINPUT, + nsISelectionController::SELECTION_IME_SELECTEDRAWTEXT, + nsISelectionController::SELECTION_IME_CONVERTEDTEXT, + nsISelectionController::SELECTION_IME_SELECTEDCONVERTEDTEXT + }; + for (uint32_t i = 0; i < ArrayLength(kIMESelections); ++i) { + nsCOMPtr<nsISelection> selectionOfIME; + if (NS_FAILED(selCon->GetSelection(kIMESelections[i], + getter_AddRefs(selectionOfIME)))) { + continue; } -#endif - - // - // run through the text range list, if any - // - nsCOMPtr<nsISelectionController> selCon; - mEditor->GetSelectionController(getter_AddRefs(selCon)); - NS_ENSURE_TRUE(selCon, NS_ERROR_NOT_INITIALIZED); + DebugOnly<nsresult> rv = selectionOfIME->RemoveAllRanges(); + NS_ASSERTION(NS_SUCCEEDED(rv), + "Failed to remove all ranges of IME selection"); + } + + // Set caret position and selection of IME composition with TextRangeArray. + bool setCaret = false; + uint32_t countOfRanges = mRanges ? mRanges->Length() : 0; + for (uint32_t i = 0; i < countOfRanges; ++i) { + const TextRange& textRange = mRanges->ElementAt(i); - uint16_t textRangeListLength,selectionStart,selectionEnd, - textRangeType; - - textRangeListLength = mRangeList->GetLength(); - nsCOMPtr<nsISelection> selection; - result = selCon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection)); - if(NS_SUCCEEDED(result)) - { - nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection)); - result = selPriv->StartBatchChanges(); - if (NS_SUCCEEDED(result)) - { - nsCOMPtr<nsISelection> imeSel; - for(int8_t selIdx = 0; selIdx < 4;selIdx++) - { - result = selCon->GetSelection(sel[selIdx], getter_AddRefs(imeSel)); - if (NS_SUCCEEDED(result)) - { - result = imeSel->RemoveAllRanges(); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot ClearSelection"); - // we just ignore the result and clean up the next one here - } - } - - nsCOMPtr<nsIPrivateTextRange> textRange; - bool setCaret=false; - for(i=0;i<textRangeListLength;i++) - { - textRange = mRangeList->Item(i); - NS_ASSERTION(textRange, "cannot get item"); - if(!textRange) - break; + // Caret needs special handling since its length may be 0 and if it's not + // specified explicitly, we need to handle it ourselves later. + if (textRange.mRangeType == NS_TEXTRANGE_CARETPOSITION) { + NS_ASSERTION(!setCaret, "The ranges already has caret position"); + NS_ASSERTION(!textRange.Length(), "nsEditor doesn't support wide caret"); + // NOTE: If the caret position is larger than max length of the editor + // content, this may fail. + rv = selection->Collapse(mElement, mOffset + textRange.mStartOffset); + setCaret = setCaret || NS_SUCCEEDED(rv); + NS_ASSERTION(setCaret, "Failed to collapse normal selection"); + continue; + } - result = textRange->GetRangeType(&textRangeType); - NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range type"); - if(NS_FAILED(result)) - break; - - result = textRange->GetRangeStart(&selectionStart); - NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range start"); - if(NS_FAILED(result)) - break; - result = textRange->GetRangeEnd(&selectionEnd); - NS_ASSERTION(NS_SUCCEEDED(result), "cannot get range end"); - if(NS_FAILED(result)) - break; + // If the clause length is 0, it's should be a bug. + if (!textRange.Length()) { + NS_WARNING("Any clauses must not be empty"); + continue; + } - if(nsIPrivateTextRange::TEXTRANGE_CARETPOSITION == textRangeType) - { - NS_ASSERTION(selectionStart == selectionEnd, - "nsEditor doesn't support wide caret"); - // Set the caret.... - result = selection->Collapse(mElement, - mOffset+selectionStart); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse"); - if(NS_SUCCEEDED(result)) - setCaret = true; - } else { - // NS_ASSERTION(selectionStart != selectionEnd, "end == start"); - if(selectionStart == selectionEnd) - continue; + nsRefPtr<nsRange> clauseRange; + rv = nsRange::CreateRange(mElement, mOffset + textRange.mStartOffset, + mElement, mOffset + textRange.mEndOffset, + getter_AddRefs(clauseRange)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to create a DOM range for a clause of composition"); + break; + } - result= selCon->GetSelection(TextRangeToSelection(textRangeType), - getter_AddRefs(imeSel)); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot get selction"); - if(NS_FAILED(result)) - break; - - nsCOMPtr<nsIContent> content = do_QueryInterface(mElement); - if (!content) { - break; - } + // Set the range of the clause to selection. + nsCOMPtr<nsISelection> selectionOfIME; + rv = selCon->GetSelection(ToSelectionType(textRange.mRangeType), + getter_AddRefs(selectionOfIME)); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to get IME selection"); + break; + } - nsRefPtr<nsRange> newRange = new nsRange(content); - result = newRange->SetStart(content, mOffset+selectionStart); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetStart"); - if(NS_FAILED(result)) - break; - - result = newRange->SetEnd(mElement,mOffset+selectionEnd); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot SetEnd"); - if(NS_FAILED(result)) - break; - - result = imeSel->AddRange(newRange); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot AddRange"); - if(NS_FAILED(result)) - break; + rv = selectionOfIME->AddRange(clauseRange); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to add selection range for a clause of composition"); + break; + } - nsCOMPtr<nsISelectionPrivate> imeSelPriv( - do_QueryInterface(imeSel)); - if (imeSelPriv) { - TextRangeStyle textRangeStyle; - result = textRange->GetRangeStyle(&textRangeStyle); - NS_ASSERTION(NS_SUCCEEDED(result), - "nsIPrivateTextRange::GetRangeStyle failed"); - if (NS_FAILED(result)) - break; - result = imeSelPriv->SetTextRangeStyle(newRange, textRangeStyle); - NS_ASSERTION(NS_SUCCEEDED(result), - "nsISelectionPrivate::SetTextRangeStyle failed"); - if (NS_FAILED(result)) - break; - } else { - NS_WARNING("IME selection doesn't have nsISelectionPrivate"); - } - } // if GetRangeEnd - } // for textRangeListLength - if(! setCaret) { - // set cursor - result = selection->Collapse(mElement,mOffset+mStringToInsert.Length()); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot Collapse"); - } - result = selPriv->EndBatchChanges(); - NS_ASSERTION(NS_SUCCEEDED(result), "Cannot EndBatchChanges"); - } // if StartBatchChanges - } // if GetSelection + // Set the style of the clause. + nsCOMPtr<nsISelectionPrivate> selectionOfIMEPriv = + do_QueryInterface(selectionOfIME); + if (!selectionOfIMEPriv) { + NS_WARNING("Failed to get nsISelectionPrivate interface from selection"); + continue; // Since this is additional feature, we can continue this job. + } + rv = selectionOfIMEPriv->SetTextRangeStyle(clauseRange, + textRange.mRangeStyle); + if (NS_FAILED(rv)) { + NS_WARNING("Failed to set selection style"); + break; // but this is unexpected... + } + } - return result; + // If the ranges doesn't include explicit caret position, let's set the + // caret to the end of composition string. + if (!setCaret) { + rv = selection->Collapse(mElement, mOffset + mStringToInsert.Length()); + NS_ASSERTION(NS_SUCCEEDED(rv), + "Failed to set caret at the end of composition string"); + } + + rv = selPriv->EndBatchChanges(); + NS_ASSERTION(NS_SUCCEEDED(rv), "Failed to end batch changes"); + + return rv; }
--- a/editor/libeditor/base/IMETextTxn.h +++ b/editor/libeditor/base/IMETextTxn.h @@ -6,19 +6,19 @@ #ifndef IMETextTxn_h__ #define IMETextTxn_h__ #include "EditTxn.h" #include "nsCOMPtr.h" #include "nsCycleCollectionParticipant.h" #include "nsID.h" #include "nsIDOMCharacterData.h" -#include "nsIPrivateTextRange.h" #include "nsString.h" #include "nscore.h" +#include "mozilla/TextRange.h" class nsITransaction; // {D4D25721-2813-11d3-9EA3-0060089FE59B} #define IME_TEXT_TXN_CID \ {0xd4d25721, 0x2813, 0x11d3, \ {0x9e, 0xa3, 0x0, 0x60, 0x8, 0x9f, 0xe5, 0x9b }} @@ -33,23 +33,24 @@ class IMETextTxn : public EditTxn { public: static const nsIID& GetCID() { static const nsIID iid = IME_TEXT_TXN_CID; return iid; } /** initialize the transaction * @param aElement the text content node * @param aOffset the location in aElement to do the insertion * @param aReplaceLength the length of text to replace (0 == no replacement) + * @param aTextRangeArray clauses and/or caret information. This may be null. * @param aString the new text to insert * @param aSelCon used to get and set the selection */ NS_IMETHOD Init(nsIDOMCharacterData *aElement, uint32_t aOffset, uint32_t aReplaceLength, - nsIPrivateTextRangeList* aTextRangeList, + mozilla::TextRangeArray* aTextRangeArray, const nsAString& aString, nsIEditor* aEditor); IMETextTxn(); NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IMETextTxn, EditTxn) NS_DECL_EDITTXN @@ -58,36 +59,33 @@ public: NS_IMETHOD MarkFixed(void); // nsISupports declarations // override QueryInterface to handle IMETextTxn request NS_IMETHOD QueryInterface(const nsIID& aIID, void** aInstancePtr); - /** return the string data associated with this transaction */ - NS_IMETHOD GetData(nsString& aResult, nsIPrivateTextRangeList** aTextRangeList); - protected: - NS_IMETHOD CollapseTextSelection(void); + nsresult SetSelectionForRanges(); /** the text element to operate upon */ nsCOMPtr<nsIDOMCharacterData> mElement; /** the offsets into mElement where the insertion should be placed*/ uint32_t mOffset; uint32_t mReplaceLength; /** the text to insert into mElement at mOffset */ nsString mStringToInsert; /** the range list **/ - nsCOMPtr<nsIPrivateTextRangeList> mRangeList; + nsRefPtr<mozilla::TextRangeArray> mRanges; /** the editor, which is used to get the selection controller */ nsIEditor *mEditor; bool mFixed; }; #endif
--- a/editor/libeditor/base/nsEditor.cpp +++ b/editor/libeditor/base/nsEditor.cpp @@ -76,17 +76,16 @@ #include "nsIHTMLDocument.h" // for nsIHTMLDocument #include "nsIInlineSpellChecker.h" // for nsIInlineSpellChecker, etc #include "nsIMEStateManager.h" // for nsIMEStateManager #include "nsNameSpaceManager.h" // for kNameSpaceID_None, etc #include "nsINode.h" // for nsINode, etc #include "nsIObserverService.h" // for nsIObserverService #include "nsIPlaintextEditor.h" // for nsIPlaintextEditor, etc #include "nsIPresShell.h" // for nsIPresShell -#include "nsIPrivateTextRange.h" // for nsIPrivateTextRange, etc #include "nsISelection.h" // for nsISelection, etc #include "nsISelectionController.h" // for nsISelectionController, etc #include "nsISelectionDisplay.h" // for nsISelectionDisplay, etc #include "nsISelectionPrivate.h" // for nsISelectionPrivate, etc #include "nsISupportsBase.h" // for nsISupports #include "nsISupportsUtils.h" // for NS_ADDREF, NS_IF_ADDREF #include "nsITransaction.h" // for nsITransaction #include "nsITransactionManager.h" @@ -160,17 +159,16 @@ nsEditor::~nsEditor() } NS_IMPL_CYCLE_COLLECTION_CLASS(nsEditor) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsEditor) NS_IMPL_CYCLE_COLLECTION_UNLINK(mRootElement) NS_IMPL_CYCLE_COLLECTION_UNLINK(mInlineSpellChecker) NS_IMPL_CYCLE_COLLECTION_UNLINK(mTxnMgr) - NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextRangeList) NS_IMPL_CYCLE_COLLECTION_UNLINK(mIMETextNode) NS_IMPL_CYCLE_COLLECTION_UNLINK(mActionListeners) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEditorObservers) NS_IMPL_CYCLE_COLLECTION_UNLINK(mDocStateListeners) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventTarget) NS_IMPL_CYCLE_COLLECTION_UNLINK(mEventListener) NS_IMPL_CYCLE_COLLECTION_UNLINK_END @@ -179,17 +177,16 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN( tmp->mRootElement ? tmp->mRootElement->GetCurrentDoc() : nullptr; if (currentDoc && nsCCUncollectableMarker::InGeneration(cb, currentDoc->GetMarkedCCGeneration())) { return NS_SUCCESS_INTERRUPTED_TRAVERSE; } NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mRootElement) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mInlineSpellChecker) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mTxnMgr) - NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextRangeList) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mIMETextNode) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mActionListeners) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEditorObservers) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mDocStateListeners) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mEventListener) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END @@ -2418,60 +2415,36 @@ nsresult nsEditor::InsertTextIntoTextNod int32_t aOffset, bool aSuppressIME) { nsRefPtr<EditTxn> txn; nsresult result = NS_OK; bool isIMETransaction = false; // aSuppressIME is used when editor must insert text, yet this text is not // part of current ime operation. example: adjusting whitespace around an ime insertion. - if (mIMETextRangeList && mComposition && !aSuppressIME) - { - if (!mIMETextNode) - { + if (mComposition && !aSuppressIME) { + if (!mIMETextNode) { mIMETextNode = aTextNode; mIMETextOffset = aOffset; } - uint16_t len ; - len = mIMETextRangeList->GetLength(); - if (len > 0) - { - nsCOMPtr<nsIPrivateTextRange> range; - for (uint16_t i = 0; i < len; i++) - { - range = mIMETextRangeList->Item(i); - if (range) - { - uint16_t type; - result = range->GetRangeType(&type); - if (NS_SUCCEEDED(result)) - { - if (type == nsIPrivateTextRange::TEXTRANGE_RAWINPUT) - { - uint16_t start, end; - result = range->GetRangeStart(&start); - if (NS_SUCCEEDED(result)) - { - result = range->GetRangeEnd(&end); - if (NS_SUCCEEDED(result)) - { - if (!mPhonetic) - mPhonetic = new nsString(); - if (mPhonetic) - { - nsAutoString tmp(aStringToInsert); - tmp.Mid(*mPhonetic, start, end-start); - } - } - } - } // if - } - } // if - } // for - } // if + // Modify mPhonetic with raw text input clauses. + const TextRangeArray* ranges = mComposition->GetRanges(); + for (uint32_t i = 0; i < (ranges ? ranges->Length() : 0); ++i) { + const TextRange& textRange = ranges->ElementAt(i); + if (!textRange.Length() || + textRange.mRangeType != NS_TEXTRANGE_RAWINPUT) { + continue; + } + if (!mPhonetic) { + mPhonetic = new nsString(); + } + nsAutoString stringToInsert(aStringToInsert); + stringToInsert.Mid(*mPhonetic, + textRange.mStartOffset, textRange.Length()); + } nsRefPtr<IMETextTxn> imeTxn; result = CreateTxnForIMEText(aStringToInsert, getter_AddRefs(imeTxn)); txn = imeTxn; isIMETransaction = true; } else { @@ -4397,19 +4370,20 @@ NS_IMETHODIMP nsEditor::CreateTxnForIMEText(const nsAString& aStringToInsert, IMETextTxn ** aTxn) { NS_ASSERTION(aTxn, "illegal value- null ptr- aTxn"); nsRefPtr<IMETextTxn> txn = new IMETextTxn(); // During handling IME composition, mComposition must have been initialized. + // TODO: We can simplify IMETextTxn::Init() with TextComposition class. nsresult rv = txn->Init(mIMETextNode, mIMETextOffset, mComposition->String().Length(), - mIMETextRangeList, aStringToInsert, this); + mComposition->GetRanges(), aStringToInsert, this); if (NS_SUCCEEDED(rv)) { txn.forget(aTxn); } return rv; }
--- a/editor/libeditor/base/nsEditor.h +++ b/editor/libeditor/base/nsEditor.h @@ -53,17 +53,16 @@ class nsIDOMNode; class nsIDOMRange; class nsIDocument; class nsIDocumentStateListener; class nsIEditActionListener; class nsIEditorObserver; class nsIInlineSpellChecker; class nsINode; class nsIPresShell; -class nsIPrivateTextRangeList; class nsISelection; class nsISupports; class nsITransaction; class nsIWidget; class nsRange; class nsString; class nsTransactionManager; @@ -828,17 +827,16 @@ protected: }; // Spellchecking nsCString mContentMIMEType; // MIME type of the doc we are editing. nsCOMPtr<nsIInlineSpellChecker> mInlineSpellChecker; nsRefPtr<nsTransactionManager> mTxnMgr; nsCOMPtr<mozilla::dom::Element> mRootElement; // cached root node - nsCOMPtr<nsIPrivateTextRangeList> mIMETextRangeList; // IME special selection ranges nsCOMPtr<nsIDOMCharacterData> mIMETextNode; // current IME text node nsCOMPtr<mozilla::dom::EventTarget> mEventTarget; // The form field as an event receiver nsCOMPtr<nsIDOMEventListener> mEventListener; nsWeakPtr mSelConWeak; // weak reference to the nsISelectionController nsWeakPtr mPlaceHolderTxn; // weak reference to placeholder for begin/end batch purposes nsWeakPtr mDocWeak; // weak reference to the nsIDOMDocument nsIAtom *mPlaceHolderName; // name of placeholder transaction nsSelectionState *mSelState; // saved selection state for placeholder txn batching
--- a/editor/libeditor/text/nsPlaintextEditor.cpp +++ b/editor/libeditor/text/nsPlaintextEditor.cpp @@ -35,18 +35,16 @@ #include "nsIDOMKeyEvent.h" #include "nsIDOMNode.h" #include "nsIDOMNodeList.h" #include "nsIDocumentEncoder.h" #include "nsIEditorIMESupport.h" #include "nsNameSpaceManager.h" #include "nsINode.h" #include "nsIPresShell.h" -#include "nsIPrivateTextEvent.h" -#include "nsIPrivateTextRange.h" #include "nsISelection.h" #include "nsISelectionController.h" #include "nsISelectionPrivate.h" #include "nsISupportsPrimitives.h" #include "nsITransferable.h" #include "nsIWeakReferenceUtils.h" #include "nsInternetCiter.h" #include "nsLiteralString.h" @@ -843,30 +841,20 @@ nsPlaintextEditor::UpdateIMEComposition( NS_ENSURE_TRUE(ps, NS_ERROR_NOT_INITIALIZED); nsCOMPtr<nsISelection> selection; nsresult rv = GetSelection(getter_AddRefs(selection)); NS_ENSURE_SUCCESS(rv, rv); nsRefPtr<nsCaret> caretP = ps->GetCaret(); - nsCOMPtr<nsIPrivateTextEvent> privateTextEvent = - do_QueryInterface(aDOMTextEvent); - NS_ENSURE_TRUE(privateTextEvent, NS_ERROR_INVALID_ARG); - { TextComposition::TextEventHandlingMarker textEventHandlingMarker(mComposition, widgetTextEvent); - // Update information of clauses in the new composition string. - // This will be refered by followed methods. - mIMETextRangeList = privateTextEvent->GetInputRange(); - NS_ABORT_IF_FALSE(mIMETextRangeList, - "mIMETextRangeList must not be nullptr"); - nsAutoPlaceHolderBatch batch(this, nsGkAtoms::IMETxnName); rv = InsertText(widgetTextEvent->theText); if (caretP) { caretP->SetCaretDOMSelection(selection); } }
--- a/editor/libeditor/text/nsPlaintextEditor.h +++ b/editor/libeditor/text/nsPlaintextEditor.h @@ -21,17 +21,16 @@ class nsIDOMDocument; class nsIDOMElement; class nsIDOMEvent; class nsIDOMEventTarget; class nsIDOMKeyEvent; class nsIDOMNode; class nsIDocumentEncoder; class nsIEditRules; class nsIOutputStream; -class nsIPrivateTextRangeList; class nsISelection; class nsISelectionController; class nsITransferable; /** * The text editor implementation. * Use to edit text document represented as a DOM tree. */
--- a/gfx/2d/Makefile.in +++ b/gfx/2d/Makefile.in @@ -9,25 +9,9 @@ endif include $(topsrcdir)/config/rules.mk # Due to bug 796023, we can't have -DUNICODE and -D_UNICODE; defining those # macros changes the type of LOGFONT to LOGFONTW instead of LOGFONTA. This # changes the symbol names of exported C++ functions that use LOGFONT. DEFINES := $(filter-out -DUNICODE -D_UNICODE,$(DEFINES)) -# The file uses SSE2 intrinsics, so it needs special compile flags on some -# compilers. -ifneq (,$(INTEL_ARCHITECTURE)) -ifdef GNU_CC -ImageScalingSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -BlurSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -FilterProcessingSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -endif - -ifdef SOLARIS_SUNPRO_CXX -ImageScalingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -BlurSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -FilterProcessingSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -endif -endif - CXXFLAGS += $(MOZ_CAIRO_CFLAGS)
--- a/gfx/2d/moz.build +++ b/gfx/2d/moz.build @@ -83,16 +83,26 @@ if CONFIG['INTEL_ARCHITECTURE']: # VC2005 doesn't support _mm_castsi128_ps, so SSE2 is turned off if CONFIG['_MSC_VER'] != '1400': SOURCES += [ 'BlurSSE2.cpp', 'FilterProcessingSSE2.cpp', 'ImageScalingSSE2.cpp', ] DEFINES['USE_SSE2'] = True + # The file uses SSE2 intrinsics, so it needs special compile flags on some + # compilers. + if CONFIG['GNU_CC']: + SOURCES['BlurSSE2.cpp'].flags += ['-msse2'] + SOURCES['FilterProcessingSSE2.cpp'].flags += ['-msse2'] + SOURCES['ImageScalingSSE2.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['BlurSSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] + SOURCES['FilterProcessingSSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] + SOURCES['ImageScalingSSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] UNIFIED_SOURCES += [ 'Blur.cpp', 'DataSourceSurface.cpp', 'DrawEventRecorder.cpp', 'DrawTargetCairo.cpp', 'DrawTargetDual.cpp', 'DrawTargetRecording.cpp',
--- a/gfx/angle/src/libGLESv2/Makefile.in +++ b/gfx/angle/src/libGLESv2/Makefile.in @@ -13,19 +13,16 @@ endif # End build_angle.gypi transcription. include $(topsrcdir)/config/rules.mk CXXFLAGS += -I'$(MOZ_DIRECTX_SDK_PATH)/include' ifdef GNU_CC -TextureSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -ImageSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 - OS_CXXFLAGS := $(filter-out -fno-exceptions,$(OS_CXXFLAGS)) -fexceptions OS_LIBS += -ld3d9 -ldxguid else EXTRA_DSO_LDOPTS = '$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/d3d9.lib' \ '$(MOZ_DIRECTX_SDK_PATH)/lib/$(MOZ_DIRECTX_SDK_CPU_SUFFIX)/dxguid.lib' \ delayimp.lib
--- a/gfx/angle/src/libGLESv2/moz.build +++ b/gfx/angle/src/libGLESv2/moz.build @@ -167,16 +167,19 @@ SOURCES += ['renderer/' + src for src in 'TextureStorage9.cpp', 'VertexBuffer.cpp', 'VertexBuffer11.cpp', 'VertexBuffer9.cpp', 'VertexDataManager.cpp', 'VertexDeclarationCache.cpp', ]] +if CONFIG['GNU_CC']: + SOURCES['renderer/ImageSSE2.cpp'].flags += ['-msse2'] + # On Windows, we don't automatically get "lib" prepended, but we need it. LIBRARY_NAME = 'libGLESv2' FORCE_SHARED_LIB = True LOCAL_INCLUDES += [ '..', '../../include',
--- a/gfx/cairo/libpixman/src/Makefile.in +++ b/gfx/cairo/libpixman/src/Makefile.in @@ -1,68 +1,19 @@ # 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/. ifeq ($(OS_TARGET),Android) MODULE_OPTIMIZE_FLAGS = -O2 endif -# Build MMX code either with VC or with gcc-on-x86 -ifdef _MSC_VER -ifeq (86,$(findstring 86,$(OS_TEST))) -USE_SSE2=1 -MMX_CFLAGS= -SSE2_CFLAGS= -endif -endif - -ifdef GNU_CC -ifeq (ppc,$(findstring ppc,$(OS_TEST))) -VMX_CFLAGS=-maltivec -endif -ifeq (86,$(findstring 86,$(OS_TEST))) -MMX_CFLAGS=-mmmx -Winline -ifeq (64,$(findstring 64,$(OS_TEST))) -USE_SSE2=1 -endif -ifdef HAVE_GCC_ALIGN_ARG_POINTER -USE_SSE2=1 -endif -ifdef USE_SSE2 -SSE2_CFLAGS=-msse -msse2 -Winline -endif -MMX_CFLAGS+=--param inline-unit-growth=10000 --param large-function-growth=10000 -endif -ifeq (arm,$(findstring arm,$(OS_TEST))) -# Apple's arm assembler doesn't support the same syntax as -# the standard GNU assembler, so use the C fallback paths for now. -# This may be fixable if clang's ARM/iOS assembler improves into a -# viable solution in the future. -ifneq (Darwin,$(OS_ARCH)) -ifdef HAVE_ARM_NEON -ARM_NEON_CFLAGS = -mfpu=neon -endif -endif -endif - -endif - include $(topsrcdir)/config/rules.mk # Disable spammy "missing initializer" GCC warning ifdef GNU_CC CFLAGS += -Wno-missing-field-initializers endif # GNU_CC -# special rule for pixman-mmx to get the right cflags -pixman-mmx.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(MMX_CFLAGS) - -pixman-sse2.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(SSE2_CFLAGS) - -pixman-arm-neon.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(ARM_NEON_CFLAGS) - -pixman-vmx.$(OBJ_SUFFIX): COMPILE_CFLAGS += $(VMX_CFLAGS) - # The ARM asm functions here don't appreciate being called by functions # compiled with -mapcs-frame. See bug 832752. CXXFLAGS := $(filter-out -mapcs-frame,$(CXXFLAGS)) CFLAGS := $(filter-out -mapcs-frame,$(CFLAGS))
--- a/gfx/cairo/libpixman/src/moz.build +++ b/gfx/cairo/libpixman/src/moz.build @@ -106,25 +106,40 @@ elif 'arm' in CONFIG['OS_TEST']: if CONFIG['HAVE_ARM_SIMD']: use_arm_simd_gcc = True if CONFIG['HAVE_ARM_NEON']: use_arm_neon_gcc = True if use_mmx: DEFINES['USE_MMX'] = True SOURCES += ['pixman-mmx.c'] + if CONFIG['GNU_CC']: + SOURCES['pixman-mmx.c'].flags += [ + '-mmmx', + '-Winline', + '--param inline-unit-growth=10000', + '--param large-function-growth=10000', + ] if use_sse2: DEFINES['USE_SSE'] = True DEFINES['USE_SSE2'] = True SOURCES += ['pixman-sse2.c'] + if CONFIG['GNU_CC']: + SOURCES['pixman-sse2.c'].flags += [ + '-msse', + '-msse2', + '-Winline', + ] if use_vmx: DEFINES['USE_VMX'] = True SOURCES += ['pixman-vmx.c'] + SOURCES['pixman-vmx.c'].flags += ['-maltivec'] if use_arm_simd_gcc: DEFINES['USE_ARM_SIMD'] = True SOURCES += ['pixman-arm-simd.c'] if use_arm_neon_gcc: DEFINES['USE_ARM_NEON'] = True SOURCES += ['pixman-arm-neon.c'] + SOURCES['pixman-arm-neon.c'].flags += ['-mfpu=neon']
--- a/gfx/gl/GLContext.cpp +++ b/gfx/gl/GLContext.cpp @@ -533,17 +533,18 @@ GLContext::InitWithPrefix(const char *pr const char *vendorMatchStrings[size_t(GLVendor::Other)] = { "Intel", "NVIDIA", "ATI", "Qualcomm", "Imagination", "nouveau", - "Vivante" + "Vivante", + "VMware, Inc." }; mVendor = GLVendor::Other; for (size_t i = 0; i < size_t(GLVendor::Other); ++i) { if (DoesStringMatch(glVendorString, vendorMatchStrings[i])) { mVendor = GLVendor(i); break; } @@ -558,17 +559,18 @@ GLContext::InitWithPrefix(const char *pr const char *rendererMatchStrings[size_t(GLRenderer::Other)] = { "Adreno 200", "Adreno 205", "Adreno (TM) 205", "Adreno (TM) 320", "PowerVR SGX 530", "PowerVR SGX 540", "NVIDIA Tegra", - "Android Emulator" + "Android Emulator", + "Gallium 0.4 on llvmpipe" }; mRenderer = GLRenderer::Other; for (size_t i = 0; i < size_t(GLRenderer::Other); ++i) { if (DoesStringMatch(glRendererString, rendererMatchStrings[i])) { mRenderer = GLRenderer(i); break; } @@ -1092,17 +1094,17 @@ GLContext::InitWithPrefix(const char *pr mMaxTextureSize = std::min(mMaxTextureSize, 8191); mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 8191); } else { // See bug 877949. mMaxTextureSize = std::min(mMaxTextureSize, 4096); mMaxRenderbufferSize = std::min(mMaxRenderbufferSize, 4096); } - + // Part of the bug 879656, but it also doesn't hurt the 877949 mNeedsTextureSizeChecks = true; } } #endif #ifdef MOZ_X11 if (mWorkAroundDriverBugs && mVendor == GLVendor::Nouveau) { @@ -1173,16 +1175,29 @@ GLContext::InitExtensions() if (WorkAroundDriverBugs() && Renderer() == GLRenderer::AndroidEmulator) { // the Android emulator, which we use to run B2G reftests on, // doesn't expose the OES_rgb8_rgba8 extension, but it seems to // support it (tautologically, as it only runs on desktop GL). MarkExtensionSupported(OES_rgb8_rgba8); } + if (WorkAroundDriverBugs() && + Vendor() == GLVendor::VMware && + Renderer() == GLRenderer::GalliumLlvmpipe) + { + // The llvmpipe driver that is used on linux try servers appears to have + // buggy support for s3tc/dxt1 compressed textures. + // See Bug 975824. + MarkExtensionUnsupported(EXT_texture_compression_s3tc); + MarkExtensionUnsupported(EXT_texture_compression_dxt1); + MarkExtensionUnsupported(ANGLE_texture_compression_dxt3); + MarkExtensionUnsupported(ANGLE_texture_compression_dxt5); + } + #ifdef DEBUG firstRun = false; #endif } void GLContext::PlatformStartup() {
--- a/gfx/gl/GLContext.h +++ b/gfx/gl/GLContext.h @@ -126,28 +126,30 @@ MOZ_END_ENUM_CLASS(ContextProfile) MOZ_BEGIN_ENUM_CLASS(GLVendor) Intel, NVIDIA, ATI, Qualcomm, Imagination, Nouveau, Vivante, + VMware, Other MOZ_END_ENUM_CLASS(GLVendor) MOZ_BEGIN_ENUM_CLASS(GLRenderer) Adreno200, Adreno205, AdrenoTM205, AdrenoTM320, SGX530, SGX540, Tegra, AndroidEmulator, + GalliumLlvmpipe, Other MOZ_END_ENUM_CLASS(GLRenderer) class GLContext : public GLLibraryLoader , public GenericAtomicRefCounted { // -----------------------------------------------------------------------------
--- a/gfx/tests/gtest/TestAsyncPanZoomController.cpp +++ b/gfx/tests/gtest/TestAsyncPanZoomController.cpp @@ -28,30 +28,30 @@ using ::testing::AtMost; using ::testing::MockFunction; using ::testing::InSequence; class Task; class AsyncPanZoomControllerTester : public ::testing::Test { protected: virtual void SetUp() { - gfxPrefs::One(); + gfxPrefs::GetSingleton(); } virtual void TearDown() { - gfxPrefs::Destroy(); + gfxPrefs::DestroySingleton(); } }; class APZCTreeManagerTester : public ::testing::Test { protected: virtual void SetUp() { - gfxPrefs::One(); + gfxPrefs::GetSingleton(); } virtual void TearDown() { - gfxPrefs::Destroy(); + gfxPrefs::DestroySingleton(); } }; class MockContentController : public GeckoContentController { public: MOCK_METHOD1(RequestContentRepaint, void(const FrameMetrics&)); MOCK_METHOD2(AcknowledgeScrollUpdate, void(const FrameMetrics::ViewID&, const uint32_t& aScrollGeneration)); MOCK_METHOD3(HandleDoubleTap, void(const CSSIntPoint&, int32_t, const ScrollableLayerGuid&));
new file mode 100644 --- /dev/null +++ b/gfx/tests/gtest/TestGfxPrefs.cpp @@ -0,0 +1,67 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* 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 "gtest/gtest.h" + +#include "gfxPrefs.h" +#ifdef GFX_DECL_PREF +#error "This is not supposed to be defined outside of gfxPrefs.h" +#endif + +// If the default values for any of these preferences change, +// just modify the test to match. We are only testing against +// a particular value to make sure we receive the correct +// result through this API. + +TEST(GfxPrefs, Singleton) { + ASSERT_FALSE(gfxPrefs::SingletonExists()); + gfxPrefs::GetSingleton(); + ASSERT_TRUE(gfxPrefs::SingletonExists()); + gfxPrefs::DestroySingleton(); + ASSERT_FALSE(gfxPrefs::SingletonExists()); +} + +TEST(GfxPrefs, LiveValues) { + ASSERT_FALSE(gfxPrefs::SingletonExists()); + gfxPrefs::GetSingleton(); + ASSERT_TRUE(gfxPrefs::SingletonExists()); + + // Live boolean, default false + ASSERT_FALSE(gfxPrefs::CanvasAzureAccelerated()); + + // Live int32_t, default 23456 + ASSERT_TRUE(gfxPrefs::LayerScopePort() == 23456); + + // Live uint32_t, default 2 + ASSERT_TRUE(gfxPrefs::MSAALevel() == 2); + + gfxPrefs::DestroySingleton(); + ASSERT_FALSE(gfxPrefs::SingletonExists()); +} + +TEST(GfxPrefs, OnceValues) { + ASSERT_FALSE(gfxPrefs::SingletonExists()); + gfxPrefs::GetSingleton(); + ASSERT_TRUE(gfxPrefs::SingletonExists()); + + // Once boolean, default true + ASSERT_TRUE(gfxPrefs::WorkAroundDriverBugs()); + + // Once boolean, default false + ASSERT_FALSE(gfxPrefs::LayersDump()); + + // Once int32_t, default 95 + ASSERT_TRUE(gfxPrefs::CanvasSkiaGLCacheSize() == 96); + + // Once uint32_t, default 5 + ASSERT_TRUE(gfxPrefs::APZMaxVelocityQueueSize() == 5); + + // Once float, default -1 (should be OK with ==) + ASSERT_TRUE(gfxPrefs::APZMaxVelocity() == -1.0f); + + gfxPrefs::DestroySingleton(); + ASSERT_FALSE(gfxPrefs::SingletonExists()); +} +
--- a/gfx/tests/gtest/moz.build +++ b/gfx/tests/gtest/moz.build @@ -8,16 +8,17 @@ LIBRARY_NAME = 'gfxtest' UNIFIED_SOURCES += [ 'gfxSurfaceRefCountTest.cpp', # Disabled on suspicion of causing bug 904227 #'gfxWordCacheTest.cpp', 'TestAsyncPanZoomController.cpp', 'TestBufferRotation.cpp', 'TestColorNames.cpp', + 'TestGfxPrefs.cpp', 'TestLayers.cpp', 'TestRegion.cpp', 'TestSkipChars.cpp', # Hangs on linux in ApplyGdkScreenFontOptions #'gfxFontSelectionTest.cpp', 'TestTextures.cpp', # Test works but it doesn't assert anything #'gfxTextRunPerfTest.cpp',
--- a/gfx/thebes/Makefile.in +++ b/gfx/thebes/Makefile.in @@ -24,22 +24,10 @@ endif ifdef MOZ_WIDGET_GTK CXXFLAGS += $(MOZ_PANGO_CFLAGS) endif ifeq ($(MOZ_WIDGET_TOOLKIT),qt) CXXFLAGS += $(CAIRO_FT_CFLAGS) $(MOZ_PANGO_CFLAGS) endif -# The file uses SSE2 intrinsics, so it needs special compile flags on some -# compilers. -ifneq (,$(INTEL_ARCHITECTURE)) -ifdef GNU_CC -gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -endif - -ifdef SOLARIS_SUNPRO_CXX -gfxAlphaRecoverySSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -endif -endif - DeprecatedPremultiplyTables.h: $(srcdir)/genTables.py $(PYTHON) $(srcdir)/genTables.py
--- a/gfx/thebes/gfxPlatform.cpp +++ b/gfx/thebes/gfxPlatform.cpp @@ -102,17 +102,16 @@ static qcms_transform *gCMSRGBTransform static qcms_transform *gCMSInverseRGBTransform = nullptr; static qcms_transform *gCMSRGBATransform = nullptr; static bool gCMSInitialized = false; static eCMSMode gCMSMode = eCMSMode_Off; static int gCMSIntent = -2; static void ShutdownCMS(); -static void MigratePrefs(); #include "mozilla/gfx/2D.h" using namespace mozilla::gfx; /* Class to listen for pref changes so that chrome code can dynamically force sRGB as an output profile. See Bug #452125. */ class SRGBOverrideObserver MOZ_FINAL : public nsIObserver, public nsSupportsWeakReference @@ -319,22 +318,18 @@ void RecordingPrefChanged(const char *aP void gfxPlatform::Init() { if (gEverInitialized) { NS_RUNTIMEABORT("Already started???"); } gEverInitialized = true; - /* Pref migration hook. */ - MigratePrefs(); - - // Initialize the preferences by creating the singleton. This should - // be done after the preference migration using MigratePrefs(). - gfxPrefs::One(); + // Initialize the preferences by creating the singleton. + gfxPrefs::GetSingleton(); gGfxPlatformPrefsLock = new Mutex("gfxPlatform::gGfxPlatformPrefsLock"); /* Initialize the GfxInfo service. * Note: we can't call functions on GfxInfo that depend * on gPlatform until after it has been initialized * below. GfxInfo initialization annotates our * crash reports so we want to do it before @@ -501,17 +496,17 @@ gfxPlatform::Shutdown() // This will block this thread untill the ImageBridge protocol is completely // deleted. ImageBridgeChild::ShutDown(); CompositorParent::ShutDown(); delete gGfxPlatformPrefsLock; - gfxPrefs::Destroy(); + gfxPrefs::DestroySingleton(); delete gPlatform; gPlatform = nullptr; } gfxPlatform::~gfxPlatform() { mScreenReferenceSurface = nullptr; @@ -1744,31 +1739,16 @@ static void ShutdownCMS() } // Reset the state variables gCMSIntent = -2; gCMSMode = eCMSMode_Off; gCMSInitialized = false; } -static void MigratePrefs() -{ - /* Migrate from the boolean color_management.enabled pref - we now use - color_management.mode. These calls should be made before gfxPrefs - is initialized, otherwise we may not pick up the correct values - with the gfxPrefs functions. - */ - if (Preferences::HasUserValue(GFX_PREF_CMS_ENABLED_OBSOLETE)) { - if (Preferences::GetBool(GFX_PREF_CMS_ENABLED_OBSOLETE, false)) { - Preferences::SetInt(GFX_PREF_CMS_MODE, static_cast<int32_t>(eCMSMode_All)); - } - Preferences::ClearUser(GFX_PREF_CMS_ENABLED_OBSOLETE); - } -} - // default SetupClusterBoundaries, based on Unicode properties; // platform subclasses may override if they wish void gfxPlatform::SetupClusterBoundaries(gfxTextRun *aTextRun, const char16_t *aString) { if (aTextRun->GetFlags() & gfxTextRunFactory::TEXT_IS_8BIT) { // 8-bit text doesn't have clusters. // XXX is this true in all languages???
--- a/gfx/thebes/gfxPrefs.cpp +++ b/gfx/thebes/gfxPrefs.cpp @@ -8,26 +8,26 @@ #include "mozilla/Preferences.h" #include "MainThreadUtils.h" using namespace mozilla; gfxPrefs* gfxPrefs::sInstance = nullptr; void -gfxPrefs::Destroy() +gfxPrefs::DestroySingleton() { if (sInstance) { delete sInstance; sInstance = nullptr; } } bool -gfxPrefs::Exists() +gfxPrefs::SingletonExists() { return sInstance != nullptr; } gfxPrefs::gfxPrefs() { // Needs to be created on the main thread. MOZ_ASSERT(NS_IsMainThread(), "must be constructed on the main thread");
--- a/gfx/thebes/gfxPrefs.h +++ b/gfx/thebes/gfxPrefs.h @@ -5,17 +5,17 @@ #ifndef GFX_PREFS_H #define GFX_PREFS_H #include <stdint.h> #include "mozilla/Assertions.h" #include "mozilla/TypedEnum.h" -// First time gfxPrefs::One() needs to be called on the main thread, +// First time gfxPrefs::GetSingleton() needs to be called on the main thread, // before any of the methods accessing the values are used, but after // the Preferences system has been initialized. // The static methods to access the preference value are safe to call // from any thread after that first call. // To register a preference, you need to add a line in this file using // the DECL_GFX_PREF macro. @@ -48,17 +48,17 @@ // Things are a bit more complicated and perhaps even dangerous when // going from Once to Live, or indeed setting a preference to be Live // in the first place, so be careful. You need to be ready for the // values changing mid execution, and if you're using those preferences // in any setup and initialization, you may need to do extra work. #define DECL_GFX_PREF(Update, Pref, Name, Type, Default) \ public: \ -static Type Name() { MOZ_ASSERT(Exists()); return One().mPref##Name.mValue; } \ +static Type Name() { MOZ_ASSERT(SingletonExists()); return GetSingleton().mPref##Name.mValue; } \ private: \ static const char* Get##Name##PrefName() { return Pref; } \ static Type Get##Name##PrefDefault() { return Default; } \ PrefTemplate<UpdatePolicy::Update, Type, Get##Name##PrefDefault, Get##Name##PrefName> mPref##Name class gfxPrefs; class gfxPrefs MOZ_FINAL { @@ -123,17 +123,17 @@ private: DECL_GFX_PREF(Live, "gfx.gralloc.fence-with-readpixels", GrallocFenceWithReadPixels, bool, false); DECL_GFX_PREF(Live, "gfx.layerscope.enabled", LayerScopeEnabled, bool, false); DECL_GFX_PREF(Live, "gfx.layerscope.port", LayerScopePort, int32_t, 23456); DECL_GFX_PREF(Once, "gfx.work-around-driver-bugs", WorkAroundDriverBugs, bool, true); DECL_GFX_PREF(Live, "gl.msaa-level", MSAALevel, uint32_t, 2); DECL_GFX_PREF(Once, "layers.acceleration.disabled", LayersAccelerationDisabled, bool, false); - DECL_GFX_PREF(Live, "layers.acceleration.draw-fps", LayersDrawFPS, bool, true); + DECL_GFX_PREF(Live, "layers.acceleration.draw-fps", LayersDrawFPS, bool, false); DECL_GFX_PREF(Once, "layers.acceleration.force-enabled", LayersAccelerationForceEnabled, bool, false); #ifdef XP_WIN // On windows, ignore the preference value, forcing async video to false. DECL_GFX_PREF(Skip, "layers.async-video.enabled", AsyncVideoEnabled, bool, false); #else DECL_GFX_PREF(Once, "layers.async-video.enabled", AsyncVideoEnabled, bool, false); #endif DECL_GFX_PREF(Once, "layers.bufferrotation.enabled", BufferRotationEnabled, bool, true); @@ -167,25 +167,25 @@ private: DECL_GFX_PREF(Once, "layout.frame_rate", LayoutFrameRate, int32_t, -1); DECL_GFX_PREF(Live, "nglayout.debug.widget_update_flashing", WidgetUpdateFlashing, bool, false); DECL_GFX_PREF(Once, "webgl.force-layers-readback", WebGLForceLayersReadback, bool, false); public: // Manage the singleton: - static gfxPrefs& One() + static gfxPrefs& GetSingleton() { if (!sInstance) { sInstance = new gfxPrefs; } return *sInstance; } - static void Destroy(); - static bool Exists(); + static void DestroySingleton(); + static bool SingletonExists(); private: static gfxPrefs* sInstance; private: // Creating these to avoid having to include Preferences.h in the .h static void PrefAddVarCache(bool*, const char*, bool); static void PrefAddVarCache(int32_t*, const char*, int32_t);
--- a/gfx/thebes/moz.build +++ b/gfx/thebes/moz.build @@ -194,19 +194,23 @@ elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'wi 'gfxDWriteFontList.cpp', 'gfxDWriteFonts.cpp', 'gfxDWriteShaper.cpp', 'gfxDWriteTextAnalysis.cpp', ] # Are we targeting x86 or x64? If so, build gfxAlphaRecoverySSE2.cpp. if CONFIG['INTEL_ARCHITECTURE']: - SOURCES += [ - 'gfxAlphaRecoverySSE2.cpp', - ] + SOURCES += ['gfxAlphaRecoverySSE2.cpp'] + # The file uses SSE2 intrinsics, so it needs special compile flags on some + # compilers. + if CONFIG['GNU_CC']: + SOURCES['gfxAlphaRecoverySSE2.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['gfxAlphaRecoverySSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] SOURCES += [ # Includes mac system header conflicting with point/size, # and includes glxXlibSurface.h which drags in Xrender.h 'gfxASurface.cpp', # on X11, gfxDrawable.cpp includes X headers for an old workaround which # we could consider removing soon (affects Ubuntus older than 10.04 LTS) # which currently prevent it from joining UNIFIED_SOURCES.
deleted file mode 100644 --- a/gfx/ycbcr/Makefile.in +++ /dev/null @@ -1,15 +0,0 @@ -include $(topsrcdir)/config/rules.mk - -# These files use MMX and SSE2 intrinsics, so they need special compile flags -# on some compilers. -ifneq (,$(INTEL_ARCHITECTURE)) -ifdef GNU_CC -yuv_convert_mmx.$(OBJ_SUFFIX): CXXFLAGS += -mmmx -yuv_convert_sse2.$(OBJ_SUFFIX): CXXFLAGS += -msse2 -endif - -ifdef SOLARIS_SUNPRO_CXX -yuv_convert_mmx.$(OBJ_SUFFIX): CXXFLAGS += -xarch=mmx -xO4 -yuv_convert_sse2.$(OBJ_SUFFIX): CXXFLAGS += -xarch=sse2 -xO4 -endif -endif
--- a/gfx/ycbcr/moz.build +++ b/gfx/ycbcr/moz.build @@ -16,30 +16,36 @@ UNIFIED_SOURCES += [ 'ycbcr_to_rgb565.cpp', 'YCbCrUtils.cpp', 'yuv_convert.cpp', 'yuv_row_c.cpp', 'yuv_row_table.cpp', ] if CONFIG['INTEL_ARCHITECTURE']: - SOURCES += [ - 'yuv_convert_sse2.cpp', - ] + # These files use MMX and SSE2 intrinsics, so they need special compile flags + # on some compilers. + SOURCES += ['yuv_convert_sse2.cpp'] + if CONFIG['GNU_CC']: + SOURCES['yuv_convert_sse2.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['yuv_convert_sse2.cpp'].flags += ['-xarch=sse2', '-xO4'] # MSVC doesn't support MMX when targeting AMD64. if CONFIG['_MSC_VER']: if CONFIG['OS_TEST'] != 'x86_64': SOURCES += [ 'yuv_convert_mmx.cpp', ] else: - SOURCES += [ - 'yuv_convert_mmx.cpp', - ] + SOURCES += ['yuv_convert_mmx.cpp'] + if CONFIG['GNU_CC']: + SOURCES['yuv_convert_mmx.cpp'].flags += ['-mmmx'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['yuv_convert_mmx.cpp'].flags += ['-xarch=mmx', '-xO4'] if CONFIG['_MSC_VER']: if CONFIG['OS_TEST'] == 'x86_64': if CONFIG['_MSC_VER'] == '1400': # VC8 doesn't support some SSE2 built-in functions SOURCES += [ 'yuv_row_win.cpp', ]
--- a/intl/strres/src/nsStringBundle.cpp +++ b/intl/strres/src/nsStringBundle.cpp @@ -713,31 +713,19 @@ nsStringBundleService::CreateExtensibleB nsresult nsStringBundleService::FormatWithBundle(nsIStringBundle* bundle, nsresult aStatus, uint32_t argCount, char16_t** argArray, char16_t* *result) { nsresult rv; nsXPIDLCString key; - // then find a key into the string bundle for that particular error: - rv = mErrorService->GetErrorStringBundleKey(aStatus, getter_Copies(key)); - - // first try looking up the error message with the string key: - if (NS_SUCCEEDED(rv)) { - rv = bundle->FormatStringFromName(NS_ConvertASCIItoUTF16(key).get(), - (const char16_t**)argArray, - argCount, result); - } - - // if the string key fails, try looking up the error message with the int key: - if (NS_FAILED(rv)) { - uint16_t code = NS_ERROR_GET_CODE(aStatus); - rv = bundle->FormatStringFromID(code, (const char16_t**)argArray, argCount, result); - } + // try looking up the error message with the int key: + uint16_t code = NS_ERROR_GET_CODE(aStatus); + rv = bundle->FormatStringFromID(code, (const char16_t**)argArray, argCount, result); // If the int key fails, try looking up the default error message. E.g. print: // An unknown error has occurred (0x804B0003). if (NS_FAILED(rv)) { nsAutoString statusStr; statusStr.AppendInt(static_cast<uint32_t>(aStatus), 16); const char16_t* otherArgArray[1]; otherArgArray[0] = statusStr.get();
deleted file mode 100644 --- a/intl/uconv/src/Makefile.in +++ /dev/null @@ -1,18 +0,0 @@ -# vim:set noet ts=8: -# 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 $(topsrcdir)/config/rules.mk - -ifneq (,$(INTEL_ARCHITECTURE)) -# nsUTF8ToUnicodeSSE2.cpp uses SSE2 intrinsics, so we need to pass -msse2 if -# we're using gcc. (See bug 585538 comment 12.) -ifdef GNU_CC -nsUTF8ToUnicodeSSE2.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -endif - -ifdef SOLARIS_SUNPRO_CXX -nsUTF8ToUnicodeSSE2.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -endif -endif
--- a/intl/uconv/src/moz.build +++ b/intl/uconv/src/moz.build @@ -196,19 +196,23 @@ UNIFIED_SOURCES += [ '../util/nsUnicodeDecodeHelper.cpp', '../util/nsUnicodeEncodeHelper.cpp', '../util/ugen.c', '../util/umap.c', '../util/uscan.c', ] if CONFIG['INTEL_ARCHITECTURE']: - SOURCES += [ - 'nsUTF8ToUnicodeSSE2.cpp', - ] + SOURCES += ['nsUTF8ToUnicodeSSE2.cpp'] + if CONFIG['GNU_CC']: + # nsUTF8ToUnicodeSSE2.cpp uses SSE2 intrinsics, so we need to pass -msse2 if + # we're using gcc. (See bug 585538 comment 12.) + SOURCES['nsUTF8ToUnicodeSSE2.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['nsUTF8ToUnicodeSSE2.cpp'].flags += ['-xarch=sse2', '-xO4'] MSVC_ENABLE_PGO = True LOCAL_INCLUDES += [ '../ucvcn', '../ucvibm', '../ucvja', '../ucvko',
--- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -355,20 +355,16 @@ ifdef HAVE_DTRACE -e '/const/!s/char \*/const char */g' \ javascript-trace.h.in > javascript-trace.h # We can't automatically generate dependencies on auto-generated headers; # we have to list them explicitly. $(addsuffix .$(OBJ_SUFFIX),Probes jsinterp jsobj): $(CURDIR)/javascript-trace.h endif -ifdef HAVE_LINUX_PERF_EVENT_H -pm_linux.$(OBJ_SUFFIX): CXXFLAGS += $(LINUX_HEADERS_INCLUDES) -endif - # Prepare self-hosted JS code for embedding export:: selfhosting selfhosting:: selfhosted.out.h selfhosting_srcs := \ $(srcdir)/builtin/Utilities.js \ $(srcdir)/builtin/Array.js \ $(srcdir)/builtin/Date.js \
--- a/js/src/builtin/Array.js +++ b/js/src/builtin/Array.js @@ -885,16 +885,23 @@ function ArrayScatterPar(targets, defaul x = collide(x, buffer[t]); UnsafePutElements(buffer, t, x, conflicts, t, true); } return buffer; } + function collide(elem1, elem2) { + if (conflictFunc === undefined) + ThrowError(JSMSG_PAR_ARRAY_SCATTER_CONFLICT); + + return conflictFunc(elem1, elem2); + } + function checkTarget(i, t) { if (TO_INT32(t) !== t) ThrowError(JSMSG_PAR_ARRAY_SCATTER_BAD_TARGET, i); if (t < 0 || t >= length) ThrowError(JSMSG_PAR_ARRAY_SCATTER_BOUNDS); // It's not enough to return t, as -0 | 0 === -0.
--- a/js/src/configure.in +++ b/js/src/configure.in @@ -4021,29 +4021,17 @@ AC_SUBST(BIN_SUFFIX) AC_SUBST(ASM_SUFFIX) AC_SUBST(IMPORT_LIB_SUFFIX) AC_SUBST(USE_N32) AC_SUBST(CC_VERSION) AC_SUBST(CXX_VERSION) AC_SUBST(MSMANIFEST_TOOL) AC_SUBST(MOZ_LINKER) -AC_MSG_CHECKING([for posix_fallocate]) -AC_TRY_LINK([#define _XOPEN_SOURCE 600 - #include <fcntl.h>], - [posix_fallocate(0, 0, 0);], - [ac_cv___posix_fallocate=true], - [ac_cv___posix_fallocate=false]) - -if test "$ac_cv___posix_fallocate" = true ; then - AC_DEFINE(HAVE_POSIX_FALLOCATE) - AC_MSG_RESULT(yes) -else - AC_MSG_RESULT(no) -fi +AC_CHECK_FUNCS(posix_fadvise posix_fallocate) dnl Check for missing components if test "$COMPILE_ENVIRONMENT"; then if test "$MOZ_X11"; then dnl ==================================================== dnl = Check if X headers exist dnl ==================================================== _SAVE_CFLAGS=$CFLAGS
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/asm.js/testBug978714.js @@ -0,0 +1,9 @@ +if (!getBuildConfiguration().parallelJS) + quit(); + +var y = Array.buildPar(9, function() {}); +Array.prototype.every.call(y, (function() { + "use asm"; + function f() {} + return f +}))
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-multi.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-multi.js @@ -13,16 +13,19 @@ * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. You're looking for a smallish function within the * "self-hosted" domain. Look for a call to ObjectIsTypeDescr far * down in the graph for pass00, with a call to DescrToSource in a * subsequent block (all of this is at the mercy of the way the code * is currently written). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; var ST1 = new T.StructType({x:T.int32}); var ST2 = new T.StructType({x:T.float64}); function check(v) { return v.toSource(); }
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-unknown.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-unknown.js @@ -13,16 +13,19 @@ * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. You're looking for a smallish function within the * "self-hosted" domain. Look for a call to ObjectIsTypeDescr far * down in the graph for pass00, with a call to DescrToSource in a * subsequent block (all of this is at the mercy of the way the code * is currently written). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; var ST = new T.StructType({x:T.int32}); function check(v) { return v.toSource(); } function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong-multi.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong-multi.js @@ -13,16 +13,19 @@ * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. You're looking for a smallish function within the * "self-hosted" domain. Look for a call to ObjectIsTypeDescr far * down in the graph for pass00, with a call to DescrToSource in a * subsequent block (all of this is at the mercy of the way the code * is currently written). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; var ST = new T.StructType({x:T.int32}); function check(v) { return v.toSource(); } function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr-wrong.js @@ -13,16 +13,19 @@ * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. You're looking for a smallish function within the * "self-hosted" domain. Look for a call to ObjectIsTypeDescr far * down in the graph for pass00, with a call to DescrToSource in a * subsequent block (all of this is at the mercy of the way the code * is currently written). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; var ST = new T.StructType({x:T.int32}); function check(v) { return v.toSource(); } function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-ObjectIsTypeDescr.js @@ -13,16 +13,19 @@ * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. You're looking for a smallish function within the * "self-hosted" domain. Look for a call to ObjectIsTypeDescr far * down in the graph for pass00, with a call to DescrToSource in a * subsequent block (all of this is at the mercy of the way the code * is currently written). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; var ST = new T.StructType({x:T.int32}); function check(v) { return v.toSource(); } function test() {
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-opaque.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-opaque.js @@ -11,16 +11,19 @@ * ObjectIsTransparentTypedObject resolves to false. * * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. func01 will likely be the one we want (look for calls to * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the * graph for pass00). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; function check(v) { return T.storage(v); } function test() { var AT = new T.ArrayType(T.Any,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-transparent.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-transparent.js @@ -11,16 +11,19 @@ * ObjectIsTransparentTypedObject resolves to true. * * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. func01 will likely be the one we want (look for calls to * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the * graph for pass00). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; function check(v) { return T.storage(v); } function test() { var AT = new T.ArrayType(T.int32,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-unknown.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-unknown.js @@ -12,16 +12,19 @@ * "HasClass" primitive. * * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. func01 will likely be the one we want (look for calls to * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the * graph for pass00). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; function check(v) { return T.storage(v); } function test() { var AT = new T.ArrayType(T.int32,10);
--- a/js/src/jit-test/tests/ion/inlining/TypedObject-storage-wrong.js +++ b/js/src/jit-test/tests/ion/inlining/TypedObject-storage-wrong.js @@ -11,16 +11,19 @@ * resolve to false. * * Load this into the js shell with IONFLAGS=logs, then exit and run * iongraph. func01 will likely be the one we want (look for calls to * ObjectIsOpaqueTypedObject and ObjectIsTransparentTypedObject in the * graph for pass00). */ +if (!this.TypedObject) + quit(); + var T = TypedObject; function check(v) { return T.storage(v); } function test() { var v = new Object; // Not actually a typed object
new file mode 100644 --- /dev/null +++ b/js/src/jit-test/tests/parallel/bug977900.js @@ -0,0 +1,5 @@ +if (!getBuildConfiguration().parallelJS) + quit(); + +function chooseMax(a, b) { return a>b?a:b;}; +var a = [1,2].scatterPar([0,0], -1, chooseMax);
--- a/js/src/jit/AsmJS.cpp +++ b/js/src/jit/AsmJS.cpp @@ -752,93 +752,16 @@ TypedArrayLoadType(ArrayBufferView::View MOZ_ASSUME_UNREACHABLE("Unexpected array type"); } enum NeedsBoundsCheck { NO_BOUNDS_CHECK, NEEDS_BOUNDS_CHECK }; -/*****************************************************************************/ - -// The Asm.js heap length is constrained by the x64 backend heap access scheme -// to be a multiple of the page size which is 4096 bytes, and also constrained -// by the limits of ARM backends 'cmp immediate' instruction which supports a -// complex range for the immediate argument. -// -// ARMv7 mode supports the following immediate constants, and the Thumb T2 -// instruction encoding also supports the subset of immediate constants used. -// abcdefgh 00000000 00000000 00000000 -// 00abcdef gh000000 00000000 00000000 -// 0000abcd efgh0000 00000000 00000000 -// 000000ab cdefgh00 00000000 00000000 -// 00000000 abcdefgh 00000000 00000000 -// 00000000 00abcdef gh000000 00000000 -// 00000000 0000abcd efgh0000 00000000 -// ... -// -// The 4096 page size constraint restricts the length to: -// xxxxxxxx xxxxxxxx xxxx0000 00000000 -// -// Intersecting all the above constraints gives: -// Heap length 0x40000000 to 0xff000000 quanta 0x01000000 -// Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000 -// Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000 -// Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000 -// Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000 -// Heap length 0x00100000 to 0x003fc000 quanta 0x00004000 -// Heap length 0x00001000 to 0x000ff000 quanta 0x00001000 -// -uint32_t -js::RoundUpToNextValidAsmJSHeapLength(uint32_t length) -{ - if (length < 0x00001000u) // Minimum length is the pages size of 4096. - return 0x1000u; - if (length < 0x00100000u) // < 1M quanta 4K - return (length + 0x00000fff) & ~0x00000fff; - if (length < 0x00400000u) // < 4M quanta 16K - return (length + 0x00003fff) & ~0x00003fff; - if (length < 0x01000000u) // < 16M quanta 64K - return (length + 0x0000ffff) & ~0x0000ffff; - if (length < 0x04000000u) // < 64M quanta 256K - return (length + 0x0003ffff) & ~0x0003ffff; - if (length < 0x10000000u) // < 256M quanta 1M - return (length + 0x000fffff) & ~0x000fffff; - if (length < 0x40000000u) // < 1024M quanta 4M - return (length + 0x003fffff) & ~0x003fffff; - // < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such - // lengths are not currently valid. - JS_ASSERT(length <= 0xff000000); - return (length + 0x00ffffff) & ~0x00ffffff; -} - -bool -js::IsValidAsmJSHeapLength(uint32_t length) -{ - if (length < AsmJSAllocationGranularity) - return false; - if (length <= 0x00100000u) - return (length & 0x00000fff) == 0; - if (length <= 0x00400000u) - return (length & 0x00003fff) == 0; - if (length <= 0x01000000u) - return (length & 0x0000ffff) == 0; - if (length <= 0x04000000u) - return (length & 0x0003ffff) == 0; - if (length <= 0x10000000u) - return (length & 0x000fffff) == 0; - if (length <= 0x40000000u) - return (length & 0x003fffff) == 0; - if (length <= 0xff000000u) - return (length & 0x00ffffff) == 0; - return false; -} - -/*****************************************************************************/ - namespace { typedef js::Vector<PropertyName*,1> LabelVector; typedef js::Vector<MBasicBlock*,8> BlockVector; // ModuleCompiler encapsulates the compilation of an entire asm.js module. Over // the course of an ModuleCompiler object's lifetime, many FunctionCompiler // objects will be created and destroyed in sequence, one for each function in
--- a/js/src/jit/AsmJS.h +++ b/js/src/jit/AsmJS.h @@ -75,23 +75,16 @@ class AsmJSActivation }; // The assumed page size; dynamically checked in CompileAsmJS. const size_t AsmJSPageSize = 4096; // The asm.js spec requires that the ArrayBuffer's byteLength be a multiple of 4096. static const size_t AsmJSAllocationGranularity = 4096; -// These functions define the valid heap lengths. -extern uint32_t -RoundUpToNextValidAsmJSHeapLength(uint32_t length); - -extern bool -IsValidAsmJSHeapLength(uint32_t length); - #ifdef JS_CODEGEN_X64 // On x64, the internal ArrayBuffer data array is inflated to 4GiB (only the // byteLength portion of which is accessible) so that out-of-bounds accesses // (made using a uint32 index) are guaranteed to raise a SIGSEGV. static const size_t AsmJSBufferProtectedSize = 4 * 1024ULL * 1024ULL * 1024ULL; // To avoid dynamically checking bounds on each load/store, asm.js code relies // on the SIGSEGV handler in AsmJSSignalHandlers.cpp. However, this only works @@ -130,11 +123,84 @@ IsAsmJSCompilationAvailable(JSContext *c { CallArgs args = CallArgsFromVp(argc, vp); args.rval().set(BooleanValue(false)); return true; } #endif // JS_ION +// The Asm.js heap length is constrained by the x64 backend heap access scheme +// to be a multiple of the page size which is 4096 bytes, and also constrained +// by the limits of ARM backends 'cmp immediate' instruction which supports a +// complex range for the immediate argument. +// +// ARMv7 mode supports the following immediate constants, and the Thumb T2 +// instruction encoding also supports the subset of immediate constants used. +// abcdefgh 00000000 00000000 00000000 +// 00abcdef gh000000 00000000 00000000 +// 0000abcd efgh0000 00000000 00000000 +// 000000ab cdefgh00 00000000 00000000 +// 00000000 abcdefgh 00000000 00000000 +// 00000000 00abcdef gh000000 00000000 +// 00000000 0000abcd efgh0000 00000000 +// ... +// +// The 4096 page size constraint restricts the length to: +// xxxxxxxx xxxxxxxx xxxx0000 00000000 +// +// Intersecting all the above constraints gives: +// Heap length 0x40000000 to 0xff000000 quanta 0x01000000 +// Heap length 0x10000000 to 0x3fc00000 quanta 0x00400000 +// Heap length 0x04000000 to 0x0ff00000 quanta 0x00100000 +// Heap length 0x01000000 to 0x03fc0000 quanta 0x00040000 +// Heap length 0x00400000 to 0x00ff0000 quanta 0x00010000 +// Heap length 0x00100000 to 0x003fc000 quanta 0x00004000 +// Heap length 0x00001000 to 0x000ff000 quanta 0x00001000 +// +inline uint32_t +RoundUpToNextValidAsmJSHeapLength(uint32_t length) +{ + if (length < 0x00001000u) // Minimum length is the pages size of 4096. + return 0x1000u; + if (length < 0x00100000u) // < 1M quanta 4K + return (length + 0x00000fff) & ~0x00000fff; + if (length < 0x00400000u) // < 4M quanta 16K + return (length + 0x00003fff) & ~0x00003fff; + if (length < 0x01000000u) // < 16M quanta 64K + return (length + 0x0000ffff) & ~0x0000ffff; + if (length < 0x04000000u) // < 64M quanta 256K + return (length + 0x0003ffff) & ~0x0003ffff; + if (length < 0x10000000u) // < 256M quanta 1M + return (length + 0x000fffff) & ~0x000fffff; + if (length < 0x40000000u) // < 1024M quanta 4M + return (length + 0x003fffff) & ~0x003fffff; + // < 4096M quanta 16M. Note zero is returned if over 0xff000000 but such + // lengths are not currently valid. + JS_ASSERT(length <= 0xff000000); + return (length + 0x00ffffff) & ~0x00ffffff; +} + +inline bool +IsValidAsmJSHeapLength(uint32_t length) +{ + if (length < AsmJSAllocationGranularity) + return false; + if (length <= 0x00100000u) + return (length & 0x00000fff) == 0; + if (length <= 0x00400000u) + return (length & 0x00003fff) == 0; + if (length <= 0x01000000u) + return (length & 0x0000ffff) == 0; + if (length <= 0x04000000u) + return (length & 0x0003ffff) == 0; + if (length <= 0x10000000u) + return (length & 0x000fffff) == 0; + if (length <= 0x40000000u) + return (length & 0x003fffff) == 0; + if (length <= 0xff000000u) + return (length & 0x00ffffff) == 0; + return false; +} + } // namespace js #endif // jit_AsmJS_h
--- a/js/src/jit/AsmJSModule.cpp +++ b/js/src/jit/AsmJSModule.cpp @@ -342,17 +342,18 @@ AsmJSModule::AsmJSModule(ScriptSource *s : globalArgumentName_(nullptr), importArgumentName_(nullptr), bufferArgumentName_(nullptr), code_(nullptr), operationCallbackExit_(nullptr), dynamicallyLinked_(false), loadedFromCache_(false), charsBegin_(charsBegin), - scriptSource_(scriptSource) + scriptSource_(scriptSource), + codeIsProtected_(false) { mozilla::PodZero(&pod); scriptSource_->incref(); pod.minHeapLength_ = AsmJSAllocationGranularity; } AsmJSModule::~AsmJSModule() {
--- a/js/src/jscntxtinlines.h +++ b/js/src/jscntxtinlines.h @@ -24,17 +24,26 @@ namespace js { #ifdef JS_CRASH_DIAGNOSTICS class CompartmentChecker { JSCompartment *compartment; public: explicit CompartmentChecker(ExclusiveContext *cx) : compartment(cx->compartment()) - {} + { +#ifdef DEBUG + // In debug builds, make sure the embedder passed the cx it claimed it + // was going to use. + JSContext *activeContext = nullptr; + if (cx->isJSContext()) + activeContext = cx->asJSContext()->runtime()->activeContext; + JS_ASSERT_IF(activeContext, cx == activeContext); +#endif + } /* * Set a breakpoint here (break js::CompartmentChecker::fail) to debug * compartment mismatches. */ static void fail(JSCompartment *c1, JSCompartment *c2) { printf("*** Compartment mismatch %p vs. %p\n", (void *) c1, (void *) c2); MOZ_CRASH(); @@ -363,17 +372,19 @@ ExclusiveContext::typeLifoAlloc() } /* namespace js */ inline void JSContext::setPendingException(js::Value v) { JS_ASSERT(!IsPoisonedValue(v)); this->throwing = true; this->unwrappedException_ = v; - js::assertSameCompartment(this, v); + // We don't use assertSameCompartment here to allow + // js::SetPendingExceptionCrossContext to work. + JS_ASSERT_IF(v.isObject(), v.toObject().compartment() == compartment()); } inline void JSContext::setDefaultCompartmentObject(JSObject *obj) { JS_ASSERT(!options().noDefaultCompartmentObject()); defaultCompartmentObject_ = obj; }
--- a/js/src/jsfriendapi.cpp +++ b/js/src/jsfriendapi.cpp @@ -389,16 +389,22 @@ js::GetObjectParentMaybeScope(JSObject * JS_FRIEND_API(JSObject *) js::GetGlobalForObjectCrossCompartment(JSObject *obj) { return &obj->global(); } JS_FRIEND_API(void) +js::SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v) +{ + cx->setPendingException(v); +} + +JS_FRIEND_API(void) js::AssertSameCompartment(JSContext *cx, JSObject *obj) { assertSameCompartment(cx, obj); } #ifdef DEBUG JS_FRIEND_API(void) js::AssertSameCompartment(JSObject *objA, JSObject *objB) @@ -1145,16 +1151,24 @@ js::DefaultJSContext(JSRuntime *rt) } JS_FRIEND_API(void) js::SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb) { rt->defaultJSContextCallback = cb; } +#ifdef DEBUG +JS_FRIEND_API(void) +js::Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) +{ + rt->activeContext = cx; +} +#endif + JS_FRIEND_API(void) js::SetCTypesActivityCallback(JSRuntime *rt, CTypesActivityCallback cb) { rt->ctypesActivityCallback = cb; } js::AutoCTypesActivityCallback::AutoCTypesActivityCallback(JSContext *cx, js::CTypesActivityType beginType,
--- a/js/src/jsfriendapi.h +++ b/js/src/jsfriendapi.h @@ -656,16 +656,21 @@ GetObjectCompartment(JSObject *obj) } JS_FRIEND_API(JSObject *) GetObjectParentMaybeScope(JSObject *obj); JS_FRIEND_API(JSObject *) GetGlobalForObjectCrossCompartment(JSObject *obj); +// Sidestep the activeContext checking implicitly performed in +// JS_SetPendingException. +JS_FRIEND_API(void) +SetPendingExceptionCrossContext(JSContext *cx, JS::HandleValue v); + JS_FRIEND_API(void) AssertSameCompartment(JSContext *cx, JSObject *obj); #ifdef JS_DEBUG JS_FRIEND_API(void) AssertSameCompartment(JSObject *objA, JSObject *objB); #else inline void AssertSameCompartment(JSObject *objA, JSObject *objB) {} @@ -1946,16 +1951,31 @@ extern JS_FRIEND_API(JSContext *) DefaultJSContext(JSRuntime *rt); typedef JSContext* (* DefaultJSContextCallback)(JSRuntime *rt); JS_FRIEND_API(void) SetDefaultJSContextCallback(JSRuntime *rt, DefaultJSContextCallback cb); +/* + * To help embedders enforce their invariants, we allow them to specify in + * advance which JSContext should be passed to JSAPI calls. If this is set + * to a non-null value, the assertSameCompartment machinery does double- + * duty (in debug builds) to verify that it matches the cx being used. + */ +#ifdef DEBUG +JS_FRIEND_API(void) +Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx); +#else +inline void +Debug_SetActiveJSContext(JSRuntime *rt, JSContext *cx) {}; +#endif + + enum CTypesActivityType { CTYPES_CALL_BEGIN, CTYPES_CALL_END, CTYPES_CALLBACK_BEGIN, CTYPES_CALLBACK_END }; typedef void
--- a/js/src/moz.build +++ b/js/src/moz.build @@ -385,16 +385,17 @@ if CONFIG['MOZ_VTUNE']: SOURCES += [ 'vtune/jitprofiling.c' ] if CONFIG['HAVE_LINUX_PERF_EVENT_H']: SOURCES += [ 'perf/pm_linux.cpp' ] + SOURCES['perf/pm_linux.cpp'].flags += [CONFIG['LINUX_HEADERS_INCLUDES']] else: SOURCES += [ 'perf/pm_stub.cpp' ] MSVC_ENABLE_PGO = True HOST_SOURCES += [
--- a/js/src/vm/Runtime.cpp +++ b/js/src/vm/Runtime.cpp @@ -156,16 +156,19 @@ JSRuntime::JSRuntime(JSRuntime *parentRu activityCallback(nullptr), activityCallbackArg(nullptr), #ifdef JS_THREADSAFE requestDepth(0), # ifdef DEBUG checkRequestDepth(0), # endif #endif +#ifdef DEBUG + activeContext(nullptr), +#endif gcInitialized(false), gcSystemAvailableChunkListHead(nullptr), gcUserAvailableChunkListHead(nullptr), gcBytes(0), gcMaxBytes(0), gcMaxMallocBytes(0), gcNumArenasFreeCommitted(0), gcMarker(this),
--- a/js/src/vm/Runtime.h +++ b/js/src/vm/Runtime.h @@ -961,16 +961,26 @@ struct JSRuntime : public JS::shadow::Ru /* The request depth for this thread. */ unsigned requestDepth; # ifdef DEBUG unsigned checkRequestDepth; # endif #endif +#ifdef DEBUG + /* + * To help embedders enforce their invariants, we allow them to specify in + * advance which JSContext should be passed to JSAPI calls. If this is set + * to a non-null value, the assertSameCompartment machinery does double- + * duty (in debug builds) to verify that it matches the cx being used. + */ + JSContext *activeContext; +#endif + /* Garbage collector state, used by jsgc.c. */ /* Garbase collector state has been sucessfully initialized. */ bool gcInitialized; /* * Set of all GC chunks with at least one allocated thing. The * conservative GC uses it to quickly check if a possible GC thing points
--- a/js/src/vm/SharedArrayObject.cpp +++ b/js/src/vm/SharedArrayObject.cpp @@ -80,32 +80,28 @@ SharedArrayRawBuffer::New(uint32_t lengt void *p = MapMemory(AsmJSMappedSize, false); if (!p) return nullptr; if (!MarkValidRegion(p, AsmJSPageSize + length)) { UnmapMemory(p, AsmJSMappedSize); return nullptr; } +#else + uint32_t allocSize = length + AsmJSPageSize; + if (allocSize <= length) + return nullptr; + void *p = MapMemory(allocSize, true); + if (!p) + return nullptr; +#endif uint8_t *buffer = reinterpret_cast<uint8_t*>(p) + AsmJSPageSize; uint8_t *base = buffer - sizeof(SharedArrayRawBuffer); return new (base) SharedArrayRawBuffer(buffer, length); -#else - uint32_t allocSize = sizeof(SharedArrayRawBuffer) + length; - if (allocSize <= length) - return nullptr; - - void *base = MapMemory(allocSize, true); - if (!base) - return nullptr; - - uint8_t *buffer = reinterpret_cast<uint8_t*>(base) + sizeof(SharedArrayRawBuffer); - return new (base) SharedArrayRawBuffer(buffer, length); -#endif } void SharedArrayRawBuffer::addReference() { JS_ASSERT(this->refcount > 0); ++this->refcount; // Atomic. } @@ -113,23 +109,22 @@ SharedArrayRawBuffer::addReference() void SharedArrayRawBuffer::dropReference() { // Drop the reference to the buffer. uint32_t refcount = --this->refcount; // Atomic. // If this was the final reference, release the buffer. if (refcount == 0) { -#ifdef JS_CPU_X64 uint8_t *p = this->dataPointer() - AsmJSPageSize; JS_ASSERT(uintptr_t(p) % AsmJSPageSize == 0); +#ifdef JS_CPU_X64 UnmapMemory(p, AsmJSMappedSize); #else - uint8_t *p = (uint8_t *)this; - UnmapMemory(p, this->length); + UnmapMemory(p, this->length + AsmJSPageSize); #endif } } /* * SharedArrayBufferObject */ bool
--- a/js/xpconnect/loader/mozJSComponentLoader.h +++ b/js/xpconnect/loader/mozJSComponentLoader.h @@ -9,16 +9,17 @@ #include "mozilla/MemoryReporting.h" #include "mozilla/ModuleLoader.h" #include "nsISupports.h" #include "nsIObserver.h" #include "nsIURI.h" #include "xpcIJSModuleLoader.h" #include "nsClassHashtable.h" +#include "nsCxPusher.h" #include "nsDataHashtable.h" #include "jsapi.h" #include "xpcIJSGetFactory.h" class nsIFile; class nsIJSRuntimeService; class nsIPrincipal; @@ -110,24 +111,23 @@ class mozJSComponentLoader : public mozi ~ModuleEntry() { Clear(); } void Clear() { getfactoryobj = nullptr; if (obj) { - JSAutoRequest ar(sSelf->mContext); - - JSAutoCompartment ac(sSelf->mContext, obj); + mozilla::AutoJSContext cx; + JSAutoCompartment ac(cx, obj); - JS_SetAllNonReservedSlotsToUndefined(sSelf->mContext, obj); - JS_RemoveObjectRoot(sSelf->mContext, &obj); + JS_SetAllNonReservedSlotsToUndefined(cx, obj); + JS_RemoveObjectRoot(cx, &obj); if (thisObjectKey) - JS_RemoveScriptRoot(sSelf->mContext, &thisObjectKey); + JS_RemoveScriptRoot(cx, &thisObjectKey); } if (location) NS_Free(location); obj = nullptr; thisObjectKey = nullptr; location = nullptr;
--- a/js/xpconnect/src/Sandbox.cpp +++ b/js/xpconnect/src/Sandbox.cpp @@ -505,16 +505,17 @@ EvalInWindow(JSContext *cx, const nsAStr nsCString filename; unsigned lineNo; if (!GetFilenameAndLineNumber(cx, filename, lineNo)) { // Default values for non-scripted callers. filename.Assign("Unknown"); lineNo = 0; } + RootedObject cxGlobal(cx, JS::CurrentGlobalOrNull(cx)); { // CompileOptions must be created from the context // we will execute this script in. JSContext *wndCx = context->GetNativeContext(); AutoCxPusher pusher(wndCx); JS::CompileOptions compileOptions(wndCx); compileOptions.setFileAndLine(filename.get(), lineNo); @@ -543,18 +544,19 @@ EvalInWindow(JSContext *cx, const nsAStr // If there was an exception thrown we should set it // on the calling context. RootedValue exn(wndCx, rval); // First we should reset the return value. rval.set(UndefinedValue()); // Then clone the exception. - if (CloneNonReflectors(cx, &exn)) - JS_SetPendingException(cx, exn); + JSAutoCompartment ac(wndCx, cxGlobal); + if (CloneNonReflectors(wndCx, &exn)) + js::SetPendingExceptionCrossContext(cx, exn); return false; } } // Let's clone the return value back to the callers compartment. if (!CloneNonReflectors(cx, rval)) { rval.set(UndefinedValue());
--- a/js/xpconnect/src/XPCJSContextStack.cpp +++ b/js/xpconnect/src/XPCJSContextStack.cpp @@ -33,34 +33,38 @@ XPCJSContextStack::Pop() { MOZ_ASSERT(!mStack.IsEmpty()); uint32_t idx = mStack.Length() - 1; // The thing we're popping JSContext *cx = mStack[idx].cx; mStack.RemoveElementAt(idx); - if (idx == 0) + if (idx == 0) { + js::Debug_SetActiveJSContext(mRuntime->Runtime(), nullptr); return cx; + } --idx; // Advance to new top of the stack XPCJSContextInfo &e = mStack[idx]; if (e.cx && e.savedFrameChain) { // Pop() can be called outside any request for e.cx. JSAutoRequest ar(e.cx); JS_RestoreFrameChain(e.cx); e.savedFrameChain = false; } + js::Debug_SetActiveJSContext(mRuntime->Runtime(), e.cx); return cx; } bool XPCJSContextStack::Push(JSContext *cx) { + js::Debug_SetActiveJSContext(mRuntime->Runtime(), cx); if (mStack.Length() == 0) { mStack.AppendElement(cx); return true; } XPCJSContextInfo &e = mStack[mStack.Length() - 1]; if (e.cx) { // The cx we're pushing is also stack-top. In general we still need to
--- a/js/xpconnect/src/XPCJSRuntime.cpp +++ b/js/xpconnect/src/XPCJSRuntime.cpp @@ -2951,17 +2951,17 @@ class XPCJSSourceHook: public js::Source static const JSWrapObjectCallbacks WrapObjectCallbacks = { xpc::WrapperFactory::Rewrap, xpc::WrapperFactory::WrapForSameCompartment, xpc::WrapperFactory::PrepareForWrapping }; XPCJSRuntime::XPCJSRuntime(nsXPConnect* aXPConnect) : CycleCollectedJSRuntime(nullptr, 32L * 1024L * 1024L, JS_USE_HELPER_THREADS), - mJSContextStack(new XPCJSContextStack()), + mJSContextStack(new XPCJSContextStack(MOZ_THIS_IN_INITIALIZER_LIST())), mCallContext(nullptr), mAutoRoots(nullptr), mResolveName(JSID_VOID), mResolvingWrapper(nullptr), mWrappedJSMap(JSObject2WrappedJSMap::newMap(XPC_JS_MAP_SIZE)), mWrappedJSClassMap(IID2WrappedJSClassMap::newMap(XPC_JS_CLASS_MAP_SIZE)), mIID2NativeInterfaceMap(IID2NativeInterfaceMap::newMap(XPC_NATIVE_INTERFACE_MAP_SIZE)), mClassInfo2NativeSetMap(ClassInfo2NativeSetMap::newMap(XPC_NATIVE_SET_MAP_SIZE)),
--- a/js/xpconnect/src/xpcprivate.h +++ b/js/xpconnect/src/xpcprivate.h @@ -2768,18 +2768,19 @@ namespace xpc { bool PushJSContextNoScriptContext(JSContext *aCx); void PopJSContextNoScriptContext(); } /* namespace xpc */ class XPCJSContextStack { public: - XPCJSContextStack() - : mSafeJSContext(nullptr) + XPCJSContextStack(XPCJSRuntime *aRuntime) + : mRuntime(aRuntime) + , mSafeJSContext(nullptr) { } virtual ~XPCJSContextStack(); uint32_t Count() { return mStack.Length(); } @@ -2802,16 +2803,17 @@ private: friend void xpc::PopJSContextNoScriptContext(); // We make these private so that stack manipulation can only happen // through one of the above friends. JSContext *Pop(); bool Push(JSContext *cx); AutoInfallibleTArray<XPCJSContextInfo, 16> mStack; + XPCJSRuntime* mRuntime; JSContext* mSafeJSContext; }; /***************************************************************************/ // 'Components' object implementations. nsXPCComponentsBase has the // less-privileged stuff that we're willing to expose to XBL. class nsXPCComponentsBase : public nsIXPCComponentsBase
--- a/js/xpconnect/src/xpcpublic.h +++ b/js/xpconnect/src/xpcpublic.h @@ -97,16 +97,25 @@ UseXBLScope(JSCompartment *c); bool IsSandboxPrototypeProxy(JSObject *obj); bool IsReflector(JSObject *obj); bool IsXrayWrapper(JSObject *obj); + +// If this function was created for a given XrayWrapper, returns the global of +// the Xrayed object. Otherwise, returns the global of the function. +// +// To emphasize the obvious: the return value here is not necessarily same- +// compartment with the argument. +JSObject * +XrayAwareCalleeGlobal(JSObject *fun); + } /* namespace xpc */ namespace JS { struct RuntimeStats; }
--- a/js/xpconnect/wrappers/XrayWrapper.cpp +++ b/js/xpconnect/wrappers/XrayWrapper.cpp @@ -48,16 +48,26 @@ GetXrayType(JSObject *obj) const js::Class* clasp = js::GetObjectClass(obj); if (IS_WN_CLASS(clasp) || clasp->ext.innerObject) return XrayForWrappedNative; return NotXray; } +JSObject * +XrayAwareCalleeGlobal(JSObject *fun) +{ + MOZ_ASSERT(js::IsFunctionObject(fun)); + JSObject *scope = js::GetObjectParent(fun); + if (IsXrayWrapper(scope)) + scope = js::UncheckedUnwrap(scope); + return js::GetGlobalForObjectCrossCompartment(scope); +} + const uint32_t JSSLOT_RESOLVING = 0; ResolvingId::ResolvingId(JSContext *cx, HandleObject wrapper, HandleId id) : mId(id), mHolder(cx, getHolderObject(wrapper)), mPrev(getResolvingId(mHolder)), mXrayShadowing(false) { js::SetReservedSlot(mHolder, JSSLOT_RESOLVING, js::PrivateValue(this)); @@ -1535,17 +1545,17 @@ XrayWrapper<Base, Traits>::getPropertyDe return JS_WrapPropertyDescriptor(cx, desc); } } if (!desc.object() && id == nsXPConnect::GetRuntimeInstance()->GetStringID(XPCJSRuntime::IDX_TO_STRING)) { - JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, holder, "toString"); + JSFunction *toString = JS_NewFunction(cx, XrayToString, 0, 0, wrapper, "toString"); if (!toString) return false; desc.object().set(wrapper); desc.setAttributes(0); desc.setGetter(nullptr); desc.setSetter(nullptr); desc.value().setObject(*JS_GetFunctionObject(toString));
--- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -48,16 +48,17 @@ #include "nsIMessageManager.h" #include "mozilla/dom/MediaQueryList.h" #include "nsSMILAnimationController.h" #include "mozilla/css/ImageLoader.h" #include "mozilla/dom/TabChild.h" #include "nsRefreshDriver.h" #include "Layers.h" #include "nsIDOMEvent.h" +#include "gfxPrefs.h" #include "nsContentUtils.h" #include "nsCxPusher.h" #include "nsPIWindowRoot.h" #include "mozilla/Preferences.h" // Needed for Start/Stop of Image Animation #include "imgIContainer.h" @@ -683,16 +684,21 @@ nsPresContext::GetFontPrefsForLang(nsIAt } return prefs; } void nsPresContext::GetDocumentColorPreferences() { + // Make sure the preferences are initialized. In the normal run, + // they would already be, because gfxPlatform would have been created, + // but in some reference tests, that is not the case. + gfxPrefs::GetSingleton(); + int32_t useAccessibilityTheme = 0; bool usePrefColors = true; nsCOMPtr<nsIDocShellTreeItem> docShell(mContainer); if (docShell) { if (nsIDocShellTreeItem::typeChrome == docShell->ItemType()) { usePrefColors = false; } else { useAccessibilityTheme =
--- a/media/libpng/mozpngconf.h +++ b/media/libpng/mozpngconf.h @@ -61,29 +61,35 @@ #define PNG_READ_COMPRESSED_TEXT_SUPPORTED #define PNG_READ_EXPAND_SUPPORTED #define PNG_READ_GAMMA_SUPPORTED #define PNG_READ_GRAY_TO_RGB_SUPPORTED #define PNG_READ_INTERLACING_SUPPORTED #define PNG_READ_SCALE_16_TO_8_SUPPORTED #define PNG_READ_TRANSFORMS_SUPPORTED -/* necessary for boot animation code */ +/* necessary for freetype color bitmap support (Android & B2G) + and boot animation code (Gonk) */ +#if defined(ANDROID) || defined(FT_CONFIG_OPTION_USE_PNG) +#define PNG_READ_PACK_SUPPORTED +#define PNG_READ_FILLER_SUPPORTED +#define PNG_READ_STRIP_16_TO_8_SUPPORTED +#define PNG_READ_USER_TRANSFORM_SUPPORTED +#define PNG_SEQUENTIAL_READ_SUPPORTED +#endif + +/* necessary for boot animation code (Gonk) */ #ifdef MOZ_WIDGET_GONK #define PNG_UNKNOWN_CHUNKS_SUPPORTED #define PNG_SET_UNKNOWN_CHUNKS_SUPPORTED #define PNG_HANDLE_AS_UNKNOWN_SUPPORTED #define PNG_EASY_ACCESS_SUPPORTED #define PNG_READ_BGR_SUPPORTED -#define PNG_READ_FILLER_SUPPORTED #define PNG_READ_GRAY_TO_RGB_SUPPORTED -#define PNG_READ_STRIP_16_TO_8_SUPPORTED #define PNG_READ_STRIP_ALPHA_SUPPORTED -#define PNG_READ_USER_TRANSFORM_SUPPORTED -#define PNG_SEQUENTIAL_READ_SUPPORTED #endif #define PNG_WRITE_SUPPORTED #define PNG_WRITE_APNG_SUPPORTED #define PNG_WRITE_tRNS_SUPPORTED #define PNG_WRITE_16BIT_SUPPORTED #define PNG_WRITE_ANCILLARY_CHUNKS_SUPPORTED #define PNG_WRITE_FLUSH_SUPPORTED @@ -104,21 +110,18 @@ #define PNG_16BIT_SUPPORTED #define PNG_CHECK_cHRM_SUPPORTED #define PNG_FLOATING_ARITHMETIC_SUPPORTED #define PNG_FLOATING_POINT_SUPPORTED #define PNG_POINTER_INDEXING_SUPPORTED #define PNG_SETJMP_SUPPORTED #define PNG_STDIO_SUPPORTED #define PNG_TEXT_SUPPORTED - -#ifdef PR_LOGGING #define PNG_ERROR_TEXT_SUPPORTED #define PNG_WARNINGS_SUPPORTED -#endif /* Mangle names of exported libpng functions so different libpng versions can coexist. It is recommended that if you do this, you give your library a different name such as "mozlibpng" instead of "libpng". */ /* The following has been present since libpng-0.88, has never changed, and is unaffected by conditional compilation macros. It will not be mangled and it is the only choice for use in configure scripts for detecting the @@ -639,21 +642,27 @@ #define png_icc_check_length MOZ_PNG_icc_check_length #define png_icc_check_tag_table MOZ_PNG_icc_check_tags #define png_icc_set_sRGB MOZ_PNG_icc_set_sRGB #define png_malloc_array MOZ_PNG_malloc_array #define png_malloc_base MOZ_PNG_malloc_base #define png_realloc_array MOZ_PNG_realloc_array #define png_zstream_error MOZ_PNG_zstream_error +/* needed by FreeType's PNG support */ +#define png_error MOZ_PNG_error + #if defined(PR_LOGGING) && defined(PNG_WARNINGS_SUPPORTED) #define png_warning MOZ_PNG_warning -#define png_error MOZ_PNG_error #define png_chunk_error MOZ_PNG_chunk_err #define png_fixed_error MOZ_PNG_fixed_err #define png_formatted_warning MOZ_PNG_formatted_warning #define png_chunk_warning MOZ_PNG_chunk_warn #define png_warning_parameter MOZ_PNG_warn_param #define png_warning_parameter_signed MOZ_PNG_warn_param_signed #define png_warning_parameter_unsigned MOZ_PNG_warn_param_unsigned #endif +#if defined(PNG_READ_PACK_SUPPORTED) || defined(PNG_WRITE_PACK_SUPPORTED) +#define png_set_packing MOZ_PNG_set_packing +#endif + #endif /* MOZPNGCONF_H */
deleted file mode 100644 --- a/media/libsoundtouch/src/Makefile.in +++ /dev/null @@ -1,16 +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 $(topsrcdir)/config/rules.mk - -ifneq (,$(INTEL_ARCHITECTURE)) -ifdef GNU_CC -mmx_optimized.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -sse_optimized.$(OBJ_SUFFIX): CXXFLAGS+=-msse2 -endif -ifdef SOLARIS_SUNPRO_CXX -mmx_optimized.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -sse_optimized.$(OBJ_SUFFIX): OS_CXXFLAGS += -xarch=sse2 -xO4 -endif -endif
--- a/media/libsoundtouch/src/moz.build +++ b/media/libsoundtouch/src/moz.build @@ -18,23 +18,27 @@ UNIFIED_SOURCES += [ 'FIRFilter.cpp', 'RateTransposer.cpp', 'SoundTouch.cpp', 'TDStretch.cpp', ] if CONFIG['INTEL_ARCHITECTURE']: if CONFIG['MOZ_SAMPLE_TYPE_FLOAT32']: - UNIFIED_SOURCES += [ - 'sse_optimized.cpp', - ] + SOURCES += ['sse_optimized.cpp'] + if CONFIG['GNU_CC']: + SOURCES['sse_optimized.cpp'].flags += ['-msse2'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['sse_optimized.cpp'].flags += ['-xarch=sse2', '-xO4'] else: - UNIFIED_SOURCES += [ - 'mmx_optimized.cpp', - ] + SOURCES += ['mmx_optimized.cpp'] + if CONFIG['GNU_CC']: + SOURCES['mmx_optimized.cpp'].flags += ['-mmmx'] + if CONFIG['SOLARIS_SUNPRO_CXX']: + SOURCES['mmx_optimized.cpp'].flags += ['-xarch=mmx', '-xO4'] MSVC_ENABLE_PGO = True if CONFIG['GKMEDIAS_SHARED_LIBRARY']: NO_VISIBILITY_FLAGS = True FINAL_LIBRARY = 'gkmedias' # Use abort() instead of exception in SoundTouch.
deleted file mode 100644 --- a/media/libspeex_resampler/src/Makefile.in +++ /dev/null @@ -1,14 +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 $(topsrcdir)/config/rules.mk - -# Only use SSE code when using floating point samples, and on x86 -ifneq (,$(INTEL_ARCHITECTURE)) -ifneq ($(OS_TARGET),Android) -ifdef GNU_CC -resample.$(OBJ_SUFFIX): CFLAGS+=-msse2 -endif -endif -endif
--- a/media/libspeex_resampler/src/moz.build +++ b/media/libspeex_resampler/src/moz.build @@ -34,8 +34,10 @@ if CONFIG['OS_TARGET'] == 'Android': DEFINES['FIXED_POINT'] = True else: DEFINES['FLOATING_POINT'] = True # Only use SSE code when using floating point samples, and on x86 if CONFIG['INTEL_ARCHITECTURE'] and CONFIG['OS_TARGET'] != 'Android': DEFINES['_USE_SSE'] = True DEFINES['_USE_SSE2'] = True + if CONFIG['GNU_CC']: + SOURCES['resample.c'].flags += ['-msse2']
--- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -5721,35 +5721,35 @@ nsHttpChannel::DoAuthRetry(nsAHttpConnec // notify "http-on-modify-request" observers CallOnModifyRequestObservers(); mIsPending = true; // get rid of the old response headers mResponseHead = nullptr; + // rewind the upload stream + if (mUploadStream) { + nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream); + if (seekable) + seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0); + } + // set sticky connection flag and disable pipelining. mCaps |= NS_HTTP_STICKY_CONNECTION; mCaps &= ~NS_HTTP_ALLOW_PIPELINING; // and create a new one... rv = SetupTransaction(); if (NS_FAILED(rv)) return rv; // transfer ownership of connection to transaction if (conn) mTransaction->SetConnection(conn); - // rewind the upload stream - if (mUploadStream) { - nsCOMPtr<nsISeekableStream> seekable = do_QueryInterface(mUploadStream); - if (seekable) - seekable->Seek(nsISeekableStream::NS_SEEK_SET, 0); - } - rv = gHttpHandler->InitiateTransaction(mTransaction, mPriority); if (NS_FAILED(rv)) return rv; rv = mTransactionPump->AsyncRead(this, nullptr); if (NS_FAILED(rv)) return rv; uint32_t suspendCount = mSuspendCount; while (suspendCount--)
--- a/python/mozboot/mozboot/base.py +++ b/python/mozboot/mozboot/base.py @@ -138,17 +138,17 @@ class BaseBootstrapper(object): def apt_update(self): command = ['apt-get', 'update'] self.run_as_root(command) def apt_add_architecture(self, arch): command = ['dpkg', '--add-architecture'] - command.extemd(arch) + command.extend(arch) self.run_as_root(command) def check_output(self, *args, **kwargs): """Run subprocess.check_output even if Python doesn't provide it.""" fn = getattr(subprocess, 'check_output', BaseBootstrapper._check_output) return fn(*args, **kwargs)
--- a/python/mozbuild/mozbuild/backend/recursivemake.py +++ b/python/mozbuild/mozbuild/backend/recursivemake.py @@ -32,16 +32,17 @@ from ..frontend.data import ( HostProgram, HostSimpleProgram, InstallationTarget, IPDLFile, JARManifest, JavaJarData, LibraryDefinition, LocalInclude, + PerSourceFlag, Program, Resources, SandboxDerived, SandboxWrapped, SimpleProgram, TestManifest, VariablePassthru, XPIDLFile, @@ -437,16 +438,19 @@ class RecursiveMakeBackend(CommonBackend self._process_host_simple_program(obj.program, backend_file) elif isinstance(obj, LocalInclude): self._process_local_include(obj.path, backend_file) elif isinstance(obj, GeneratedInclude): self._process_generated_include(obj.path, backend_file) + elif isinstance(obj, PerSourceFlag): + self._process_per_source_flag(obj, backend_file) + elif isinstance(obj, InstallationTarget): self._process_installation_target(obj, backend_file) elif isinstance(obj, SandboxWrapped): # Process a rich build system object from the front-end # as-is. Please follow precedent and handle CamelCaseData # in a function named _process_camel_case_data. At some # point in the future, this unwrapping process may be @@ -1080,16 +1084,20 @@ class RecursiveMakeBackend(CommonBackend def _process_generated_include(self, generated_include, backend_file): if generated_include.startswith('/'): path = self.environment.topobjdir.replace('\\', '/') else: path = '' backend_file.write('LOCAL_INCLUDES += -I%s%s\n' % (path, generated_include)) + def _process_per_source_flag(self, per_source_flag, backend_file): + for flag in per_source_flag.flags: + backend_file.write('%s_FLAGS += %s\n' % (per_source_flag.file_name, flag)) + def _process_java_jar_data(self, jar, backend_file): target = jar.name backend_file.write('JAVA_JAR_TARGETS += %s\n' % target) backend_file.write('%s_DEST := %s.jar\n' % (target, jar.name)) if jar.sources: backend_file.write('%s_JAVAFILES := %s\n' % (target, ' '.join(jar.sources))) if jar.generated_sources:
--- a/python/mozbuild/mozbuild/frontend/data.py +++ b/python/mozbuild/mozbuild/frontend/data.py @@ -465,16 +465,31 @@ class GeneratedInclude(SandboxDerived): ) def __init__(self, sandbox, path): SandboxDerived.__init__(self, sandbox) self.path = path +class PerSourceFlag(SandboxDerived): + """Describes compiler flags specified for individual source files.""" + + __slots__ = ( + 'file_name', + 'flags', + ) + + def __init__(self, sandbox, file_name, flags): + SandboxDerived.__init__(self, sandbox) + + self.file_name = file_name + self.flags = flags + + class JARManifest(SandboxDerived): """Describes an individual JAR manifest file and how to process it. This class isn't very useful for optimizing backends yet because we don't capture defines. We can't capture defines safely until all of them are defined in moz.build and not Makefile.in files. """ __slots__ = (
--- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -28,16 +28,17 @@ from .data import ( HeaderFileSubstitution, HostProgram, HostSimpleProgram, InstallationTarget, IPDLFile, JARManifest, LibraryDefinition, LocalInclude, + PerSourceFlag, PreprocessedTestWebIDLFile, PreprocessedWebIDLFile, Program, ReaderSummary, Resources, SandboxWrapped, SimpleProgram, TestWebIDLFile, @@ -302,16 +303,21 @@ class TreeMetadataEmitter(LoggingMixin): no_pgo_sources = [f for f in sources if sources[f].no_pgo] if no_pgo: if no_pgo_sources: raise SandboxValidationError('NO_PGO and SOURCES[...].no_pgo cannot be set at the same time') passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo if no_pgo_sources: passthru.variables['NO_PROFILE_GUIDED_OPTIMIZE'] = no_pgo_sources + sources_with_flags = [f for f in sources if sources[f].flags] + for f in sources_with_flags: + ext = mozpath.splitext(f)[1] + yield PerSourceFlag(sandbox, f, sources[f].flags) + exports = sandbox.get('EXPORTS') if exports: yield Exports(sandbox, exports, dist_install=not sandbox.get('NO_DIST_INSTALL', False)) defines = sandbox.get('DEFINES') if defines: yield Defines(sandbox, defines)
--- a/python/mozbuild/mozbuild/frontend/sandbox_symbols.py +++ b/python/mozbuild/mozbuild/frontend/sandbox_symbols.py @@ -79,17 +79,17 @@ VARIABLES = { 'ANDROID_ECLIPSE_PROJECT_TARGETS': (dict, dict, """Defines Android Eclipse project targets. This variable should not be populated directly. Instead, it should populated by calling add_android_eclipse{_library}_project(). """, 'export'), - 'SOURCES': (StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool}), list, + 'SOURCES': (StrictOrderingOnAppendListWithFlagsFactory({'no_pgo': bool, 'flags': list}), list, """Source code files. This variable contains a list of source code files to compile. Accepts assembler, C, C++, Objective C/C++. """, 'compile'), 'GENERATED_SOURCES': (StrictOrderingOnAppendList, list, """Generated source code files.
--- a/security/manager/ssl/src/NSSErrorsService.cpp +++ b/security/manager/ssl/src/NSSErrorsService.cpp @@ -95,17 +95,16 @@ NSSErrorsService::GetErrorClass(nsresult switch (aNSPRCode) { case SEC_ERROR_UNKNOWN_ISSUER: case SEC_ERROR_CA_CERT_INVALID: case SEC_ERROR_UNTRUSTED_ISSUER: case SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE: case SEC_ERROR_UNTRUSTED_CERT: - case SEC_ERROR_INADEQUATE_KEY_USAGE: case SSL_ERROR_BAD_CERT_DOMAIN: case SEC_ERROR_EXPIRED_CERTIFICATE: case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: *aErrorClass = ERROR_CLASS_BAD_CERT; break; default: *aErrorClass = ERROR_CLASS_SSL_PROTOCOL; break;
--- a/security/manager/ssl/src/TransportSecurityInfo.cpp +++ b/security/manager/ssl/src/TransportSecurityInfo.cpp @@ -629,19 +629,16 @@ AppendErrorTextUntrusted(PRErrorCode err if (chain && NS_FAILED(chain->GetLength(&length))) length = 0; if (length == 1) errorID = "certErrorTrust_MissingChain"; else errorID = "certErrorTrust_UnknownIssuer"; break; } - case SEC_ERROR_INADEQUATE_KEY_USAGE: - // Should get an individual string in the future - // For now, use the same as CaInvalid case SEC_ERROR_CA_CERT_INVALID: errorID = "certErrorTrust_CaInvalid"; break; case SEC_ERROR_UNTRUSTED_ISSUER: errorID = "certErrorTrust_Issuer"; break; case SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED: errorID = "certErrorTrust_SignatureAlgorithmDisabled";
--- a/security/manager/ssl/tests/unit/test_cert_overrides.js +++ b/security/manager/ssl/tests/unit/test_cert_overrides.js @@ -108,16 +108,28 @@ function add_simple_tests(useInsanity) { : SEC_ERROR_EXPIRED_ISSUER_CERTIFICATE)); add_cert_override_test("md5signature.example.com", Ci.nsICertOverrideService.ERROR_UNTRUSTED, getXPCOMStatusFromNSS( SEC_ERROR_CERT_SIGNATURE_ALGORITHM_DISABLED)); add_cert_override_test("mismatch.example.com", Ci.nsICertOverrideService.ERROR_MISMATCH, getXPCOMStatusFromNSS(SSL_ERROR_BAD_CERT_DOMAIN)); + + // Inadequate key usage is no longer overridable. + add_connection_test("inadequatekeyusage.example.com", + getXPCOMStatusFromNSS(SEC_ERROR_INADEQUATE_KEY_USAGE), + null, + function (securityInfo) { + // bug 754369 - no SSLStatus probably means this is + // a non-overridable error, which is what we're testing + // (although it would be best to test this directly). + securityInfo.QueryInterface(Ci.nsISSLStatusProvider); + do_check_eq(securityInfo.SSLStatus, null); + }); } function add_combo_tests(useInsanity) { // Note that "untrusted" here really is "unknown issuer" in the // insanity::pkix case. add_cert_override_test("mismatch-expired.example.com", Ci.nsICertOverrideService.ERROR_MISMATCH | @@ -166,17 +178,16 @@ function add_distrust_tests(useInsanity) // XXX(Bug 975777): Active distrust is an overridable error when NSS-based // verification is used. add_distrust_override_test("tlsserver/other-test-ca.der", "untrustedissuer.example.com", getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER), useInsanity ? getXPCOMStatusFromNSS(SEC_ERROR_UNTRUSTED_ISSUER) : Cr.NS_OK); - } function add_distrust_override_test(certFileName, hostName, expectedResultBefore, expectedResultAfter) { let certToDistrust = constructCertFromFile(certFileName); add_test(function () { // "pu" means the cert is actively distrusted.
index 82f76a6ed791e47c4078f18a19fdeade3ad97a2e..ab5dffe785a67ba80741b7979178ec92ef5a96c3 GIT binary patch literal 65536 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 v000000000000000000000000000000000000000000000000000H*&RU4>)C
--- a/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp +++ b/security/manager/ssl/tests/unit/tlsserver/cmd/BadCertServer.cpp @@ -34,16 +34,17 @@ const BadCertHost sBadCertHosts[] = { "md5signature.example.com", "md5signature" }, { "untrusted.example.com", "localhostAndExampleCom" }, { "untrustedissuer.example.com", "untrustedissuer" }, { "mismatch-expired.example.com", "mismatch-expired" }, { "mismatch-untrusted.example.com", "mismatch-untrusted" }, { "untrusted-expired.example.com", "untrusted-expired" }, { "md5signature-expired.example.com", "md5signature-expired" }, { "mismatch-untrusted-expired.example.com", "mismatch-untrusted-expired" }, + { "inadequatekeyusage.example.com", "inadequatekeyusage" }, { nullptr, nullptr } }; int32_t DoSNISocketConfig(PRFileDesc *aFd, const SECItem *aSrvNameArr, uint32_t aSrvNameArrSize, void *aArg) { const BadCertHost *host = GetHostForSNI(aSrvNameArr, aSrvNameArrSize,
index 9100328605be1f4db33e0528bfbfa979052af957..7e6f9654dabd2a6220f7cecccda64a707059f9cc GIT binary patch literal 527 zc$_n6V&XPvVk}v}%*4pV#K>sC%f_kI=F#?@mywZ`mBB#BP{4qXjX9KsS(rT}wYWsV z+0j5woY&CAz{tSZ$k5c%$Sg{n*94hsAY~|FAO_LH57y(Fm!g}RSCUy$Y0x+y*#<^d z2Ij_I27|^<rp88whh}aQ^IwHXKAiZ~Ik#20ciZXDI?;bp52Q~1Qdh;|Ijgwy*0043 zx3;<;74kCibD9vYqi{QnrMSAiVwSj1RpILU-?h^tL=Bp28V}}f{WR^aDf5dD%(g{q z+CDZdIJ-YfW<kI0;V|h%3L=edZMqBXrh7+99%Xs@ea4gAo1C|{=pAKZW@KPooN175 zpbT`qtRRbwfm9P`PJVJ?PDXxlNfWP@UTQ^RZb43}UUGh}fe{;rHXAUI*clmF)C^P% zlwf=V#x}8xl9B=|eSNrQD+>b)1APM?kio)?jQ?4f3>eVDni&`b9&>BtZgkApYsa7e z<=`QYwvWdBN`_I77-BnnUw(TcC0du?s<N=4f8{BONBjAcA~cH@y)zYwRg|0aF8&EG zbANyPf&JEr6`%9IuQr>J{FtxZ(SfC4)rmt7*`s&!Y4nJ!`h3OHwmAFir7!!~cSS7N WVd`OE$iDW~{f;j6qz)PJ=otVHe6~#h
--- a/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh +++ b/security/manager/ssl/tests/unit/tlsserver/generate_certs.sh @@ -139,9 +139,11 @@ NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE m make_EE untrustedissuer 'CN=Test End-entity with untrusted issuer' otherCA "untrustedissuer.example.com" make_EE mismatch-expired 'CN=Mismatch-Expired Test End-entity' testCA "doesntmatch.example.com" "-w -400" make_EE mismatch-untrusted 'CN=Mismatch-Untrusted Test End-entity' otherCA "doesntmatch.example.com" make_EE untrusted-expired 'CN=Untrusted-Expired Test End-entity' otherCA "untrusted-expired.example.com" "-w -400" make_EE mismatch-untrusted-expired 'CN=Mismatch-Untrusted-Expired Test End-entity' otherCA "doesntmatch.example.com" "-w -400" NSS_ALLOW_WEAK_SIGNATURE_ALG=1 make_EE md5signature-expired 'CN=Test MD5Signature-Expired End-entity' testCA "md5signature-expired.example.com" "-Z MD5" "-w -400" +make_EE inadequatekeyusage 'CN=Inadequate Key Usage Test End-entity' testCA "inadequatekeyusage.example.com" "--keyUsage crlSigning" + cleanup
index c5ae5df7a2045460217167d36a047ddc75e0a376..6793d58fa6a354fe7a401c4fa9dd6f85d82975fb GIT binary patch literal 53248 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 M2~Qyve5q12`*r7$*8l(j
index e3d76676da15d3bde5ac053f8ce43fb8a0c0ae0e..357c00a748f8ba04d5aeaac0242179b20e8d2ff4 GIT binary patch literal 452 zc$_n6Vmx5b#HhJ|nTe5!iIrhqdCXM<UN%mxHjlRNyo`*jtPBPchGGUHY|No7%)-3> zB^jwj3MHw<B?``t26E!Oh9(9^2F6B)rj|x#QR2KN$Xq-+8|Ne2!pO?N+}O)t(Ade; z*vPQB|J><CQf1E1I&S<em|R|T-ib&1=PLCx1+%hJE==``{PfE?bXrV$e%3VYuMN66 z63Z3kAKTt6UT{0ebfc4P&+b{Fia$T(=X~2*qq^<<<vliwJoU>bPF-mxa%b<SKg``0 z?yDO1FPT?ucH{d(`;XzPY_n&7+rE6_=^pM&Tb2e#KWt@UW@KPo40O4H5YX+i!i<dn zSvU;XfD{uWBU<1v1Klf95%gi@^xw?+yDl!7{{Og#GSjomHmlw)S)J9p`|hD{QRn<( z)Adch+$xzn;dktw&OD~ivb=_yV#_(4zt7jGmYKis*SgPahnZBh(%Cj2xDhoa`04Fe yUc9wO|7c9$;*!*^GIW|PomCcjbkj@yjEC1AJ2;E1ZdxZ>!>r%2PJK^Ji#q_tgRN2k
index d499ddd477252fee875c6d3f702e3dfe30959a74..080be8ed53e6bf1cd3f248c9d67e083275088c01 GIT binary patch literal 440 zc$_n6V%%cT#3;LfnTe5!iIrhqdCV09UN%mxHjlRNyo`*jtPBQ1h5`nBY|No7%);y; zsl_D<&W;9h;=G0?21W+PMuw)AMrKjsye7z8ta=*fBb&^~%D~*%%V5yh$<)}$aEjNd z^?Uid)t?Q1YAWmH)En|eeAYU2anlU{MQr!(oqMwWyG&H;NsSX0JU)&WzKEzeyf?`| z7~5GtOa4q!vdzIsS0Df1Ep#<GxOskG%GWlJ9L|t^&owumjeStPgZJ774><;fx2)W& z6JLs+k1O1p<Mrvw)jx+i?}t8Gp6>U1$vn;3Ow5c7jElt#L=1$0u9g*MWc<&<VZa8Y zm>3z+0)!dpUZn%;oTJ)(v;T`PU`;*Pc6!yp(x*j9^=!V2mreh3=Y;<+Qy$eFA&;Dv ze2d=Ho}b(l-u0+aw&T#F>rA;?sefhpX4|PM&u7?lS8Zvke9z(ITf^%Pm_@vixi;%^ sM`CwxlEF^xx$7H3bvySwZY~ylUsl(0N>N|?;WQhsjr9UG_jw)z00U#EC;$Ke
--- a/testing/marionette/marionette-server.js +++ b/testing/marionette/marionette-server.js @@ -34,17 +34,19 @@ Cu.import("resource://gre/modules/NetUti Services.prefs.setBoolPref("marionette.contentListener", false); let appName = Services.appinfo.name; // dumpn needed/used by dbg-transport.js this.dumpn = function dumpn(str) { logger.trace(str); } -loader.loadSubScript("resource://gre/modules/devtools/DevToolsUtils.js"); +let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +let DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js"); +this.DevToolsUtils = DevToolsUtils; loader.loadSubScript("resource://gre/modules/devtools/server/transport.js"); let bypassOffline = false; let qemu = "0"; let device = null; try { XPCOMUtils.defineLazyGetter(this, "libcutils", function () {
--- a/testing/mochitest/b2g-debug.json +++ b/testing/mochitest/b2g-debug.json @@ -9,16 +9,17 @@ "toolkit/devtools/apps": "" }, "excludetests": { "content/xul":"tests that use xul", "layout/xul" : "", "dom/apps":"bug 972927, nearly perma-fail", "dom/datastore":"bug 974270, frequent failures", "dom/datastore/tests/test_changes.html":"intermittent failures, bug 961021", + "dom/downloads":"bug 979446, frequent failures", "dom/tests/mochitest/general/test_focusrings.xul":"", "layout/base/tests/test_bug465448.xul":"", "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795", "content/media/test":"bug 918299", "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests", "content/media/mediasource/test/test_MediaSource.html": " ReferenceError: MediaSource is not defined", "content/media/test/test_autoplay_contentEditable.html": "bug 899074 - timeouts",
--- a/testing/mochitest/b2g-desktop.json +++ b/testing/mochitest/b2g-desktop.json @@ -7,16 +7,17 @@ "dom": "", "layout": "", "toolkit/devtools/apps": "" }, "excludetests": { "b2g/chrome/content/test/mochitest": "require OOP support for mochitest-b2g-desktop, Bug 957554", "content/xul":"tests that use xul", "layout/xul" : "", + "dom/downloads":"bug 979446, frequent failures", "dom/plugins": "tests that use plugins", "dom/tests/mochitest/general/test_focusrings.xul":"", "layout/base/tests/test_bug465448.xul":"", "layout/forms/test/test_bug287446.html": "bug 947789", "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795", "content/media/test":"bug 918299", "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests",
--- a/testing/mochitest/b2g.json +++ b/testing/mochitest/b2g.json @@ -8,16 +8,17 @@ "layout": "", "toolkit/devtools/apps": "" }, "excludetests": { "content/xul":"tests that use xul", "layout/xul" : "", "dom/apps":"bug 972927, nearly perma-fail", "dom/datastore":"bug 974270, frequent failures", + "dom/downloads":"bug 979446, frequent failures", "dom/tests/mochitest/general/test_focusrings.xul":"", "layout/base/tests/test_bug465448.xul":"", "layout/forms/test/test_bug478219.xhtml":"window.closed not working, bug 907795", "content/media/test/test_bug448534.html": "Timed out, bug 894922? Bug 902677 is for the timing out of a lot of media tests", "content/media/mediasource/test/test_MediaSource.html": " ReferenceError: MediaSource is not defined", "content/media/test/test_autoplay_contentEditable.html": "bug 899074 - timeouts", "content/media/test/test_bug465498.html":"",
--- a/testing/mochitest/tests/SimpleTest/EventUtils.js +++ b/testing/mochitest/tests/SimpleTest/EventUtils.js @@ -941,18 +941,31 @@ function synthesizeText(aEvent, aWindow) !aEvent.composition.clauses[0]) { return; } var compositionString = utils.createCompositionStringSynthesizer(); compositionString.setString(aEvent.composition.string); if (aEvent.composition.clauses[0].length) { for (var i = 0; i < aEvent.composition.clauses.length; i++) { - compositionString.appendClause(aEvent.composition.clauses[i].length, - aEvent.composition.clauses[i].attr); + switch (aEvent.composition.clauses[i].attr) { + case compositionString.ATTR_RAWINPUT: + case compositionString.ATTR_SELECTEDRAWTEXT: + case compositionString.ATTR_CONVERTEDTEXT: + case compositionString.ATTR_SELECTEDCONVERTEDTEXT: + compositionString.appendClause(aEvent.composition.clauses[i].length, + aEvent.composition.clauses[i].attr); + break; + case 0: + // Ignore dummy clause for the argument. + break; + default: + throw new Error("invalid clause attribute specified"); + break; + } } } if (aEvent.caret) { compositionString.setCaret(aEvent.caret.start, aEvent.caret.length); } compositionString.dispatchEvent();
--- a/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py +++ b/testing/mozbase/mozdevice/mozdevice/devicemanagerADB.py @@ -202,17 +202,17 @@ class DeviceManagerADB(DeviceManager): self._checkCmd(["push", os.path.realpath(localname), destname], retryLimit=retryLimit) def mkDir(self, name): result = self._runCmd(["shell", "mkdir", name]).stdout.read() if 'read-only file system' in result.lower(): raise DMError("Error creating directory: read only file system") - def pushDir(self, localDir, remoteDir, retryLimit=None): + def pushDir(self, localDir, remoteDir, retryLimit=None, timeout=None): # adb "push" accepts a directory as an argument, but if the directory # contains symbolic links, the links are pushed, rather than the linked # files; we either zip/unzip or re-copy the directory into a temporary # one to get around this limitation retryLimit = retryLimit or self.retryLimit if not self.dirExists(remoteDir): self.mkDirs(remoteDir+"/x") if self._useZip: @@ -221,17 +221,17 @@ class DeviceManagerADB(DeviceManager): remoteZip = remoteDir + "/adbdmtmp.zip" subprocess.Popen(["zip", "-r", localZip, '.'], cwd=localDir, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate() self.pushFile(localZip, remoteZip, retryLimit=retryLimit, createDir=False) mozfile.remove(localZip) data = self._runCmd(["shell", "unzip", "-o", remoteZip, "-d", remoteDir]).stdout.read() self._checkCmd(["shell", "rm", remoteZip], - retryLimit=retryLimit) + retryLimit=retryLimit, timeout=timeout) if re.search("unzip: exiting", data) or re.search("Operation not permitted", data): raise Exception("unzip failed, or permissions error") except: self._logger.info("zip/unzip failure: falling back to normal push") self._useZip = False self.pushDir(localDir, remoteDir, retryLimit=retryLimit) else: tmpDir = tempfile.mkdtemp()
--- a/toolkit/devtools/DevToolsUtils.js +++ b/toolkit/devtools/DevToolsUtils.js @@ -1,24 +1,24 @@ /* 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/. */ "use strict"; /* General utilities used throughout devtools. */ +const { Ci, Cu } = require("chrome"); -let Cu = Components.utils; -let { Promise: promise } = Components.utils.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}); -let { Services } = Components.utils.import("resource://gre/modules/Services.jsm", {}); +let { Promise: promise } = Cu.import("resource://gre/modules/commonjs/sdk/core/promise.js", {}); +let { Services } = Cu.import("resource://gre/modules/Services.jsm", {}); /** * Turn the error |aError| into a string, without fail. */ -this.safeErrorString = function safeErrorString(aError) { +exports.safeErrorString = function safeErrorString(aError) { try { let errorString = aError.toString(); if (typeof errorString == "string") { // Attempt to attach a stack to |errorString|. If it throws an error, or // isn't a string, don't use it. try { if (aError.stack) { let stack = aError.stack.toString(); @@ -37,28 +37,28 @@ this.safeErrorString = function safeErro } catch (ee) { } return "<failed trying to find error description>"; } /** * Report that |aWho| threw an exception, |aException|. */ -this.reportException = function reportException(aWho, aException) { - let msg = aWho + " threw an exception: " + safeErrorString(aException); +exports.reportException = function reportException(aWho, aException) { + let msg = aWho + " threw an exception: " + exports.safeErrorString(aException); dump(msg + "\n"); - if (Components.utils.reportError) { + if (Cu.reportError) { /* * Note that the xpcshell test harness registers an observer for * console messages, so when we're running tests, this will cause * the test to quit. */ - Components.utils.reportError(msg); + Cu.reportError(msg); } } /** * Given a handler function that may throw, return an infallible handler * function that calls the fallible handler, and logs any exceptions it * throws. * @@ -66,44 +66,44 @@ this.reportException = function reportEx * A handler function, which may throw. * @param aName string * A name for aHandler, for use in error messages. If omitted, we use * aHandler.name. * * (SpiderMonkey does generate good names for anonymous functions, but we * don't have a way to get at them from JavaScript at the moment.) */ -this.makeInfallible = function makeInfallible(aHandler, aName) { +exports.makeInfallible = function makeInfallible(aHandler, aName) { if (!aName) aName = aHandler.name; return function (/* arguments */) { try { return aHandler.apply(this, arguments); } catch (ex) { let who = "Handler function"; if (aName) { who += " " + aName; } - reportException(who, ex); + exports.reportException(who, ex); } } } /** * Interleaves two arrays element by element, returning the combined array, like * a zip. In the case of arrays with different sizes, undefined values will be * interleaved at the end along with the extra values of the larger array. * * @param Array a * @param Array b * @returns Array * The combined array, in the form [a1, b1, a2, b2, ...] */ -this.zip = function zip(a, b) { +exports.zip = function zip(a, b) { if (!b) { return a; } if (!a) { return b; } const pairs = []; for (let i = 0, aLength = a.length, bLength = b.length; @@ -111,34 +111,34 @@ this.zip = function zip(a, b) { i++) { pairs.push([a[i], b[i]]); } return pairs; }; const executeSoon = aFn => { Services.tm.mainThread.dispatch({ - run: this.makeInfallible(aFn) - }, Components.interfaces.nsIThread.DISPATCH_NORMAL); + run: exports.makeInfallible(aFn) + }, Ci.nsIThread.DISPATCH_NORMAL); }; /** * Like Array.prototype.forEach, but doesn't cause jankiness when iterating over * very large arrays by yielding to the browser and continuing execution on the * next tick. * * @param Array aArray * The array being iterated over. * @param Function aFn * The function called on each item in the array. * @returns Promise * A promise that is resolved once the whole array has been iterated * over. */ -this.yieldingEach = function yieldingEach(aArray, aFn) { +exports.yieldingEach = function yieldingEach(aArray, aFn) { const deferred = promise.defer(); let i = 0; let len = aArray.length; (function loop() { const start = Date.now(); @@ -175,17 +175,17 @@ this.yieldingEach = function yieldingEac * @param Object aObject * The prototype object to define the lazy getter on. * @param String aKey * The key to define the lazy getter on. * @param Function aCallback * The callback that will be called to determine the value. Will be * called with the |this| value of the current instance. */ -this.defineLazyPrototypeGetter = +exports.defineLazyPrototypeGetter = function defineLazyPrototypeGetter(aObject, aKey, aCallback) { Object.defineProperty(aObject, aKey, { configurable: true, get: function() { const value = aCallback.call(this); Object.defineProperty(this, aKey, { configurable: true, @@ -203,65 +203,65 @@ function defineLazyPrototypeGetter(aObje * the prototype chain until the property is found. * * @param Debugger.Object aObject * The Debugger.Object to get the value from. * @param String aKey * The key to look for. * @return Any */ -this.getProperty = function getProperty(aObj, aKey) { +exports.getProperty = function getProperty(aObj, aKey) { let root = aObj; try { do { const desc = aObj.getOwnPropertyDescriptor(aKey); if (desc) { if ("value" in desc) { return desc.value; } // Call the getter if it's safe. - return hasSafeGetter(desc) ? desc.get.call(root).return : undefined; + return exports.hasSafeGetter(desc) ? desc.get.call(root).return : undefined; } aObj = aObj.proto; } while (aObj); } catch (e) { // If anything goes wrong report the error and return undefined. - reportException("getProperty", e); + exports.reportException("getProperty", e); } return undefined; }; /** * Determines if a descriptor has a getter which doesn't call into JavaScript. * * @param Object aDesc * The descriptor to check for a safe getter. * @return Boolean * Whether a safe getter was found. */ -this.hasSafeGetter = function hasSafeGetter(aDesc) { +exports.hasSafeGetter = function hasSafeGetter(aDesc) { let fn = aDesc.get; return fn && fn.callable && fn.class == "Function" && fn.script === undefined; }; /** * Check if it is safe to read properties and execute methods from the given JS * object. Safety is defined as being protected from unintended code execution * from content scripts (or cross-compartment code). * * See bugs 945920 and 946752 for discussion. * * @type Object aObj * The object to check. * @return Boolean * True if it is safe to read properties from aObj, or false otherwise. */ -this.isSafeJSObject = function isSafeJSObject(aObj) { +exports.isSafeJSObject = function isSafeJSObject(aObj) { if (Cu.getGlobalForObject(aObj) == - Cu.getGlobalForObject(isSafeJSObject)) { + Cu.getGlobalForObject(exports.isSafeJSObject)) { return true; // aObj is not a cross-compartment wrapper. } let principal = Services.scriptSecurityManager.getObjectPrincipal(aObj); if (Services.scriptSecurityManager.isSystemPrincipal(principal)) { return true; // allow chrome objects }
--- a/toolkit/devtools/DevToolsUtils.jsm +++ b/toolkit/devtools/DevToolsUtils.jsm @@ -2,31 +2,17 @@ * 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/. */ "use strict"; /* * General utilities used throughout devtools. * - * To support chrome debugging, the debugger server needs to have all its - * code in one global, so it must use loadSubScript directly. Everyone else, - * though, prefers a JSM. + * When using chrome debugging, the debugger server is unable to debug itself. + * To avoid this, it must be loaded with a custom devtools loader with the + * invisibleToDebugger flag set to true. Everyone else, though, prefers a JSM. */ this.EXPORTED_SYMBOLS = [ "DevToolsUtils" ]; -Components.classes["@mozilla.org/moz/jssubscript-loader;1"] - .getService(Components.interfaces.mozIJSSubScriptLoader) - .loadSubScript("resource://gre/modules/devtools/DevToolsUtils.js", this); - -this.DevToolsUtils = { - safeErrorString: safeErrorString, - reportException: reportException, - makeInfallible: makeInfallible, - zip: zip, - yieldingEach: yieldingEach, - reportingDisabled: false , // Used by tests. - defineLazyPrototypeGetter: defineLazyPrototypeGetter, - getProperty: getProperty, - hasSafeGetter: hasSafeGetter, - isSafeJSObject: isSafeJSObject, -}; +const { devtools } = Components.utils.import("resource://gre/modules/devtools/Loader.jsm", {}); +this.DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js");
--- a/toolkit/devtools/server/actors/profiler.js +++ b/toolkit/devtools/server/actors/profiler.js @@ -136,17 +136,17 @@ ProfilerActor.prototype = { if (idx == -1) continue; Services.obs.removeObserver(this, event); this._observedEvents.splice(idx, 1); unregistered.push(event); } return { unregistered: unregistered } }, - observe: makeInfallible(function(aSubject, aTopic, aData) { + observe: DevToolsUtils.makeInfallible(function(aSubject, aTopic, aData) { /* * this.conn.send can only transmit acyclic values. However, it is * idiomatic for wrapped JS objects like aSubject (and possibly aData?) * to have a 'wrappedJSObject' property pointing to themselves. * * this.conn.send also assumes that it can retain the object it is * passed to be handled on later event ticks; and that it's okay to * freeze it. Since we don't really know what aSubject and aData are,
--- a/toolkit/devtools/server/actors/script.js +++ b/toolkit/devtools/server/actors/script.js @@ -1071,17 +1071,17 @@ ThreadActor.prototype = { } let packet = this._resumed(); this._popThreadPause(); return packet; }, error => { return error instanceof Error ? { error: "unknownError", - message: safeErrorString(error) } + message: DevToolsUtils.safeErrorString(error) } // It is a known error, and the promise was rejected with an error // packet. : error; }); }, /** * Spin up a nested event loop so we can synchronously resolve a promise. @@ -2504,17 +2504,17 @@ SourceActor.prototype = { }; }) .then(null, aError => { reportError(aError, "Got an exception during SA_onSource: "); return { "from": this.actorID, "error": "loadSourceError", "message": "Could not load the source for " + this._url + ".\n" - + safeErrorString(aError) + + DevToolsUtils.safeErrorString(aError) }; }); }, /** * Handler for the "prettyPrint" packet. */ onPrettyPrint: function ({ indent }) {
--- a/toolkit/devtools/server/actors/tracer.js +++ b/toolkit/devtools/server/actors/tracer.js @@ -1,19 +1,15 @@ /* 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/. */ "use strict"; const { Cu } = require("chrome"); - -const { reportException } = - Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {}).DevToolsUtils; - const { DebuggerServer } = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); Cu.import("resource://gre/modules/jsdebugger.jsm"); addDebuggerToGlobal(this); // TODO bug 943125: remove this polyfill and use Debugger.Frame.prototype.depth // once it is implemented. if (!Object.getOwnPropertyDescriptor(Debugger.Frame.prototype, "depth")) { @@ -135,17 +131,17 @@ TraceActor.prototype = { /** * Add a debuggee global to the Debugger object. */ _addDebuggee: function(aGlobal) { try { this.dbg.addDebuggee(aGlobal); } catch (e) { // Ignore attempts to add the debugger's compartment as a debuggee. - reportException("TraceActor", + DevToolsUtils.reportException("TraceActor", new Error("Ignoring request to add the debugger's " + "compartment as a debuggee")); } }, /** * Add the provided window and all windows in its frame tree as debuggees. */ @@ -604,17 +600,17 @@ function createValueSnapshot(aValue, aDe case "object": if (aValue === null) { return { type: "null" }; } return aDetailed ? detailedObjectSnapshot(aValue) : objectSnapshot(aValue); default: - reportException("TraceActor", + DevToolsUtils.reportException("TraceActor", new Error("Failed to provide a grip for: " + aValue)); return null; } } /** * Create a very minimal snapshot of the given debuggee object. *
--- a/toolkit/devtools/server/actors/webapps.js +++ b/toolkit/devtools/server/actors/webapps.js @@ -792,17 +792,17 @@ WebappsActor.prototype = { _connectToApp: function (aFrame) { let deferred = Promise.defer(); let mm = aFrame.QueryInterface(Ci.nsIFrameLoaderOwner).frameLoader.messageManager; mm.loadFrameScript("resource://gre/modules/devtools/server/child.js", false); let childTransport, prefix; - let onActorCreated = makeInfallible(function (msg) { + let onActorCreated = DevToolsUtils.makeInfallible(function (msg) { mm.removeMessageListener("debug:actor", onActorCreated); dump("***** Got debug:actor\n"); let { actor, appId } = msg.json; prefix = msg.json.prefix; // Pipe Debugger message from/to parent/child via the message manager childTransport = new ChildDebuggerTransport(mm, prefix); @@ -817,17 +817,17 @@ WebappsActor.prototype = { debug("establishing forwarding for app with prefix " + prefix); this._appActorsMap.set(mm, actor); deferred.resolve(actor); }).bind(this); mm.addMessageListener("debug:actor", onActorCreated); - let onMessageManagerDisconnect = makeInfallible(function (subject, topic, data) { + let onMessageManagerDisconnect = DevToolsUtils.makeInfallible(function (subject, topic, data) { if (subject == mm) { Services.obs.removeObserver(onMessageManagerDisconnect, topic); if (childTransport) { // If we have a child transport, the actor has already // been created. We need to stop using this message manager. childTransport.close(); this.conn.cancelForwarding(prefix); } else {
--- a/toolkit/devtools/server/actors/webbrowser.js +++ b/toolkit/devtools/server/actors/webbrowser.js @@ -352,17 +352,17 @@ BrowserTabList.prototype._listenForEvent } this[aGuard] = aShouldListen; } }; /** * Implement nsIDOMEventListener. */ -BrowserTabList.prototype.handleEvent = makeInfallible(function(aEvent) { +BrowserTabList.prototype.handleEvent = DevToolsUtils.makeInfallible(function(aEvent) { switch (aEvent.type) { case "TabOpen": case "TabSelect": /* Don't create a new actor; iterate will take care of that. Just notify. */ this._notifyListChanged(); this._checkListening(); break; case "TabClose": @@ -393,18 +393,18 @@ BrowserTabList.prototype._listenToMediat * See _onTabClosed for explanation of why we needn't actually tweak any * actors or tables here. * * An nsIWindowMediatorListener's methods get passed all sorts of windows; we * only care about the tab containers. Those have 'getBrowser' methods. */ BrowserTabList.prototype.onWindowTitleChange = () => { }; -BrowserTabList.prototype.onOpenWindow = makeInfallible(function(aWindow) { - let handleLoad = makeInfallible(() => { +BrowserTabList.prototype.onOpenWindow = DevToolsUtils.makeInfallible(function(aWindow) { + let handleLoad = DevToolsUtils.makeInfallible(() => { /* We don't want any further load events from this window. */ aWindow.removeEventListener("load", handleLoad, false); if (appShellDOMWindowType(aWindow) !== DebuggerServer.chromeWindowType) return; // Listen for future tab activity. if (this._listeningForTabOpen) { @@ -428,29 +428,29 @@ BrowserTabList.prototype.onOpenWindow = * nsIWindowMediator enumeration from within listeners (bug 873589). */ aWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindow); aWindow.addEventListener("load", handleLoad, false); }, "BrowserTabList.prototype.onOpenWindow"); -BrowserTabList.prototype.onCloseWindow = makeInfallible(function(aWindow) { +BrowserTabList.prototype.onCloseWindow = DevToolsUtils.makeInfallible(function(aWindow) { aWindow = aWindow.QueryInterface(Ci.nsIInterfaceRequestor) .getInterface(Ci.nsIDOMWindow); if (appShellDOMWindowType(aWindow) !== DebuggerServer.chromeWindowType) return; /* * nsIWindowMediator deadlocks if you call its GetEnumerator method from * a nsIWindowMediatorListener's onCloseWindow hook (bug 873589), so * handle the close in a different tick. */ - Services.tm.currentThread.dispatch(makeInfallible(() => { + Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => { /* * Scan the entire map for actors representing tabs that were in this * top-level window, and exit them. */ for (let [browser, actor] of this._actorByBrowser) { /* The browser document of a closed window has no default view. */ if (!browser.ownerDocument.defaultView) { this._handleActorClose(actor, browser); @@ -729,29 +729,29 @@ BrowserTabActor.prototype = { }, /** * Reload the page in this tab. */ onReload: function(aRequest) { // Wait a tick so that the response packet can be dispatched before the // subsequent navigation event packet. - Services.tm.currentThread.dispatch(makeInfallible(() => { + Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => { this.window.location.reload(); }, "BrowserTabActor.prototype.onReload's delayed body"), 0); return {}; }, /** * Navigate this tab to a new location */ onNavigateTo: function(aRequest) { // Wait a tick so that the response packet can be dispatched before the // subsequent navigation event packet. - Services.tm.currentThread.dispatch(makeInfallible(() => { + Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(() => { this.window.location = aRequest.url; }, "BrowserTabActor.prototype.onNavigateTo's delayed body"), 0); return {}; }, /** * Reconfigure options. */ @@ -889,17 +889,17 @@ BrowserTabActor.prototype = { }, /** * Handle location changes, by clearing the previous debuggees and enabling * debugging, which may have been disabled temporarily by the * DebuggerProgressListener. */ onWindowCreated: - makeInfallible(function BTA_onWindowCreated(evt) { + DevToolsUtils.makeInfallible(function BTA_onWindowCreated(evt) { // pageshow events for non-persisted pages have already been handled by a // prior DOMWindowCreated event. if (!this._attached || (evt.type == "pageshow" && !evt.persisted)) { return; } if (evt.target === this.browser.contentDocument ) { this.threadActor.clearDebuggees(); if (this.threadActor.dbg) { @@ -1042,17 +1042,17 @@ function DebuggerProgressListener(aBrows this._tabActor = aBrowserTabActor; this._tabActor._tabbrowser.addProgressListener(this); let EventEmitter = devtools.require("devtools/toolkit/event-emitter"); EventEmitter.decorate(this); } DebuggerProgressListener.prototype = { onStateChange: - makeInfallible(function DPL_onStateChange(aProgress, aRequest, aFlag, aStatus) { + DevToolsUtils.makeInfallible(function DPL_onStateChange(aProgress, aRequest, aFlag, aStatus) { let isStart = aFlag & Ci.nsIWebProgressListener.STATE_START; let isStop = aFlag & Ci.nsIWebProgressListener.STATE_STOP; let isDocument = aFlag & Ci.nsIWebProgressListener.STATE_IS_DOCUMENT; let isNetwork = aFlag & Ci.nsIWebProgressListener.STATE_IS_NETWORK; let isRequest = aFlag & Ci.nsIWebProgressListener.STATE_IS_REQUEST; let isWindow = aFlag & Ci.nsIWebProgressListener.STATE_IS_WINDOW; // Skip non-interesting states.
--- a/toolkit/devtools/server/child.js +++ b/toolkit/devtools/server/child.js @@ -2,17 +2,18 @@ * 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/. */ "use strict"; // Encapsulate in its own scope to allows loading this frame script // more than once. (function () { - const {DevToolsUtils} = Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm", {}); + let { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); + const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js"); const {DebuggerServer, ActorPool} = Cu.import("resource://gre/modules/devtools/dbg-server.jsm", {}); if (!DebuggerServer.initialized) { DebuggerServer.init(); } // In case of apps being loaded in parent process, DebuggerServer is already // initialized, but child specific actors are not registered.
--- a/toolkit/devtools/server/main.js +++ b/toolkit/devtools/server/main.js @@ -4,39 +4,41 @@ * 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/. */ "use strict"; /** * Toolkit glue for the remote debugging protocol, loaded into the * debugging global. */ +let DevToolsUtils = require("devtools/toolkit/DevToolsUtils.js"); // Until all Debugger server code is converted to SDK modules, // imports Components.* alias from chrome module. var { Ci, Cc, CC, Cu, Cr } = require("chrome"); // On B2G, `this` != Global scope, so `Ci` won't be binded on `this` // (i.e. this.Ci is undefined) Then later, when using loadSubScript, // Ci,... won't be defined for sub scripts. this.Ci = Ci; this.Cc = Cc; this.CC = CC; this.Cu = Cu; this.Cr = Cr; +this.DevToolsUtils = DevToolsUtils; + // Overload `Components` to prevent SDK loader exception on Components // object usage Object.defineProperty(this, "Components", { get: function () require("chrome").components }); const DBG_STRINGS_URI = "chrome://global/locale/devtools/debugger.properties"; const nsFile = CC("@mozilla.org/file/local;1", "nsIFile", "initWithPath"); Cu.import("resource://gre/modules/reflect.jsm"); -Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm"); let wantLogging = Services.prefs.getBoolPref("devtools.debugger.log"); Cu.import("resource://gre/modules/jsdebugger.jsm"); addDebuggerToGlobal(this); function loadSubScript(aURL) @@ -57,18 +59,16 @@ let {defer, resolve, reject, promised, a this.defer = defer; this.resolve = resolve; this.reject = reject; this.promised = promised; this.all = all; Cu.import("resource://gre/modules/devtools/SourceMap.jsm"); -loadSubScript.call(this, "resource://gre/modules/devtools/DevToolsUtils.js"); - function dumpn(str) { if (wantLogging) { dump("DBG-SERVER: " + str + "\n"); } } this.dumpn = dumpn; function dbg_assert(cond, e) { @@ -522,17 +522,17 @@ var DebuggerServer = { let transport = new ChildDebuggerTransport(aMessageManager, aPrefix); return this._onConnection(transport, aPrefix, true); }, // nsIServerSocketListener implementation onSocketAccepted: - makeInfallible(function DS_onSocketAccepted(aSocket, aTransport) { + DevToolsUtils.makeInfallible(function DS_onSocketAccepted(aSocket, aTransport) { if (Services.prefs.getBoolPref("devtools.debugger.prompt-connection") && !this._allowConnection()) { return; } dumpn("New debugging connection on " + aTransport.host + ":" + aTransport.port); let input = aTransport.openInputStream(0, 0, 0); let output = aTransport.openOutputStream(0, 0, 0); let transport = new DebuggerTransport(input, output); @@ -926,17 +926,17 @@ DebuggerServerConnection.prototype = { if (pool.has(aActorID)) { return pool; } } return null; }, _unknownError: function DSC__unknownError(aPrefix, aError) { - let errorString = aPrefix + ": " + safeErrorString(aError); + let errorString = aPrefix + ": " + DevToolsUtils.safeErrorString(aError); Cu.reportError(errorString); dumpn(errorString); return { error: "unknownError", message: errorString }; },
--- a/toolkit/devtools/server/tests/unit/head_dbg.js +++ b/toolkit/devtools/server/tests/unit/head_dbg.js @@ -10,17 +10,18 @@ const Cr = Components.results; Cu.import("resource://gre/modules/Services.jsm"); // Always log packets when running tests. runxpcshelltests.py will throw // the output away anyway, unless you give it the --verbose flag. Services.prefs.setBoolPref("devtools.debugger.log", true); // Enable remote debugging for the relevant tests. Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true); -Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); +const { devtools } = Cu.import("resource://gre/modules/devtools/Loader.jsm", {}); +const DevToolsUtils = devtools.require("devtools/toolkit/DevToolsUtils.js"); function tryImport(url) { try { Cu.import(url); } catch (e) { dump("Error importing " + url + "\n"); dump(DevToolsUtils.safeErrorString(e) + "\n"); throw e;
--- a/toolkit/devtools/server/tests/unit/test_dbgsocket.js +++ b/toolkit/devtools/server/tests/unit/test_dbgsocket.js @@ -1,16 +1,13 @@ /* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); -Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); - -var { safeErrorString } = DevToolsUtils; let port = 2929; function run_test() { do_print("Starting test at " + new Date().toTimeString()); initTestDebuggerServer(); @@ -139,17 +136,17 @@ function makeInfallible(aHandler, aName) return function (/* arguments */) { try { return aHandler.apply(this, arguments); } catch (ex) { let msg = "Handler function "; if (aName) { msg += aName + " "; } - msg += "threw an exception: " + safeErrorString(ex); + msg += "threw an exception: " + DevToolsUtils.safeErrorString(ex); if (ex.stack) { msg += "\nCall stack:\n" + ex.stack; } do_print(msg + "\n"); if (Cu.reportError) { /*
--- a/toolkit/devtools/server/tests/unit/test_dbgsocket_connection_drop.js +++ b/toolkit/devtools/server/tests/unit/test_dbgsocket_connection_drop.js @@ -5,17 +5,16 @@ /** * Bug 755412 - checks if the server drops the connection on an improperly * framed packet, i.e. when the length header is invalid. */ Cu.import("resource://gre/modules/devtools/dbg-server.jsm"); Cu.import("resource://gre/modules/devtools/dbg-client.jsm"); -Cu.import("resource://gre/modules/devtools/DevToolsUtils.jsm"); let port = 2929; function run_test() { do_print("Starting test at " + new Date().toTimeString()); initTestDebuggerServer();
--- a/toolkit/devtools/server/transport.js +++ b/toolkit/devtools/server/transport.js @@ -89,17 +89,17 @@ DebuggerTransport.prototype = { _flushOutgoing: function DT_flushOutgoing() { if (this._outgoing.length > 0) { var threadManager = Cc["@mozilla.org/thread-manager;1"].getService(); this._output.asyncWait(this, 0, 0, threadManager.currentThread); } }, onOutputStreamReady: - makeInfallible(function DT_onOutputStreamReady(aStream) { + DevToolsUtils.makeInfallible(function DT_onOutputStreamReady(aStream) { let written = 0; try { written = aStream.write(this._outgoing, this._outgoing.length); } catch(e if e.result == Components.results.NS_BASE_STREAM_CLOSED) { dumpn("Connection closed."); this.close(); return; } @@ -116,30 +116,30 @@ DebuggerTransport.prototype = { let pump = Cc["@mozilla.org/network/input-stream-pump;1"] .createInstance(Ci.nsIInputStreamPump); pump.init(this._input, -1, -1, 0, 0, false); pump.asyncRead(this, null); }, // nsIStreamListener onStartRequest: - makeInfallible(function DT_onStartRequest(aRequest, aContext) {}, + DevToolsUtils.makeInfallible(function DT_onStartRequest(aRequest, aContext) {}, "DebuggerTransport.prototype.onStartRequest"), onStopRequest: - makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) { + DevToolsUtils.makeInfallible(function DT_onStopRequest(aRequest, aContext, aStatus) { this.close(); if (this.hooks) { this.hooks.onClosed(aStatus); this.hooks = null; } }, "DebuggerTransport.prototype.onStopRequest"), onDataAvailable: - makeInfallible(function DT_onDataAvailable(aRequest, aContext, + DevToolsUtils.makeInfallible(function DT_onDataAvailable(aRequest, aContext, aStream, aOffset, aCount) { this._incoming += NetUtil.readInputStreamToString(aStream, aStream.available()); while (this._processIncoming()) {}; }, "DebuggerTransport.prototype.onDataAvailable"), /** * Process incoming packets. Returns true if a packet has been received, either @@ -189,17 +189,17 @@ DebuggerTransport.prototype = { dump(msg + "\n"); return true; } if (wantLogging) { dumpn("Got: " + JSON.stringify(parsed, null, 2)); } let self = this; - Services.tm.currentThread.dispatch(makeInfallible(function() { + Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(function() { // Ensure the hooks are still around by the time this runs (they will go // away when the transport is closed). if (self.hooks) { self.hooks.onPacket(parsed); } }, "DebuggerTransport instance's this.hooks.onPacket"), 0); return true; @@ -244,17 +244,17 @@ LocalDebuggerTransport.prototype = { dumpn("Packet " + serial + " sent from " + uneval(aPacket.from)); } else if (aPacket.to) { dumpn("Packet " + serial + " sent to " + uneval(aPacket.to)); } } this._deepFreeze(aPacket); let other = this.other; if (other) { - Services.tm.currentThread.dispatch(makeInfallible(function() { + Services.tm.currentThread.dispatch(DevToolsUtils.makeInfallible(function() { // Avoid the cost of JSON.stringify() when logging is disabled. if (wantLogging) { dumpn("Received packet " + serial + ": " + JSON.stringify(aPacket, null, 2)); } if (other.hooks) { other.hooks.onPacket(aPacket); } }, "LocalDebuggerTransport instance's this.other.hooks.onPacket"), 0);
--- a/toolkit/mozapps/downloads/nsHelperAppDlg.js +++ b/toolkit/mozapps/downloads/nsHelperAppDlg.js @@ -1,10 +1,10 @@ -/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ +/* -*- Mode: javascript; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2; js-indent-level: 2; -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* # 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/. */ Components.utils.import("resource://gre/modules/Services.jsm"); @@ -30,22 +30,19 @@ function nsUnknownContentTypeDialogProgr this.helperAppDlg = aHelperAppDialog; } nsUnknownContentTypeDialogProgressListener.prototype = { // nsIWebProgressListener methods. // Look for error notifications and display alert to user. onStatusChange: function( aWebProgress, aRequest, aStatus, aMessage ) { if ( aStatus != Components.results.NS_OK ) { - // Get prompt service. - var prompter = Components.classes[ "@mozilla.org/embedcomp/prompt-service;1" ] - .getService( Components.interfaces.nsIPromptService ); // Display error alert (using text supplied by back-end). // FIXME this.dialog is undefined? - prompter.alert( this.dialog, this.helperAppDlg.mTitle, aMessage ); + Services.prompt.alert( this.dialog, this.helperAppDlg.mTitle, aMessage ); // Close the dialog. this.helperAppDlg.onCancel(); if ( this.helperAppDlg.mDialog ) { this.helperAppDlg.mDialog.close(); } } }, @@ -177,41 +174,56 @@ nsUnknownContentTypeDialog.prototype = { // Hook up utility functions. this.getSpecialFolderKey = this.mDialog.getSpecialFolderKey; // Watch for error notifications. var progressListener = new nsUnknownContentTypeDialogProgressListener(this); this.mLauncher.setWebProgressListener(progressListener); }, + // + // displayBadPermissionAlert() + // + // Diplay an alert panel about the bad permission of folder/directory. + // + displayBadPermissionAlert: function () { + let bundle = + Services.strings.createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties"); + + Services.prompt.alert(this.dialog, + bundle.GetStringFromName("badPermissions.title"), + bundle.GetStringFromName("badPermissions")); + }, + // promptForSaveToFile: Display file picker dialog and return selected file. // This is called by the External Helper App Service // after the ucth dialog calls |saveToDisk| with a null // target filename (no target, therefore user must pick). // // Alternatively, if the user has selected to have all // files download to a specific location, return that // location and don't ask via the dialog. // // Note - this function is called without a dialog, so it cannot access any part // of the dialog XUL as other functions on this object do. + promptForSaveToFile: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) { throw new Components.Exception("Async version must be used", Components.results.NS_ERROR_NOT_AVAILABLE); }, promptForSaveToFileAsync: function(aLauncher, aContext, aDefaultFile, aSuggestedFileExtension, aForcePrompt) { var result = null; this.mLauncher = aLauncher; let prefs = Components.classes["@mozilla.org/preferences-service;1"] .getService(Components.interfaces.nsIPrefBranch); - let bundle = Components.classes["@mozilla.org/intl/stringbundle;1"]. - getService(Components.interfaces.nsIStringBundleService). - createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties"); + let bundle = + Services.strings + .createBundle("chrome://mozapps/locale/downloads/unknownContentType.properties"); Task.spawn(function() { if (!aForcePrompt) { // Check to see if the user wishes to auto save to the default download // folder without prompting. Note that preference might not be set. let autodownload = false; try { autodownload = prefs.getBoolPref(PREF_BD_USEDOWNLOADDIR); @@ -221,32 +233,23 @@ nsUnknownContentTypeDialog.prototype = { // Retrieve the user's default download directory let preferredDir = yield Downloads.getPreferredDownloadsDirectory(); let defaultFolder = new FileUtils.File(preferredDir); try { result = this.validateLeafName(defaultFolder, aDefaultFile, aSuggestedFileExtension); } catch (ex) { - if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) { - let prompter = Components.classes["@mozilla.org/embedcomp/prompt-service;1"]. - getService(Components.interfaces.nsIPromptService); - - // Display error alert (using text supplied by back-end) - prompter.alert(this.dialog, - bundle.GetStringFromName("badPermissions.title"), - bundle.GetStringFromName("badPermissions")); - - aLauncher.saveDestinationAvailable(null); - return; - } + // When the default download directory is write-protected, + // prompt the user for a different target file. } // Check to make sure we have a valid directory, otherwise, prompt if (result) { + // This path is taken when we have a writable default download directory. aLauncher.saveDestinationAvailable(result); return; } } } // Use file picker to show dialog. var nsIFilePicker = Components.interfaces.nsIFilePicker; @@ -273,17 +276,17 @@ nsUnknownContentTypeDialog.prototype = { if (aSuggestedFileExtension) { wildCardExtension += aSuggestedFileExtension; picker.appendFilter(this.mLauncher.MIMEInfo.description, wildCardExtension); } picker.appendFilters( nsIFilePicker.filterAll ); // Default to lastDir if it is valid, otherwise use the user's default - // downloads directory. getPreferredDownloadsDirectory should always + // downloads directory. getPreferredDownloadsDirectory should always // return a valid directory path, so we can safely default to it. let preferredDir = yield Downloads.getPreferredDownloadsDirectory(); picker.displayDirectory = new FileUtils.File(preferredDir); gDownloadLastDir.getFileAsync(aLauncher.source, function LastDirCallback(lastDir) { if (lastDir && isUsableDirectory(lastDir)) picker.displayDirectory = lastDir; @@ -301,23 +304,41 @@ nsUnknownContentTypeDialog.prototype = { if (result) { try { // Remove the file so that it's not there when we ensure non-existence later; // this is safe because for the file to exist, the user would have had to // confirm that he wanted the file overwritten. if (result.exists()) result.remove(false); } - catch (e) { } + catch (ex) { + // As it turns out, the failure to remove the file, for example due to + // permission error, will be handled below eventually somehow. + } + var newDir = result.parent.QueryInterface(Components.interfaces.nsILocalFile); // Do not store the last save directory as a pref inside the private browsing mode gDownloadLastDir.setFile(aLauncher.source, newDir); - result = this.validateLeafName(newDir, result.leafName, null); + try { + result = this.validateLeafName(newDir, result.leafName, null); + } + catch (ex) { + // When the chosen download directory is write-protected, + // display an informative error message. + // In all cases, download will be stopped. + + if (ex.result == Components.results.NS_ERROR_FILE_ACCESS_DENIED) { + this.displayBadPermissionAlert(); + aLauncher.saveDestinationAvailable(null); + return; + } + + } } aLauncher.saveDestinationAvailable(result); }.bind(this)); }.bind(this)).then(null, Components.utils.reportError); }, /** * Ensures that a local folder/file combination does not already exist in @@ -329,30 +350,35 @@ nsUnknownContentTypeDialog.prototype = { * @param aLeafName * the string name of the file (may be empty if no name is known, * in which case a name will be chosen) * @param aFileExt * the extension of the file, if one is known; this will be ignored * if aLeafName is non-empty * @return nsILocalFile * the created file + * @throw an error such as permission doesn't allow creation of + * file, etc. */ validateLeafName: function (aLocalFolder, aLeafName, aFileExt) { - if (!(aLocalFolder && isUsableDirectory(aLocalFolder))) - return null; - + if (!(aLocalFolder && isUsableDirectory(aLocalFolder))) { + throw new Components.Exception("Destination directory non-existing or permission error", + Components.results.NS_ERROR_FILE_ACCESS_DENIED); + } // Remove any leading periods, since we don't want to save hidden files // automatically. aLeafName = aLeafName.replace(/^\.+/, ""); if (aLeafName == "") aLeafName = "unnamed" + (aFileExt ? "." + aFileExt : ""); aLocalFolder.append(aLeafName); + // The following assignment can throw an exception, but + // is now caught properly in the caller of validateLeafName. var createdFile = DownloadPaths.createNiceUniqueFile(aLocalFolder); #ifdef XP_WIN let ext; try { // We can fail here if there's no primary extension set ext = "." + this.mLauncher.MIMEInfo.primaryExtension; } catch (e) { } @@ -842,18 +868,17 @@ nsUnknownContentTypeDialog.prototype = { // Verify typed app path, if necessary. if (this.useOtherHandler) { var helperApp = this.helperAppChoice(); if (!helperApp || !helperApp.executable || !helperApp.executable.exists()) { // Show alert and try again. var bundle = this.dialogElement("strings"); var msg = bundle.getFormattedString("badApp", [this.dialogElement("otherHandler").getAttribute("path")]); - var svc = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService); - svc.alert(this.mDialog, bundle.getString("badApp.title"), msg); + Services.prompt.alert(this.mDialog, bundle.getString("badApp.title"), msg); // Disable the OK button. this.mDialog.document.documentElement.getButton("accept").disabled = true; this.dialogElement("mode").focus(); // Clear chosen application. this.chosenApp = null;
--- a/toolkit/mozapps/plugins/content/pluginProblemContent.css +++ b/toolkit/mozapps/plugins/content/pluginProblemContent.css @@ -48,17 +48,16 @@ html|applet:not([height]), html|applet[h /* used to block inherited properties */ text-transform: none; text-indent: 0; cursor: initial; white-space: initial; word-spacing: initial; letter-spacing: initial; line-height: initial; - z-index: 2147483647; position: relative; } /* Initialize the overlay with visibility:hidden to prevent flickering if * the plugin is too small to show the overlay */ .mainBox > .hoverBox, .mainBox > .closeIcon { visibility: hidden;
--- a/tools/profiler/platform.h +++ b/tools/profiler/platform.h @@ -70,17 +70,17 @@ } while (0) # define LOGF(format, ...) \ do { if (moz_profiler_verbose()) fprintf(stderr, "Profiler: " format \ "\n", __VA_ARGS__); \ } while (0) #endif -#if defined(XP_MACOSX) || defined(XP_WIN) +#if defined(XP_MACOSX) || defined(XP_WIN) || defined(XP_LINUX) #define ENABLE_SPS_LEAF_DATA #endif extern mozilla::TimeStamp sStartTime; typedef uint8_t* Address; // ----------------------------------------------------------------------------
--- a/widget/EventForwards.h +++ b/widget/EventForwards.h @@ -64,13 +64,13 @@ struct EventFlags; // TextEvents.h struct AlternativeCharCode; // TextRange.h struct TextRangeStyle; struct TextRange; -typedef TextRange* TextRangeArray; +class TextRangeArray; } // namespace mozilla #endif // mozilla_EventForwards_h__
--- a/widget/TextEvents.h +++ b/widget/TextEvents.h @@ -176,33 +176,29 @@ class WidgetTextEvent : public WidgetGUI { private: friend class dom::PBrowserParent; friend class dom::PBrowserChild; friend class plugins::PPluginInstanceChild; WidgetTextEvent() : mSeqno(kLatestSeqno) - , rangeCount(0) - , rangeArray(nullptr) , isChar(false) { } public: uint32_t mSeqno; public: virtual WidgetTextEvent* AsTextEvent() MOZ_OVERRIDE { return this; } WidgetTextEvent(bool aIsTrusted, uint32_t aMessage, nsIWidget* aWidget) : WidgetGUIEvent(aIsTrusted, aMessage, aWidget, NS_TEXT_EVENT) , mSeqno(kLatestSeqno) - , rangeCount(0) - , rangeArray(nullptr) , isChar(false) { } virtual WidgetEvent* Duplicate() const MOZ_OVERRIDE { MOZ_ASSERT(eventStructType == NS_TEXT_EVENT, "Duplicate() must be overridden by sub class"); @@ -210,46 +206,46 @@ public: WidgetTextEvent* result = new WidgetTextEvent(false, message, nullptr); result->AssignTextEventData(*this, true); result->mFlags = mFlags; return result; } // The composition string or the commit string. nsString theText; - // Count of rangeArray. - uint32_t rangeCount; - // Pointer to the first item of the ranges (clauses). - // Note that the range array may not specify a caret position; in that - // case there will be no range of type NS_TEXTRANGE_CARETPOSITION in the - // array. - TextRangeArray rangeArray; // Indicates whether the event signifies printable text. // XXX This is not a standard, and most platforms don't set this properly. // So, perhaps, we can get rid of this. bool isChar; + nsRefPtr<TextRangeArray> mRanges; + void AssignTextEventData(const WidgetTextEvent& aEvent, bool aCopyTargets) { AssignGUIEventData(aEvent, aCopyTargets); isChar = aEvent.isChar; // Currently, we don't need to copy the other members because they are // for internal use only (not available from JS). } bool IsComposing() const { - for (uint32_t i = 0; i < rangeCount; i++) { - if (rangeArray[i].IsClause()) { - return true; - } - } - return false; + return mRanges && mRanges->IsComposing(); + } + + uint32_t TargetClauseOffset() const + { + return mRanges ? mRanges->TargetClauseOffset() : 0; + } + + uint32_t RangeCount() const + { + return mRanges ? mRanges->Length() : 0; } }; /****************************************************************************** * mozilla::WidgetCompositionEvent ******************************************************************************/ class WidgetCompositionEvent : public WidgetGUIEvent
--- a/widget/TextRange.h +++ b/widget/TextRange.h @@ -3,18 +3,20 @@ * 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 mozilla_TextRage_h_ #define mozilla_TextRage_h_ #include <stdint.h> +#include "nsAutoPtr.h" #include "nsColor.h" #include "nsStyleConsts.h" +#include "nsTArray.h" namespace mozilla { /****************************************************************************** * mozilla::TextRangeStyle ******************************************************************************/ struct TextRangeStyle @@ -119,17 +121,16 @@ struct TextRangeStyle nscolor mBackgroundColor; // DEFINED_BACKGROUND_COLOR nscolor mUnderlineColor; // DEFINED_UNDERLINE_COLOR }; /****************************************************************************** * mozilla::TextRange ******************************************************************************/ -// Sync with nsIPrivateTextRange.h when you change these constants. #define NS_TEXTRANGE_CARETPOSITION 0x01 #define NS_TEXTRANGE_RAWINPUT 0x02 #define NS_TEXTRANGE_SELECTEDRAWTEXT 0x03 #define NS_TEXTRANGE_CONVERTEDTEXT 0x04 #define NS_TEXTRANGE_SELECTEDCONVERTEDTEXT 0x05 struct TextRange { @@ -154,17 +155,42 @@ struct TextRange mRangeType <= NS_TEXTRANGE_SELECTEDCONVERTEDTEXT, "Invalid range type"); return mRangeType != NS_TEXTRANGE_CARETPOSITION; } }; /****************************************************************************** * mozilla::TextRangeArray - * - * XXX This should be replaced with nsTArray<TextRange>. ******************************************************************************/ +class TextRangeArray MOZ_FINAL : public nsAutoTArray<TextRange, 10> +{ + NS_INLINE_DECL_REFCOUNTING(TextRangeArray) -typedef TextRange* TextRangeArray; +public: + bool IsComposing() const + { + for (uint32_t i = 0; i < Length(); ++i) { + if (ElementAt(i).IsClause()) { + return true; + } + } + return false; + } + + // Returns target clase offset. If there are selected clauses, this returns + // the first selected clause offset. Otherwise, 0. + uint32_t TargetClauseOffset() const + { + for (uint32_t i = 0; i < Length(); ++i) { + const TextRange& range = ElementAt(i); + if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT || + range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) { + return range.mStartOffset; + } + } + return 0; + } +}; } // namespace mozilla #endif // mozilla_TextRage_h_
--- a/widget/android/nsWindow.cpp +++ b/widget/android/nsWindow.cpp @@ -171,16 +171,17 @@ nsWindow::DumpWindows(const nsTArray<nsW nsWindow::nsWindow() : mIsVisible(false), mParent(nullptr), mFocus(nullptr), mIMEComposing(false), mIMEMaskSelectionUpdate(false), mIMEMaskTextUpdate(false), mIMEMaskEventsCount(1), // Mask IME events since there's no focus yet + mIMERanges(new TextRangeArray()), mIMEUpdatingContext(false), mIMESelectionChanged(false) { } nsWindow::~nsWindow() { gTopLevelWindows.RemoveElement(this); @@ -1982,17 +1983,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent * range.mRangeStyle.mLineStyle = ae->RangeLineStyle(); range.mRangeStyle.mIsBoldLine = ae->RangeBoldLine(); range.mRangeStyle.mForegroundColor = ConvertAndroidColor(uint32_t(ae->RangeForeColor())); range.mRangeStyle.mBackgroundColor = ConvertAndroidColor(uint32_t(ae->RangeBackColor())); range.mRangeStyle.mUnderlineColor = ConvertAndroidColor(uint32_t(ae->RangeLineColor())); - mIMERanges.AppendElement(range); + mIMERanges->AppendElement(range); } break; case AndroidGeckoEvent::IME_UPDATE_COMPOSITION: { /* Update the composition from ae->Start() to ae->End() using information from added ranges. This is only used for visual indication and does not affect the text content. @@ -2005,18 +2006,18 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent * */ AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); RemoveIMEComposition(); WidgetTextEvent event(true, NS_TEXT_TEXT, this); InitEvent(event, nullptr); - event.rangeArray = mIMERanges.Elements(); - event.rangeCount = mIMERanges.Length(); + event.mRanges = new TextRangeArray(); + mIMERanges.swap(event.mRanges); { WidgetSelectionEvent event(true, NS_SELECTION_SET, this); InitEvent(event, nullptr); event.mOffset = uint32_t(ae->Start()); event.mLength = uint32_t(ae->End() - ae->Start()); event.mExpandToClusterBoundary = false; DispatchEvent(&event); @@ -2043,21 +2044,20 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent * compositionUpdate.data = event.theText; DispatchEvent(&compositionUpdate); } #ifdef DEBUG_ANDROID_IME const NS_ConvertUTF16toUTF8 theText8(event.theText); const char* text = theText8.get(); ALOGIME("IME: IME_SET_TEXT: text=\"%s\", length=%u, range=%u", - text, event.theText.Length(), mIMERanges.Length()); + text, event.theText.Length(), event.mRanges->Length()); #endif // DEBUG_ANDROID_IME DispatchEvent(&event); - mIMERanges.Clear(); // Notify SelectionHandler of final caret position // Required in cases of keyboards providing autoCorrections AndroidGeckoEvent* broadcastEvent = AndroidGeckoEvent::MakeBroadcastEvent( NS_LITERAL_CSTRING("TextSelection:UpdateCaretPos"), NS_LITERAL_CSTRING("")); nsAppShell::gAppShell->PostEvent(broadcastEvent); } @@ -2069,17 +2069,17 @@ nsWindow::OnIMEEvent(AndroidGeckoEvent * * visual indication and does not affect the text content. * * Selection and text updates are masked so the result of * temporary events are not passed on to Java */ AutoIMEMask selMask(mIMEMaskSelectionUpdate); AutoIMEMask textMask(mIMEMaskTextUpdate); RemoveIMEComposition(); - mIMERanges.Clear(); + mIMERanges->Clear(); } break; } } nsWindow * nsWindow::FindWindowForPoint(const nsIntPoint& pt) {
--- a/widget/android/nsWindow.h +++ b/widget/android/nsWindow.h @@ -192,17 +192,17 @@ protected: double mLastDist; nsCOMPtr<nsIIdleServiceInternal> mIdleService; bool mIMEComposing; bool mIMEMaskSelectionUpdate, mIMEMaskTextUpdate; int32_t mIMEMaskEventsCount; // Mask events when > 0 nsString mIMEComposingText; - nsAutoTArray<mozilla::TextRange, 4> mIMERanges; + nsRefPtr<mozilla::TextRangeArray> mIMERanges; bool mIMEUpdatingContext; nsAutoTArray<mozilla::AndroidGeckoEvent, 8> mIMEKeyEvents; struct IMEChange { int32_t mStart, mOldEnd, mNewEnd; IMEChange() : mStart(-1), mOldEnd(-1), mNewEnd(-1)
--- a/widget/cocoa/TextInputHandler.h +++ b/widget/cocoa/TextInputHandler.h @@ -1062,31 +1062,28 @@ private: * NSUnderlineStyleAttributeName ranges you with * to know. * @return The count of NSUnderlineStyleAttributeName * ranges in aAttrString. */ uint32_t GetRangeCount(NSAttributedString *aString); /** - * SetTextRangeList() appends text ranges to aTextRangeList. + * CreateTextRangeArray() returns text ranges for clauses and/or caret. * - * @param aTextRangeList When SetTextRangeList() returns, this will - * be set to the NSUnderlineStyleAttributeName - * ranges in aAttrString. Note that if you pass - * in a large enough auto-range instance for most - * cases (e.g., nsAutoTArray<TextRange, 4>), - * it prevents memory fragmentation. * @param aAttrString An NSAttributedString instance which indicates * current composition string. * @param aSelectedRange Current selected range (or caret position). + * @return The result is set to the + * NSUnderlineStyleAttributeName ranges in + * aAttrString. */ - void SetTextRangeList(nsTArray<TextRange>& aTextRangeList, - NSAttributedString *aAttrString, - NSRange& aSelectedRange); + already_AddRefed<mozilla::TextRangeArray> + CreateTextRangeArray(NSAttributedString *aAttrString, + NSRange& aSelectedRange); /** * InitCompositionEvent() initializes aCompositionEvent. * * @param aCompositionEvent A composition event which you want to * initialize. */ void InitCompositionEvent(WidgetCompositionEvent& aCompositionEvent);
--- a/widget/cocoa/TextInputHandler.mm +++ b/widget/cocoa/TextInputHandler.mm @@ -2628,68 +2628,71 @@ IMEInputHandler::GetRangeCount(NSAttribu ("%p IMEInputHandler::GetRangeCount, aAttrString=\"%s\", count=%llu", this, GetCharacters([aAttrString string]), count)); return count; NS_OBJC_END_TRY_ABORT_BLOCK_RETURN(0); } -void -IMEInputHandler::SetTextRangeList(nsTArray<TextRange>& aTextRangeList, - NSAttributedString *aAttrString, - NSRange& aSelectedRange) +already_AddRefed<mozilla::TextRangeArray> +IMEInputHandler::CreateTextRangeArray(NSAttributedString *aAttrString, + NSRange& aSelectedRange) { - NS_OBJC_BEGIN_TRY_ABORT_BLOCK; + NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NIL; // Convert the Cocoa range into the TextRange Array used in Gecko. // Iterate through the attributed string and map the underline attribute to // Gecko IME textrange attributes. We may need to change the code here if // we change the implementation of validAttributesForMarkedText. NSRange limitRange = NSMakeRange(0, [aAttrString length]); uint32_t rangeCount = GetRangeCount(aAttrString); + nsRefPtr<mozilla::TextRangeArray> textRangeArray = + new mozilla::TextRangeArray(); for (uint32_t i = 0; i < rangeCount && limitRange.length > 0; i++) { NSRange effectiveRange; id attributeValue = [aAttrString attribute:NSUnderlineStyleAttributeName atIndex:limitRange.location longestEffectiveRange:&effectiveRange inRange:limitRange]; TextRange range; range.mStartOffset = effectiveRange.location; range.mEndOffset = NSMaxRange(effectiveRange); range.mRangeType = ConvertToTextRangeType([attributeValue intValue], aSelectedRange); - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); PR_LOG(gLog, PR_LOG_ALWAYS, - ("%p IMEInputHandler::SetTextRangeList, " + ("%p IMEInputHandler::CreateTextRangeArray, " "range={ mStartOffset=%llu, mEndOffset=%llu, mRangeType=%s }", this, range.mStartOffset, range.mEndOffset, GetRangeTypeName(range.mRangeType))); limitRange = NSMakeRange(NSMaxRange(effectiveRange), NSMaxRange(limitRange) - NSMaxRange(effectiveRange)); } // Get current caret position. TextRange range; range.mStartOffset = aSelectedRange.location + aSelectedRange.length; range.mEndOffset = range.mStartOffset; range.mRangeType = NS_TEXTRANGE_CARETPOSITION; - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); PR_LOG(gLog, PR_LOG_ALWAYS, - ("%p IMEInputHandler::SetTextRangeList, " + ("%p IMEInputHandler::CreateTextRangeArray, " "range={ mStartOffset=%llu, mEndOffset=%llu, mRangeType=%s }", this, range.mStartOffset, range.mEndOffset, GetRangeTypeName(range.mRangeType))); - NS_OBJC_END_TRY_ABORT_BLOCK; + return textRangeArray.forget(); + + NS_OBJC_END_TRY_ABORT_BLOCK_NIL; } bool IMEInputHandler::DispatchTextEvent(const nsString& aText, NSAttributedString* aAttrString, NSRange& aSelectedRange, bool aDoCommit) { @@ -2705,22 +2708,19 @@ IMEInputHandler::DispatchTextEvent(const NS_ENSURE_TRUE(!Destroyed(), false); nsRefPtr<IMEInputHandler> kungFuDeathGrip(this); WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mWidget); textEvent.time = PR_IntervalNow(); textEvent.theText = aText; - nsAutoTArray<TextRange, 4> textRanges; if (!aDoCommit) { - SetTextRangeList(textRanges, aAttrString, aSelectedRange); + textEvent.mRanges = CreateTextRangeArray(aAttrString, aSelectedRange); } - textEvent.rangeArray = textRanges.Elements(); - textEvent.rangeCount = textRanges.Length(); if (textEvent.theText != mLastDispatchedCompositionString) { WidgetCompositionEvent compositionUpdate(true, NS_COMPOSITION_UPDATE, mWidget); compositionUpdate.time = textEvent.time; compositionUpdate.data = textEvent.theText; mLastDispatchedCompositionString = textEvent.theText; DispatchEvent(compositionUpdate);
--- a/widget/gonk/libdisplay/BootAnimation.cpp +++ b/widget/gonk/libdisplay/BootAnimation.cpp @@ -262,17 +262,17 @@ struct RawReadState { uint32_t length; }; static void RawReader(png_structp png_ptr, png_bytep data, png_size_t length) { RawReadState *state = (RawReadState *)png_get_io_ptr(png_ptr); if (length > (state->length - state->offset)) - png_err(png_ptr); + png_error(png_ptr, "PNG read overrun"); memcpy(data, state->start + state->offset, length); state->offset += length; } static void TransformTo565(png_structp png_ptr, png_row_infop row_info, png_bytep data) {
--- a/widget/gtk/nsGtkIMModule.cpp +++ b/widget/gtk/nsGtkIMModule.cpp @@ -1188,33 +1188,23 @@ nsGtkIMModule::DispatchTextEvent(const n } } WidgetTextEvent textEvent(true, NS_TEXT_TEXT, mLastFocusedWindow); InitEvent(textEvent); uint32_t targetOffset = mCompositionStart; - nsAutoTArray<TextRange, 4> textRanges; if (!aIsCommit) { // NOTE: SetTextRangeList() assumes that mDispatchedCompositionString // has been updated already. - SetTextRangeList(textRanges); - for (uint32_t i = 0; i < textRanges.Length(); i++) { - TextRange& range = textRanges[i]; - if (range.mRangeType == NS_TEXTRANGE_SELECTEDRAWTEXT || - range.mRangeType == NS_TEXTRANGE_SELECTEDCONVERTEDTEXT) { - targetOffset += range.mStartOffset; - break; - } - } + textEvent.mRanges = CreateTextRangeArray(); + targetOffset += textEvent.mRanges->TargetClauseOffset(); } - textEvent.rangeCount = textRanges.Length(); - textEvent.rangeArray = textRanges.Elements(); textEvent.theText = mDispatchedCompositionString.get(); mCompositionState = aIsCommit ? eCompositionState_CommitTextEventDispatched : eCompositionState_TextEventDispatched; mLastFocusedWindow->DispatchEvent(&textEvent, status); if (lastFocusedWindow->IsDestroyed() || @@ -1227,45 +1217,45 @@ nsGtkIMModule::DispatchTextEvent(const n // We cannot call SetCursorPosition for e10s-aware. // DispatchEvent is async on e10s, so composition rect isn't updated now // on tab parent. mCompositionTargetOffset = targetOffset; return true; } -void -nsGtkIMModule::SetTextRangeList(nsTArray<TextRange> &aTextRangeList) +already_AddRefed<TextRangeArray> +nsGtkIMModule::CreateTextRangeArray() { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, - ("GtkIMModule(%p): SetTextRangeList", this)); + ("GtkIMModule(%p): CreateTextRangeArray", this)); - NS_PRECONDITION(aTextRangeList.IsEmpty(), "aTextRangeList must be empty"); + nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray(); gchar *preedit_string; gint cursor_pos; PangoAttrList *feedback_list; gtk_im_context_get_preedit_string(GetContext(), &preedit_string, &feedback_list, &cursor_pos); if (!preedit_string || !*preedit_string) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" preedit_string is null")); pango_attr_list_unref(feedback_list); g_free(preedit_string); - return; + return textRangeArray.forget(); } PangoAttrIterator* iter; iter = pango_attr_list_get_iterator(feedback_list); if (!iter) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" FAILED, iterator couldn't be allocated")); pango_attr_list_unref(feedback_list); g_free(preedit_string); - return; + return textRangeArray.forget(); } /* * Depend on gtk2's implementation on XIM support. * In aFeedback got from gtk2, there are only three types of data: * PANGO_ATTR_UNDERLINE, PANGO_ATTR_FOREGROUND, PANGO_ATTR_BACKGROUND. * Corresponding to XIMUnderline, XIMReverse. * Don't take PANGO_ATTR_BACKGROUND into account, since @@ -1321,17 +1311,17 @@ nsGtkIMModule::SetTextRangeList(nsTArray if (!uniStr) { range.mEndOffset = range.mStartOffset; } else { range.mEndOffset = range.mStartOffset + uniStrLen; g_free(uniStr); uniStr = nullptr; } - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" mStartOffset=%u, mEndOffset=%u, mRangeType=%s", range.mStartOffset, range.mEndOffset, GetRangeTypeName(range.mRangeType))); } while (pango_attr_iterator_next(iter)); TextRange range; @@ -1339,26 +1329,28 @@ nsGtkIMModule::SetTextRangeList(nsTArray range.mStartOffset = 0; } else if (uint32_t(cursor_pos) > mDispatchedCompositionString.Length()) { range.mStartOffset = mDispatchedCompositionString.Length(); } else { range.mStartOffset = uint32_t(cursor_pos); } range.mEndOffset = range.mStartOffset; range.mRangeType = NS_TEXTRANGE_CARETPOSITION; - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, (" mStartOffset=%u, mEndOffset=%u, mRangeType=%s", range.mStartOffset, range.mEndOffset, GetRangeTypeName(range.mRangeType))); pango_attr_iterator_destroy(iter); pango_attr_list_unref(feedback_list); g_free(preedit_string); + + return textRangeArray.forget(); } void nsGtkIMModule::SetCursorPosition(uint32_t aTargetOffset) { PR_LOG(gGtkIMLog, PR_LOG_ALWAYS, ("GtkIMModule(%p): SetCursorPosition, aTargetOffset=%u", this, aTargetOffset));
--- a/widget/gtk/nsGtkIMModule.h +++ b/widget/gtk/nsGtkIMModule.h @@ -8,16 +8,17 @@ #ifndef __nsGtkIMModule_h__ #define __nsGtkIMModule_h__ #include <gdk/gdk.h> #include <gtk/gtk.h> #include "nsString.h" #include "nsAutoPtr.h" +#include "nsCOMPtr.h" #include "nsTArray.h" #include "nsIWidget.h" #include "mozilla/EventForwards.h" class nsWindow; class nsGtkIMModule { @@ -262,18 +263,18 @@ protected: // Reset the current composition of IME. All native composition events // during this processing are ignored. void ResetIME(); // Gets the current composition string by the native APIs. void GetCompositionString(nsAString &aCompositionString); - // Generates our text range list from current composition string. - void SetTextRangeList(nsTArray<mozilla::TextRange>& aTextRangeList); + // Generates our text range array from current composition string. + already_AddRefed<mozilla::TextRangeArray> CreateTextRangeArray(); // Sets the offset's cursor position to IME. void SetCursorPosition(uint32_t aTargetOffset); // Queries the current selection offset of the window. uint32_t GetSelectionOffset(nsWindow* aWindow); // Get current paragraph text content and cursor position
--- a/widget/nsGUIEventIPC.h +++ b/widget/nsGUIEventIPC.h @@ -374,63 +374,89 @@ struct ParamTraits<mozilla::TextRange> return ReadParam(aMsg, aIter, &aResult->mStartOffset) && ReadParam(aMsg, aIter, &aResult->mEndOffset) && ReadParam(aMsg, aIter, &aResult->mRangeType) && ReadParam(aMsg, aIter, &aResult->mRangeStyle); } }; template<> +struct ParamTraits<mozilla::TextRangeArray> +{ + typedef mozilla::TextRangeArray paramType; + + static void Write(Message* aMsg, const paramType& aParam) + { + WriteParam(aMsg, aParam.Length()); + for (uint32_t index = 0; index < aParam.Length(); index++) { + WriteParam(aMsg, aParam[index]); + } + } + + static bool Read(const Message* aMsg, void** aIter, paramType* aResult) + { + uint32_t length; + if (!ReadParam(aMsg, aIter, &length)) { + return false; + } + for (uint32_t index = 0; index < length; index++) { + mozilla::TextRange textRange; + if (!ReadParam(aMsg, aIter, &textRange)) { + aResult->Clear(); + return false; + } + aResult->AppendElement(textRange); + } + return true; + } +}; + +template<> struct ParamTraits<mozilla::WidgetTextEvent> { typedef mozilla::WidgetTextEvent paramType; static void Write(Message* aMsg, const paramType& aParam) { WriteParam(aMsg, static_cast<mozilla::WidgetGUIEvent>(aParam)); WriteParam(aMsg, aParam.mSeqno); WriteParam(aMsg, aParam.theText); WriteParam(aMsg, aParam.isChar); - WriteParam(aMsg, aParam.rangeCount); - for (uint32_t index = 0; index < aParam.rangeCount; index++) - WriteParam(aMsg, aParam.rangeArray[index]); + bool hasRanges = !!aParam.mRanges; + WriteParam(aMsg, hasRanges); + if (hasRanges) { + WriteParam(aMsg, *aParam.mRanges.get()); + } } static bool Read(const Message* aMsg, void** aIter, paramType* aResult) { + bool hasRanges; if (!ReadParam(aMsg, aIter, static_cast<mozilla::WidgetGUIEvent*>(aResult)) || !ReadParam(aMsg, aIter, &aResult->mSeqno) || !ReadParam(aMsg, aIter, &aResult->theText) || !ReadParam(aMsg, aIter, &aResult->isChar) || - !ReadParam(aMsg, aIter, &aResult->rangeCount)) + !ReadParam(aMsg, aIter, &hasRanges)) { return false; - - if (!aResult->rangeCount) { - aResult->rangeArray = nullptr; - return true; } - aResult->rangeArray = new mozilla::TextRange[aResult->rangeCount]; - if (!aResult->rangeArray) - return false; - - for (uint32_t index = 0; index < aResult->rangeCount; index++) - if (!ReadParam(aMsg, aIter, &aResult->rangeArray[index])) { - Free(*aResult); + if (!hasRanges) { + aResult->mRanges = nullptr; + } else { + aResult->mRanges = new mozilla::TextRangeArray(); + if (!aResult->mRanges) { return false; } + if (!ReadParam(aMsg, aIter, aResult->mRanges.get())) { + return false; + } + } return true; } - - static void Free(const paramType& aResult) - { - if (aResult.rangeArray) - delete [] aResult.rangeArray; - } }; template<> struct ParamTraits<mozilla::WidgetCompositionEvent> { typedef mozilla::WidgetCompositionEvent paramType; static void Write(Message* aMsg, const paramType& aParam)
--- a/widget/tests/test_composition_text_querycontent.xul +++ b/widget/tests/test_composition_text_querycontent.xul @@ -14,17 +14,17 @@ </div> <pre id="test"> </pre> </body> <script class="testbody" type="application/javascript"> <![CDATA[ -SimpleTest.expectAssertions(4); +SimpleTest.expectAssertions(2); SimpleTest.waitForExplicitFinish(); window.open("window_composition_text_querycontent.xul", "_blank", "chrome,width=600,height=600"); ]]> </script> </window>
--- a/widget/windows/nsIMM32Handler.cpp +++ b/widget/windows/nsIMM32Handler.cpp @@ -1605,102 +1605,103 @@ nsIMM32Handler::DispatchTextEvent(nsWind } SetIMERelatedWindowsPos(aWindow, aIMEContext); } WidgetTextEvent event(true, NS_TEXT_TEXT, aWindow); aWindow->InitEvent(event, &point); - nsAutoTArray<TextRange, 4> textRanges; - if (aCheckAttr) { - SetTextRangeList(textRanges); + event.mRanges = CreateTextRangeArray(); } - event.rangeCount = textRanges.Length(); - event.rangeArray = textRanges.Elements(); - event.theText = mCompositionString.get(); aWindow->DispatchWindowEvent(&event); // Calling SetIMERelatedWindowsPos will be failure on e10s at this point. // text event will notify NOTIFY_IME_OF_COMPOSITION_UPDATE, then // it will call SetIMERelatedWindowsPos. } -void -nsIMM32Handler::SetTextRangeList(nsTArray<TextRange> &aTextRangeList) +already_AddRefed<TextRangeArray> +nsIMM32Handler::CreateTextRangeArray() { // Sogou (Simplified Chinese IME) returns contradictory values: The cursor // position is actual cursor position. However, other values (composition // string and attributes) are empty. So, if you want to remove following // assertion, be careful. NS_ASSERTION(ShouldDrawCompositionStringOurselves(), - "SetTextRangeList is called when we don't need to fire text event"); + "CreateTextRangeArray is called when we don't need to fire text event"); + + nsRefPtr<TextRangeArray> textRangeArray = new TextRangeArray(); TextRange range; if (mClauseArray.Length() == 0) { // Some IMEs don't return clause array information, then, we assume that // all characters in the composition string are in one clause. range.mStartOffset = 0; range.mEndOffset = mCompositionString.Length(); range.mRangeType = NS_TEXTRANGE_RAWINPUT; - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: SetTextRangeList, mClauseLength=0\n")); + ("IMM32: CreateTextRangeArray, mClauseLength=0\n")); } else { // iterate over the attributes uint32_t lastOffset = 0; for (uint32_t i = 0; i < mClauseArray.Length() - 1; i++) { uint32_t current = mClauseArray[i + 1]; if (current > mCompositionString.Length()) { PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: SetTextRangeList, mClauseArray[%ld]=%lu. This is larger than mCompositionString.Length()=%lu\n", + ("IMM32: CreateTextRangeArray, mClauseArray[%ld]=%lu. " + "This is larger than mCompositionString.Length()=%lu\n", i + 1, current, mCompositionString.Length())); current = int32_t(mCompositionString.Length()); } range.mRangeType = PlatformToNSAttr(mAttributeArray[lastOffset]); range.mStartOffset = lastOffset; range.mEndOffset = current; - aTextRangeList.AppendElement(range); + textRangeArray->AppendElement(range); lastOffset = current; PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: SetTextRangeList, index=%ld, rangeType=%s, range=[%lu-%lu]\n", + ("IMM32: CreateTextRangeArray, index=%ld, rangeType=%s, range=[%lu-%lu]\n", i, GetRangeTypeName(range.mRangeType), range.mStartOffset, range.mEndOffset)); } } if (mCursorPosition == NO_IME_CARET) { PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: GetTextRangeList, no caret\n")); - return; + ("IMM32: CreateTextRangeArray, no caret\n")); + return textRangeArray.forget(); } int32_t cursor = mCursorPosition; if (uint32_t(cursor) > mCompositionString.Length()) { PR_LOG(gIMM32Log, PR_LOG_ALWAYS, - ("IMM32: SetTextRangeList, mCursorPosition=%ld. This is larger than mCompositionString.Length()=%lu\n", + ("IMM32: CreateTextRangeArray, mCursorPosition=%ld. " + "This is larger than mCompositionString.Length()=%lu\n", mCursorPosition, mCompositionString.Length()))