Merge latest green fx-team changeset and mozilla-central

This commit is contained in:
Ed Morley 2013-07-09 08:52:05 +01:00
Родитель c926eefe62 ffac98fbda
Коммит f2a832c8ec
178 изменённых файлов: 3163 добавлений и 1659 удалений

Просмотреть файл

@ -1,4 +1,4 @@
{
"revision": "09cdef3222986569ee93081d7ef0e7f9cc0894f9",
"revision": "58d73404571f7619b478116dfec8faced97be13d",
"repo_path": "/integration/gaia-central"
}

Просмотреть файл

@ -5,7 +5,7 @@
#aboutDialogContainer {
background-image: url("chrome://branding/content/about-background.png");
background-repeat: no-repeat;
background-color: #000;
background-color: rgb(19,8,36);
color: #fff;
}

Просмотреть файл

@ -5,7 +5,7 @@
#aboutDialogContainer {
background-image: url("chrome://branding/content/about-background.png");
background-repeat: no-repeat;
background-color: #000;
background-color: rgb(10,17,37);
color: #fff;
}

Просмотреть файл

@ -185,6 +185,32 @@ let Util = {
aElement instanceof Ci.nsIDOMHTMLTextAreaElement);
},
isEditableContent: function isEditableContent(aElement) {
if (!aElement)
return false;
if (aElement.isContentEditable || aElement.designMode == "on")
return true;
return false;
},
isEditable: function isEditable(aElement) {
if (!aElement)
return false;
if (this.isTextInput(aElement) || this.isEditableContent(aElement))
return true;
// If a body element is editable and the body is the child of an
// iframe or div we can assume this is an advanced HTML editor
if ((aElement instanceof Ci.nsIDOMHTMLIFrameElement ||
aElement instanceof Ci.nsIDOMHTMLDivElement) &&
aElement.contentDocument &&
this.isEditableContent(aElement.contentDocument.body)) {
return true;
}
return aElement.ownerDocument && aElement.ownerDocument.designMode == "on";
},
isMultilineInput: function isMultilineInput(aElement) {
return (aElement instanceof Ci.nsIDOMHTMLTextAreaElement);
},

Просмотреть файл

@ -4,6 +4,8 @@
- 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/. -->
<!-- When not in use, make sure you disable this or it will run continuously
in the background sucking up cpu. -->
<bindings
xmlns="http://www.mozilla.org/xbl"
xmlns:xbl="http://www.mozilla.org/xbl"
@ -11,7 +13,7 @@
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<binding id="cssthrobberBinding" extends="xul:box">
<content>
<html:div class="progressContainer">
<html:div anonid="container" id="container" class="progressContainer">
<html:div class="progressBall" />
<html:div class="progressBall" />
<html:div class="progressBall" />
@ -19,5 +21,20 @@
<html:div class="progressBall" />
</html:div>
</content>
<implementation>
<field name="container" readonly="true">document.getAnonymousElementByAttribute(this, "anonid", "container");</field>
<property name="enabled">
<setter>
<![CDATA[
if (val) {
this.container.setAttribute("enabled", true);
} else {
this.container.removeAttribute("enabled");
}
return val;
]]>
</setter>
</property>
</implementation>
</binding>
</bindings>

Просмотреть файл

@ -73,9 +73,7 @@ var Browser = {
BrowserTouchHandler.init();
PopupBlockerObserver.init();
// Warning, total hack ahead. All of the real-browser related scrolling code
// lies in a pretend scrollbox here. Let's not land this as-is. Maybe it's time
// to redo all the dragging code.
// Init the touch scrollbox
this.contentScrollbox = Elements.browsers;
this.contentScrollboxScroller = {
scrollBy: function(aDx, aDy) {
@ -147,10 +145,6 @@ var Browser = {
messageManager.addMessageListener("Browser:TapOnSelection", this);
messageManager.addMessageListener("Browser:PluginClickToPlayClicked", this);
// Let everyone know what kind of mouse input we are
// starting with:
InputSourceHelper.fireUpdate();
Task.spawn(function() {
// Activation URIs come from protocol activations, secondary tiles, and file activations
let activationURI = yield this.getShortcutOrURI(MetroUtils.activationURI);
@ -199,6 +193,9 @@ var Browser = {
loadStartupURI();
}
// Notify about our input type
InputSourceHelper.fireUpdate();
// Broadcast a UIReady message so add-ons know we are finished with startup
let event = document.createEvent("Events");
event.initEvent("UIReady", true, false);

Просмотреть файл

@ -52,7 +52,7 @@
<broadcasterset id="broadcasterset">
<broadcaster id="bcast_contentShowing" disabled="false"/>
<broadcaster id="bcast_urlbarState" mode="view"/>
<broadcaster id="bcast_preciseInput" input="imprecise"/>
<broadcaster id="bcast_preciseInput" input="precise"/>
<broadcaster id="bcast_windowState" viewstate=""/>
</broadcasterset>
@ -288,6 +288,7 @@
completeselectedindex="true"
placeholder="&urlbar.emptytext;"
flex="1"
onpaste="this.focus();"
ontextentered="BrowserUI.handleUrlbarEnter(param);"
onkeydown="BrowserUI.navEditKeyPress();"
onblur="BrowserUI._urlbarBlurred();"/>
@ -446,10 +447,10 @@
<button label="&sync.setup.remove;" oncommand="Sync.disconnect();" />
</hbox>
</vbox>
<vbox id="sync-disconnectthrobber" collapsed="true">
<vbox id="sync-disconnectpanel">
<hbox>
<spacer flex="1" />
<cssthrobber id="syncdisconnectthrobber" />
<cssthrobber id="sync-disconnectthrobber"/>
<label>&sync.removethrobber.label;</label>
<spacer flex="1" />
</hbox>
@ -492,8 +493,7 @@
<deck id="clear-notification" flex="2" selectedIndex="0" align="center">
<spacer id="clear-notification-empty"/>
<hbox id="clear-notification-clearing" align="center">
<!-- TODO: we need a more metro-y throbber. See bug 852622 -->
<image src="chrome://browser/skin/images/throbber.png" />
<cssthrobber id="clearprivacythrobber"/>
</hbox>
<description id="clear-notification-done">&clearPrivateData.done;</description>
</deck>

Просмотреть файл

@ -291,7 +291,7 @@ let Content = {
this.formAssistant.focusSync = false;
// A tap on a form input triggers touch input caret selection
if (Util.isTextInput(element) &&
if (Util.isEditable(element) &&
aEvent.mozInputSource == Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH) {
let { offsetX, offsetY } = Util.translateToTopLevelWindow(element);
sendAsyncMessage("Content:SelectionCaret", {

Просмотреть файл

@ -224,7 +224,7 @@ var SelectionHandler = {
}
// This should never happen, but we check to make sure
if (!this._targetIsEditable || !Util.isTextInput(this._targetElement)) {
if (!this._targetIsEditable) {
this._onFail("Unexpected, coordiates didn't find a text input element.");
return;
}
@ -402,7 +402,7 @@ var SelectionHandler = {
this._contentWindow = contentWindow;
this._contentOffset = offset;
this._domWinUtils = utils;
this._targetIsEditable = this._isTextInput(this._targetElement);
this._targetIsEditable = Util.isEditable(this._targetElement);
return true;
},
@ -618,12 +618,6 @@ var SelectionHandler = {
};
},
_isTextInput: function _isTextInput(aElement) {
return ((aElement instanceof Ci.nsIDOMHTMLInputElement &&
aElement.mozIsTextField(false)) ||
aElement instanceof Ci.nsIDOMHTMLTextAreaElement);
},
_getDocShell: function _getDocShell(aWindow) {
if (aWindow == null)
return null;

Просмотреть файл

@ -135,6 +135,9 @@ var ChromeSelectionHandler = {
this._handleSelectionPoint(aMsg.change, pos, true);
this._selectionMoveActive = false;
// Clear any existing scroll timers
this._clearTimers();
// Update the position of our selection monocles
this._updateSelectionUI("end", true, true);
},

Просмотреть файл

@ -1157,49 +1157,52 @@ var GestureModule = {
*/
var InputSourceHelper = {
isPrecise: false,
treatMouseAsTouch: false,
init: function ish_init() {
// debug feature, make all input imprecise
try {
this.treatMouseAsTouch = Services.prefs.getBoolPref(kDebugMouseInputPref);
} catch (e) {}
if (!this.treatMouseAsTouch) {
window.addEventListener("mousemove", this, true);
window.addEventListener("mousedown", this, true);
window.addEventListener("mousemove", this, true);
window.addEventListener("mousedown", this, true);
window.addEventListener("touchstart", this, true);
},
_precise: function () {
if (!this.isPrecise) {
this.isPrecise = true;
this._fire("MozPrecisePointer");
}
},
_imprecise: function () {
if (this.isPrecise) {
this.isPrecise = false;
this._fire("MozImprecisePointer");
}
},
handleEvent: function ish_handleEvent(aEvent) {
if (aEvent.type == "touchstart") {
this._imprecise();
return;
}
switch (aEvent.mozInputSource) {
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_MOUSE:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_PEN:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_ERASER:
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_CURSOR:
if (!this.isPrecise && !this.treatMouseAsTouch) {
this.isPrecise = true;
this._fire("MozPrecisePointer");
}
this._precise();
break;
case Ci.nsIDOMMouseEvent.MOZ_SOURCE_TOUCH:
if (this.isPrecise) {
this.isPrecise = false;
this._fire("MozImprecisePointer");
}
this._imprecise();
break;
}
},
fireUpdate: function fireUpdate() {
if (this.treatMouseAsTouch) {
this._fire("MozImprecisePointer");
if (this.isPrecise) {
this._fire("MozPrecisePointer");
} else {
if (this.isPrecise) {
this._fire("MozPrecisePointer");
} else {
this._fire("MozImprecisePointer");
}
this._fire("MozImprecisePointer");
}
},

Просмотреть файл

@ -243,7 +243,7 @@ SelectionPrototype.prototype = {
clientPoint.yPos -= halfLineHeight;
// Modify selection based on monocle movement
if (this._targetIsEditable) {
if (this._targetIsEditable && !Util.isEditableContent(this._targetElement)) {
this._adjustEditableSelection(aMarker, clientPoint, aEndOfSelection);
} else {
this._adjustSelectionAtPoint(aMarker, clientPoint, aEndOfSelection);
@ -307,8 +307,7 @@ SelectionPrototype.prototype = {
let cp =
this._contentWindow.document.caretPositionFromPoint(constrainedPoint.xPos,
constrainedPoint.yPos);
if (!cp || (cp.offsetNode != this._targetElement &&
this._contentWindow.document.getBindingParent(cp.offsetNode) != this._targetElement)) {
if (!cp || !this._offsetNodeIsValid(cp.offsetNode)) {
return;
}
if (aMarker == "start") {
@ -319,6 +318,19 @@ SelectionPrototype.prototype = {
}
},
/*
* Make sure caretPositionFromPoint gave us an offset node that equals our
* editable, or in the case of getBindingParent identifies an anonymous
* element in chrome content within our target element. (navbar)
*/
_offsetNodeIsValid: function (aNode) {
if (aNode == this._targetElement ||
this._contentWindow.document.getBindingParent(aNode) == this._targetElement) {
return true;
}
return false;
},
/*
* _adjustSelectionAtPoint
*

Просмотреть файл

@ -1,86 +1,88 @@
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* 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";
var SanitizeUI = {
_sanitizer: null,
_privDataElement: null,
get _privData() {
if (this._privDataElement === null) {
this._privDataElement = document.getElementById("prefs-privdata");
}
return this._privDataElement;
},
init: function () {
this._sanitizer = new Sanitizer();
this._privData.addEventListener("CheckboxStateChange", this, true);
},
_clearNotificationTimeout: null,
onSanitize: function onSanitize() {
let button = document.getElementById("prefs-clear-data");
let clearNotificationDeck = document.getElementById("clear-notification");
let clearNotificationEmpty = document.getElementById("clear-notification-empty");
let clearNotificationClearing = document.getElementById("clear-notification-clearing");
let clearNotificationDone = document.getElementById("clear-notification-done");
let allCheckboxes = SanitizeUI._privData.querySelectorAll("checkbox");
let allSelected = SanitizeUI._privData.querySelectorAll(
"#prefs-privdata-history[checked], " +
"#prefs-privdata-other[checked] + #prefs-privdata-subitems .privdata-subitem-item[checked]");
// disable button and checkboxes temporarily to indicate something is happening
button.disabled = true;
for (let checkbox of allCheckboxes) {
checkbox.disabled = true;
}
clearNotificationDeck.selectedPanel = clearNotificationClearing;
// Run asynchronously to let UI update
setTimeout(function() {
for (let item of allSelected) {
let itemName = item.getAttribute("itemName");
try {
SanitizeUI._sanitizer.clearItem(itemName);
} catch(e) {
Components.utils.reportError("Error sanitizing " + itemName + ": " + e);
}
}
button.disabled = false;
for (let checkbox of allCheckboxes) {
checkbox.disabled = false;
}
clearNotificationDeck.selectedPanel = clearNotificationDone;
// Clear notifications after 4 seconds
clearTimeout(SanitizeUI._clearNotificationTimeout);
SanitizeUI._clearNotificationTimeout = setTimeout(function() {
clearNotificationDeck.selectedPanel = clearNotificationEmpty;
}, 4000);
}, 0);
},
/* Disable the clear button when nothing is selected */
_onCheckboxChange: function _onCheckboxChange() {
let anySelected = SanitizeUI._privData.querySelector(
"#prefs-privdata-history[checked], " +
"#prefs-privdata-other[checked] + #prefs-privdata-subitems .privdata-subitem-item[checked]");
let clearButton = document.getElementById("prefs-clear-data");
clearButton.disabled = !anySelected;
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "CheckboxStateChange":
this._onCheckboxChange();
break;
}
},
// -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; js2-basic-offset: 2; js2-skip-preprocessor-directives: t; -*-
/* 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";
var SanitizeUI = {
_sanitizer: null,
_privDataElement: null,
get _privData() {
if (this._privDataElement === null) {
this._privDataElement = document.getElementById("prefs-privdata");
}
return this._privDataElement;
},
init: function () {
this._sanitizer = new Sanitizer();
this._privData.addEventListener("CheckboxStateChange", this, true);
},
_clearNotificationTimeout: null,
onSanitize: function onSanitize() {
let button = document.getElementById("prefs-clear-data");
let clearNotificationDeck = document.getElementById("clear-notification");
let clearNotificationEmpty = document.getElementById("clear-notification-empty");
let clearNotificationClearing = document.getElementById("clear-notification-clearing");
let clearNotificationDone = document.getElementById("clear-notification-done");
let allCheckboxes = SanitizeUI._privData.querySelectorAll("checkbox");
let allSelected = SanitizeUI._privData.querySelectorAll(
"#prefs-privdata-history[checked], " +
"#prefs-privdata-other[checked] + #prefs-privdata-subitems .privdata-subitem-item[checked]");
// disable button and checkboxes temporarily to indicate something is happening
button.disabled = true;
for (let checkbox of allCheckboxes) {
checkbox.disabled = true;
}
clearNotificationDeck.selectedPanel = clearNotificationClearing;
document.getElementById("clearprivacythrobber").enabled = true;
// Run asynchronously to let UI update
setTimeout(function() {
for (let item of allSelected) {
let itemName = item.getAttribute("itemName");
try {
SanitizeUI._sanitizer.clearItem(itemName);
} catch(e) {
Components.utils.reportError("Error sanitizing " + itemName + ": " + e);
}
}
button.disabled = false;
for (let checkbox of allCheckboxes) {
checkbox.disabled = false;
}
clearNotificationDeck.selectedPanel = clearNotificationDone;
document.getElementById("clearprivacythrobber").enabled = false;
// Clear notifications after 4 seconds
clearTimeout(SanitizeUI._clearNotificationTimeout);
SanitizeUI._clearNotificationTimeout = setTimeout(function() {
clearNotificationDeck.selectedPanel = clearNotificationEmpty;
}, 4000);
}, 0);
},
/* Disable the clear button when nothing is selected */
_onCheckboxChange: function _onCheckboxChange() {
let anySelected = SanitizeUI._privData.querySelector(
"#prefs-privdata-history[checked], " +
"#prefs-privdata-other[checked] + #prefs-privdata-subitems .privdata-subitem-item[checked]");
let clearButton = document.getElementById("prefs-clear-data");
clearButton.disabled = !anySelected;
},
handleEvent: function (aEvent) {
switch (aEvent.type) {
case "CheckboxStateChange":
this._onCheckboxChange();
break;
}
},
};

Просмотреть файл

@ -448,8 +448,8 @@ let Sync = {
});
let settingids = ["device", "connect", "connected", "disconnect", "lastsync", "pairdevice",
"errordescription", "accountinfo", "disconnectwarnpanel", "disconnectthrobber",
"disconnectwarntitle", "description"];
"errordescription", "accountinfo", "disconnectwarnpanel", "disconnectpanel",
"disconnectthrobber", "disconnectwarntitle", "description"];
settingids.forEach(function(id) {
elements[id] = document.getElementById("sync-" + id);
});
@ -471,6 +471,7 @@ let Sync = {
let pairdevice = this._elements.pairdevice;
let accountinfo = this._elements.accountinfo;
let description = this._elements.description;
let disconnectpanel = this._elements.disconnectpanel;
let disconnectthrobber = this._elements.disconnectthrobber;
// This gets updated when an error occurs
@ -481,10 +482,11 @@ let Sync = {
// If we're in the process of disconnecting we are no longer configured.
if (this._disconnecting) {
isConfigured = false;
// display the throbber with the appropriate message
disconnectthrobber.collapsed = false;
disconnectpanel.collapsed = false;
disconnectthrobber.enabled = true;
} else {
disconnectthrobber.collapsed = true;
disconnectpanel.collapsed = true;
disconnectthrobber.enabled = false;
}
connect.collapsed = isConfigured;

Просмотреть файл

@ -20,6 +20,7 @@ PERF_TEST_FILES = \
browser_msgmgr_01.js \
msgmanagerecho.js \
browser_layers_01.js \
browser_firstx.js \
$(NULL)
PERF_RESOURCE_FILES = \

Просмотреть файл

@ -0,0 +1,29 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
Services.scriptloader.loadSubScript(testDir + "/perfhelpers.js", this);
runTests();
}
gTests.push({
desc: "first x metrics",
run: function run() {
PerfTest.declareTest("5F2A456E-2BB2-4073-A751-936F222FEAE0",
"startup perf metrics", "browser", "ux",
"Tracks various metrics reported by nsIAppStartup.getStartupInfo(). Values are in msec.");
let startup = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup).getStartupInfo();
PerfTest.declareNumericalResults([
{ value: startup['start'] - startup.process, desc: "start" },
{ value: startup['main'] - startup.process, desc: "main", shareAxis: 0 },
{ value: startup['startupCrashDetectionBegin'] - startup.process, desc: "startupCrashDetectionBegin", shareAxis: 0 },
{ value: startup['firstPaint'] - startup.process, desc: "firstPaint", shareAxis: 0 },
{ value: startup['sessionRestored'] - startup.process, desc: "sessionRestored", shareAxis: 0 },
{ value: startup['createTopLevelWindow'] - startup.process, desc: "createTopLevelWindow", shareAxis: 0 },
{ value: startup['firstLoadURI'] - startup.process, desc: "firstLoadURI", shareAxis: 0 },
]);
}
});

Просмотреть файл

@ -50,6 +50,8 @@ BROWSER_TESTS += \
browser_selection_frame_inputs.js \
browser_selection_frame_inputs.html \
browser_selection_urlbar.js \
browser_selection_contenteditable.js \
browser_selection_contenteditable.html \
$(NULL)
endif

Просмотреть файл

@ -25,6 +25,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
gTests.push({
@ -42,7 +44,6 @@ gTests.push({
yield hideContextUI();
gWindow = Browser.selectedTab.browser.contentWindow;
InputSourceHelper.isPrecise = false;
},
});

Просмотреть файл

@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>
<head>
<style>
HTML {
height: 100%;
cursor: text;
margin: 50px;
}
BODY {
height: 100%;
border: 0;
margin: 0;
}
div {
border: solid 1px gray;
min-width: 800px;
width: 800px;
max-width: 800px;
}
</style>
<title>Content editable selection test page</title>
</head>
<body style="font-size: 12pt;" contenteditable="true">
<div id="testdiv">Testing sending an email in the outlook.com email client.</div>
</body>
</html>

Просмотреть файл

@ -0,0 +1,76 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
let gWindow = null;
const kMarkerOffsetY = 12;
const kCommonWaitMs = 5000;
const kCommonPollMs = 100;
///////////////////////////////////////////////////
// content editable tests
///////////////////////////////////////////////////
gTests.push({
desc: "normalize browser",
run: function test() {
info(chromeRoot + "browser_selection_contenteditable.html");
yield addTab(chromeRoot + "browser_selection_contenteditable.html");
yield waitForCondition(function () {
return !StartUI.isStartPageVisible;
}, kCommonWaitMs, kCommonPollMs);
yield hideContextUI();
gWindow = Browser.selectedTab.browser.contentWindow;
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
},
});
gTests.push({
desc: "simple test to make sure content editable selection works",
run: function test() {
let div = gWindow.document.getElementById("testdiv");
ok(div, "have the div");
sendElementTap(gWindow, div, 295); // end of 'outlook.com'
yield waitForCondition(function () {
return SelectionHelperUI.isCaretUIVisible;
}, kCommonWaitMs, kCommonPollMs);
let xpos = SelectionHelperUI.caretMark.xPos;
let ypos = SelectionHelperUI.caretMark.yPos + 10;
var touchdrag = new TouchDragAndHold();
yield touchdrag.start(gWindow, xpos, ypos, 100, ypos); // start of 'sending'
touchdrag.end();
yield waitForCondition(function () {
return !SelectionHelperUI.hasActiveDrag;
}, kCommonWaitMs, kCommonPollMs);
yield SelectionHelperUI.pingSelectionHandler();
let str = getTrimmedSelection(gWindow).toString();
is(str, "sending an email in the outlook.com", "selected string matches");
},
tearDown: function () {
emptyClipboard();
if (gWindow)
clearSelection(gWindow);
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
}
});
function test() {
if (!isLandscapeMode()) {
todo(false, "browser_selection_tests need landscape mode to run.");
return;
}
setDevPixelEqualToPx();
runTests();
}

Просмотреть файл

@ -25,6 +25,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
gTests.push({
@ -43,8 +45,6 @@ gTests.push({
gWindow = Browser.selectedTab.browser.contentWindow;
gFrame = gWindow.document.getElementById("frame1");
InputSourceHelper.isPrecise = false;
},
});
@ -144,7 +144,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
@ -185,7 +185,6 @@ gTests.push({
gFrame.contentDocument.defaultView.scrollBy(0, 200);
yield scrollPromise;
InputSourceHelper.isPrecise = false;
sendContextMenuClick(114, 130);
yield waitForCondition(function () {

Просмотреть файл

@ -28,6 +28,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
gTests.push({
@ -51,8 +53,6 @@ gTests.push({
ok(gWindow != null, "gWindow");
ok(gFrame != null, "gFrame");
ok(gInput != null, "gInput");
InputSourceHelper.isPrecise = false;
},
});
@ -75,7 +75,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -109,7 +109,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {

Просмотреть файл

@ -28,6 +28,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
gTests.push({
@ -50,8 +52,6 @@ gTests.push({
ok(gWindow != null, "gWindow");
ok(gFrame != null, "gFrame");
ok(gTextArea != null, "gTextArea");
InputSourceHelper.isPrecise = false;
},
});
@ -74,7 +74,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -89,7 +89,7 @@ gTests.push({
});
gTests.push({
desc: "drag selection",
desc: "drag selection 1",
setUp: setUpAndTearDown,
tearDown: setUpAndTearDown,
run: function test() {
@ -107,7 +107,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -154,7 +154,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
let string = "";
@ -166,7 +166,7 @@ gTests.push({
});
gTests.push({
desc: "drag selection",
desc: "drag selection 2",
setUp: setUpAndTearDown,
tearDown: setUpAndTearDown,
run: function test() {
@ -188,7 +188,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -235,7 +235,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
let string = "";

Просмотреть файл

@ -25,6 +25,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
/*
@ -49,7 +51,6 @@ gTests.push({
gWindow = Browser.selectedTab.browser.contentWindow;
gInput = gWindow.document.getElementById("a");
InputSourceHelper.isPrecise = false;
},
});
@ -72,7 +73,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -101,7 +102,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {
@ -147,7 +148,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
yield waitForCondition(function () {

Просмотреть файл

@ -25,6 +25,8 @@ function setUpAndTearDown() {
yield waitForCondition(function () {
return !SelectionHelperUI.isSelectionUIVisible;
}, kCommonWaitMs, kCommonPollMs);
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
}
gTests.push({
@ -42,7 +44,6 @@ gTests.push({
yield hideContextUI();
gWindow = Browser.selectedTab.browser.contentWindow;
InputSourceHelper.isPrecise = false;
},
});
@ -65,7 +66,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");
@ -101,7 +102,7 @@ gTests.push({
ok(menuItem, "menu item exists");
ok(!menuItem.hidden, "menu item visible");
let popupPromise = waitForEvent(document, "popuphidden");
EventUtils.synthesizeMouse(menuItem, 10, 10, {}, gWindow);
sendElementTap(gWindow, menuItem);
yield popupPromise;
ok(popupPromise && !(popupPromise instanceof Error), "promise error");

Просмотреть файл

@ -19,9 +19,6 @@ const kCommonPollMs = 100;
gTests.push({
desc: "normalize browser",
run: function test() {
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
info(chromeRoot + "res/textblock01.html");
yield addTab(chromeRoot + "res/textblock01.html");
@ -30,6 +27,9 @@ gTests.push({
});
yield hideContextUI();
InputSourceHelper.isPrecise = false;
InputSourceHelper.fireUpdate();
},
});

Просмотреть файл

@ -561,26 +561,21 @@ flyoutpanel > settings:first-child {
width: 400px;
}
#sync-disconnectpanel {
margin-top: 25px;
}
#sync-disconnectwarntitle {
font-weight: bold;
}
#sync-disconnectthrobber {
margin-top: 25px;
}
#disconnectthrobber {
width: 25px;
height: 25px;
}
#syncdisconnectthrobber .progressContainer {
#sync-disconnectthrobber .progressContainer {
width: 25px;
height: 25px;
margin-right: 10px;
}
#syncdisconnectthrobber .progressBall {
#sync-disconnectthrobber .progressBall {
margin: 2px;
width: 22px;
height: 22px;
@ -712,6 +707,21 @@ setting[type="radio"] > vbox {
width: 50%;
}
#clear-notification {
max-height: 25px;
}
#clearprivacythrobber .progressContainer {
width: 25px;
height: 25px;
}
#clearprivacythrobber .progressBall {
margin: 2px;
width: 22px;
height: 22px;
}
#clear-notification-done {
font-weight: bold;
}

Просмотреть файл

@ -5,41 +5,38 @@
%filter substitution
%include defines.inc
.progressContainer {
}
.progressBall {
#container[enabled] .progressBall {
position: absolute;
opacity: 0;
transform: rotate(225deg);
animation: orbit 7.15s infinite;
}
.progressBall:nth-child(1) {
#container[enabled] .progressBall:nth-child(1) {
animation-delay: 1.56s;
}
.progressBall:nth-child(2) {
#container[enabled] .progressBall:nth-child(2) {
animation-delay: 0.31s;
}
.progressBall:nth-child(3) {
#container[enabled] .progressBall:nth-child(3) {
animation-delay: 0.62s;
}
.progressBall:nth-child(4) {
#container[enabled] .progressBall:nth-child(4) {
animation-delay: 0.94s;
}
.progressBall:nth-child(5) {
#container[enabled] .progressBall:nth-child(5) {
animation-delay: 1.25s;
}
.progressBall:nth-child(1)::after,
.progressBall:nth-child(2)::after,
.progressBall:nth-child(3)::after,
.progressBall:nth-child(4)::after,
.progressBall:nth-child(5)::after {
#container[enabled] .progressBall:nth-child(1)::after,
#container[enabled] .progressBall:nth-child(2)::after,
#container[enabled] .progressBall:nth-child(3)::after,
#container[enabled] .progressBall:nth-child(4)::after,
#container[enabled] .progressBall:nth-child(5)::after {
content: "";
display: block;
width: 5px;

Двоичные данные
browser/metro/theme/images/throbber.png

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 12 KiB

Просмотреть файл

@ -70,7 +70,6 @@ chrome.jar:
skin/images/errorpage-warning.png (images/errorpage-warning.png)
skin/images/errorpage-larry-white.png (images/errorpage-larry-white.png)
skin/images/errorpage-larry-black.png (images/errorpage-larry-black.png)
skin/images/throbber.png (images/throbber.png)
skin/images/alert-downloads-30.png (images/alert-downloads-30.png)
skin/images/identity-default-hdpi.png (images/identity-default-hdpi.png)
skin/images/identity-ssl-hdpi.png (images/identity-ssl-hdpi.png)

Просмотреть файл

@ -5,7 +5,7 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ChildIterator.h"
#include "nsXBLChildrenElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
namespace mozilla {
namespace dom {
@ -19,7 +19,7 @@ ExplicitChildIterator::GetNextChild()
MOZ_ASSERT(mChild->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL));
MOZ_ASSERT(!mDefaultChild);
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(mChild);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(mChild);
if (mIndexInInserted < point->mInsertedChildren.Length()) {
return point->mInsertedChildren[mIndexInInserted++];
}
@ -46,7 +46,7 @@ ExplicitChildIterator::GetNextChild()
// Iterate until we find a non-<children>, or a <children> with content.
while (mChild &&
mChild->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(mChild);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(mChild);
if (!point->mInsertedChildren.IsEmpty()) {
mIndexInInserted = 1;
return point->mInsertedChildren[0];
@ -97,7 +97,7 @@ nsIContent* FlattenedChildIterator::Get()
MOZ_ASSERT(!mIsFirst);
if (mIndexInInserted) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(mChild);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(mChild);
return point->mInsertedChildren[mIndexInInserted - 1];
}
return mDefaultChild ? mDefaultChild : mChild;
@ -109,7 +109,7 @@ nsIContent* FlattenedChildIterator::GetPreviousChild()
if (mIndexInInserted) {
// NB: mIndexInInserted points one past the last returned child so we need
// to look *two* indices back in order to return the previous child.
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(mChild);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(mChild);
if (--mIndexInInserted) {
return point->mInsertedChildren[mIndexInInserted - 1];
}
@ -133,7 +133,7 @@ nsIContent* FlattenedChildIterator::GetPreviousChild()
// Iterate until we find a non-<children>, or a <children> with content.
while (mChild &&
mChild->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(mChild);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(mChild);
if (!point->mInsertedChildren.IsEmpty()) {
mIndexInInserted = point->InsertedChildrenLength();
return point->mInsertedChildren[mIndexInInserted - 1];

Просмотреть файл

@ -18,7 +18,7 @@
#include "nsDataHashtable.h"
#include "nsString.h"
#include "nsINodeInfo.h"
#include "nsXBLChildrenElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
using namespace mozilla;
using namespace mozilla::dom;
@ -205,7 +205,7 @@ NS_NewElement(nsIContent** aResult,
return NS_NewSVGElement(aResult, aNodeInfo, aFromParser);
}
if (ns == kNameSpaceID_XBL && aNodeInfo.get()->Equals(nsGkAtoms::children)) {
NS_ADDREF(*aResult = new nsXBLChildrenElement(aNodeInfo));
NS_ADDREF(*aResult = new XBLChildrenElement(aNodeInfo));
return NS_OK;
}
return NS_NewXMLElement(aResult, aNodeInfo);

Просмотреть файл

@ -96,6 +96,8 @@
#include <limits>
#include "nsIColorPicker.h"
// input type=date
#include "js/Date.h"
@ -377,6 +379,103 @@ HTMLInputElement::nsFilePickerShownCallback::Done(int16_t aResult)
NS_IMPL_ISUPPORTS1(HTMLInputElement::nsFilePickerShownCallback,
nsIFilePickerShownCallback)
class nsColorPickerShownCallback MOZ_FINAL
: public nsIColorPickerShownCallback
{
public:
nsColorPickerShownCallback(HTMLInputElement* aInput,
nsIColorPicker* aColorPicker)
: mInput(aInput)
, mColorPicker(aColorPicker)
, mValueChanged(false)
{}
NS_DECL_ISUPPORTS
NS_IMETHOD Update(const nsAString& aColor) MOZ_OVERRIDE;
NS_IMETHOD Done(const nsAString& aColor) MOZ_OVERRIDE;
private:
/**
* Updates the internals of the object using aColor as the new value.
* If aTrustedUpdate is true, it will consider that aColor is a new value.
* Otherwise, it will check that aColor is different from the current value.
*/
nsresult UpdateInternal(const nsAString& aColor, bool aTrustedUpdate);
nsRefPtr<HTMLInputElement> mInput;
nsCOMPtr<nsIColorPicker> mColorPicker;
bool mValueChanged;
};
nsresult
nsColorPickerShownCallback::UpdateInternal(const nsAString& aColor,
bool aTrustedUpdate)
{
bool valueChanged = false;
nsAutoString oldValue;
if (aTrustedUpdate) {
valueChanged = true;
} else {
mInput->GetValue(oldValue);
}
mInput->SetValue(aColor);
if (!aTrustedUpdate) {
nsAutoString newValue;
mInput->GetValue(newValue);
if (!oldValue.Equals(newValue)) {
valueChanged = true;
}
}
if (valueChanged) {
mValueChanged = true;
return nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("input"), true,
false);
}
return NS_OK;
}
NS_IMETHODIMP
nsColorPickerShownCallback::Update(const nsAString& aColor)
{
return UpdateInternal(aColor, true);
}
NS_IMETHODIMP
nsColorPickerShownCallback::Done(const nsAString& aColor)
{
/**
* When Done() is called, we might be at the end of a serie of Update() calls
* in which case mValueChanged is set to true and a change event will have to
* be fired but we might also be in a one shot Done() call situation in which
* case we should fire a change event iif the value actually changed.
* UpdateInternal(bool) is taking care of that logic for us.
*/
nsresult rv = NS_OK;
if (!aColor.IsEmpty()) {
UpdateInternal(aColor, false);
}
if (mValueChanged) {
rv = nsContentUtils::DispatchTrustedEvent(mInput->OwnerDoc(),
static_cast<nsIDOMHTMLInputElement*>(mInput.get()),
NS_LITERAL_STRING("change"), true,
false);
}
return rv;
}
NS_IMPL_ISUPPORTS1(nsColorPickerShownCallback, nsIColorPickerShownCallback)
HTMLInputElement::AsyncClickHandler::AsyncClickHandler(HTMLInputElement* aInput)
: mInput(aInput)
{
@ -400,8 +499,50 @@ HTMLInputElement::AsyncClickHandler::Run()
nsresult
HTMLInputElement::AsyncClickHandler::InitColorPicker()
{
// TODO
return NS_OK;
// Get parent nsPIDOMWindow object.
nsCOMPtr<nsIDocument> doc = mInput->OwnerDoc();
nsCOMPtr<nsPIDOMWindow> win = doc->GetWindow();
if (!win) {
return NS_ERROR_FAILURE;
}
// Check if page is allowed to open the popup
if (mPopupControlState > openControlled) {
nsCOMPtr<nsIPopupWindowManager> pm =
do_GetService(NS_POPUPWINDOWMANAGER_CONTRACTID);
if (!pm) {
return NS_OK;
}
uint32_t permission;
pm->TestPermission(doc->NodePrincipal(), &permission);
if (permission == nsIPopupWindowManager::DENY_POPUP) {
nsGlobalWindow::FirePopupBlockedEvent(doc, win, nullptr, EmptyString(), EmptyString());
return NS_OK;
}
}
// Get Loc title
nsXPIDLString title;
nsContentUtils::GetLocalizedString(nsContentUtils::eFORMS_PROPERTIES,
"ColorPicker", title);
nsCOMPtr<nsIColorPicker> colorPicker = do_CreateInstance("@mozilla.org/colorpicker;1");
if (!colorPicker) {
return NS_ERROR_FAILURE;
}
nsAutoString initialValue;
mInput->GetValueInternal(initialValue);
nsresult rv = colorPicker->Init(win, title, initialValue);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIColorPickerShownCallback> callback =
new nsColorPickerShownCallback(mInput, colorPicker);
return colorPicker->Open(callback);
}
nsresult

Просмотреть файл

@ -24,7 +24,6 @@
#include "mozilla/Decimal.h"
class nsDOMFileList;
class nsIFilePicker;
class nsIRadioGroupContainer;
class nsIRadioGroupVisitor;
class nsIRadioVisitor;

Просмотреть файл

@ -62,6 +62,10 @@ MOCHITEST_FILES = \
test_input_event.html \
test_input_number_rounding.html \
test_valueAsDate_pref.html \
test_input_color_picker_initial.html \
test_input_color_picker_update.html \
test_input_color_picker_popup.html \
test_input_color_input_change_events.html \
$(NULL)
include $(topsrcdir)/config/rules.mk

Просмотреть файл

@ -0,0 +1,120 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=885996
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1234567</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8">
/** Test that update() modifies the element value such as done() when it is
* not called as a concellation.
*/
SimpleTest.waitForExplicitFinish();
var MockColorPicker = SpecialPowers.MockColorPicker;
var test = runTest();
SimpleTest.waitForFocus(function() {
test.next();
});
function runTest() {
MockColorPicker.init(window);
var element = null;
MockColorPicker.showCallback = function(picker, update) {
is(picker.initialColor, element.value);
var inputEvent = false;
var changeEvent = false;
element.oninput = function() {
inputEvent = true;
};
element.onchange = function() {
changeEvent = true;
};
if (element.dataset.type == 'update') {
update('#f00ba4');
is(inputEvent, true, 'input event should have been received');
is(changeEvent, false, 'change event should not have been received');
inputEvent = changeEvent = false;
is(element.value, '#f00ba4');
MockColorPicker.returnColor = '#f00ba7';
isnot(element.value, MockColorPicker.returnColor);
} else if (element.dataset.type == 'cancel') {
MockColorPicker.returnColor = '#bababa';
isnot(element.value, MockColorPicker.returnColor);
} else if (element.dataset.type == 'done') {
MockColorPicker.returnColor = '#098766';
isnot(element.value, MockColorPicker.returnColor);
} else if (element.dataset.type == 'noop-done') {
MockColorPicker.returnColor = element.value;
is(element.value, MockColorPicker.returnColor);
}
SimpleTest.executeSoon(function() {
if (element.dataset.type == 'cancel') {
isnot(element.value, MockColorPicker.returnColor);
is(inputEvent, false, 'no input event should have been sent');
is(changeEvent, false, 'no change event should have been sent');
} else if (element.dataset.type == 'noop-done') {
is(element.value, MockColorPicker.returnColor);
is(inputEvent, false, 'no input event should have been sent');
is(changeEvent, false, 'no change event should have been sent');
} else {
is(element.value, MockColorPicker.returnColor);
is(inputEvent, true, 'input event should have been sent');
is(changeEvent, true, 'change event should have been sent');
}
changeEvent = false;
element.blur();
setTimeout(function() {
is(changeEvent, false, "change event should not be fired on blur");
test.next();
});
});
return element.dataset.type == 'cancel' ? "" : MockColorPicker.returnColor;
};
for (var i = 0; i < document.getElementsByTagName('input').length; ++i) {
element = document.getElementsByTagName('input')[i];
element.focus();
synthesizeMouseAtCenter(element, {});
yield;
};
MockColorPicker.cleanup();
SimpleTest.finish();
yield;
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=885996">Mozilla Bug 885996</a>
<p id="display"></p>
<div id="content">
<input type='color' data-type='update'>
<input type='color' data-type='cancel'>
<input type='color' data-type='done'>
<input type='color' data-type='noop-done'>
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,79 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=885996
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1234567</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8">
/** Test that the initial value of the nsIColorPicker is the current value of
the <input type='color'> element. **/
SimpleTest.waitForExplicitFinish();
var MockColorPicker = SpecialPowers.MockColorPicker;
var test = runTest();
SimpleTest.waitForFocus(function() {
test.next();
});
function runTest() {
MockColorPicker.init(window);
var element = null;
MockColorPicker.showCallback = function(picker) {
is(picker.initialColor, element.value);
SimpleTest.executeSoon(function() {
test.next();
});
return "";
};
for (var i = 0; i < document.getElementsByTagName('input').length; ++i) {
element = document.getElementsByTagName('input')[i];
if (element.parentElement.id === 'dynamic-values') {
element.value = '#deadbe';
}
synthesizeMouseAtCenter(element, {});
yield;
};
MockColorPicker.cleanup();
SimpleTest.finish();
yield;
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=885996">Mozilla Bug 885996</a>
<p id="display"></p>
<div id="content">
<div id='valid-values'>
<input type='color' value='#ff00ff'>
<input type='color' value='#ab3275'>
<input type='color' value='#abcdef'>
<input type='color' value='#ABCDEF'>
</div>
<div id='invalid-values'>
<input type='color' value='ffffff'>
<input type='color' value='#abcdez'>
<input type='color' value='#0123456'>
</div>
<div id='dynamic-values'>
<input type='color' value='#ab4594'>
<input type='color' value='#984534'>
<input type='color' value='#f8b9a0'>
</div>
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,139 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=885996
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1234567</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8">
/** Test the behaviour of the <input type='color'> when clicking on it from
different ways. **/
SimpleTest.waitForExplicitFinish();
var MockColorPicker = SpecialPowers.MockColorPicker;
var test = runTest();
var testData = [
{ id: 'normal', result: true },
{ id: 'hidden', result: false },
{ id: 'normal', type: 'untrusted', result: true },
{ id: 'normal', type: 'prevent-default-1', result: false },
{ id: 'normal', type: 'prevent-default-2', result: false },
{ id: 'normal', type: 'click-method', result: true },
{ id: 'normal', type: 'right-click', result: false },
{ id: 'normal', type: 'middle-click', result: false },
{ id: 'label-1', result: true },
{ id: 'label-2', result: true },
{ id: 'label-3', result: true },
{ id: 'label-4', result: true },
{ id: 'button-click', result: true },
{ id: 'button-down', result: true },
{ id: 'button-up', result: true },
{ id: 'div-click', result: true },
{ id: 'div-click-on-demand', result: true },
];
var currentTest = null;
SimpleTest.waitForFocus(function() {
test.next();
});
function runTest() {
MockColorPicker.init(window);
var element = null;
MockColorPicker.showCallback = function(picker) {
ok(currentTest.result);
SimpleTest.executeSoon(function() {
test.next();
});
return "";
};
while (testData.length != 0) {
var currentTest = testData.shift();
element = document.getElementById(currentTest.id);
// To make sure we can actually click on the element.
element.focus();
switch (currentTest.type) {
case 'untrusted':
var e = document.createEvent('MouseEvents');
e.initEvent('click', true, false);
document.getElementById(element.dispatchEvent(e));
break;
case 'prevent-default-1':
element.onclick = function() {
return false;
};
element.click();
element.onclick = function() {};
break;
case 'prevent-default-2':
element.onclick = function(e) {
e.preventDefault();
};
element.click();
element.onclick = function() {};
break;
case 'click-method':
element.click();
break;
case 'right-click':
synthesizeMouseAtCenter(element, { button: 2 });
break;
case 'middle-click':
synthesizeMouseAtCenter(element, { button: 1 });
break;
default:
synthesizeMouseAtCenter(element, {});
}
if (!currentTest.result) {
setTimeout(function() {
setTimeout(function() {
ok(true);
SimpleTest.executeSoon(function() {
test.next();
});
});
});
}
yield;
};
MockColorPicker.cleanup();
SimpleTest.finish();
yield;
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=885996">Mozilla Bug 885996</a>
<p id="display"></p>
<div id="content">
<input type='color' id='normal'>
<input type='color' id='hidden' hidden>
<label id='label-1'>foo<input type='color'></label>
<label id='label-2' for='labeled-2'>foo</label><input id='labeled-2' type='color'></label>
<label id='label-3'>foo<input type='color'></label>
<label id='label-4' for='labeled-4'>foo</label><input id='labeled-4' type='color'></label>
<input id='by-button' type='color'>
<button id='button-click' onclick="document.getElementById('by-button').click();">click</button>
<button id='button-down' onclick="document.getElementById('by-button').click();">click</button>
<button id='button-up' onclick="document.getElementById('by-button').click();">click</button>
<div id='div-click' onclick="document.getElementById('by-button').click();">click</div>
<div id='div-click-on-demand' onclick="var i=document.createElement('input'); i.type='color'; i.click();">click</div>
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -0,0 +1,86 @@
<!DOCTYPE HTML>
<html>
<!--
https://bugzilla.mozilla.org/show_bug.cgi?id=885996
-->
<head>
<meta charset="utf-8">
<title>Test for Bug 1234567</title>
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
<script type="application/javascript;version=1.8">
/** Test that update() modifies the element value such as done() when it is
* not called as a concellation.
*/
SimpleTest.waitForExplicitFinish();
var MockColorPicker = SpecialPowers.MockColorPicker;
var test = runTest();
SimpleTest.waitForFocus(function() {
test.next();
});
function runTest() {
MockColorPicker.init(window);
var element = null;
MockColorPicker.showCallback = function(picker, update) {
is(picker.initialColor, element.value);
if (element.dataset.type == 'update') {
update('#f00ba4');
is(element.value, '#f00ba4');
MockColorPicker.returnColor = '#f00ba7';
isnot(element.value, MockColorPicker.returnColor);
} else if (element.dataset.type == 'cancel') {
MockColorPicker.returnColor = '#bababa';
isnot(element.value, MockColorPicker.returnColor);
} else if (element.dataset.type == 'done') {
MockColorPicker.returnColor = '#098766';
isnot(element.value, MockColorPicker.returnColor);
}
SimpleTest.executeSoon(function() {
if (element.dataset.type == 'cancel') {
isnot(element.value, MockColorPicker.returnColor);
} else {
is(element.value, MockColorPicker.returnColor);
}
test.next();
});
return element.dataset.type == 'cancel' ? "" : MockColorPicker.returnColor;
};
for (var i = 0; i < document.getElementsByTagName('input').length; ++i) {
element = document.getElementsByTagName('input')[i];
synthesizeMouseAtCenter(element, {});
yield;
};
MockColorPicker.cleanup();
SimpleTest.finish();
yield;
}
</script>
</head>
<body>
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=885996">Mozilla Bug 885996</a>
<p id="display"></p>
<div id="content">
<input type='color' data-type='update'>
<input type='color' data-type='cancel'>
<input type='color' data-type='done'>
</div>
<pre id="test">
</pre>
</body>
</html>

Просмотреть файл

@ -4,40 +4,43 @@
* 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 "nsXBLChildrenElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
#include "nsCharSeparatedTokenizer.h"
#include "mozilla/dom/NodeListBinding.h"
nsXBLChildrenElement::~nsXBLChildrenElement()
namespace mozilla {
namespace dom {
XBLChildrenElement::~XBLChildrenElement()
{
}
NS_IMPL_ADDREF_INHERITED(nsXBLChildrenElement, Element)
NS_IMPL_RELEASE_INHERITED(nsXBLChildrenElement, Element)
NS_IMPL_ADDREF_INHERITED(XBLChildrenElement, Element)
NS_IMPL_RELEASE_INHERITED(XBLChildrenElement, Element)
NS_INTERFACE_TABLE_HEAD(nsXBLChildrenElement)
NS_INTERFACE_TABLE_INHERITED2(nsXBLChildrenElement, nsIDOMNode,
NS_INTERFACE_TABLE_HEAD(XBLChildrenElement)
NS_INTERFACE_TABLE_INHERITED2(XBLChildrenElement, nsIDOMNode,
nsIDOMElement)
NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE
NS_INTERFACE_MAP_END_INHERITING(Element)
NS_IMPL_ELEMENT_CLONE(nsXBLChildrenElement)
NS_IMPL_ELEMENT_CLONE(XBLChildrenElement)
nsIAtom*
nsXBLChildrenElement::GetIDAttributeName() const
XBLChildrenElement::GetIDAttributeName() const
{
return nullptr;
}
nsIAtom*
nsXBLChildrenElement::DoGetID() const
XBLChildrenElement::DoGetID() const
{
return nullptr;
}
nsresult
nsXBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
XBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
{
if (aAttribute == nsGkAtoms::includes &&
aNameSpaceID == kNameSpaceID_None) {
@ -48,10 +51,10 @@ nsXBLChildrenElement::UnsetAttr(int32_t aNameSpaceID, nsIAtom* aAttribute,
}
bool
nsXBLChildrenElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
XBLChildrenElement::ParseAttribute(int32_t aNamespaceID,
nsIAtom* aAttribute,
const nsAString& aValue,
nsAttrValue& aResult)
{
if (aAttribute == nsGkAtoms::includes &&
aNamespaceID == kNameSpaceID_None) {
@ -66,6 +69,11 @@ nsXBLChildrenElement::ParseAttribute(int32_t aNamespaceID,
return false;
}
} // namespace mozilla
} // namespace dom
using namespace mozilla::dom;
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_1(nsAnonymousContentList, mParent)
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsAnonymousContentList)
@ -94,7 +102,7 @@ nsAnonymousContentList::GetLength(uint32_t* aLength)
child;
child = child->GetNextSibling()) {
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(child);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
if (!point->mInsertedChildren.IsEmpty()) {
count += point->mInsertedChildren.Length();
}
@ -135,7 +143,7 @@ nsAnonymousContentList::Item(uint32_t aIndex)
child;
child = child->GetNextSibling()) {
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(child);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
if (!point->mInsertedChildren.IsEmpty()) {
if (remIndex < point->mInsertedChildren.Length()) {
return point->mInsertedChildren[remIndex];
@ -176,7 +184,7 @@ nsAnonymousContentList::IndexOf(nsIContent* aContent)
child;
child = child->GetNextSibling()) {
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(child);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
if (!point->mInsertedChildren.IsEmpty()) {
uint32_t insIndex = point->mInsertedChildren.IndexOf(aContent);
if (insIndex != point->mInsertedChildren.NoIndex) {

Просмотреть файл

@ -12,26 +12,23 @@
#include "nsBindingManager.h"
#include "mozilla/dom/nsXMLElement.h"
class nsAnonymousContentList;
namespace mozilla {
namespace dom {
class ExplicitChildIterator;
}
}
class nsAnonymousContentList;
class nsXBLChildrenElement : public nsXMLElement
class XBLChildrenElement : public nsXMLElement
{
public:
friend class mozilla::dom::ExplicitChildIterator;
friend class nsAnonymousContentList;
nsXBLChildrenElement(already_AddRefed<nsINodeInfo> aNodeInfo)
XBLChildrenElement(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsXMLElement(aNodeInfo)
{
}
~nsXBLChildrenElement();
~XBLChildrenElement();
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
@ -148,6 +145,9 @@ private:
nsTArray<nsCOMPtr<nsIAtom> > mIncludes;
};
} // namespace dom
} // namespace mozilla
class nsAnonymousContentList : public nsINodeList
{
public:

Просмотреть файл

@ -12,13 +12,16 @@ EXPORTS += [
'nsXBLService.h',
]
EXPORTS.mozilla.dom += [
'XBLChildrenElement.h',
]
CPP_SOURCES += [
'nsBindingManager.cpp',
'nsXBLBinding.cpp',
'nsXBLContentSink.cpp',
'nsXBLDocumentInfo.cpp',
'nsXBLEventHandler.cpp',
'nsXBLChildrenElement.cpp',
'nsXBLProtoImpl.cpp',
'nsXBLProtoImplField.cpp',
'nsXBLProtoImplMethod.cpp',
@ -30,5 +33,6 @@ CPP_SOURCES += [
'nsXBLSerialize.cpp',
'nsXBLService.cpp',
'nsXBLWindowKeyHandler.cpp',
'XBLChildrenElement.cpp',
]

Просмотреть файл

@ -27,7 +27,7 @@
#include "nsXBLBinding.h"
#include "nsXBLPrototypeBinding.h"
#include "nsXBLDocumentInfo.h"
#include "nsXBLChildrenElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
#include "nsIStyleRuleProcessor.h"
#include "nsRuleProcessorData.h"
@ -48,6 +48,7 @@
#include "mozilla/dom/NodeListBinding.h"
using namespace mozilla;
using namespace mozilla::dom;
//
// Generic pldhash table stuff for mapping one nsISupports to another
@ -970,7 +971,7 @@ nsBindingManager::AppendAllSheets(nsTArray<nsCSSStyleSheet*>& aArray)
static void
InsertAppendedContent(nsBindingManager* aManager,
nsXBLChildrenElement* aPoint,
XBLChildrenElement* aPoint,
nsIContent* aFirstNewContent)
{
uint32_t insertionIndex;
@ -1008,7 +1009,7 @@ nsBindingManager::ContentAppended(nsIDocument* aDocument,
}
// Try to find insertion points for all the new kids.
nsXBLChildrenElement* point = nullptr;
XBLChildrenElement* point = nullptr;
nsIContent* parent = aContainer;
bool first = true;
do {
@ -1081,7 +1082,7 @@ nsBindingManager::ContentRemoved(nsIDocument* aDocument,
{
SetInsertionParent(aChild, nullptr);
nsXBLChildrenElement* point = nullptr;
XBLChildrenElement* point = nullptr;
nsIContent* parent = aContainer;
do {
nsXBLBinding* binding = GetBindingWithContent(parent);
@ -1118,7 +1119,7 @@ void
nsBindingManager::ClearInsertionPointsRecursively(nsIContent* aContent)
{
if (aContent->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
static_cast<nsXBLChildrenElement*>(aContent)->ClearInsertedChildrenAndInsertionParents(this);
static_cast<XBLChildrenElement*>(aContent)->ClearInsertedChildrenAndInsertionParents(this);
}
uint32_t childCount = aContent->GetChildCount();
@ -1211,7 +1212,7 @@ nsBindingManager::HandleChildInsertion(nsIContent* aContainer,
uint32_t(aContainer->IndexOf(aChild)) == aIndexInContainer,
"Child not at the right index?");
nsXBLChildrenElement* point = nullptr;
XBLChildrenElement* point = nullptr;
nsIContent* parent = aContainer;
while (parent) {
nsXBLBinding* binding = GetBindingWithContent(parent);
@ -1263,7 +1264,7 @@ nsBindingManager::FindNestedInsertionPoint(nsIContent* aContainer,
nsIContent* parent = aContainer;
if (aContainer->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
if (static_cast<nsXBLChildrenElement*>(aContainer)->
if (static_cast<XBLChildrenElement*>(aContainer)->
HasInsertedChildren()) {
return nullptr;
}
@ -1276,7 +1277,7 @@ nsBindingManager::FindNestedInsertionPoint(nsIContent* aContainer,
break;
}
nsXBLChildrenElement* point = binding->FindInsertionPointFor(aChild);
XBLChildrenElement* point = binding->FindInsertionPointFor(aChild);
if (!point) {
return nullptr;
}
@ -1299,7 +1300,7 @@ nsBindingManager::FindNestedSingleInsertionPoint(nsIContent* aContainer,
nsIContent* parent = aContainer;
if (aContainer->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
if (static_cast<nsXBLChildrenElement*>(aContainer)->
if (static_cast<XBLChildrenElement*>(aContainer)->
HasInsertedChildren()) {
return nullptr;
}
@ -1317,7 +1318,7 @@ nsBindingManager::FindNestedSingleInsertionPoint(nsIContent* aContainer,
return nullptr;
}
nsXBLChildrenElement* point = binding->GetDefaultInsertionPoint();
XBLChildrenElement* point = binding->GetDefaultInsertionPoint();
if (!point) {
return nullptr;
}

Просмотреть файл

@ -48,7 +48,7 @@
#include "nsIPrincipal.h"
#include "nsIScriptSecurityManager.h"
#include "nsGUIEvent.h"
#include "nsXBLChildrenElement.h"
#include "mozilla/dom/XBLChildrenElement.h"
#include "prprf.h"
#include "nsNodeUtils.h"
@ -338,7 +338,7 @@ nsXBLBinding::GenerateAnonymousContent()
// order.
for (nsIContent* child = mContent; child; child = child->GetNextNode(mContent)) {
if (child->NodeInfo()->Equals(nsGkAtoms::children, kNameSpaceID_XBL)) {
nsXBLChildrenElement* point = static_cast<nsXBLChildrenElement*>(child);
XBLChildrenElement* point = static_cast<XBLChildrenElement*>(child);
if (point->IsDefaultInsertion()) {
mDefaultInsertionPoint = point;
} else {
@ -361,7 +361,7 @@ nsXBLBinding::GenerateAnonymousContent()
} else if (!mInsertionPoints.IsEmpty()) {
ExplicitChildIterator iter(mBoundElement);
for (nsIContent* child = iter.GetNextChild(); child; child = iter.GetNextChild()) {
nsXBLChildrenElement* point = FindInsertionPointForInternal(child);
XBLChildrenElement* point = FindInsertionPointForInternal(child);
if (point) {
point->AppendInsertedChild(child, bindingManager);
}
@ -404,7 +404,7 @@ nsXBLBinding::GenerateAnonymousContent()
}
}
nsXBLChildrenElement*
XBLChildrenElement*
nsXBLBinding::FindInsertionPointFor(nsIContent* aChild)
{
// XXX We should get rid of this function as it causes us to traverse the
@ -417,11 +417,11 @@ nsXBLBinding::FindInsertionPointFor(nsIContent* aChild)
: nullptr;
}
nsXBLChildrenElement*
XBLChildrenElement*
nsXBLBinding::FindInsertionPointForInternal(nsIContent* aChild)
{
for (uint32_t i = 0; i < mInsertionPoints.Length(); ++i) {
nsXBLChildrenElement* point = mInsertionPoints[i];
XBLChildrenElement* point = mInsertionPoints[i];
if (point->Includes(aChild)) {
return point;
}
@ -681,7 +681,7 @@ nsXBLBinding::UnhookEventHandlers()
static void
UpdateInsertionParent(nsBindingManager* aBindingManager,
nsXBLChildrenElement* aPoint,
XBLChildrenElement* aPoint,
nsIContent* aOldBoundElement)
{
if (aPoint->IsDefaultInsertion()) {

Просмотреть файл

@ -22,7 +22,15 @@ class nsIContent;
class nsIAtom;
class nsIDocument;
class nsIScriptContext;
class nsXBLChildrenElement;
namespace mozilla {
namespace dom {
class XBLChildrenElement;
}
}
class nsAnonymousContentList;
struct JSContext;
class JSObject;
@ -136,14 +144,14 @@ public:
bool AllowScripts(); // XXX make const
nsXBLChildrenElement* FindInsertionPointFor(nsIContent* aChild);
mozilla::dom::XBLChildrenElement* FindInsertionPointFor(nsIContent* aChild);
bool HasFilteredInsertionPoints()
{
return !mInsertionPoints.IsEmpty();
}
nsXBLChildrenElement* GetDefaultInsertionPoint()
mozilla::dom::XBLChildrenElement* GetDefaultInsertionPoint()
{
return mDefaultInsertionPoint;
}
@ -176,11 +184,11 @@ protected:
// attribute. These points must be up-to-date with respect to their parent's
// children, even if their parent has another binding attached to it,
// preventing us from rendering their contents directly.
nsRefPtr<nsXBLChildrenElement> mDefaultInsertionPoint;
nsTArray<nsRefPtr<nsXBLChildrenElement> > mInsertionPoints;
nsRefPtr<mozilla::dom::XBLChildrenElement> mDefaultInsertionPoint;
nsTArray<nsRefPtr<mozilla::dom::XBLChildrenElement> > mInsertionPoints;
nsRefPtr<nsAnonymousContentList> mAnonymousContentList;
nsXBLChildrenElement* FindInsertionPointForInternal(nsIContent* aChild);
mozilla::dom::XBLChildrenElement* FindInsertionPointForInternal(nsIContent* aChild);
};
#endif // nsXBLBinding_h_

Просмотреть файл

@ -35,7 +35,9 @@ AlarmsManager.prototype = {
classID : ALARMSMANAGER_CID,
QueryInterface : XPCOMUtils.generateQI([nsIDOMMozAlarmsManager, Ci.nsIDOMGlobalPropertyInitializer]),
QueryInterface : XPCOMUtils.generateQI([nsIDOMMozAlarmsManager,
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
classInfo : XPCOMUtils.generateCI({ classID: ALARMSMANAGER_CID,
contractID: ALARMSMANAGER_CONTRACTID,
@ -162,7 +164,7 @@ AlarmsManager.prototype = {
this._cpmm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
// Add the valid messages to be listened.
this.initHelper(aWindow, ["AlarmsManager:Add:Return:OK", "AlarmsManager:Add:Return:KO",
this.initDOMRequestHelper(aWindow, ["AlarmsManager:Add:Return:OK", "AlarmsManager:Add:Return:KO",
"AlarmsManager:GetAll:Return:OK", "AlarmsManager:GetAll:Return:KO"]);
// Get the manifest URL if this is an installed app

Просмотреть файл

@ -242,7 +242,7 @@ WebappsRegistry.prototype = {
// nsIDOMGlobalPropertyInitializer implementation
init: function(aWindow) {
this.initHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
this.initDOMRequestHelper(aWindow, ["Webapps:Install:Return:OK", "Webapps:Install:Return:KO",
"Webapps:GetInstalled:Return:OK",
"Webapps:GetSelf:Return:OK",
"Webapps:CheckInstalled:Return:OK" ]);
@ -264,7 +264,8 @@ WebappsRegistry.prototype = {
classID: Components.ID("{fff440b3-fae2-45c1-bf03-3b5a2e432270}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationRegistry,
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
Ci.mozIDOMApplicationRegistry,
#ifdef MOZ_B2G
Ci.mozIDOMApplicationRegistry2,
#elifdef MOZ_WIDGET_ANDROID
@ -364,7 +365,7 @@ WebappsApplication.prototype = {
this._downloadError = null;
this.initHelper(aWindow, ["Webapps:OfflineCache",
this.initDOMRequestHelper(aWindow, ["Webapps:OfflineCache",
"Webapps:CheckForUpdate:Return:OK",
"Webapps:CheckForUpdate:Return:KO",
"Webapps:Launch:Return:OK",
@ -636,7 +637,8 @@ WebappsApplication.prototype = {
classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplication]),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplication,
Ci.nsISupportsWeakReference]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{723ed303-7757-4fb0-b261-4f78b1f6bd22}"),
contractID: "@mozilla.org/webapps/application;1",
@ -649,7 +651,7 @@ WebappsApplication.prototype = {
* mozIDOMApplicationMgmt object
*/
function WebappsApplicationMgmt(aWindow) {
this.initHelper(aWindow, ["Webapps:GetAll:Return:OK",
this.initDOMRequestHelper(aWindow, ["Webapps:GetAll:Return:OK",
"Webapps:GetAll:Return:KO",
"Webapps:Uninstall:Return:OK",
"Webapps:Uninstall:Broadcast:Return:OK",
@ -787,7 +789,7 @@ WebappsApplicationMgmt.prototype = {
classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationMgmt]),
QueryInterface: XPCOMUtils.generateQI([Ci.mozIDOMApplicationMgmt, Ci.nsISupportsWeakReference]),
classInfo: XPCOMUtils.generateCI({classID: Components.ID("{8c1bca96-266f-493a-8d57-ec7a95098c15}"),
contractID: "@mozilla.org/webapps/application-mgmt;1",

Просмотреть файл

@ -3,10 +3,10 @@
* You can obtain one at http://mozilla.org/MPL/2.0/. */
/**
* helper object for APIs that deal with DOMRequest and need to release them properly
* when the window goes out of scope
*/
const Cu = Components.utils;
* Helper object for APIs that deal with DOMRequests and need to release them
* when the window goes out of scope.
*/
const Cu = Components.utils;
const Cc = Components.classes;
const Ci = Components.interfaces;
@ -19,10 +19,109 @@ XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
"@mozilla.org/childprocessmessagemanager;1",
"nsIMessageListenerManager");
/**
* We use DOMRequestIpcHelperMessageListener to avoid leaking objects which
* "inherit" from DOMRequestIpcHelper.
*
* The issue is that the message manager will hold a strong ref to the message
* listener we register with it. But we don't want to hold a strong ref to the
* DOMRequestIpcHelper object, because that object may be arbitrarily large.
*
* So instead the message manager holds a strong ref to the
* DOMRequestIpcHelperMessageListener, and that holds a /weak/ ref to its
* DOMRequestIpcHelper.
*
* Additionally, we want to unhook all of these message listeners when the
* appropriate window is destroyed. We use DOMRequestIpcHelperMessageListener
* for this, too.
*/
this.DOMRequestIpcHelperMessageListener = function(aHelper, aWindow, aMessages) {
this._weakHelper = Cu.getWeakReference(aHelper);
this._messages = aMessages;
this._messages.forEach(function(msgName) {
cpmm.addMessageListener(msgName, this);
}, this);
Services.obs.addObserver(this, "inner-window-destroyed", /* weakRef */ true);
// aWindow may be null; in that case, the DOMRequestIpcHelperMessageListener
// is not tied to a particular window and lives forever.
if (aWindow) {
let util = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this._innerWindowID = util.currentInnerWindowID;
}
}
DOMRequestIpcHelperMessageListener.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIMessageListener,
Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
observe: function(aSubject, aTopic, aData) {
if (aTopic !== "inner-window-destroyed") {
return;
}
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId != this._innerWindowID) {
return;
}
this.destroy();
},
receiveMessage: function(aMsg) {
let helper = this._weakHelper.get();
if (helper) {
helper.receiveMessage(aMsg);
} else {
this.destroy();
}
},
destroy: function() {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._messages.forEach(function(msgName) {
cpmm.removeMessageListener(msgName, this);
}, this);
this._messages = null;
let helper = this._weakHelper.get();
if (helper) {
helper.destroyDOMRequestHelper();
}
}
}
this.DOMRequestIpcHelper = function DOMRequestIpcHelper() {
}
DOMRequestIpcHelper.prototype = {
/**
* An object which "inherits" from DOMRequestIpcHelper and declares its own
* queryInterface method MUST implement Ci.nsISupportsWeakReference.
*/
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference]),
initDOMRequestHelper: function(aWindow, aMessages) {
this._DOMRequestIpcHelperMessageListener =
new DOMRequestIpcHelperMessageListener(this, aWindow, aMessages);
this._window = aWindow;
this._requests = [];
this._id = this._getRandomId();
if (this._window) {
// We don't use this.innerWindowID, but other classes rely on it.
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
this.innerWindowID = util.currentInnerWindowID;
}
},
getRequestId: function(aRequest) {
let id = "id" + this._getRandomId();
this._requests[id] = aRequest;
@ -51,48 +150,22 @@ DOMRequestIpcHelper.prototype = {
return Cc["@mozilla.org/uuid-generator;1"].getService(Ci.nsIUUIDGenerator).generateUUID().toString();
},
observe: function(aSubject, aTopic, aData) {
if (aTopic !== "inner-window-destroyed") {
destroyDOMRequestHelper: function() {
// This function is re-entrant --
// DOMRequestIpcHelperMessageListener.destroy() calls back into this
// function, and this.uninit() may also call it.
if (this._destroyed) {
return;
}
this._destroyed = true;
let wId = aSubject.QueryInterface(Ci.nsISupportsPRUint64).data;
if (wId == this.innerWindowID) {
Services.obs.removeObserver(this, "inner-window-destroyed");
this._requests = [];
this._window = null;
this.removeMessageListener();
if(this.uninit)
this.uninit();
}
},
initRequests: function initRequests() {
this._DOMRequestIpcHelperMessageListener.destroy();
this._requests = [];
},
this._window = null;
initMessageListener: function initMessageListener(aMessages) {
this._messages = aMessages;
this._messages.forEach(function(msgName) {
cpmm.addMessageListener(msgName, this);
}, this);
},
initHelper: function(aWindow, aMessages) {
this.initMessageListener(aMessages);
this.initRequests();
this._id = this._getRandomId();
Services.obs.addObserver(this, "inner-window-destroyed", false);
this._window = aWindow;
let util = this._window.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
this.innerWindowID = util.currentInnerWindowID;
},
removeMessageListener: function removeMessageListener() {
this._messages.forEach(function(msgName) {
cpmm.removeMessageListener(msgName, this);
}, this);
this._messages = null;
if(this.uninit) {
this.uninit();
}
},
createRequest: function() {

Просмотреть файл

@ -911,7 +911,7 @@ ContactManager.prototype = {
},
init: function(aWindow) {
this.initHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
this.initDOMRequestHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
"Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
"Contact:Save:Return:OK", "Contact:Save:Return:KO",
"Contact:Remove:Return:OK", "Contact:Remove:Return:KO",
@ -929,7 +929,9 @@ ContactManager.prototype = {
},
classID : CONTACTMANAGER_CID,
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager, Ci.nsIDOMGlobalPropertyInitializer]),
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager,
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
classInfo : XPCOMUtils.generateCI({classID: CONTACTMANAGER_CID,
contractID: CONTACTMANAGER_CONTRACTID,

Просмотреть файл

@ -42,7 +42,8 @@ DOMFMRadioChild.prototype = {
}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMFMRadio,
Ci.nsIDOMGlobalPropertyInitializer]),
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
// nsIDOMGlobalPropertyInitializer implementation
init: function(aWindow) {
@ -72,7 +73,7 @@ DOMFMRadioChild.prototype = {
"DOMFMRadio:frequencyChange",
"DOMFMRadio:powerStateChange",
"DOMFMRadio:antennaChange"];
this.initHelper(aWindow, messages);
this.initDOMRequestHelper(aWindow, messages);
let els = Cc["@mozilla.org/eventlistenerservice;1"]
.getService(Ci.nsIEventListenerService);

Просмотреть файл

@ -27,3 +27,4 @@ NoFilesSelected=No files selected.
# <input type='file' multiple> when there are more than one selected file.
# %S will be a number greater or equal to 2.
XFilesSelected=%S files selected.
ColorPicker=Choose a color

Просмотреть файл

@ -248,7 +248,7 @@ SystemMessageManager.prototype = {
// nsIDOMGlobalPropertyInitializer implementation.
init: function sysMessMgr_init(aWindow) {
debug("init");
this.initHelper(aWindow, ["SystemMessageManager:Message",
this.initDOMRequestHelper(aWindow, ["SystemMessageManager:Message",
"SystemMessageManager:GetPendingMessages:Return"]);
let principal = aWindow.document.nodePrincipal;
@ -307,7 +307,8 @@ SystemMessageManager.prototype = {
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMNavigatorSystemMessages,
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsIObserver]),
Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
classInfo: XPCOMUtils.generateCI({
classID: Components.ID("{bc076ea0-609b-4d8f-83d7-5af7cbdc3bb2}"),

Просмотреть файл

@ -219,7 +219,7 @@ NetworkStatsManager.prototype = {
return null;
}
this.initHelper(aWindow, ["NetworkStats:Get:Return",
this.initDOMRequestHelper(aWindow, ["NetworkStats:Get:Return",
"NetworkStats:Clear:Return"]);
},
@ -232,7 +232,8 @@ NetworkStatsManager.prototype = {
classID : NETWORKSTATSMANAGER_CID,
QueryInterface : XPCOMUtils.generateQI([nsIDOMMozNetworkStatsManager,
Ci.nsIDOMGlobalPropertyInitializer]),
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
classInfo : XPCOMUtils.generateCI({classID: NETWORKSTATSMANAGER_CID,
contractID: NETWORKSTATSMANAGER_CONTRACTID,

Просмотреть файл

@ -31,7 +31,8 @@ PaymentContentHelper.prototype = {
__proto__: DOMRequestIpcHelper.prototype,
QueryInterface: XPCOMUtils.generateQI([Ci.nsINavigatorPayment,
Ci.nsIDOMGlobalPropertyInitializer]),
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
classID: PAYMENTCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({
classID: PAYMENTCONTENTHELPER_CID,
@ -78,7 +79,7 @@ PaymentContentHelper.prototype = {
init: function(aWindow) {
this._window = aWindow;
this.initHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
this.initDOMRequestHelper(aWindow, PAYMENT_IPC_MSG_NAMES);
return this.pay.bind(this);
},

Просмотреть файл

@ -34,7 +34,8 @@ Push.prototype = {
classID : PUSH_CID,
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer]),
QueryInterface : XPCOMUtils.generateQI([Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
init: function(aWindow) {
debug("init()");
@ -58,9 +59,7 @@ Push.prototype = {
if (perm != Ci.nsIPermissionManager.ALLOW_ACTION)
return null;
this.initHelper(aWindow, []);
this.initMessageListener([
this.initDOMRequestHelper(aWindow, [
"PushService:Register:OK",
"PushService:Register:KO",
"PushService:Unregister:OK",

Просмотреть файл

@ -375,8 +375,7 @@ function RILContentHelper() {
};
this.voicemailInfo = new VoicemailInfo();
this.initRequests();
this.initMessageListener(RIL_IPC_MSG_NAMES);
this.initDOMRequestHelper(/* aWindow */ null, RIL_IPC_MSG_NAMES);
this._windowsMap = [];
Services.obs.addObserver(this, "xpcom-shutdown", false);
}
@ -389,7 +388,8 @@ RILContentHelper.prototype = {
Ci.nsIVoicemailProvider,
Ci.nsITelephonyProvider,
Ci.nsIIccProvider,
Ci.nsIObserver]),
Ci.nsIObserver,
Ci.nsISupportsWeakReference]),
classID: RILCONTENTHELPER_CID,
classInfo: XPCOMUtils.generateCI({classID: RILCONTENTHELPER_CID,
classDescription: "RILContentHelper",
@ -1236,7 +1236,7 @@ RILContentHelper.prototype = {
observe: function observe(subject, topic, data) {
if (topic == "xpcom-shutdown") {
this.removeMessageListener();
this.destroyDOMRequestHelper();
Services.obs.removeObserver(this, "xpcom-shutdown");
}
},

Просмотреть файл

@ -15,8 +15,9 @@ dictionary SocketsDict {
};
dictionary HttpConnInfoDict {
sequence<unsigned long> rtt;
sequence<unsigned long> ttl;
sequence<unsigned long> rtt;
sequence<unsigned long> ttl;
sequence<DOMString> protocolVersion;
};
dictionary HttpConnDict {

Просмотреть файл

@ -56,7 +56,8 @@ DOMWifiManager.prototype = {
flags: Ci.nsIClassInfo.DOM_OBJECT}),
QueryInterface: XPCOMUtils.generateQI([Ci.nsIDOMWifiManager,
Ci.nsIDOMGlobalPropertyInitializer]),
Ci.nsIDOMGlobalPropertyInitializer,
Ci.nsISupportsWeakReference]),
// nsIDOMGlobalPropertyInitializer implementation
init: function(aWindow) {
@ -93,7 +94,7 @@ DOMWifiManager.prototype = {
"WifiManager:onwpstimeout", "WifiManager:onwpsfail",
"WifiManager:onwpsoverlap", "WifiManager:connectionInfoUpdate",
"WifiManager:onconnectingfailed"];
this.initHelper(aWindow, messages);
this.initDOMRequestHelper(aWindow, messages);
this._mm = Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsISyncMessageSender);
var state = this._mm.sendSyncMessage("WifiManager:getState")[0];

Просмотреть файл

@ -156,13 +156,13 @@ DataSourceSurfaceD2D::DataSourceSurfaceD2D(SourceSurfaceD2D* aSourceSurface)
return;
}
D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1_RENDER_TARGET_PROPERTIES rtProps = D2D1::RenderTargetProperties(
D2D1_RENDER_TARGET_TYPE_DEFAULT,
D2D1::PixelFormat(DXGI_FORMAT_UNKNOWN, D2D1_ALPHA_MODE_PREMULTIPLIED));
RefPtr<ID2D1RenderTarget> renderTarget;
hr = DrawTargetD2D::factory()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
&rtProps,
hr = DrawTargetD2D::factory()->CreateDxgiSurfaceRenderTarget(dxgiSurface,
&rtProps,
byRef(renderTarget));
if (FAILED(hr)) {
gfxWarning() << "Failed to create render target. Code: " << hr;

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "SanityChecks.h"

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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/. */
#pragma once

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "TestBase.h"

Просмотреть файл

@ -26,7 +26,7 @@ class TestBase
public:
TestBase() {}
typedef void (TestBase::*TestCall)();
typedef void (TestBase::*TestCall)();
int RunTests(int *aFailures);

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "TestDrawTargetBase.h"
#include <sstream>

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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/. */
#pragma once

Просмотреть файл

@ -1,20 +1,20 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "TestDrawTargetD2D.h"
using namespace mozilla::gfx;
TestDrawTargetD2D::TestDrawTargetD2D()
{
::D3D10CreateDevice1(nullptr,
D3D10_DRIVER_TYPE_HARDWARE,
nullptr,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
D3D10_FEATURE_LEVEL_10_0,
D3D10_1_SDK_VERSION,
::D3D10CreateDevice1(nullptr,
D3D10_DRIVER_TYPE_HARDWARE,
nullptr,
D3D10_CREATE_DEVICE_BGRA_SUPPORT |
D3D10_CREATE_DEVICE_PREVENT_INTERNAL_THREADING_OPTIMIZATIONS,
D3D10_FEATURE_LEVEL_10_0,
D3D10_1_SDK_VERSION,
byRef(mDevice));
Factory::SetDirect3D10Device(mDevice);

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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/. */
#pragma once
@ -16,4 +16,4 @@ public:
private:
mozilla::RefPtr<ID3D10Device1> mDevice;
};
};

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "TestPoint.h"

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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/. */
#pragma once

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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 "TestScaling.h"

Просмотреть файл

@ -1,7 +1,7 @@
/* -*- Mode: C++; tab-width: 20; 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/. */
/* -*- Mode: C++; tab-width: 20; 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/. */
#pragma once

Просмотреть файл

@ -17,7 +17,21 @@ using namespace mozilla::gfx;
namespace layers {
class TextureSourceBasic : public TextureHost
/**
* A texture source interface that can be used by the software Compositor.
*/
class TextureSourceBasic
{
public:
virtual ~TextureSourceBasic() {}
virtual gfx::SourceSurface* GetSurface() = 0;
};
/**
* Texture source and host implementaion for software compositing.
*/
class TextureHostBasic : public TextureHost
, public TextureSourceBasic
{
public:
virtual IntSize GetSize() const MOZ_OVERRIDE { return mSize; }
@ -31,7 +45,7 @@ public:
mCompositor = static_cast<BasicCompositor*>(aCompositor);
}
virtual const char *Name() { return "TextureSourceBasic"; }
virtual const char *Name() { return "TextureHostBasic"; }
protected:
virtual void UpdateImpl(const SurfaceDescriptor& aImage,
@ -91,7 +105,7 @@ DeserializerToPlanarYCbCrImageData(YCbCrImageDataDeserializer& aDeserializer, Pl
aData.mPicSize = aDeserializer.GetYSize();
}
class YCbCrTextureHostBasic : public TextureSourceBasic
class YCbCrTextureHostBasic : public TextureHostBasic
{
public:
virtual void UpdateImpl(const SurfaceDescriptor& aImage,
@ -160,7 +174,7 @@ CreateBasicTextureHost(SurfaceDescriptorType aDescriptorType,
MOZ_ASSERT(aDescriptorType == SurfaceDescriptor::TShmem ||
aDescriptorType == SurfaceDescriptor::TMemoryImage,
"We can only support Shmem currently");
return new TextureSourceBasic();
return new TextureHostBasic();
}
BasicCompositor::BasicCompositor(nsIWidget *aWidget)

Просмотреть файл

@ -1,7 +1,7 @@
/* 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/. */
/* 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/. */
#if 0
//
// FX Version: fx_4_0

Просмотреть файл

@ -1,7 +1,7 @@
/* 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/. */
/* 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/. */
#if 0
//
// Generated by Microsoft (R) HLSL Shader Compiler 9.29.952.3111

Просмотреть файл

@ -75,8 +75,10 @@ ShaderProgramFromTargetAndFormat(GLenum aTarget,
{
switch(aTarget) {
case LOCAL_GL_TEXTURE_EXTERNAL:
MOZ_ASSERT(aFormat == gfx::FORMAT_R8G8B8A8);
return RGBALayerExternalProgramType;
case LOCAL_GL_TEXTURE_RECTANGLE_ARB:
MOZ_ASSERT(aFormat == gfx::FORMAT_R8G8B8A8);
return RGBARectLayerProgramType;
default:
return ShaderProgramFromSurfaceFormat(aFormat);

Просмотреть файл

@ -110,6 +110,107 @@ TEST(AsyncPanZoomController, SimpleTransform) {
EXPECT_EQ(viewTransformOut, ViewTransform());
}
TEST(AsyncPanZoomController, ComplexTransform) {
TimeStamp testStartTime = TimeStamp::Now();
AsyncPanZoomController::SetFrameTime(testStartTime);
// This test assumes there is a page that gets rendered to
// two layers. In CSS pixels, the first layer is 50x50 and
// the second layer is 25x50. The widget scale factor is 3.0
// and the presShell resolution is 2.0. Therefore, these layers
// end up being 300x300 and 150x300 in layer pixels.
//
// The second (child) layer has an additional CSS transform that
// stretches it by 2.0 on the x-axis. Therefore, after applying
// CSS transforms, the two layers are the same size in screen
// pixels.
//
// The screen itself is 24x24 in screen pixels (therefore 4x4 in
// CSS pixels). The displayport is 1 extra CSS pixel on all
// sides.
nsRefPtr<MockContentController> mcc = new MockContentController();
nsRefPtr<AsyncPanZoomController> apzc = new AsyncPanZoomController(mcc);
const char* layerTreeSyntax = "c(c)";
// LayerID 0 1
nsIntRegion layerVisibleRegion[] = {
nsIntRegion(nsIntRect(0, 0, 300, 300)),
nsIntRegion(nsIntRect(0, 0, 150, 300)),
};
gfx3DMatrix transforms[] = {
gfx3DMatrix(),
gfx3DMatrix(),
};
transforms[0].ScalePost(0.5f, 0.5f, 1.0f); // this results from the 2.0 resolution on the root layer
transforms[1].ScalePost(2.0f, 1.0f, 1.0f); // this is the 2.0 x-axis CSS transform on the child layer
nsTArray<nsRefPtr<Layer> > layers;
nsRefPtr<LayerManager> lm;
nsRefPtr<Layer> root = CreateLayerTree(layerTreeSyntax, layerVisibleRegion, transforms, lm, layers);
FrameMetrics metrics;
metrics.mCompositionBounds = ScreenIntRect(0, 0, 24, 24);
metrics.mDisplayPort = CSSRect(-1, -1, 6, 6);
metrics.mViewport = CSSRect(0, 0, 4, 4);
metrics.mScrollOffset = CSSPoint(10, 10);
metrics.mScrollableRect = CSSRect(0, 0, 50, 50);
metrics.mResolution = LayoutDeviceToLayerScale(2);
metrics.mZoom = ScreenToScreenScale(1);
metrics.mDevPixelsPerCSSPixel = CSSToLayoutDeviceScale(3);
metrics.mScrollId = FrameMetrics::ROOT_SCROLL_ID;
FrameMetrics childMetrics = metrics;
childMetrics.mScrollId = FrameMetrics::START_SCROLL_ID;
layers[0]->AsContainerLayer()->SetFrameMetrics(metrics);
layers[1]->AsContainerLayer()->SetFrameMetrics(childMetrics);
ScreenPoint pointOut;
ViewTransform viewTransformOut;
// Both the parent and child layer should behave exactly the same here, because
// the CSS transform on the child layer does not affect the SampleContentTransformForFrame code
// initial transform
apzc->NotifyLayersUpdated(metrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[0]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
apzc->NotifyLayersUpdated(childMetrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[1]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(), LayoutDeviceToScreenScale(2)), viewTransformOut);
EXPECT_EQ(ScreenPoint(60, 60), pointOut);
// do an async scroll by 5 pixels and check the transform
metrics.mScrollOffset += CSSPoint(5, 0);
apzc->NotifyLayersUpdated(metrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[0]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
childMetrics.mScrollOffset += CSSPoint(5, 0);
apzc->NotifyLayersUpdated(childMetrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[1]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(2)), viewTransformOut);
EXPECT_EQ(ScreenPoint(90, 60), pointOut);
// do an async zoom of 1.5x and check the transform
metrics.mZoom.scale *= 1.5f;
apzc->NotifyLayersUpdated(metrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[0]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
childMetrics.mZoom.scale *= 1.5f;
apzc->NotifyLayersUpdated(childMetrics, true);
apzc->SampleContentTransformForFrame(testStartTime, layers[0]->AsContainerLayer(), &viewTransformOut, pointOut);
EXPECT_EQ(ViewTransform(LayerPoint(-30, 0), LayoutDeviceToScreenScale(3)), viewTransformOut);
EXPECT_EQ(ScreenPoint(135, 90), pointOut);
}
TEST(AsyncPanZoomController, Pan) {
TimeStamp testStartTime = TimeStamp::Now();
AsyncPanZoomController::SetFrameTime(testStartTime);

Просмотреть файл

@ -1419,409 +1419,14 @@ gfxFontUtils::ReadNames(hb_blob_t *aNameTable, uint32_t aNameID,
#ifdef XP_WIN
// Embedded OpenType (EOT) handling
// needed for dealing with downloadable fonts on Windows
//
// EOT version 0x00020001
// based on http://www.w3.org/Submission/2008/SUBM-EOT-20080305/
//
// EOT header consists of a fixed-size portion containing general font
// info, followed by a variable-sized portion containing name data,
// followed by the actual TT/OT font data (non-byte values are always
// stored in big-endian format)
//
// EOT header is stored in *little* endian order!!
#pragma pack(1)
struct EOTFixedHeader {
uint32_t eotSize; // Total structure length in PRUint8s (including string and font data)
uint32_t fontDataSize; // Length of the OpenType font (FontData) in PRUint8s
uint32_t version; // Version number of this format - 0x00010000
uint32_t flags; // Processing Flags
uint8_t panose[10]; // The PANOSE value for this font - See http://www.microsoft.com/typography/otspec/os2.htm#pan
uint8_t charset; // In Windows this is derived from TEXTMETRIC.tmCharSet. This value specifies the character set of the font. DEFAULT_CHARSET (0x01) indicates no preference. - See http://msdn2.microsoft.com/en-us/library/ms534202.aspx
uint8_t italic; // If the bit for ITALIC is set in OS/2.fsSelection, the value will be 0x01 - See http://www.microsoft.com/typography/otspec/os2.htm#fss
uint32_t weight; // The weight value for this font - See http://www.microsoft.com/typography/otspec/os2.htm#wtc
uint16_t fsType; // Type flags that provide information about embedding permissions - See http://www.microsoft.com/typography/otspec/os2.htm#fst
uint16_t magicNumber; // Magic number for EOT file - 0x504C. Used to check for data corruption.
uint32_t unicodeRange1; // OS/2.UnicodeRange1 (bits 0-31) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
uint32_t unicodeRange2; // OS/2.UnicodeRange2 (bits 32-63) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
uint32_t unicodeRange3; // OS/2.UnicodeRange3 (bits 64-95) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
uint32_t unicodeRange4; // OS/2.UnicodeRange4 (bits 96-127) - See http://www.microsoft.com/typography/otspec/os2.htm#ur
uint32_t codePageRange1; // CodePageRange1 (bits 0-31) - See http://www.microsoft.com/typography/otspec/os2.htm#cpr
uint32_t codePageRange2; // CodePageRange2 (bits 32-63) - See http://www.microsoft.com/typography/otspec/os2.htm#cpr
uint32_t checkSumAdjustment; // head.CheckSumAdjustment - See http://www.microsoft.com/typography/otspec/head.htm
uint32_t reserved[4]; // Reserved - must be 0
uint16_t padding1; // Padding to maintain long alignment. Padding value must always be set to 0x0000.
enum {
EOT_VERSION = 0x00020001,
EOT_MAGIC_NUMBER = 0x504c,
EOT_DEFAULT_CHARSET = 0x01,
EOT_EMBED_PRINT_PREVIEW = 0x0004,
EOT_FAMILY_NAME_INDEX = 0, // order of names in variable portion of EOT header
EOT_STYLE_NAME_INDEX = 1,
EOT_VERSION_NAME_INDEX = 2,
EOT_FULL_NAME_INDEX = 3,
EOT_NUM_NAMES = 4
};
};
#pragma pack()
// EOT headers are only used on Windows
// EOT variable-sized header (version 0x00020001 - contains 4 name
// fields, each with the structure):
//
// // number of bytes in the name array
// uint16_t size;
// // array of UTF-16 chars, total length = <size> bytes
// // note: english version of name record string
// uint8_t name[size];
//
// This structure is used for the following names, each separated by two
// bytes of padding (always 0 with no padding after the rootString):
//
// familyName - based on name ID = 1
// styleName - based on name ID = 2
// versionName - based on name ID = 5
// fullName - based on name ID = 4
// rootString - used to restrict font usage to a specific domain
//
#if DEBUG
static void
DumpEOTHeader(uint8_t *aHeader, uint32_t aHeaderLen)
{
uint32_t offset = 0;
uint8_t *ch = aHeader;
printf("\n\nlen == %d\n\n", aHeaderLen);
while (offset < aHeaderLen) {
printf("%7.7x ", offset);
int i;
for (i = 0; i < 16; i++) {
printf("%2.2x ", *ch++);
}
printf("\n");
offset += 16;
}
}
#endif
nsresult
gfxFontUtils::MakeEOTHeader(const uint8_t *aFontData, uint32_t aFontDataLength,
FallibleTArray<uint8_t> *aHeader,
FontDataOverlay *aOverlay)
{
NS_ASSERTION(aFontData && aFontDataLength != 0, "null font data");
NS_ASSERTION(aHeader, "null header");
NS_ASSERTION(aHeader->Length() == 0, "non-empty header passed in");
NS_ASSERTION(aOverlay, "null font overlay struct passed in");
aOverlay->overlaySrc = 0;
if (!aHeader->AppendElements(sizeof(EOTFixedHeader)))
return NS_ERROR_OUT_OF_MEMORY;
EOTFixedHeader *eotHeader = reinterpret_cast<EOTFixedHeader*>(aHeader->Elements());
memset(eotHeader, 0, sizeof(EOTFixedHeader));
uint32_t fontDataSize = aFontDataLength;
// set up header fields
eotHeader->fontDataSize = fontDataSize;
eotHeader->version = EOTFixedHeader::EOT_VERSION;
eotHeader->flags = 0; // don't specify any special processing
eotHeader->charset = EOTFixedHeader::EOT_DEFAULT_CHARSET;
eotHeader->fsType = EOTFixedHeader::EOT_EMBED_PRINT_PREVIEW;
eotHeader->magicNumber = EOTFixedHeader::EOT_MAGIC_NUMBER;
// read in the sfnt header
if (sizeof(SFNTHeader) > aFontDataLength)
return NS_ERROR_FAILURE;
const SFNTHeader *sfntHeader = reinterpret_cast<const SFNTHeader*>(aFontData);
if (!IsValidSFNTVersion(sfntHeader->sfntVersion))
return NS_ERROR_FAILURE;
// iterate through the table headers to find the head, name and OS/2 tables
bool foundHead = false, foundOS2 = false, foundName = false, foundGlyphs = false;
uint32_t headOffset, headLen, nameOffset, nameLen, os2Offset, os2Len;
uint32_t i, numTables;
numTables = sfntHeader->numTables;
if (sizeof(SFNTHeader) + sizeof(TableDirEntry) * numTables > aFontDataLength)
return NS_ERROR_FAILURE;
uint64_t dataLength(aFontDataLength);
// table directory entries begin immediately following SFNT header
const TableDirEntry *dirEntry = reinterpret_cast<const TableDirEntry*>(aFontData + sizeof(SFNTHeader));
for (i = 0; i < numTables; i++, dirEntry++) {
// sanity check on offset, length values
if (uint64_t(dirEntry->offset) + uint64_t(dirEntry->length) > dataLength)
return NS_ERROR_FAILURE;
switch (dirEntry->tag) {
case TRUETYPE_TAG('h','e','a','d'):
foundHead = true;
headOffset = dirEntry->offset;
headLen = dirEntry->length;
if (headLen < sizeof(HeadTable))
return NS_ERROR_FAILURE;
break;
case TRUETYPE_TAG('n','a','m','e'):
foundName = true;
nameOffset = dirEntry->offset;
nameLen = dirEntry->length;
break;
case TRUETYPE_TAG('O','S','/','2'):
foundOS2 = true;
os2Offset = dirEntry->offset;
os2Len = dirEntry->length;
break;
case TRUETYPE_TAG('g','l','y','f'): // TrueType-style quadratic glyph table
foundGlyphs = true;
break;
case TRUETYPE_TAG('C','F','F',' '): // PS-style cubic glyph table
foundGlyphs = true;
break;
default:
break;
}
if (foundHead && foundName && foundOS2 && foundGlyphs)
break;
}
// require these three tables on Windows
if (!foundHead || !foundName || !foundOS2)
return NS_ERROR_FAILURE;
// at this point, all table offset/length values are within bounds
// read in the data from those tables
// -- head table data
const HeadTable *headData = reinterpret_cast<const HeadTable*>(aFontData + headOffset);
if (headData->tableVersionNumber != HeadTable::HEAD_VERSION ||
headData->magicNumber != HeadTable::HEAD_MAGIC_NUMBER) {
return NS_ERROR_FAILURE;
}
eotHeader->checkSumAdjustment = headData->checkSumAdjustment;
// -- name table data
// -- first, read name table header
const NameHeader *nameHeader = reinterpret_cast<const NameHeader*>(aFontData + nameOffset);
uint32_t nameStringsBase = uint32_t(nameHeader->stringOffset);
uint32_t nameCount = nameHeader->count;
// -- sanity check the number of name records
if (uint64_t(nameCount) * sizeof(NameRecord) + uint64_t(nameOffset) > dataLength)
return NS_ERROR_FAILURE;
// bug 496573 -- dummy names in case the font didn't contain English names
const nsString dummyNames[EOTFixedHeader::EOT_NUM_NAMES] = {
NS_LITERAL_STRING("Unknown"),
NS_LITERAL_STRING("Regular"),
EmptyString(),
dummyNames[EOTFixedHeader::EOT_FAMILY_NAME_INDEX]
};
// -- iterate through name records, look for specific name ids with
// matching platform/encoding/etc. and store offset/lengths
NameRecordData names[EOTFixedHeader::EOT_NUM_NAMES] = {0};
const NameRecord *nameRecord = reinterpret_cast<const NameRecord*>(aFontData + nameOffset + sizeof(NameHeader));
uint32_t needNames = (1 << EOTFixedHeader::EOT_FAMILY_NAME_INDEX) |
(1 << EOTFixedHeader::EOT_STYLE_NAME_INDEX) |
(1 << EOTFixedHeader::EOT_FULL_NAME_INDEX) |
(1 << EOTFixedHeader::EOT_VERSION_NAME_INDEX);
for (i = 0; i < nameCount; i++, nameRecord++) {
// looking for Microsoft English US name strings, skip others
if (uint32_t(nameRecord->platformID) != PLATFORM_ID_MICROSOFT ||
uint32_t(nameRecord->encodingID) != ENCODING_ID_MICROSOFT_UNICODEBMP ||
uint32_t(nameRecord->languageID) != LANG_ID_MICROSOFT_EN_US)
continue;
uint32_t index;
switch ((uint32_t)nameRecord->nameID) {
case NAME_ID_FAMILY:
index = EOTFixedHeader::EOT_FAMILY_NAME_INDEX;
break;
case NAME_ID_STYLE:
index = EOTFixedHeader::EOT_STYLE_NAME_INDEX;
break;
case NAME_ID_FULL:
index = EOTFixedHeader::EOT_FULL_NAME_INDEX;
break;
case NAME_ID_VERSION:
index = EOTFixedHeader::EOT_VERSION_NAME_INDEX;
break;
default:
continue;
}
names[index].offset = nameRecord->offset;
names[index].length = nameRecord->length;
needNames &= ~(1 << index);
if (needNames == 0)
break;
}
// -- expand buffer if needed to include variable-length portion
uint32_t eotVariableLength = 0;
for (i = 0; i < EOTFixedHeader::EOT_NUM_NAMES; i++) {
if (!(needNames & (1 << i))) {
eotVariableLength += names[i].length & (~1);
} else {
eotVariableLength += dummyNames[i].Length() * sizeof(PRUnichar);
}
}
eotVariableLength += EOTFixedHeader::EOT_NUM_NAMES * (2 /* size */
+ 2 /* padding */) +
2 /* null root string size */;
if (!aHeader->AppendElements(eotVariableLength))
return NS_ERROR_OUT_OF_MEMORY;
// append the string data to the end of the EOT header
uint8_t *eotEnd = aHeader->Elements() + sizeof(EOTFixedHeader);
uint32_t strOffset, strLen;
for (i = 0; i < EOTFixedHeader::EOT_NUM_NAMES; i++) {
if (!(needNames & (1 << i))) {
uint32_t namelen = names[i].length;
uint32_t nameoff = names[i].offset; // offset from base of string storage
// sanity check the name string location
if (uint64_t(nameOffset) + uint64_t(nameStringsBase) +
uint64_t(nameoff) + uint64_t(namelen) > dataLength) {
return NS_ERROR_FAILURE;
}
strOffset = nameOffset + nameStringsBase + nameoff;
// output 2-byte str size
strLen = namelen & (~1); // UTF-16 string len must be even
*((uint16_t*) eotEnd) = uint16_t(strLen);
eotEnd += 2;
// length is number of UTF-16 chars, not bytes
CopySwapUTF16(reinterpret_cast<const uint16_t*>(aFontData + strOffset),
reinterpret_cast<uint16_t*>(eotEnd),
(strLen >> 1));
} else {
// bug 496573 -- English names are not present.
// supply an artificial one.
strLen = dummyNames[i].Length() * sizeof(PRUnichar);
*((uint16_t*) eotEnd) = uint16_t(strLen);
eotEnd += 2;
memcpy(eotEnd, dummyNames[i].BeginReading(), strLen);
}
eotEnd += strLen;
// add 2-byte zero padding to the end of each string
*eotEnd++ = 0;
*eotEnd++ = 0;
// Note: Microsoft's WEFT tool produces name strings which
// include an extra null at the end of each string, in addition
// to the 2-byte zero padding that separates the string fields.
// Don't think this is important to imitate...
}
// append null root string size
*eotEnd++ = 0;
*eotEnd++ = 0;
NS_ASSERTION(eotEnd == aHeader->Elements() + aHeader->Length(),
"header length calculation incorrect");
// bug 496573 -- fonts with a fullname that does not begin with the
// family name cause the EOT font loading API to hiccup
uint32_t famOff = names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].offset;
uint32_t famLen = names[EOTFixedHeader::EOT_FAMILY_NAME_INDEX].length;
uint32_t fullOff = names[EOTFixedHeader::EOT_FULL_NAME_INDEX].offset;
uint32_t fullLen = names[EOTFixedHeader::EOT_FULL_NAME_INDEX].length;
const uint8_t *nameStrings = aFontData + nameOffset + nameStringsBase;
// assure that the start of the fullname matches the family name
if (famLen <= fullLen
&& memcmp(nameStrings + famOff, nameStrings + fullOff, famLen)) {
aOverlay->overlaySrc = nameOffset + nameStringsBase + famOff;
aOverlay->overlaySrcLen = famLen;
aOverlay->overlayDest = nameOffset + nameStringsBase + fullOff;
}
// -- OS/2 table data
const OS2Table *os2Data = reinterpret_cast<const OS2Table*>(aFontData + os2Offset);
memcpy(eotHeader->panose, os2Data->panose, sizeof(eotHeader->panose));
eotHeader->italic = (uint16_t) os2Data->fsSelection & 0x01;
eotHeader->weight = os2Data->usWeightClass;
eotHeader->unicodeRange1 = os2Data->unicodeRange1;
eotHeader->unicodeRange2 = os2Data->unicodeRange2;
eotHeader->unicodeRange3 = os2Data->unicodeRange3;
eotHeader->unicodeRange4 = os2Data->unicodeRange4;
eotHeader->codePageRange1 = os2Data->codePageRange1;
eotHeader->codePageRange2 = os2Data->codePageRange2;
eotHeader->eotSize = aHeader->Length() + fontDataSize;
// DumpEOTHeader(aHeader->Elements(), aHeader->Length());
return NS_OK;
}
/* static */
bool
gfxFontUtils::IsCffFont(const uint8_t* aFontData, bool& hasVertical)
gfxFontUtils::IsCffFont(const uint8_t* aFontData)
{
// this is only called after aFontData has passed basic validation,
// so we know there is enough data present to allow us to read the version!
const SFNTHeader *sfntHeader = reinterpret_cast<const SFNTHeader*>(aFontData);
uint32_t i;
uint32_t numTables = sfntHeader->numTables;
const TableDirEntry *dirEntry =
reinterpret_cast<const TableDirEntry*>(aFontData + sizeof(SFNTHeader));
hasVertical = false;
for (i = 0; i < numTables; i++, dirEntry++) {
if (dirEntry->tag == TRUETYPE_TAG('v','h','e','a')) {
hasVertical = true;
break;
}
}
return (sfntHeader->sfntVersion == TRUETYPE_TAG('O','T','T','O'));
}
#endif
#endif

Просмотреть файл

@ -800,21 +800,10 @@ public:
uint32_t aUnicode, uint32_t aVarSelector = 0);
#ifdef XP_WIN
// given a TrueType/OpenType data file, produce a EOT-format header
// for use with Windows T2Embed API AddFontResource type API's
// effectively hide existing fonts with matching names aHeaderLen is
// the size of the header buffer on input, the actual size of the
// EOT header on output
static nsresult
MakeEOTHeader(const uint8_t *aFontData, uint32_t aFontDataLength,
FallibleTArray<uint8_t> *aHeader, FontDataOverlay *aOverlay);
// determine whether a font (which has already been sanitized, so is known
// to be a valid sfnt) is CFF format rather than TrueType
static bool
IsCffFont(const uint8_t* aFontData, bool& hasVertical);
IsCffFont(const uint8_t* aFontData);
#endif
// determine the format of font data

Просмотреть файл

@ -31,7 +31,6 @@
#include "mozilla/Telemetry.h"
#include <usp10.h>
#include <t2embapi.h>
using namespace mozilla;
@ -66,58 +65,26 @@ BuildKeyNameFromFontName(nsAString &aName)
// Implementation of gfxPlatformFontList for Win32 GDI,
// using GDI font enumeration APIs to get the list of fonts
typedef LONG
(WINAPI *TTLoadEmbeddedFontProc)(HANDLE* phFontReference, ULONG ulFlags,
ULONG* pulPrivStatus, ULONG ulPrivs,
ULONG* pulStatus,
READEMBEDPROC lpfnReadFromStream,
LPVOID lpvReadStream,
LPWSTR szWinFamilyName,
LPSTR szMacFamilyName,
TTLOADINFO* pTTLoadInfo);
typedef LONG
(WINAPI *TTDeleteEmbeddedFontProc)(HANDLE hFontReference, ULONG ulFlags,
ULONG* pulStatus);
static TTLoadEmbeddedFontProc TTLoadEmbeddedFontPtr = nullptr;
static TTDeleteEmbeddedFontProc TTDeleteEmbeddedFontPtr = nullptr;
class WinUserFontData : public gfxUserFontData {
public:
WinUserFontData(HANDLE aFontRef, bool aIsEmbedded)
: mFontRef(aFontRef), mIsEmbedded(aIsEmbedded)
WinUserFontData(HANDLE aFontRef)
: mFontRef(aFontRef)
{ }
virtual ~WinUserFontData()
{
if (mIsEmbedded) {
ULONG pulStatus;
LONG err;
err = TTDeleteEmbeddedFontPtr(mFontRef, 0, &pulStatus);
DebugOnly<BOOL> success;
success = RemoveFontMemResourceEx(mFontRef);
#if DEBUG
if (err != E_NONE) {
char buf[256];
sprintf(buf, "error deleting embedded font handle (%p) - TTDeleteEmbeddedFont returned %8.8x", mFontRef, err);
NS_ASSERTION(err == E_NONE, buf);
}
#endif
} else {
DebugOnly<BOOL> success;
success = RemoveFontMemResourceEx(mFontRef);
#if DEBUG
if (!success) {
char buf[256];
sprintf(buf, "error deleting font handle (%p) - RemoveFontMemResourceEx failed", mFontRef);
NS_ASSERTION(success, buf);
}
#endif
if (!success) {
char buf[256];
sprintf(buf, "error deleting font handle (%p) - RemoveFontMemResourceEx failed", mFontRef);
NS_ASSERTION(success, buf);
}
#endif
}
HANDLE mFontRef;
bool mIsEmbedded;
};
BYTE
@ -599,8 +566,6 @@ GDIFontFamily::FindStyleVariations()
gfxGDIFontList::gfxGDIFontList()
{
mFontSubstitutes.Init(50);
InitializeFontEmbeddingProcs();
}
static void
@ -790,104 +755,6 @@ gfxGDIFontList::LookupLocalFont(const gfxProxyFontEntry *aProxyEntry,
return fe;
}
void gfxGDIFontList::InitializeFontEmbeddingProcs()
{
static HMODULE fontlib = LoadLibraryW(L"t2embed.dll");
if (!fontlib)
return;
TTLoadEmbeddedFontPtr = (TTLoadEmbeddedFontProc)
GetProcAddress(fontlib, "TTLoadEmbeddedFont");
TTDeleteEmbeddedFontPtr = (TTDeleteEmbeddedFontProc)
GetProcAddress(fontlib, "TTDeleteEmbeddedFont");
}
// used to control stream read by Windows TTLoadEmbeddedFont API
class EOTFontStreamReader {
public:
EOTFontStreamReader(const uint8_t *aFontData, uint32_t aLength, uint8_t *aEOTHeader,
uint32_t aEOTHeaderLen, FontDataOverlay *aNameOverlay)
: mCurrentChunk(0), mChunkOffset(0)
{
NS_ASSERTION(aFontData, "null font data ptr passed in");
NS_ASSERTION(aEOTHeader, "null EOT header ptr passed in");
NS_ASSERTION(aNameOverlay, "null name overlay struct passed in");
if (aNameOverlay->overlaySrc) {
mNumChunks = 4;
// 0 : EOT header
mDataChunks[0].mData = aEOTHeader;
mDataChunks[0].mLength = aEOTHeaderLen;
// 1 : start of font data to overlayDest
mDataChunks[1].mData = aFontData;
mDataChunks[1].mLength = aNameOverlay->overlayDest;
// 2 : overlay data
mDataChunks[2].mData = aFontData + aNameOverlay->overlaySrc;
mDataChunks[2].mLength = aNameOverlay->overlaySrcLen;
// 3 : rest of font data
mDataChunks[3].mData = aFontData + aNameOverlay->overlayDest + aNameOverlay->overlaySrcLen;
mDataChunks[3].mLength = aLength - aNameOverlay->overlayDest - aNameOverlay->overlaySrcLen;
} else {
mNumChunks = 2;
// 0 : EOT header
mDataChunks[0].mData = aEOTHeader;
mDataChunks[0].mLength = aEOTHeaderLen;
// 1 : font data
mDataChunks[1].mData = aFontData;
mDataChunks[1].mLength = aLength;
}
}
~EOTFontStreamReader()
{
}
struct FontDataChunk {
const uint8_t *mData;
uint32_t mLength;
};
uint32_t mNumChunks;
FontDataChunk mDataChunks[4];
uint32_t mCurrentChunk;
uint32_t mChunkOffset;
unsigned long Read(void *outBuffer, const unsigned long aBytesToRead)
{
uint32_t bytesLeft = aBytesToRead; // bytes left in the out buffer
uint8_t *out = static_cast<uint8_t*> (outBuffer);
while (mCurrentChunk < mNumChunks && bytesLeft) {
FontDataChunk& currentChunk = mDataChunks[mCurrentChunk];
uint32_t bytesToCopy = std::min(bytesLeft,
currentChunk.mLength - mChunkOffset);
memcpy(out, currentChunk.mData + mChunkOffset, bytesToCopy);
bytesLeft -= bytesToCopy;
mChunkOffset += bytesToCopy;
out += bytesToCopy;
NS_ASSERTION(mChunkOffset <= currentChunk.mLength, "oops, buffer overrun");
if (mChunkOffset == currentChunk.mLength) {
mCurrentChunk++;
mChunkOffset = 0;
}
}
return aBytesToRead - bytesLeft;
}
static unsigned long ReadEOTStream(void *aReadStream, void *outBuffer,
const unsigned long aBytesToRead)
{
EOTFontStreamReader *eotReader =
static_cast<EOTFontStreamReader*> (aReadStream);
return eotReader->Read(outBuffer, aBytesToRead);
}
};
gfxFontEntry*
gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
const uint8_t *aFontData,
@ -904,95 +771,48 @@ gfxGDIFontList::MakePlatformFont(const gfxProxyFontEntry *aProxyEntry,
};
FontDataDeleter autoDelete(aFontData);
bool hasVertical;
bool isCFF = gfxFontUtils::IsCffFont(aFontData, hasVertical);
bool isCFF = gfxFontUtils::IsCffFont(aFontData);
nsresult rv;
HANDLE fontRef = nullptr;
bool isEmbedded = false;
nsAutoString uniqueName;
rv = gfxFontUtils::MakeUniqueUserFontName(uniqueName);
if (NS_FAILED(rv))
return nullptr;
// for TTF fonts, first try using the t2embed library if available
if (!isCFF && TTLoadEmbeddedFontPtr && TTDeleteEmbeddedFontPtr) {
// TrueType-style glyphs, use EOT library
AutoFallibleTArray<uint8_t,2048> eotHeader;
uint8_t *buffer;
uint32_t eotlen;
FallibleTArray<uint8_t> newFontData;
isEmbedded = true;
uint32_t nameLen = std::min<uint32_t>(uniqueName.Length(), LF_FACESIZE - 1);
nsAutoString fontName(Substring(uniqueName, 0, nameLen));
rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
if (NS_FAILED(rv))
return nullptr;
FontDataOverlay overlayNameData = {0, 0, 0};
DWORD numFonts = 0;
rv = gfxFontUtils::MakeEOTHeader(aFontData, aLength, &eotHeader,
&overlayNameData);
if (NS_SUCCEEDED(rv)) {
uint8_t *fontData = reinterpret_cast<uint8_t*> (newFontData.Elements());
uint32_t fontLength = newFontData.Length();
NS_ASSERTION(fontData, "null font data after renaming");
// load in embedded font data
eotlen = eotHeader.Length();
buffer = reinterpret_cast<uint8_t*> (eotHeader.Elements());
int32_t ret;
ULONG privStatus, pulStatus;
EOTFontStreamReader eotReader(aFontData, aLength, buffer, eotlen,
&overlayNameData);
// http://msdn.microsoft.com/en-us/library/ms533942(VS.85).aspx
// "A font that is added by AddFontMemResourceEx is always private
// to the process that made the call and is not enumerable."
fontRef = AddFontMemResourceEx(fontData, fontLength,
0 /* reserved */, &numFonts);
if (!fontRef)
return nullptr;
ret = TTLoadEmbeddedFontPtr(&fontRef, TTLOAD_PRIVATE, &privStatus,
LICENSE_PREVIEWPRINT, &pulStatus,
EOTFontStreamReader::ReadEOTStream,
&eotReader,
(PRUnichar*)(fontName.get()), 0, 0);
if (ret != E_NONE) {
fontRef = nullptr;
char buf[256];
sprintf(buf, "font (%s) not loaded using TTLoadEmbeddedFont - error %8.8x",
NS_ConvertUTF16toUTF8(aProxyEntry->Name()).get(), ret);
NS_WARNING(buf);
}
}
}
// load CFF fonts or fonts that failed with t2embed loader
if (fontRef == nullptr) {
// Postscript-style glyphs, swizzle name table, load directly
FallibleTArray<uint8_t> newFontData;
isEmbedded = false;
rv = gfxFontUtils::RenameFont(uniqueName, aFontData, aLength, &newFontData);
if (NS_FAILED(rv))
return nullptr;
DWORD numFonts = 0;
uint8_t *fontData = reinterpret_cast<uint8_t*> (newFontData.Elements());
uint32_t fontLength = newFontData.Length();
NS_ASSERTION(fontData, "null font data after renaming");
// http://msdn.microsoft.com/en-us/library/ms533942(VS.85).aspx
// "A font that is added by AddFontMemResourceEx is always private
// to the process that made the call and is not enumerable."
fontRef = AddFontMemResourceEx(fontData, fontLength,
0 /* reserved */, &numFonts);
if (!fontRef)
return nullptr;
// only load fonts with a single face contained in the data
// AddFontMemResourceEx generates an additional face name for
// vertical text if the font supports vertical writing
if (fontRef && numFonts != 1 + !!hasVertical) {
RemoveFontMemResourceEx(fontRef);
return nullptr;
}
// only load fonts with a single face contained in the data
// AddFontMemResourceEx generates an additional face name for
// vertical text if the font supports vertical writing but since
// the font is referenced via the name this can be ignored
if (fontRef && numFonts > 2) {
RemoveFontMemResourceEx(fontRef);
return nullptr;
}
// make a new font entry using the unique name
WinUserFontData *winUserFontData = new WinUserFontData(fontRef, isEmbedded);
WinUserFontData *winUserFontData = new WinUserFontData(fontRef);
uint16_t w = (aProxyEntry->mWeight == 0 ? 400 : aProxyEntry->mWeight);
GDIFontEntry *fe = GDIFontEntry::CreateFontEntry(uniqueName,

Просмотреть файл

@ -332,8 +332,6 @@ private:
gfxGDIFontList();
void InitializeFontEmbeddingProcs();
nsresult GetFontSubstitutes();
static int CALLBACK EnumFontFamExProc(ENUMLOGFONTEXW *lpelfe,

Просмотреть файл

@ -327,9 +327,10 @@ bool LaunchApp(const std::wstring& cmdline,
if (!createdOK)
return false;
gProcessLog.print("==> process %d launched child process %d\n",
gProcessLog.print("==> process %d launched child process %d (%S)\n",
GetCurrentProcId(),
process_info.dwProcessId);
process_info.dwProcessId,
cmdline.c_str());
// Handles must be closed or they will leak
CloseHandle(process_info.hThread);

Просмотреть файл

@ -1675,10 +1675,18 @@ public:
m_formatter.immediate32(imm);
}
// Intentionally left undefined. If you need this operation, consider
// naming it movq_i32r_signExtended to highlight the fact the operand size
// is not 32; the 32-bit immediate is sign-extended.
void movq_i32r(int imm, RegisterID dst);
// Note that this instruction sign-extends its 32-bit immediate field to 64
// bits and loads the 64-bit value into a 64-bit register.
//
// Note also that this is similar to the movl_i32r instruction, except that
// movl_i32r *zero*-extends its 32-bit immediate, and it has smaller code
// size, so it's preferred for values which could use either.
void movq_i32r(int imm, RegisterID dst) {
spew("movq $%d, %s",
imm, nameIReg(dst));
m_formatter.oneByteOp64(OP_GROUP11_EvIz, GROUP11_MOV, dst);
m_formatter.immediate32(imm);
}
void movq_i64r(int64_t imm, RegisterID dst)
{

Просмотреть файл

@ -1436,7 +1436,7 @@ ion::UnsplitEdges(LIRGraph *lir)
// over-conservative, but we're attempting to keep everything in MIR
// current as we modify the LIR, so only proceed if the MIR is simple.
if (mirBlock->numPredecessors() == 0 || mirBlock->numSuccessors() != 1 ||
!mirBlock->resumePointsEmpty() || !mirBlock->begin()->isGoto())
!mirBlock->begin()->isGoto())
{
continue;
}

Просмотреть файл

@ -7097,8 +7097,8 @@ IonBuilder::jsop_arguments_getelem()
return true;
}
// inlined not constant not supported, yet.
return abort("NYI inlined not constant get argument element");
// inlined not constant not supported, yet.
return abort("NYI inlined not constant get argument element");
}
bool

Просмотреть файл

@ -1290,6 +1290,14 @@ MMul::canOverflow()
return !range() || !range()->isInt32();
}
bool
MUrsh::canOverflow()
{
if (!canOverflow_)
return false;
return !range() || !range()->isInt32();
}
static inline bool
KnownNonStringPrimitive(MDefinition *op)
{

Просмотреть файл

@ -2895,25 +2895,7 @@ class MUrsh : public MShiftInstruction
void infer(BaselineInspector *inspector, jsbytecode *pc);
bool canOverflow() {
// solution is only negative when lhs < 0 and rhs & 0x1f == 0
MDefinition *lhs = getOperand(0);
MDefinition *rhs = getOperand(1);
if (lhs->isConstant()) {
Value lhsv = lhs->toConstant()->value();
if (lhsv.isInt32() && lhsv.toInt32() >= 0)
return false;
}
if (rhs->isConstant()) {
Value rhsv = rhs->toConstant()->value();
if (rhsv.isInt32() && rhsv.toInt32() % 32 != 0)
return false;
}
return canOverflow_;
}
bool canOverflow();
bool fallible() {
return canOverflow();

Просмотреть файл

@ -609,6 +609,9 @@ class MIRGraph
ReversePostorderIterator rpoBegin() {
return blocks_.begin();
}
ReversePostorderIterator rpoBegin(MBasicBlock *at) {
return blocks_.begin(at);
}
ReversePostorderIterator rpoEnd() {
return blocks_.end();
}

Просмотреть файл

@ -465,11 +465,22 @@ Range::or_(const Range *lhs, const Range *rhs)
int64_t lower = INT32_MIN;
int64_t upper = INT32_MAX;
// If the sign bits are the same, the result has the same sign.
if (lhs->lower_ >= 0 && rhs->lower_ >= 0)
lower = 0;
else if (lhs->upper_ < 0 || rhs->upper_ < 0)
upper = -1;
if (lhs->lower_ >= 0 && rhs->lower_ >= 0) {
// Both operands are non-negative, so the result won't be greater than either.
lower = Max(lhs->lower_, rhs->lower_);
// The result will have leading zeros where both operands have leading zeros.
upper = UINT32_MAX >> Min(js_bitscan_clz32(lhs->upper_),
js_bitscan_clz32(rhs->upper_));
} else {
// The result will have leading ones where either operand has leading ones.
if (lhs->upper_ < 0)
lower = Max(lower, (int64_t)(int32_t)~(UINT32_MAX >> js_bitscan_clz32(~lhs->lower_)));
if (rhs->upper_ < 0)
lower = Max(lower, (int64_t)(int32_t)~(UINT32_MAX >> js_bitscan_clz32(~rhs->lower_)));
// If either operand is negative, the result is negative.
if (lhs->upper_ < 0 && rhs->upper_ < 0)
upper = -1;
}
return new Range(lower, upper);
}
@ -480,11 +491,31 @@ Range::xor_(const Range *lhs, const Range *rhs)
int64_t lower = INT32_MIN;
int64_t upper = INT32_MAX;
// If the sign bits are identical, the result is non-negative.
if (lhs->lower_ >= 0 && rhs->lower_ >= 0)
if (lhs->lower_ >= 0 && rhs->lower_ >= 0) {
// Both operands are non-negative. The result will be non-negative and
// not greater than either.
lower = 0;
else if (lhs->upper_ < 0 && rhs->upper_ < 0)
upper = UINT32_MAX >> Min(js_bitscan_clz32(lhs->upper_),
js_bitscan_clz32(rhs->upper_));
} else if (lhs->upper_ < 0 && rhs->upper_ < 0) {
// Both operands are negative. The result will be non-negative and
// will have leading zeros where both operands have leading ones.
lower = 0;
upper = UINT32_MAX >> Min(js_bitscan_clz32(~lhs->lower_),
js_bitscan_clz32(~rhs->lower_));
} else if (lhs->upper_ < 0 && rhs->lower_ >= 0) {
// One operand is negative and the other is non-negative. The result
// will have leading ones where the negative operand has leading ones
// and the non-negative operand has leading zeros.
upper = -1;
lower = (int32_t)~(UINT32_MAX >> Min(js_bitscan_clz32(~lhs->lower_),
js_bitscan_clz32(rhs->upper_)));
} else if (lhs->lower_ >= 0 && rhs->upper_ < 0) {
// One operand is negative and the other is non-negative. As above.
upper = -1;
lower = (int32_t)~(UINT32_MAX >> Min(js_bitscan_clz32(lhs->upper_),
js_bitscan_clz32(~rhs->lower_)));
}
return new Range(lower, upper);
}
@ -492,16 +523,7 @@ Range::xor_(const Range *lhs, const Range *rhs)
Range *
Range::not_(const Range *op)
{
int64_t lower = INT32_MIN;
int64_t upper = INT32_MAX;
// Not inverts all bits, including the sign bit.
if (op->lower_ >= 0)
upper = -1;
else if (op->upper_ < 0)
lower = 0;
return new Range(lower, upper);
return new Range(~op->upper_, ~op->lower_);
}
Range *
@ -528,12 +550,12 @@ Range::lsh(const Range *lhs, int32_t c)
// If the shift doesn't loose bits or shift bits into the sign bit, we
// can simply compute the correct range by shifting.
if (((uint32_t)lhs->lower_ << shift << 1 >> shift >> 1) == lhs->lower_ &&
((uint32_t)lhs->upper_ << shift << 1 >> shift >> 1) == lhs->upper_)
if ((int32_t)((uint32_t)lhs->lower_ << shift << 1 >> shift >> 1) == lhs->lower_ &&
(int32_t)((uint32_t)lhs->upper_ << shift << 1 >> shift >> 1) == lhs->upper_)
{
return new Range(
(int64_t)lhs->lower_ << shift,
(int64_t)lhs->upper_ << shift);
(uint32_t)lhs->lower_ << shift,
(uint32_t)lhs->upper_ << shift);
}
return new Range(INT32_MIN, INT32_MAX);
@ -1022,6 +1044,8 @@ RangeAnalysis::markBlocksInLoopBody(MBasicBlock *header, MBasicBlock *current)
void
RangeAnalysis::analyzeLoop(MBasicBlock *header)
{
JS_ASSERT(header->hasUniqueBackedge());
// Try to compute an upper bound on the number of times the loop backedge
// will be taken. Look for tests that dominate the backedge and which have
// an edge leaving the loop body.
@ -1075,17 +1099,14 @@ RangeAnalysis::analyzeLoop(MBasicBlock *header)
// Try to compute symbolic bounds for the phi nodes at the head of this
// loop, expressed in terms of the iteration bound just computed.
for (MDefinitionIterator iter(header); iter; iter++) {
MDefinition *def = *iter;
if (def->isPhi())
analyzeLoopPhi(header, iterationBound, def->toPhi());
}
for (MPhiIterator iter(header->phisBegin()); iter != header->phisEnd(); iter++)
analyzeLoopPhi(header, iterationBound, *iter);
// Try to hoist any bounds checks from the loop using symbolic bounds.
Vector<MBoundsCheck *, 0, IonAllocPolicy> hoistedChecks;
for (ReversePostorderIterator iter(graph_.rpoBegin()); iter != graph_.rpoEnd(); iter++) {
for (ReversePostorderIterator iter(graph_.rpoBegin(header)); iter != graph_.rpoEnd(); iter++) {
MBasicBlock *block = *iter;
if (!block->isMarked())
continue;
@ -1236,8 +1257,7 @@ RangeAnalysis::analyzeLoopPhi(MBasicBlock *header, LoopIterationBound *loopBound
// but is required to change at most N and be either nondecreasing or
// nonincreasing.
if (phi->numOperands() != 2)
return;
JS_ASSERT(phi->numOperands() == 2);
MBasicBlock *preLoop = header->loopPredecessor();
JS_ASSERT(!preLoop->isMarked() && preLoop->successorWithPhis() == header);

Просмотреть файл

@ -362,12 +362,27 @@ class Assembler : public AssemblerX86Shared
}
CodeOffsetLabel movWithPatch(const ImmWord &word, const Register &dest) {
movq(word, dest);
masm.movq_i64r(word.value, dest.code());
return masm.currentOffset();
}
// Load an ImmWord value into a register. Note that this instruction will
// attempt to optimize its immediate field size. When a full 64-bit
// immediate is needed for a relocation, use movWithPatch.
void movq(ImmWord word, const Register &dest) {
masm.movq_i64r(word.value, dest.code());
// Load a 64-bit immediate into a register. If the value falls into
// certain ranges, we can use specialized instructions which have
// smaller encodings.
if (word.value <= UINT32_MAX) {
// movl has a 32-bit unsigned (effectively) immediate field.
masm.movl_i32r((uint32_t)word.value, dest.code());
} else if ((intptr_t)word.value >= INT32_MIN && (intptr_t)word.value <= INT32_MAX) {
// movq has a 32-bit signed immediate field.
masm.movq_i32r((int32_t)(intptr_t)word.value, dest.code());
} else {
// Otherwise use movabs.
masm.movq_i64r(word.value, dest.code());
}
}
void movq(ImmGCPtr ptr, const Register &dest) {
masm.movq_i64r(ptr.value, dest.code());
@ -523,16 +538,7 @@ class Assembler : public AssemblerX86Shared
}
void mov(ImmWord word, const Register &dest) {
// If the word value is in [0,UINT32_MAX], we can use the more compact
// movl instruction, which has a 32-bit immediate field which it
// zero-extends into the 64-bit register.
if (word.value <= UINT32_MAX) {
uint32_t value32 = static_cast<uint32_t>(word.value);
Imm32 imm32(static_cast<int32_t>(value32));
movl(imm32, dest);
} else {
movq(word, dest);
}
movq(word, dest);
}
void mov(const Imm32 &imm32, const Register &dest) {
movl(imm32, dest);

Просмотреть файл

@ -161,9 +161,12 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
template <typename T>
void storeValue(const Value &val, const T &dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movq(ImmWord(jv.asBits), ScratchReg);
if (val.isMarkable())
if (val.isMarkable()) {
movWithPatch(ImmWord(jv.asBits), ScratchReg);
writeDataRelocation(val);
} else {
mov(ImmWord(jv.asBits), ScratchReg);
}
movq(ScratchReg, Operand(dest));
}
void storeValue(ValueOperand val, BaseIndex dest) {
@ -213,7 +216,7 @@ class MacroAssemblerX64 : public MacroAssemblerX86Shared
void moveValue(const Value &val, const Register &dest) {
jsval_layout jv = JSVAL_TO_IMPL(val);
movq(ImmWord(jv.asPtr), dest);
movWithPatch(ImmWord(jv.asPtr), dest);
writeDataRelocation(val);
}
void moveValue(const Value &src, const ValueOperand &dest) {

Просмотреть файл

@ -88,7 +88,7 @@ JSCompartment::init(JSContext *cx)
{
/*
* As a hack, we clear our timezone cache every time we create a new
* compartment. This ensures that the cache is always relatively fresh, but
* compartment. This ensures that the cache is always relatively fresh, but
* shouldn't interfere with benchmarks which create tons of date objects
* (unless they also create tons of iframes, which seems unlikely).
*/

Просмотреть файл

@ -500,9 +500,11 @@ def process_test_results(results, num_tests, options):
doing = 'after %s' % res.test.path
if not ok:
failures.append(res)
pb.message("FAIL - %s" % res.test.path)
if res.timed_out:
timeouts += 1
if res.timed_out:
pb.message("TIMEOUT - %s" % res.test.path)
timeouts += 1
else:
pb.message("FAIL - %s" % res.test.path)
if options.tinderbox:
if ok:

Просмотреть файл

@ -70,7 +70,6 @@
#include "nsRuleNode.h"
#include "nsIDOMMutationEvent.h"
#include "ChildIterator.h"
#include "nsXBLChildrenElement.h"
#include "nsCSSRendering.h"
#include "nsError.h"
#include "nsLayoutUtils.h"

Просмотреть файл

@ -112,8 +112,6 @@ skip-if(B2G) HTTP(..) == name-collision.html name-collision-ref.html # bug 77348
skip-if(B2G) HTTP(..) == name-collision-bad-url.html name-collision-bad-url-ref.html # bug 773482
HTTP(..) == name-collision-with-prefs-font.html name-collision-with-prefs-font-ref.html # bug 668758
# t2embed lib on windows is picky about fullname
HTTP(..) == load-badfullname.html load-badfullname-ref.html
# 507960-1-* : a collection of tests using DeLarge from openfontlibrary.org

Просмотреть файл

@ -61,7 +61,6 @@
#include "mozilla/LookAndFeel.h"
#include "mozilla/Likely.h"
#include "mozilla/Util.h"
#include "nsXBLChildrenElement.h"
using namespace mozilla;
using namespace mozilla::dom;

Просмотреть файл

@ -1,5 +1,5 @@
#define VERSION "1.3.0"
#define BUILD "2013-05-25"
#define VERSION "1.3.0"
#define BUILD "2013-05-25"
#define PACKAGE_NAME "libjpeg-turbo"
/* Need to use Mozilla-specific function inlining. */

Просмотреть файл

@ -995,8 +995,8 @@ gsmsdp_negotiate_offer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
negotiated_transport = SDP_TRANSPORT_RTPSAVPF;
break;
case SDP_TRANSPORT_SCTPDTLS:
negotiated_transport = SDP_TRANSPORT_SCTPDTLS;
case SDP_TRANSPORT_DTLSSCTP:
negotiated_transport = SDP_TRANSPORT_DTLSSCTP;
break;
default:
@ -1076,8 +1076,8 @@ gsmsdp_negotiate_answer_crypto (fsmdef_dcb_t *dcb_p, cc_sdp_t *cc_sdp_p,
negotiated_transport = SDP_TRANSPORT_RTPSAVPF;
break;
case SDP_TRANSPORT_SCTPDTLS:
negotiated_transport = SDP_TRANSPORT_SCTPDTLS;
case SDP_TRANSPORT_DTLSSCTP:
negotiated_transport = SDP_TRANSPORT_DTLSSCTP;
break;
default:
@ -1315,7 +1315,7 @@ gsmsdp_init_sdp_media_transport (fsmdef_dcb_t *dcb_p, void *sdp_p,
config_get_value(CFGID_SDPMODE, &sdpmode, sizeof(sdpmode));
if (SDP_MEDIA_APPLICATION == media->type) {
media->transport = SDP_TRANSPORT_SCTPDTLS;
media->transport = SDP_TRANSPORT_DTLSSCTP;
} else if (rtpsavpf) {
media->transport = SDP_TRANSPORT_RTPSAVPF;
} else if (sdpmode) {

Просмотреть файл

@ -179,7 +179,7 @@ typedef enum {
SDP_TRANSPORT_RTPSAVP,
SDP_TRANSPORT_TCP,
SDP_TRANSPORT_RTPSAVPF,
SDP_TRANSPORT_SCTPDTLS,
SDP_TRANSPORT_DTLSSCTP,
SDP_MAX_TRANSPORT_TYPES,
SDP_TRANSPORT_UNSUPPORTED,
SDP_TRANSPORT_INVALID

Просмотреть файл

@ -229,7 +229,7 @@ const sdp_namearray_t sdp_transport[SDP_MAX_TRANSPORT_TYPES] =
{"RTP/SAVP", sizeof("RTP/SAVP")},
{"tcp", sizeof("tcp")},
{"RTP/SAVPF", sizeof("RTP/SAVPF")},
{"SCTP/DTLS", sizeof("SCTP/DTLS")}
{"DTLS/SCTP", sizeof("DTLS/SCTP")}
};
/* Note: These *must* be in the same order as the enum type. */

Просмотреть файл

@ -1196,14 +1196,14 @@ sdp_result_e sdp_parse_media (sdp_t *sdp_p, u16 level, const char *ptr)
}
}
/* TODO(ehugg): This block is for forward
compatibility with FF24. Should be in FF23 only.
See Bug 886134 */
#define DATACHANNEL_NEW_TRANSPORT "DTLS/SCTP"
/* TODO(ehugg): Remove this next block when backward
compatibility with versions earlier than FF24
is no longer required. See Bug 886134 */
#define DATACHANNEL_OLD_TRANSPORT "SCTP/DTLS"
if (mca_p->transport == SDP_TRANSPORT_UNSUPPORTED) {
if (cpr_strncasecmp(tmp, DATACHANNEL_NEW_TRANSPORT,
strlen(DATACHANNEL_NEW_TRANSPORT)) == 0) {
mca_p->transport = SDP_TRANSPORT_SCTPDTLS;
if (cpr_strncasecmp(tmp, DATACHANNEL_OLD_TRANSPORT,
strlen(DATACHANNEL_OLD_TRANSPORT)) == 0) {
mca_p->transport = SDP_TRANSPORT_DTLSSCTP;
}
}
@ -1231,7 +1231,7 @@ sdp_result_e sdp_parse_media (sdp_t *sdp_p, u16 level, const char *ptr)
(mca_p->transport == SDP_TRANSPORT_UDPTL) ||
(mca_p->transport == SDP_TRANSPORT_UDPSPRT) ||
(mca_p->transport == SDP_TRANSPORT_LOCAL) ||
(mca_p->transport == SDP_TRANSPORT_SCTPDTLS)) {
(mca_p->transport == SDP_TRANSPORT_DTLSSCTP)) {
/* Port format is simply <port>. Make sure that either
* the choose param is allowed or that the choose value
* wasn't specified.
@ -1383,8 +1383,8 @@ sdp_result_e sdp_parse_media (sdp_t *sdp_p, u16 level, const char *ptr)
sdp_parse_payload_types(sdp_p, mca_p, ptr);
}
/* Parse SCTP/DTLS port */
if (mca_p->transport == SDP_TRANSPORT_SCTPDTLS) {
/* Parse DTLS/SCTP port */
if (mca_p->transport == SDP_TRANSPORT_DTLSSCTP) {
ptr = sdp_getnextstrtok(ptr, port, sizeof(port), " \t", &result);
if (result != SDP_SUCCESS) {
sdp_parse_error(sdp_p->peerconnection,
@ -1565,7 +1565,7 @@ sdp_result_e sdp_build_media (sdp_t *sdp_p, u16 level, flex_string *fs)
flex_string_sprintf(fs, "%s",
sdp_get_transport_name(mca_p->transport));
if(mca_p->transport != SDP_TRANSPORT_SCTPDTLS) {
if(mca_p->transport != SDP_TRANSPORT_DTLSSCTP) {
/* Build the format lists */
for (i=0; i < mca_p->num_payloads; i++) {
@ -1577,7 +1577,7 @@ sdp_result_e sdp_build_media (sdp_t *sdp_p, u16 level, flex_string *fs)
}
}
} else {
/* Add port to SDP if transport is SCTP/DTLS */
/* Add port to SDP if transport is DTLS/SCTP */
flex_string_sprintf(fs, " %u ", (u32)mca_p->sctpport);
}

Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше