зеркало из https://github.com/mozilla/gecko-dev.git
Merge latest green fx-team changeset and mozilla-central
This commit is contained in:
Коммит
f2a832c8ec
|
@ -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
Двоичные данные
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);
|
||||
}
|
||||
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче