This commit is contained in:
Brad Lassey 2012-02-18 17:29:33 -05:00
Родитель 635110f850 a14af63ba4
Коммит 7ba6e1d0cd
536 изменённых файлов: 17038 добавлений и 7159 удалений

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

@ -1494,28 +1494,24 @@ nsHTMLTableAccessible::IsProbablyForLayout(bool *aIsProbablyForLayout)
* Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward * Rules for non-bordered tables with 2-4 columns and 2+ rows from here on forward
*/ */
// Check for styled background color across the row // Check for styled background color across rows (alternating background
// Alternating background color is a common way // color is a common feature for data tables).
nsCOMPtr<nsIDOMNodeList> nodeList; PRUint32 childCount = GetChildCount();
nsCOMPtr<nsIDOMElement> tableElt(do_QueryInterface(mContent)); nsAutoString rowColor, prevRowColor;
tableElt->GetElementsByTagName(NS_LITERAL_STRING("tr"), getter_AddRefs(nodeList)); for (PRUint32 childIdx = 0; childIdx < childCount; childIdx++) {
NS_ENSURE_TRUE(nodeList, NS_ERROR_FAILURE); nsAccessible* child = GetChildAt(childIdx);
PRUint32 length; if (child->Role() == roles::ROW) {
nodeList->GetLength(&length); nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl =
nsAutoString color, lastRowColor; nsCoreUtils::GetComputedStyleDeclaration(EmptyString(),
for (PRUint32 rowCount = 0; rowCount < length; rowCount ++) { child->GetContent());
nsCOMPtr<nsIDOMNode> rowNode; if (styleDecl) {
nodeList->Item(rowCount, getter_AddRefs(rowNode)); prevRowColor = rowColor;
nsCOMPtr<nsIContent> rowContent(do_QueryInterface(rowNode)); styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"),
rowColor);
nsCOMPtr<nsIDOMCSSStyleDeclaration> styleDecl = if (childIdx > 0 && !prevRowColor.Equals(rowColor)) {
nsCoreUtils::GetComputedStyleDeclaration(EmptyString(), rowContent); RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
NS_ENSURE_TRUE(styleDecl, NS_ERROR_FAILURE); }
}
lastRowColor = color;
styleDecl->GetPropertyValue(NS_LITERAL_STRING("background-color"), color);
if (rowCount > 0 && false == lastRowColor.Equals(color)) {
RETURN_LAYOUT_ANSWER(false, "2 styles of row background color, non-bordered");
} }
} }

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

@ -48,6 +48,7 @@ include $(topsrcdir)/config/rules.mk
_TEST_FILES =\ _TEST_FILES =\
test_ariadialog.html \ test_ariadialog.html \
test_colorpicker.xul \ test_colorpicker.xul \
test_cssoverflow.html \
test_contextmenu.xul \ test_contextmenu.xul \
test_doc.html \ test_doc.html \
test_gencontent.html \ test_gencontent.html \

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

@ -0,0 +1,141 @@
<html>
<head>
<title>Testing HTML scrollable frames (css overflow style)</title>
<link rel="stylesheet" type="text/css"
href="chrome://mochikit/content/tests/SimpleTest/test.css" />
<script type="application/javascript"
src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
<script type="application/javascript"
src="../common.js"></script>
<script type="application/javascript"
src="../events.js"></script>
<script type="application/javascript">
////////////////////////////////////////////////////////////////////////////
// Invokers
////////////////////////////////////////////////////////////////////////////
/**
* Change scroll range to not empty size and inserts a child into container
* to trigger tree update of the container. Prior to bug 677154 not empty
* size resulted to accessible creation for scroll area, container tree
* update picked up that accessible unattaching scroll area accessible
* subtree.
*/
function changeScrollRange(aContainerID, aScrollAreaID)
{
this.containerNode = getNode(aContainerID);
this.container = getAccessible(this.containerNode);
this.scrollAreaNode = getNode(aScrollAreaID);
this.eventSeq = [
new invokerChecker(EVENT_REORDER, this.container)
];
this.invoke = function changeScrollRange_invoke()
{
this.scrollAreaNode.style.width = "20px";
this.containerNode.appendChild(document.createElement("input"));
}
this.finalCheck = function changeScrollRange_finalCheck()
{
var accTree =
{ SECTION: [ // container
{ SECTION: [ // scroll area
{ ENTRY: [] } // child content
] },
{ ENTRY: [] } // inserted input
] };
testAccessibleTree(this.container, accTree);
}
this.getID = function changeScrollRange_getID()
{
return "change scroll range for " + prettyName(aScrollAreaID);
}
}
/**
* Change scrollbar styles from hidden to auto. That makes us to create an
* accessible for scroll area.
*/
function changeScrollbarStyles(aContainerID, aScrollAreaID)
{
this.container = getAccessible(aContainerID);
this.scrollAreaNode = getNode(aScrollAreaID);
this.eventSeq = [
new invokerChecker(EVENT_SHOW, getAccessible, this.scrollAreaNode),
new invokerChecker(EVENT_REORDER, this.container)
];
this.invoke = function changeScrollbarStyles_invoke()
{
var accTree =
{ SECTION: [] };
testAccessibleTree(this.container, accTree);
this.scrollAreaNode.style.overflow = "auto";
}
this.finalCheck = function changeScrollbarStyles_finalCheck()
{
var accTree =
{ SECTION: [ // container
{ SECTION: [] } // scroll area
] };
testAccessibleTree(this.container, accTree);
}
this.getID = function changeScrollbarStyles_getID()
{
return "change scrollbar styles " + prettyName(aScrollAreaID);
}
}
////////////////////////////////////////////////////////////////////////////
// Do tests
////////////////////////////////////////////////////////////////////////////
var gQueue = null;
//gA11yEventDumpID = "eventdump"; // debug stuff
//gA11yEventDumpToConsole = true;
function doTests()
{
gQueue = new eventQueue();
gQueue.push(new changeScrollRange("container", "scrollarea"));
gQueue.push(new changeScrollbarStyles("container2", "scrollarea2"));
gQueue.invoke(); // Will call SimpleTest.finish();
}
SimpleTest.waitForExplicitFinish();
addA11yLoadEvent(doTests);
</script>
</head>
<body>
<a target="_blank"
href="https://bugzilla.mozilla.org/show_bug.cgi?id=677154"
title="Detached document accessibility tree">
Mozilla Bug 677154</a>
<p id="display"></p>
<div id="content" style="display: none"></div>
<pre id="test">
</pre>
<div id="eventdump"></div>
<div id="container"><div id="scrollarea" style="overflow:auto;"><input></div></div>
<div id="container2"><div id="scrollarea2" style="overflow:hidden;"></div></div>
</body>
</html>

1
aclocal.m4 поставляемый
Просмотреть файл

@ -17,6 +17,7 @@ builtin(include, build/autoconf/acwinpaths.m4)dnl
builtin(include, build/autoconf/lto.m4)dnl builtin(include, build/autoconf/lto.m4)dnl
builtin(include, build/autoconf/gcc-pr49911.m4)dnl builtin(include, build/autoconf/gcc-pr49911.m4)dnl
builtin(include, build/autoconf/frameptr.m4)dnl builtin(include, build/autoconf/frameptr.m4)dnl
builtin(include, build/autoconf/compiler-opts.m4)dnl
MOZ_PROG_CHECKMSYS() MOZ_PROG_CHECKMSYS()

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

@ -426,7 +426,13 @@ pref("media.realtime_decoder.enabled", true);
// by bug 710563. // by bug 710563.
pref("layout.frame_rate.precise", true); pref("layout.frame_rate.precise", true);
// Temporary remote js console hack
pref("b2g.remote-js.enabled", true);
pref("b2g.remote-js.port", 9999);
// Screen timeout in minutes // Screen timeout in minutes
pref("power.screen.timeout", 60); pref("power.screen.timeout", 60);
pref("full-screen-api.enabled", true); pref("full-screen-api.enabled", true);
pref("media.volume.steps", 10);

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

@ -8,6 +8,7 @@ const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
const Cu = Components.utils; const Cu = Components.utils;
const CC = Components.Constructor; const CC = Components.Constructor;
const Cr = Components.results;
const LocalFile = CC('@mozilla.org/file/local;1', const LocalFile = CC('@mozilla.org/file/local;1',
'nsILocalFile', 'nsILocalFile',
@ -25,11 +26,18 @@ XPCOMUtils.defineLazyGetter(Services, 'ss', function() {
return Cc['@mozilla.org/content/style-sheet-service;1'] return Cc['@mozilla.org/content/style-sheet-service;1']
.getService(Ci.nsIStyleSheetService); .getService(Ci.nsIStyleSheetService);
}); });
XPCOMUtils.defineLazyGetter(Services, 'idle', function() { XPCOMUtils.defineLazyGetter(Services, 'idle', function() {
return Cc['@mozilla.org/widget/idleservice;1'] return Cc['@mozilla.org/widget/idleservice;1']
.getService(Ci.nsIIdleService); .getService(Ci.nsIIdleService);
}); });
XPCOMUtils.defineLazyServiceGetter(Services, 'fm', function(){
return Cc['@mozilla.org/focus-managr;1']
.getService(Ci.nsFocusManager);
});
// In order to use http:// scheme instead of file:// scheme // In order to use http:// scheme instead of file:// scheme
// (that is much more restricted) the following code kick-off // (that is much more restricted) the following code kick-off
// a local http server listening on http://127.0.0.1:7777 and // a local http server listening on http://127.0.0.1:7777 and
@ -105,6 +113,7 @@ var shell = {
window.addEventListener('keypress', this); window.addEventListener('keypress', this);
window.addEventListener('MozApplicationManifest', this); window.addEventListener('MozApplicationManifest', this);
window.addEventListener("AppCommand", this); window.addEventListener("AppCommand", this);
window.addEventListener('mozfullscreenchange', this);
this.contentBrowser.addEventListener('load', this, true); this.contentBrowser.addEventListener('load', this, true);
try { try {
@ -186,6 +195,24 @@ var shell = {
Services.prefs.setBoolPref("nglayout.debug.paint_flashing", false); Services.prefs.setBoolPref("nglayout.debug.paint_flashing", false);
} }
}, },
changeVolume: function shell_changeVolume(aDelta) {
let audioManager = Cc["@mozilla.org/telephony/audiomanager;1"].getService(Ci.nsIAudioManager);
let steps = 10;
try {
steps = Services.prefs.getIntPref("media.volume.steps");
if (steps <= 0)
steps = 1;
} catch(e) {}
let volume = audioManager.masterVolume + aDelta / steps;
if (volume > 1)
volume = 1;
if (volume < 0)
volume = 0;
audioManager.masterVolume = volume;
},
handleEvent: function shell_handleEvent(evt) { handleEvent: function shell_handleEvent(evt) {
switch (evt.type) { switch (evt.type) {
@ -217,8 +244,22 @@ var shell = {
case 'Search': case 'Search':
this.toggleDebug(); this.toggleDebug();
break; break;
case 'VolumeUp':
this.changeVolume(1);
break;
case 'VolumeDown':
this.changeVolume(-1);
break;
} }
break; break;
case 'mozfullscreenchange':
// When the screen goes fullscreen make sure to set the focus to the
// main window so noboby can prevent the ESC key to get out fullscreen
// mode
if (document.mozFullScreen)
Services.fm.focusedWindow = window;
break;
case 'load': case 'load':
this.contentBrowser.removeEventListener('load', this, true); this.contentBrowser.removeEventListener('load', this, true);
this.turnScreenOn(); this.turnScreenOn();
@ -339,3 +380,50 @@ Services.obs.addObserver(function onConsoleAPILogEvent(subject, topic, data) {
" in " + (message.functionName || "anonymous") + ": "; " in " + (message.functionName || "anonymous") + ": ";
Services.console.logStringMessage(prefix + Array.join(message.arguments, " ")); Services.console.logStringMessage(prefix + Array.join(message.arguments, " "));
}, "console-api-log-event", false); }, "console-api-log-event", false);
(function Repl() {
if (!Services.prefs.getBoolPref('b2g.remote-js.enabled')) {
return;
}
const prompt = 'JS> ';
let output;
let reader = {
onInputStreamReady : function repl_readInput(input) {
let sin = Cc['@mozilla.org/scriptableinputstream;1']
.createInstance(Ci.nsIScriptableInputStream);
sin.init(input);
try {
let val = eval(sin.read(sin.available()));
let ret = (typeof val === 'undefined') ? 'undefined\n' : val + '\n';
output.write(ret, ret.length);
// TODO: check if socket has been closed
} catch (e) {
if (e.result === Cr.NS_BASE_STREAM_CLOSED ||
(typeof e === 'object' && e.result === Cr.NS_BASE_STREAM_CLOSED)) {
return;
}
let message = (typeof e === 'object') ? e.message + '\n' : e + '\n';
output.write(message, message.length);
}
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
}
}
let listener = {
onSocketAccepted: function repl_acceptConnection(serverSocket, clientSocket) {
dump('Accepted connection on ' + clientSocket.host + '\n');
let input = clientSocket.openInputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0)
.QueryInterface(Ci.nsIAsyncInputStream);
output = clientSocket.openOutputStream(Ci.nsITransport.OPEN_BLOCKING, 0, 0);
output.write(prompt, prompt.length);
input.asyncWait(reader, 0, 0, Services.tm.mainThread);
}
}
let serverPort = Services.prefs.getIntPref('b2g.remote-js.port');
let serverSocket = Cc['@mozilla.org/network/server-socket;1']
.createInstance(Ci.nsIServerSocket);
serverSocket.init(serverPort, true, -1);
dump('Opened socket on ' + serverSocket.port + '\n');
serverSocket.asyncListen(listener);
})();

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

@ -177,19 +177,22 @@ const ContentPanning = {
} }
}, },
position: { position: new Point(0 , 0),
origin: new Point(0, 0),
current: new Point(0 , 0)
},
onTouchStart: function cp_onTouchStart(evt) { onTouchStart: function cp_onTouchStart(evt) {
this.dragging = true; this.dragging = true;
KineticPanning.stop();
// If there is a pan animation running (from a previous pan gesture) and
// the user touch back the screen, stop this animation immediatly and
// prevent the possible click action.
if (KineticPanning.active) {
KineticPanning.stop();
this.preventNextClick = true;
}
this.scrollCallback = this.getPannable(evt.originalTarget); this.scrollCallback = this.getPannable(evt.originalTarget);
this.position.origin.set(evt.screenX, evt.screenY); this.position.set(evt.screenX, evt.screenY);
this.position.current.set(evt.screenX, evt.screenY); KineticPanning.record(new Point(0, 0), evt.timeStamp);
KineticPanning.record(new Point(0, 0));
}, },
onTouchEnd: function cp_onTouchEnd(evt) { onTouchEnd: function cp_onTouchEnd(evt) {
@ -197,26 +200,29 @@ const ContentPanning = {
return; return;
this.dragging = false; this.dragging = false;
if (this.isPan()) { this.onTouchMove(evt);
if (evt.detail) // The event will generate a click
evt.target.addEventListener('click', this, true);
let pan = KineticPanning.isPan();
let click = evt.detail;
if (click && (pan || this.preventNextClick))
evt.target.addEventListener('click', this, true);
this.preventNextClick = false;
if (pan)
KineticPanning.start(this); KineticPanning.start(this);
}
}, },
onTouchMove: function cp_onTouchMove(evt) { onTouchMove: function cp_onTouchMove(evt) {
if (!this.dragging || !this.scrollCallback) if (!this.dragging || !this.scrollCallback)
return; return;
let current = this.position.current; let current = this.position;
let delta = new Point(evt.screenX - current.x, evt.screenY - current.y); let delta = new Point(evt.screenX - current.x, evt.screenY - current.y);
current.set(evt.screenX, evt.screenY); current.set(evt.screenX, evt.screenY);
if (this.isPan()) { KineticPanning.record(delta, evt.timeStamp);
KineticPanning.record(delta); this.scrollCallback(delta.scale(-1));
this.scrollCallback(delta.scale(-1));
}
}, },
@ -232,24 +238,11 @@ const ContentPanning = {
this.scrollCallback = null; this.scrollCallback = null;
}, },
isPan: function cp_isPan() {
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.displayDPI;
let threshold = Services.prefs.getIntPref('ui.dragThresholdX') / 240 * dpi;
let deltaX = this.position.origin.x - this.position.current.x;
let deltaY = this.position.origin.y - this.position.current.y;
return (Math.abs(deltaX) > threshold || Math.abs(deltaY) > threshold);
},
getPannable: function cp_getPannable(node) { getPannable: function cp_getPannable(node) {
if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML') if (!(node instanceof Ci.nsIDOMHTMLElement) || node.tagName == 'HTML')
return null; return null;
let content = node.ownerDocument.defaultView; let content = node.ownerDocument.defaultView;
while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) { while (!(node instanceof Ci.nsIDOMHTMLBodyElement)) {
let style = content.getComputedStyle(node, null); let style = content.getComputedStyle(node, null);
@ -299,7 +292,7 @@ const kMinVelocity = 0.4;
const kMaxVelocity = 6; const kMaxVelocity = 6;
// Constants that affect the "friction" of the scroll pane. // Constants that affect the "friction" of the scroll pane.
const kExponentialC = 1400; const kExponentialC = 1000;
const kPolynomialC = 100 / 1000000; const kPolynomialC = 100 / 1000000;
// How often do we change the position of the scroll pane? // How often do we change the position of the scroll pane?
@ -307,17 +300,25 @@ const kPolynomialC = 100 / 1000000;
// Too little and panning will be choppy. In milliseconds. // Too little and panning will be choppy. In milliseconds.
const kUpdateInterval = 16; const kUpdateInterval = 16;
// The numbers of momentums to use for calculating the velocity of the pan.
// Those are taken from the end of the action
const kSamples = 5;
const KineticPanning = { const KineticPanning = {
_position: new Point(0, 0), _position: new Point(0, 0),
_velocity: new Point(0, 0), _velocity: new Point(0, 0),
_acceleration: new Point(0, 0), _acceleration: new Point(0, 0),
get active() {
return this.target !== null;
},
_target: null, _target: null,
start: function kp_start(target) { start: function kp_start(target) {
this.target = target; this.target = target;
// Calculate the initial velocity of the movement based on user input // Calculate the initial velocity of the movement based on user input
let momentums = this.momentums; let momentums = this.momentums.slice(-kSamples);
let distance = new Point(0, 0); let distance = new Point(0, 0);
momentums.forEach(function(momentum) { momentums.forEach(function(momentum) {
@ -338,6 +339,7 @@ const KineticPanning = {
let velocity = this._velocity; let velocity = this._velocity;
velocity.set(Math.abs(velocityX) < kMinVelocity ? 0 : velocityX, velocity.set(Math.abs(velocityX) < kMinVelocity ? 0 : velocityX,
Math.abs(velocityY) < kMinVelocity ? 0 : velocityY); Math.abs(velocityY) < kMinVelocity ? 0 : velocityY);
this.momentums = [];
// Set acceleration vector to opposite signs of velocity // Set acceleration vector to opposite signs of velocity
function sign(x) { function sign(x) {
@ -358,20 +360,32 @@ const KineticPanning = {
if (!this.target) if (!this.target)
return; return;
this.momentums.splice(0); this.momentums = [];
this.target.onKineticEnd(); this.target.onKineticEnd();
this.target = null; this.target = null;
}, },
momentums: [], momentums: [],
record: function kp_record(delta) { record: function kp_record(delta, timestamp) {
// If the panning direction has changed, stop the current activity. this.momentums.push({ 'time': timestamp, 'dx' : delta.x, 'dy' : delta.y });
if (this.target && ((delta.x * this._velocity.x < 0) || },
(delta.y * this._velocity.y < 0)))
this.stop();
this.momentums.push({ 'time': Date.now(), 'dx' : delta.x, 'dy' : delta.y }); isPan: function cp_isPan() {
let dpi = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils)
.displayDPI;
let threshold = Services.prefs.getIntPref('ui.dragThresholdX') / 240 * dpi;
let deltaX = 0;
let deltaY = 0;
let start = this.momentums[0].time;
return this.momentums.slice(1).some(function(momentum) {
deltaX += momentum.dx;
deltaY += momentum.dy;
return (Math.abs(deltaX) > threshold) || (Math.abs(deltaY) > threshold);
});
}, },
_startAnimation: function kp_startAnimation() { _startAnimation: function kp_startAnimation() {

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

@ -151,9 +151,6 @@
@BINPATH@/components/dom_system_b2g.xpt @BINPATH@/components/dom_system_b2g.xpt
#endif #endif
@BINPATH@/components/dom_battery.xpt @BINPATH@/components/dom_battery.xpt
#ifdef MOZ_B2G_BT
@BINPATH@/components/dom_bluetooth.xpt
#endif
@BINPATH@/components/dom_canvas.xpt @BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_core.xpt @BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt @BINPATH@/components/dom_css.xpt

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

@ -1,5 +1,5 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1328822681000"> <blocklist xmlns="http://www.mozilla.org/2006/addons-blocklist" lastupdate="1329176667000">
<emItems> <emItems>
<emItem blockID="i58" id="webmaster@buzzzzvideos.info"> <emItem blockID="i58" id="webmaster@buzzzzvideos.info">
<versionRange minVersion="0" maxVersion="*"> <versionRange minVersion="0" maxVersion="*">
@ -27,8 +27,12 @@
</targetApplication> </targetApplication>
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}"> <emItem blockID="i65" id="activity@facebook.com">
<versionRange minVersion="1.1b1" maxVersion="1.1b1"> <versionRange minVersion="0" maxVersion="*">
</versionRange>
</emItem>
<emItem blockID="i66" id="youtubeer@youtuber.com">
<versionRange minVersion="0" maxVersion="*">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i54" id="applebeegifts@mozilla.doslash.org"> <emItem blockID="i54" id="applebeegifts@mozilla.doslash.org">
@ -122,8 +126,11 @@
<versionRange minVersion="0" maxVersion="*"> <versionRange minVersion="0" maxVersion="*">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i56" id="flash@adobe.com"> <emItem blockID="i23" id="firefox@bandoo.com">
<versionRange minVersion="0" maxVersion="*"> <versionRange minVersion="5.0" maxVersion="5.0" severity="1">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i55" id="youtube@youtube7.com"> <emItem blockID="i55" id="youtube@youtube7.com">
@ -178,11 +185,8 @@
<versionRange minVersion="2.2" maxVersion="2.2"> <versionRange minVersion="2.2" maxVersion="2.2">
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i23" id="firefox@bandoo.com"> <emItem blockID="i56" id="flash@adobe.com">
<versionRange minVersion="5.0" maxVersion="5.0" severity="1"> <versionRange minVersion="0" maxVersion="*">
<targetApplication id="{ec8030f7-c20a-464f-9b0e-13a3a9e97384}">
<versionRange minVersion="3.7a1pre" maxVersion="*" />
</targetApplication>
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}"> <emItem blockID="i45" id="{22119944-ED35-4ab1-910B-E619EA06A115}">
@ -192,6 +196,10 @@
</targetApplication> </targetApplication>
</versionRange> </versionRange>
</emItem> </emItem>
<emItem blockID="i19" id="{46551EC9-40F0-4e47-8E18-8E5CF550CFB8}">
<versionRange minVersion="1.1b1" maxVersion="1.1b1">
</versionRange>
</emItem>
<emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org"> <emItem blockID="i3" id="langpack-vi-VN@firefox.mozilla.org">
<versionRange minVersion="2.0" maxVersion="2.0"> <versionRange minVersion="2.0" maxVersion="2.0">
</versionRange> </versionRange>

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

@ -282,6 +282,7 @@ pref("browser.urlbar.doubleClickSelectsAll", true);
pref("browser.urlbar.doubleClickSelectsAll", false); pref("browser.urlbar.doubleClickSelectsAll", false);
#endif #endif
pref("browser.urlbar.autoFill", false); pref("browser.urlbar.autoFill", false);
pref("browser.urlbar.autoFill.typed", true);
// 0: Match anywhere (e.g., middle of words) // 0: Match anywhere (e.g., middle of words)
// 1: Match on word boundaries and then try matching anywhere // 1: Match on word boundaries and then try matching anywhere
// 2: Match only on word boundaries (e.g., after / or .) // 2: Match only on word boundaries (e.g., after / or .)

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

@ -9053,7 +9053,14 @@ XPCOMUtils.defineLazyGetter(Scratchpad, "ScratchpadManager", function() {
var StyleEditor = { var StyleEditor = {
prefEnabledName: "devtools.styleeditor.enabled", prefEnabledName: "devtools.styleeditor.enabled",
openChrome: function SE_openChrome() /**
* Opens the style editor. If the UI is already open, it will be focused.
*
* @param {CSSStyleSheet} [aSelectedStyleSheet] default Stylesheet.
* @param {Number} [aLine] Line to which the caret should be moved (one-indexed).
* @param {Number} [aCol] Column to which the caret should be moved (one-indexed).
*/
openChrome: function SE_openChrome(aSelectedStyleSheet, aLine, aCol)
{ {
const CHROME_URL = "chrome://browser/content/styleeditor.xul"; const CHROME_URL = "chrome://browser/content/styleeditor.xul";
const CHROME_WINDOW_TYPE = "Tools:StyleEditor"; const CHROME_WINDOW_TYPE = "Tools:StyleEditor";
@ -9067,14 +9074,23 @@ var StyleEditor = {
while (enumerator.hasMoreElements()) { while (enumerator.hasMoreElements()) {
var win = enumerator.getNext(); var win = enumerator.getNext();
if (win.styleEditorChrome.contentWindowID == contentWindowID) { if (win.styleEditorChrome.contentWindowID == contentWindowID) {
if (aSelectedStyleSheet) {
win.styleEditorChrome.selectStyleSheet(aSelectedStyleSheet, aLine, aCol);
}
win.focus(); win.focus();
return win; return win;
} }
} }
let args = {
contentWindow: contentWindow,
selectedStyleSheet: aSelectedStyleSheet,
line: aLine,
col: aCol
};
args.wrappedJSObject = args;
let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank", let chromeWindow = Services.ww.openWindow(null, CHROME_URL, "_blank",
CHROME_WINDOW_FLAGS, CHROME_WINDOW_FLAGS, args);
contentWindow);
chromeWindow.focus(); chromeWindow.focus();
return chromeWindow; return chromeWindow;
} }

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

@ -90,6 +90,7 @@
lightweightthemes="true" lightweightthemes="true"
lightweightthemesfooter="browser-bottombox" lightweightthemesfooter="browser-bottombox"
windowtype="navigator:browser" windowtype="navigator:browser"
macanimationtype="document"
screenX="4" screenY="4" screenX="4" screenY="4"
browsingmode="normal" browsingmode="normal"
persist="screenX screenY width height sizemode"> persist="screenX screenY width height sizemode">

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

@ -1266,6 +1266,12 @@
else { else {
t._animStartTime = Date.now(); t._animStartTime = Date.now();
t.setAttribute("fadein", "true"); t.setAttribute("fadein", "true");
// This call to adjustTabstrip is redundant but needed so that
// when opening a second tab, the first tab's close buttons
// appears immediately rather than when the transition ends.
if (tabContainer.childNodes.length == 2)
tabContainer.adjustTabstrip();
} }
}, 0, this.tabContainer); }, 0, this.tabContainer);
} }
@ -1365,7 +1371,8 @@
// pretend the user typed this so it'll be available till // pretend the user typed this so it'll be available till
// the document successfully loads // the document successfully loads
b.userTypedValue = aURI; if (!isBlankPageURL(aURI))
b.userTypedValue = aURI;
let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE; let flags = Ci.nsIWebNavigation.LOAD_FLAGS_NONE;
if (aAllowThirdPartyFixup) if (aAllowThirdPartyFixup)
@ -1557,15 +1564,26 @@
<parameter name="aCloseWindowFastpath"/> <parameter name="aCloseWindowFastpath"/>
<body> <body>
<![CDATA[ <![CDATA[
if (aTab.closing || this._windowIsClosing) if (aTab.closing ||
aTab._pendingPermitUnload ||
this._windowIsClosing)
return false; return false;
var browser = this.getBrowserForTab(aTab); var browser = this.getBrowserForTab(aTab);
if (!aTabWillBeMoved) { if (!aTabWillBeMoved) {
let ds = browser.docShell; let ds = browser.docShell;
if (ds && ds.contentViewer && !ds.contentViewer.permitUnload()) if (ds && ds.contentViewer) {
return false; // We need to block while calling permitUnload() because it
// processes the event queue and may lead to another removeTab()
// call before permitUnload() even returned.
aTab._pendingPermitUnload = true;
let permitUnload = ds.contentViewer.permitUnload();
delete aTab._pendingPermitUnload;
if (!permitUnload)
return false;
}
} }
var closeWindow = false; var closeWindow = false;
@ -3533,12 +3551,14 @@
// it triggers will correctly update our URL bar. // it triggers will correctly update our URL bar.
this.tabbrowser.selectedTab = newTab; this.tabbrowser.selectedTab = newTab;
} else { } else {
let url = browserDragAndDrop.drop(event, { }); // Pass true to disallow dropping javascript: or data: urls
let url;
try {
url = browserDragAndDrop.drop(event, { }, true);
} catch (ex) {}
// valid urls don't contain spaces ' '; if we have a space it isn't a valid url. // valid urls don't contain spaces ' '; if we have a space it isn't a valid url.
// Also disallow dropping javascript: or data: urls--bail out if (!url || url.indexOf(" ") != -1)
if (!url || !url.length || url.indexOf(" ", 0) != -1 ||
/^\s*(javascript|data):/.test(url))
return; return;
let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground"); let bgLoad = Services.prefs.getBoolPref("browser.tabs.loadInBackground");
@ -4055,7 +4075,7 @@
let alignRight = false; let alignRight = false;
if (getComputedStyle(document.documentElement).direction == "rtl") if (getComputedStyle(document.documentElement).direction == "rtl")
alighRight = !alignRight; alignRight = !alignRight;
let rect = this.getBoundingClientRect(); let rect = this.getBoundingClientRect();
this._mouseTargetRect = { this._mouseTargetRect = {

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

@ -268,6 +268,7 @@ _BROWSER_FILES = \
browser_aboutSyncProgress.js \ browser_aboutSyncProgress.js \
browser_middleMouse_inherit.js \ browser_middleMouse_inherit.js \
redirect_bug623155.sjs \ redirect_bug623155.sjs \
browser_tabDrop.js \
$(NULL) $(NULL)
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT)) ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))

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

@ -0,0 +1,71 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
let newTab = gBrowser.selectedTab = gBrowser.addTab("about:blank", {skipAnimation: true});
registerCleanupFunction(function () {
gBrowser.removeTab(newTab);
});
let scriptLoader = Cc["@mozilla.org/moz/jssubscript-loader;1"].
getService(Ci.mozIJSSubScriptLoader);
let chromeUtils = {};
scriptLoader.loadSubScript("chrome://mochikit/content/tests/SimpleTest/ChromeUtils.js", chromeUtils);
let tabContainer = gBrowser.tabContainer;
var receivedDropCount = 0;
function dropListener() {
receivedDropCount++;
if (receivedDropCount == triggeredDropCount) {
is(openedTabs, validDropCount, "correct number of tabs were opened");
executeSoon(finish);
}
}
tabContainer.addEventListener("drop", dropListener, false);
registerCleanupFunction(function () {
tabContainer.removeEventListener("drop", dropListener, false);
});
var openedTabs = 0;
function tabOpenListener(e) {
openedTabs++;
let tab = e.target;
executeSoon(function () {
gBrowser.removeTab(tab);
});
}
tabContainer.addEventListener("TabOpen", tabOpenListener, false);
registerCleanupFunction(function () {
tabContainer.removeEventListener("TabOpen", tabOpenListener, false);
});
var triggeredDropCount = 0;
var validDropCount = 0;
function drop(text, valid) {
triggeredDropCount++;
if (valid)
validDropCount++;
executeSoon(function () {
// A drop type of "link" onto an existing tab would normally trigger a
// load in that same tab, but tabbrowser code in _getDragTargetTab treats
// drops on the outer edges of a tab differently (loading a new tab
// instead). The events created by synthesizeDrop have all of their
// coordinates set to 0 (screenX/screenY), so they're treated as drops
// on the outer edge of the tab, thus they open new tabs.
chromeUtils.synthesizeDrop(newTab, newTab, [[{type: "text/plain", data: text}]], "link", window, EventUtils);
});
}
// Begin and end with valid drops to make sure we wait for all drops before
// ending the test
drop("mochi.test/first", true);
drop("javascript:'bad'");
drop("jAvascript:'bad'");
drop("space bad");
drop("mochi.test/second", true);
drop("data:text/html,bad");
drop("mochi.test/third", true);
}

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

@ -1,2 +1 @@
MOZ_APP_DISPLAYNAME=Firefox MOZ_APP_DISPLAYNAME=Firefox
MOZ_UA_BUILDID=20100101

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

@ -72,6 +72,7 @@ const Cr = Components.results;
const Cu = Components.utils; const Cu = Components.utils;
Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/XPCOMUtils.jsm");
Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource:///modules/TelemetryStopwatch.jsm");
const STATE_RUNNING_STR = "running"; const STATE_RUNNING_STR = "running";
const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 megabytes const MAX_FILE_SIZE = 100 * 1024 * 1024; // 100 megabytes
@ -127,23 +128,30 @@ SessionStartup.prototype = {
return; return;
// parse the session state into a JS object // parse the session state into a JS object
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0)
if (iniString.charAt(0) == '(')
iniString = iniString.slice(1, -1);
let corruptFile = false;
try { try {
// remove unneeded braces (added for compatibility with Firefox 2.0 and 3.0) this._initialState = JSON.parse(iniString);
if (iniString.charAt(0) == '(') }
iniString = iniString.slice(1, -1); catch (ex) {
debug("The session file contained un-parse-able JSON: " + ex);
// Try to eval.
// evalInSandbox will throw if iniString is not parse-able.
try { try {
this._initialState = JSON.parse(iniString);
}
catch (exJSON) {
var s = new Cu.Sandbox("about:blank", {sandboxName: 'nsSessionStartup'}); var s = new Cu.Sandbox("about:blank", {sandboxName: 'nsSessionStartup'});
this._initialState = Cu.evalInSandbox("(" + iniString + ")", s); this._initialState = Cu.evalInSandbox("(" + iniString + ")", s);
} catch(ex) {
debug("The session file contained un-eval-able JSON: " + ex);
corruptFile = true;
} }
// If this is a normal restore then throw away any previous session
if (!doResumeSessionOnce)
delete this._initialState.lastSessionState;
} }
catch (ex) { debug("The session file is invalid: " + ex); } Services.telemetry.getHistogramById("FX_SESSION_RESTORE_CORRUPT_FILE").add(corruptFile);
// If this is a normal restore then throw away any previous session
if (!doResumeSessionOnce)
delete this._initialState.lastSessionState;
let resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash"); let resumeFromCrash = prefBranch.getBoolPref("sessionstore.resume_from_crash");
let lastSessionCrashed = let lastSessionCrashed =
@ -154,8 +162,7 @@ SessionStartup.prototype = {
// Report shutdown success via telemetry. Shortcoming here are // Report shutdown success via telemetry. Shortcoming here are
// being-killed-by-OS-shutdown-logic, shutdown freezing after // being-killed-by-OS-shutdown-logic, shutdown freezing after
// session restore was written, etc. // session restore was written, etc.
let Telemetry = Cc["@mozilla.org/base/telemetry;1"].getService(Ci.nsITelemetry); Services.telemetry.getHistogramById("SHUTDOWN_OK").add(!lastSessionCrashed);
Telemetry.getHistogramById("SHUTDOWN_OK").add(!lastSessionCrashed);
// set the startup type // set the startup type
if (lastSessionCrashed && resumeFromCrash) if (lastSessionCrashed && resumeFromCrash)
@ -296,9 +303,11 @@ SessionStartup.prototype = {
* @returns a session state string * @returns a session state string
*/ */
_readStateFile: function sss_readStateFile(aFile) { _readStateFile: function sss_readStateFile(aFile) {
TelemetryStopwatch.start("FX_SESSION_RESTORE_READ_FILE_MS");
var stateString = Cc["@mozilla.org/supports-string;1"]. var stateString = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString); createInstance(Ci.nsISupportsString);
stateString.data = this._readFile(aFile) || ""; stateString.data = this._readFile(aFile) || "";
TelemetryStopwatch.finish("FX_SESSION_RESTORE_READ_FILE_MS");
Services.obs.notifyObservers(stateString, "sessionstore-state-read", ""); Services.obs.notifyObservers(stateString, "sessionstore-state-read", "");

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

@ -131,6 +131,7 @@ Cu.import("resource://gre/modules/Services.jsm");
Cu.import("resource://gre/modules/debug.js"); Cu.import("resource://gre/modules/debug.js");
Cu.import("resource:///modules/TelemetryTimestamps.jsm"); Cu.import("resource:///modules/TelemetryTimestamps.jsm");
Cu.import("resource:///modules/TelemetryStopwatch.jsm");
XPCOMUtils.defineLazyGetter(this, "NetUtil", function() { XPCOMUtils.defineLazyGetter(this, "NetUtil", function() {
Cu.import("resource://gre/modules/NetUtil.jsm"); Cu.import("resource://gre/modules/NetUtil.jsm");
@ -3653,6 +3654,8 @@ SessionStoreService.prototype = {
// if we crash. // if we crash.
let pinnedOnly = this._loadState == STATE_RUNNING && !this._resume_from_crash; let pinnedOnly = this._loadState == STATE_RUNNING && !this._resume_from_crash;
TelemetryStopwatch.start("FX_SESSION_RESTORE_COLLECT_DATA_MS");
var oState = this._getCurrentState(aUpdateAll, pinnedOnly); var oState = this._getCurrentState(aUpdateAll, pinnedOnly);
if (!oState) if (!oState)
return; return;
@ -3691,6 +3694,8 @@ SessionStoreService.prototype = {
if (this._lastSessionState) if (this._lastSessionState)
oState.lastSessionState = this._lastSessionState; oState.lastSessionState = this._lastSessionState;
TelemetryStopwatch.finish("FX_SESSION_RESTORE_COLLECT_DATA_MS");
this._saveStateObject(oState); this._saveStateObject(oState);
}, },
@ -3698,9 +3703,11 @@ SessionStoreService.prototype = {
* write a state object to disk * write a state object to disk
*/ */
_saveStateObject: function sss_saveStateObject(aStateObj) { _saveStateObject: function sss_saveStateObject(aStateObj) {
TelemetryStopwatch.start("FX_SESSION_RESTORE_SERIALIZE_DATA_MS");
var stateString = Cc["@mozilla.org/supports-string;1"]. var stateString = Cc["@mozilla.org/supports-string;1"].
createInstance(Ci.nsISupportsString); createInstance(Ci.nsISupportsString);
stateString.data = this._toJSONString(aStateObj); stateString.data = this._toJSONString(aStateObj);
TelemetryStopwatch.finish("FX_SESSION_RESTORE_SERIALIZE_DATA_MS");
Services.obs.notifyObservers(stateString, "sessionstore-state-write", ""); Services.obs.notifyObservers(stateString, "sessionstore-state-write", "");
@ -3809,7 +3816,7 @@ SessionStoreService.prototype = {
argString.data = ""; argString.data = "";
// Build feature string // Build feature string
let features = "chrome,dialog=no,all"; let features = "chrome,dialog=no,macsuppressanimation,all";
let winState = aState.windows[0]; let winState = aState.windows[0];
WINDOW_ATTRIBUTES.forEach(function(aFeature) { WINDOW_ATTRIBUTES.forEach(function(aFeature) {
// Use !isNaN as an easy way to ignore sizemode and check for numbers // Use !isNaN as an easy way to ignore sizemode and check for numbers
@ -4427,6 +4434,7 @@ SessionStoreService.prototype = {
* String data * String data
*/ */
_writeFile: function sss_writeFile(aFile, aData) { _writeFile: function sss_writeFile(aFile, aData) {
TelemetryStopwatch.start("FX_SESSION_RESTORE_WRITE_FILE_MS");
// Initialize the file output stream. // Initialize the file output stream.
var ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"]. var ostream = Cc["@mozilla.org/network/safe-file-output-stream;1"].
createInstance(Ci.nsIFileOutputStream); createInstance(Ci.nsIFileOutputStream);
@ -4442,6 +4450,7 @@ SessionStoreService.prototype = {
var self = this; var self = this;
NetUtil.asyncCopy(istream, ostream, function(rc) { NetUtil.asyncCopy(istream, ostream, function(rc) {
if (Components.isSuccessCode(rc)) { if (Components.isSuccessCode(rc)) {
TelemetryStopwatch.finish("FX_SESSION_RESTORE_WRITE_FILE_MS");
Services.obs.notifyObservers(null, Services.obs.notifyObservers(null,
"sessionstore-state-write-complete", "sessionstore-state-write-complete",
""); "");

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

@ -0,0 +1,24 @@
. $topsrcdir/build/macosx/universal/mozconfig
# Universal builds override the default of browser (bug 575283 comment 29)
ac_add_options --enable-application=browser
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
ac_add_options --enable-codesighs
ac_add_options --disable-install-strip
# Nightlies only since this has a cost in performance
ac_add_options --enable-js-diagnostics
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
mk_add_options MOZ_MAKE_FLAGS="-j12"
ac_add_options --with-macbundlename-prefix=Firefox
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
ac_add_options --with-ccache

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

@ -0,0 +1,20 @@
. $topsrcdir/build/macosx/universal/mozconfig
# Universal builds override the default of browser (bug 575283 comment 29)
ac_add_options --enable-application=browser
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
ac_add_options --enable-official-branding
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
export MOZ_TELEMETRY_REPORTING=1
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j4"
ac_add_options --with-ccache

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

@ -0,0 +1,26 @@
# Just like nightlies, but without tests, not on an update channel, and with
# shark and dtrace enabled
. $topsrcdir/build/macosx/universal/mozconfig
# Universal builds override the default of browser (bug 575283 comment 29)
ac_add_options --enable-application=browser
ac_add_options --disable-tests
ac_add_options --disable-install-strip
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j12"
# shark specific options
ac_add_options --enable-shark
ac_add_options --enable-dtrace
# Need this to prevent name conflicts with the normal nightly build packages
export MOZ_PKG_SPECIAL="shark"
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
ac_add_options --with-ccache

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

@ -0,0 +1,12 @@
. $topsrcdir/build/macosx/mozconfig.leopard
ac_add_options --enable-debug
ac_add_options --enable-trace-malloc
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j12"
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
ac_add_options --with-macbundlename-prefix=Firefox
ac_add_options --with-ccache

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

@ -0,0 +1,17 @@
. $topsrcdir/build/macosx/common
ac_add_options --enable-debug
ac_add_options --enable-trace-malloc
ac_add_options --enable-accessibility
# Enable parallel compiling
mk_add_options MOZ_MAKE_FLAGS="-j12"
# Needed to enable breakpad in application.ini
export MOZILLA_OFFICIAL=1
ac_add_options --with-macbundlename-prefix=Firefox
# Treat warnings as errors in directories with FAIL_ON_WARNINGS.
ac_add_options --enable-warnings-as-errors
ac_add_options --with-ccache

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

@ -0,0 +1,5 @@
ac_add_options --with-l10n-base=../../l10n-central
ac_add_options --enable-official-branding
ac_add_options --enable-update-channel=${MOZ_UPDATE_CHANNEL}
ac_add_options --enable-update-packaging
ac_add_options --with-ccache

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

@ -72,6 +72,7 @@ _BROWSER_TEST_FILES = \
browser_dbg_pause-resume.js \ browser_dbg_pause-resume.js \
browser_dbg_update-editor-mode.js \ browser_dbg_update-editor-mode.js \
browser_dbg_select-line.js \ browser_dbg_select-line.js \
browser_dbg_clean-exit.js \
head.js \ head.js \
$(NULL) $(NULL)

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

@ -0,0 +1,42 @@
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// Test that closing a tab with the debugger in a paused state exits cleanly.
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
const DEBUGGER_TAB_URL = "http://example.com/browser/browser/devtools/" +
"debugger/test/" +
"browser_dbg_debuggerstatement.html";
function test() {
debug_tab_pane(DEBUGGER_TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.debuggerWindow;
testCleanExit();
});
}
function testCleanExit() {
gPane.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
is(gDebugger.StackFrames.activeThread.paused, true,
"Should be paused after the debugger statement.");
gPane._client.addOneTimeListener("tabDetached", function () {
finish();
});
removeTab(gTab);
}}, 0);
});
gTab.linkedBrowser.contentWindow.wrappedJSObject.runDebuggerStatement();
}

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

@ -763,6 +763,9 @@ InspectorUI.prototype = {
this.boundRuleViewChanged = this.ruleViewChanged.bind(this); this.boundRuleViewChanged = this.ruleViewChanged.bind(this);
this.ruleView.element.addEventListener("CssRuleViewChanged", this.ruleView.element.addEventListener("CssRuleViewChanged",
this.boundRuleViewChanged); this.boundRuleViewChanged);
this.cssRuleViewBoundCSSLinkClicked = this.ruleViewCSSLinkClicked.bind(this);
this.ruleView.element.addEventListener("CssRuleViewCSSLinkClicked",
this.cssRuleViewBoundCSSLinkClicked);
doc.documentElement.appendChild(this.ruleView.element); doc.documentElement.appendChild(this.ruleView.element);
this.ruleView.highlight(this.selection); this.ruleView.highlight(this.selection);
@ -800,6 +803,30 @@ InspectorUI.prototype = {
this.nodeChanged(this.ruleViewObject); this.nodeChanged(this.ruleViewObject);
}, },
/**
* When a css link is clicked this method is called in order to either:
* 1. Open the link in view source (for element style attributes)
* 2. Open the link in the style editor
*
* @param aEvent The event containing the style rule to act on
*/
ruleViewCSSLinkClicked: function(aEvent)
{
if (!this.chromeWin) {
return;
}
let rule = aEvent.detail.rule;
let styleSheet = rule.sheet;
if (styleSheet) {
this.chromeWin.StyleEditor.openChrome(styleSheet, rule.ruleLine);
} else {
let href = rule.elementStyle.element.ownerDocument.location.href;
this.chromeWin.openUILinkIn("view-source:" + href, "window");
}
},
/** /**
* Destroy the rule view. * Destroy the rule view.
*/ */
@ -811,6 +838,8 @@ InspectorUI.prototype = {
if (this.ruleView) { if (this.ruleView) {
this.ruleView.element.removeEventListener("CssRuleViewChanged", this.ruleView.element.removeEventListener("CssRuleViewChanged",
this.boundRuleViewChanged); this.boundRuleViewChanged);
this.ruleView.element.removeEventListener("CssRuleViewCSSLinkClicked",
this.cssRuleViewBoundCSSLinkClicked);
delete boundRuleViewChanged; delete boundRuleViewChanged;
this.ruleView.clear(); this.ruleView.clear();
delete this.ruleView; delete this.ruleView;

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

@ -51,6 +51,7 @@
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
title="&window.title;" title="&window.title;"
windowtype="devtools:scratchpad" windowtype="devtools:scratchpad"
macanimationtype="document"
screenX="4" screenY="4" screenX="4" screenY="4"
width="640" height="480" width="640" height="480"
persist="screenX screenY width height sizemode"> persist="screenX screenY width height sizemode">

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

@ -78,6 +78,9 @@ const ORION_EVENTS = {
Selection: "Selection", Selection: "Selection",
Focus: "Focus", Focus: "Focus",
Blur: "Blur", Blur: "Blur",
MouseOver: "MouseOver",
MouseOut: "MouseOut",
MouseMove: "MouseMove",
}; };
/** /**

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

@ -161,6 +161,30 @@ SourceEditor.EVENTS = {
* The blur event is fired when the editor goes out of focus. * The blur event is fired when the editor goes out of focus.
*/ */
BLUR: "Blur", BLUR: "Blur",
/**
* The MouseMove event is sent when the user moves the mouse over a line
* annotation. The event object properties:
* - event - the DOM mousemove event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_MOVE: "MouseMove",
/**
* The MouseOver event is sent when the mouse pointer enters a line
* annotation. The event object properties:
* - event - the DOM mouseover event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_OVER: "MouseOver",
/**
* This MouseOut event is sent when the mouse pointer exits a line
* annotation. The event object properties:
* - event - the DOM mouseout event object.
* - x and y - the mouse coordinates relative to the document being edited.
*/
MOUSE_OUT: "MouseOut",
}; };
/** /**

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

@ -55,6 +55,7 @@ _BROWSER_TEST_FILES = \
browser_bug687160_line_api.js \ browser_bug687160_line_api.js \
browser_bug650345_find.js \ browser_bug650345_find.js \
browser_bug703692_focus_blur.js \ browser_bug703692_focus_blur.js \
browser_bug725388_mouse_events.js \
head.js \ head.js \
libs:: $(_BROWSER_TEST_FILES) libs:: $(_BROWSER_TEST_FILES)

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

@ -0,0 +1,97 @@
/* 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 tempScope = {};
Cu.import("resource:///modules/source-editor.jsm", tempScope);
let SourceEditor = tempScope.SourceEditor;
let testWin;
let editor;
function test()
{
waitForExplicitFinish();
const windowUrl = "data:text/xml,<?xml version='1.0'?>" +
"<window xmlns='http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul'" +
" title='Test for bug 725388' width='600' height='500'><hbox flex='1'/></window>";
const windowFeatures = "chrome,titlebar,toolbar,centerscreen,resizable,dialog=no";
testWin = Services.ww.openWindow(null, windowUrl, "_blank", windowFeatures, null);
testWin.addEventListener("load", function onWindowLoad() {
testWin.removeEventListener("load", onWindowLoad, false);
waitForFocus(initEditor, testWin);
}, false);
}
function initEditor()
{
let hbox = testWin.document.querySelector("hbox");
editor = new SourceEditor();
editor.init(hbox, {}, editorLoaded);
}
function editorLoaded()
{
let text = "BrowserBug - 725388";
editor.setText(text);
let target = editor.editorElement;
let targetWin = target.ownerDocument.defaultView;
let mMoveHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
is(aEvent.event.type, "mousemove", "MouseMove event fired.");
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
waitForFocus(function() {
EventUtils.synthesizeMouse(target, 10, 10, {type: "mouseover"},
targetWin);
});
};
let mOverHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OVER, mOverHandler);
is(aEvent.event.type, "mouseover", "MouseOver event fired.");
editor.addEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
waitForFocus(function() {
EventUtils.synthesizeMouse(target, -10, -10, {type: "mouseout"},
targetWin);
}, targetWin);
};
let mOutHandler = function(aEvent) {
editor.removeEventListener(SourceEditor.EVENTS.MOUSE_OUT, mOutHandler);
is(aEvent.event.type, "mouseout", "MouseOut event fired.");
executeSoon(testEnd);
};
editor.addEventListener(SourceEditor.EVENTS.MOUSE_MOVE, mMoveHandler);
editor.focus();
waitForFocus(function() {
EventUtils.synthesizeMouse(target, 1, 1, {type: "mousemove"},
targetWin);
}, targetWin);
}
function testEnd()
{
if (editor) {
editor.destroy();
}
if (testWin) {
testWin.close();
}
testWin = editor = null;
waitForFocus(finish, window);
}

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

@ -146,7 +146,7 @@ StyleEditor.prototype = {
*/ */
get styleSheet() get styleSheet()
{ {
assert(this._styleSheet, "StyleSheet must be loaded first.") assert(this._styleSheet, "StyleSheet must be loaded first.");
return this._styleSheet; return this._styleSheet;
}, },
@ -921,9 +921,11 @@ StyleEditor.prototype = {
aArgs.unshift(this); aArgs.unshift(this);
} }
// copy the list of listeners to allow adding/removing listeners in handlers
let listeners = this._actionListeners.concat();
// trigger all listeners that have this action handler // trigger all listeners that have this action handler
for (let i = 0; i < this._actionListeners.length; ++i) { for (let i = 0; i < listeners.length; ++i) {
let listener = this._actionListeners[i]; let listener = listeners[i];
let actionHandler = listener["on" + aName]; let actionHandler = listener["on" + aName];
if (actionHandler) { if (actionHandler) {
actionHandler.apply(listener, aArgs); actionHandler.apply(listener, aArgs);

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

@ -270,9 +270,11 @@ StyleEditorChrome.prototype = {
aArgs.unshift(this); aArgs.unshift(this);
} }
// trigger all listeners that have this named handler // copy the list of listeners to allow adding/removing listeners in handlers
for (let i = 0; i < this._listeners.length; ++i) { let listeners = this._listeners.concat();
let listener = this._listeners[i]; // trigger all listeners that have this named handler.
for (let i = 0; i < listeners.length; i++) {
let listener = listeners[i];
let handler = listener["on" + aName]; let handler = listener["on" + aName];
if (handler) { if (handler) {
handler.apply(listener, aArgs); handler.apply(listener, aArgs);
@ -329,10 +331,10 @@ StyleEditorChrome.prototype = {
{ {
this._resetChrome(); this._resetChrome();
this._document.title = _("chromeWindowTitle",
this.contentDocument.title || this.contentDocument.location.href);
let document = this.contentDocument; let document = this.contentDocument;
this._document.title = _("chromeWindowTitle",
document.title || document.location.href);
for (let i = 0; i < document.styleSheets.length; ++i) { for (let i = 0; i < document.styleSheets.length; ++i) {
let styleSheet = document.styleSheets[i]; let styleSheet = document.styleSheets[i];
@ -352,6 +354,79 @@ StyleEditorChrome.prototype = {
}, this); }, this);
}, },
/**
* selects a stylesheet and optionally moves the cursor to a selected line
*
* @param {CSSStyleSheet} [aSheet]
* Stylesheet that should be selected. If a stylesheet is not passed
* and the editor is not initialized we focus the first stylesheet. If
* a stylesheet is not passed and the editor is initialized we ignore
* the call.
* @param {Number} [aLine]
* Line to which the caret should be moved (one-indexed).
* @param {Number} [aCol]
* Column to which the caret should be moved (one-indexed).
*/
selectStyleSheet: function SEC_selectSheet(aSheet, aLine, aCol)
{
let select = function DEC_select(aEditor) {
let summary = aSheet ? this.getSummaryElementForEditor(aEditor)
: this._view.getSummaryElementByOrdinal(0);
let setCaret = false;
if (aLine || aCol) {
aLine = aLine || 1;
aCol = aCol || 1;
setCaret = true;
}
if (!aEditor.sourceEditor) {
// If a line or column was specified we move the caret appropriately.
if (setCaret) {
aEditor.addActionListener({
onAttach: function SEC_selectSheet_onAttach()
{
aEditor.removeActionListener(this);
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
}
});
}
this._view.activeSummary = summary;
} else {
this._view.activeSummary = summary;
// If a line or column was specified we move the caret appropriately.
if (setCaret) {
aEditor.sourceEditor.setCaretPosition(aLine - 1, aCol - 1);
}
}
}.bind(this);
if (!this.editors.length) {
// We are in the main initialization phase so we wait for the editor
// containing the target stylesheet to be added and select the target
// stylesheet, optionally moving the cursor to a selected line.
this.addChromeListener({
onEditorAdded: function SEC_selectSheet_onEditorAdded(aChrome, aEditor) {
if ((!aSheet && aEditor.styleSheetIndex == 0) ||
aEditor.styleSheet == aSheet) {
aChrome.removeChromeListener(this);
select(aEditor);
}
}
});
} else if (aSheet) {
// We are already initialized and a stylesheet has been specified. Here
// we iterate through the editors and select the one containing the target
// stylesheet, optionally moving the cursor to a selected line.
for each (let editor in this.editors) {
if (editor.styleSheet == aSheet) {
select(editor);
break;
}
}
}
},
/** /**
* Disable all UI, effectively making editors read-only. * Disable all UI, effectively making editors read-only.
* This is automatically called when no content window is attached. * This is automatically called when no content window is attached.
@ -455,9 +530,8 @@ StyleEditorChrome.prototype = {
} }
}, false); }, false);
// autofocus the first or new stylesheet // autofocus new stylesheets
if (editor.styleSheetIndex == 0 || if (editor.hasFlag(StyleEditorFlags.NEW)) {
editor.hasFlag(StyleEditorFlags.NEW)) {
this._view.activeSummary = aSummary; this._view.activeSummary = aSummary;
} }

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

@ -132,8 +132,10 @@
<xul:script type="application/javascript"><![CDATA[ <xul:script type="application/javascript"><![CDATA[
Components.utils.import("resource:///modules/devtools/StyleEditorChrome.jsm"); Components.utils.import("resource:///modules/devtools/StyleEditorChrome.jsm");
let chromeRoot = document.getElementById("style-editor-chrome"); let chromeRoot = document.getElementById("style-editor-chrome");
let contentWindow = window.arguments[0]; let args = window.arguments[0].wrappedJSObject;
let contentWindow = args.contentWindow;
let chrome = new StyleEditorChrome(chromeRoot, contentWindow); let chrome = new StyleEditorChrome(chromeRoot, contentWindow);
chrome.selectStyleSheet(args.selectedStyleSheet, args.line, args.col);
window.styleEditorChrome = chrome; window.styleEditorChrome = chrome;
]]></xul:script> ]]></xul:script>
</xul:window> </xul:window>

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

@ -51,6 +51,7 @@ _BROWSER_TEST_FILES = \
browser_styleeditor_init.js \ browser_styleeditor_init.js \
browser_styleeditor_loading.js \ browser_styleeditor_loading.js \
browser_styleeditor_new.js \ browser_styleeditor_new.js \
browser_styleeditor_passedinsheet.js \
browser_styleeditor_pretty.js \ browser_styleeditor_pretty.js \
browser_styleeditor_readonly.js \ browser_styleeditor_readonly.js \
browser_styleeditor_reopen.js \ browser_styleeditor_reopen.js \

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

@ -0,0 +1,61 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
const TESTCASE_URI = TEST_BASE + "simple.html";
const LINE = 6;
const COL = 2;
let editor = null;
let sheet = null;
function test()
{
waitForExplicitFinish();
gBrowser.selectedBrowser.addEventListener("load", function () {
gBrowser.selectedBrowser.removeEventListener("load", arguments.callee, true);
run();
}, true);
content.location = TESTCASE_URI;
}
function run()
{
sheet = content.document.styleSheets[1];
launchStyleEditorChrome(function attachListeners(aChrome) {
aChrome.addChromeListener({
onEditorAdded: checkSourceEditor
});
}, sheet, LINE, COL);
}
function checkSourceEditor(aChrome, aEditor)
{
if (!aEditor.sourceEditor) {
aEditor.addActionListener({
onAttach: function (aEditor) {
aEditor.removeActionListener(this);
validate(aEditor);
}
});
} else {
validate(aEditor);
}
}
function validate(aEditor)
{
info("validating style editor");
let sourceEditor = aEditor.sourceEditor;
let caretPosition = sourceEditor.getCaretPosition();
is(caretPosition.line, LINE - 1, "caret row is correct"); // index based
is(caretPosition.col, COL - 1, "caret column is correct");
is(aEditor.styleSheet, sheet, "loaded stylesheet matches document stylesheet");
finishUp();
}
function finishUp()
{
editor = sheet = null;
finish();
}

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

@ -19,9 +19,9 @@ function cleanup()
} }
} }
function launchStyleEditorChrome(aCallback) function launchStyleEditorChrome(aCallback, aSheet, aLine, aCol)
{ {
gChromeWindow = StyleEditor.openChrome(); gChromeWindow = StyleEditor.openChrome(aSheet, aLine, aCol);
if (gChromeWindow.document.readyState != "complete") { if (gChromeWindow.document.readyState != "complete") {
gChromeWindow.addEventListener("load", function onChromeLoad() { gChromeWindow.addEventListener("load", function onChromeLoad() {
gChromeWindow.removeEventListener("load", onChromeLoad, true); gChromeWindow.removeEventListener("load", onChromeLoad, true);
@ -34,12 +34,12 @@ function launchStyleEditorChrome(aCallback)
} }
} }
function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback) function addTabAndLaunchStyleEditorChromeWhenLoaded(aCallback, aSheet, aLine, aCol)
{ {
gBrowser.selectedTab = gBrowser.addTab(); gBrowser.selectedTab = gBrowser.addTab();
gBrowser.selectedBrowser.addEventListener("load", function onLoad() { gBrowser.selectedBrowser.addEventListener("load", function onLoad() {
gBrowser.selectedBrowser.removeEventListener("load", onLoad, true); gBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
launchStyleEditorChrome(aCallback); launchStyleEditorChrome(aCallback, aSheet, aLine, aCol);
}, true); }, true);
} }

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

@ -273,6 +273,7 @@ CssHtmlTree.prototype = {
this._matchedProperties = null; this._matchedProperties = null;
if (this.htmlComplete) { if (this.htmlComplete) {
this.refreshSourceFilter();
this.refreshPanel(); this.refreshPanel();
} else { } else {
if (this._refreshProcess) { if (this._refreshProcess) {
@ -281,6 +282,9 @@ CssHtmlTree.prototype = {
CssHtmlTree.processTemplate(this.templateRoot, this.root, this); CssHtmlTree.processTemplate(this.templateRoot, this.root, this);
// Refresh source filter ... this must be done after templateRoot has been
// processed.
this.refreshSourceFilter();
this.numVisibleProperties = 0; this.numVisibleProperties = 0;
let fragment = this.doc.createDocumentFragment(); let fragment = this.doc.createDocumentFragment();
this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, { this._refreshProcess = new UpdateProcess(this.win, CssHtmlTree.propertyNames, {
@ -362,21 +366,28 @@ CssHtmlTree.prototype = {
}, },
/** /**
* The change event handler for the onlyUserStyles checkbox. When * The change event handler for the onlyUserStyles checkbox.
* onlyUserStyles.checked is true we do not display properties that have no
* matched selectors, and we do not display UA styles. If .checked is false we
* do display even properties with no matched selectors, and we include the UA
* styles.
* *
* @param {Event} aEvent the DOM Event object. * @param {Event} aEvent the DOM Event object.
*/ */
onlyUserStylesChanged: function CssHtmltree_onlyUserStylesChanged(aEvent) onlyUserStylesChanged: function CssHtmltree_onlyUserStylesChanged(aEvent)
{
this.refreshSourceFilter();
this.refreshPanel();
},
/**
* When onlyUserStyles.checked is true we only display properties that have
* matched selectors and have been included by the document or one of the
* document's stylesheets. If .checked is false we display all properties
* including those that come from UA stylesheets.
*/
refreshSourceFilter: function CssHtmlTree_setSourceFilter()
{ {
this._matchedProperties = null; this._matchedProperties = null;
this.cssLogic.sourceFilter = this.showOnlyUserStyles ? this.cssLogic.sourceFilter = this.showOnlyUserStyles ?
CssLogic.FILTER.ALL : CssLogic.FILTER.ALL :
CssLogic.FILTER.UA; CssLogic.FILTER.UA;
this.refreshPanel();
}, },
/** /**
@ -974,4 +985,24 @@ SelectorView.prototype = {
return result; return result;
}, },
/**
* When a css link is clicked this method is called in order to either:
* 1. Open the link in view source (for element style attributes).
* 2. Open the link in the style editor.
*
* @param aEvent The click event
*/
openStyleEditor: function(aEvent)
{
if (this.selectorInfo.selector._cssRule._cssSheet) {
let styleSheet = this.selectorInfo.selector._cssRule._cssSheet.domSheet;
let line = this.selectorInfo.ruleLine;
this.tree.win.StyleEditor.openChrome(styleSheet, line);
} else {
let href = this.selectorInfo.sourceElement.ownerDocument.location.href;
this.tree.win.openUILinkIn("view-source:" + href, "window");
}
},
}; };

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

@ -232,7 +232,7 @@ CssLogic.prototype = {
// Update the CssSheet objects. // Update the CssSheet objects.
this.forEachSheet(function(aSheet) { this.forEachSheet(function(aSheet) {
aSheet._sheetAllowed = -1; aSheet._sheetAllowed = -1;
if (!aSheet.systemSheet && aSheet.sheetAllowed) { if (aSheet.contentSheet && aSheet.sheetAllowed) {
ruleCount += aSheet.ruleCount; ruleCount += aSheet.ruleCount;
} }
}, this); }, this);
@ -345,7 +345,7 @@ CssLogic.prototype = {
let sheets = []; let sheets = [];
this.forEachSheet(function (aSheet) { this.forEachSheet(function (aSheet) {
if (!aSheet.systemSheet) { if (aSheet.contentSheet) {
sheets.push(aSheet); sheets.push(aSheet);
} }
}, this); }, this);
@ -395,7 +395,7 @@ CssLogic.prototype = {
} }
sheet = new CssSheet(this, aDomSheet, aIndex); sheet = new CssSheet(this, aDomSheet, aIndex);
if (sheet.sheetAllowed && !sheet.systemSheet) { if (sheet.sheetAllowed && sheet.contentSheet) {
this._ruleCount += sheet.ruleCount; this._ruleCount += sheet.ruleCount;
} }
@ -569,7 +569,7 @@ CssLogic.prototype = {
this.forEachSheet(function (aSheet) { this.forEachSheet(function (aSheet) {
// We do not show unmatched selectors from system stylesheets // We do not show unmatched selectors from system stylesheets
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) { if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
return; return;
} }
@ -664,7 +664,7 @@ CssLogic.prototype = {
sheet._passId = this._passId; sheet._passId = this._passId;
} }
if (filter !== CssLogic.FILTER.UA && sheet.systemSheet) { if (filter === CssLogic.FILTER.ALL && !sheet.contentSheet) {
continue; continue;
} }
@ -710,7 +710,7 @@ CssLogic.prototype = {
let result = {}; let result = {};
this.forSomeSheets(function (aSheet) { this.forSomeSheets(function (aSheet) {
if (aSheet.systemSheet || aSheet.disabled || !aSheet.mediaMatches) { if (!aSheet.contentSheet || aSheet.disabled || !aSheet.mediaMatches) {
return false; return false;
} }
@ -865,29 +865,23 @@ XPCOMUtils.defineLazyGetter(CssLogic, "_strings", function() Services.strings
.createBundle("chrome://browser/locale/devtools/styleinspector.properties")); .createBundle("chrome://browser/locale/devtools/styleinspector.properties"));
/** /**
* Is the given property sheet a system (user agent) stylesheet? * Is the given property sheet a content stylesheet?
* *
* @param {CSSStyleSheet} aSheet a stylesheet * @param {CSSStyleSheet} aSheet a stylesheet
* @return {boolean} true if the given stylesheet is a system stylesheet or * @return {boolean} true if the given stylesheet is a content stylesheet,
* false otherwise. * false otherwise.
*/ */
CssLogic.isSystemStyleSheet = function CssLogic_isSystemStyleSheet(aSheet) CssLogic.isContentStylesheet = function CssLogic_isContentStylesheet(aSheet)
{ {
if (!aSheet) { // All sheets with owner nodes have been included by content.
if (aSheet.ownerNode) {
return true; return true;
} }
let url = aSheet.href; // If the sheet has a CSSImportRule we need to check the parent stylesheet.
if (aSheet.ownerRule instanceof Ci.nsIDOMCSSImportRule) {
if (!url) return false; return CssLogic.isContentStylesheet(aSheet.parentStyleSheet);
if (url.length === 0) return true; }
// Check for http[s]
if (url[0] === 'h') return false;
if (url.substr(0, 9) === "resource:") return true;
if (url.substr(0, 7) === "chrome:") return true;
if (url === "XPCSafeJSObjectWrapper.cpp") return true;
if (url.substr(0, 6) === "about:") return true;
return false; return false;
}; };
@ -942,7 +936,7 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
{ {
this._cssLogic = aCssLogic; this._cssLogic = aCssLogic;
this.domSheet = aDomSheet; this.domSheet = aDomSheet;
this.index = this.systemSheet ? -100 * aIndex : aIndex; this.index = this.contentSheet ? aIndex : -100 * aIndex;
// Cache of the sheets href. Cached by the getter. // Cache of the sheets href. Cached by the getter.
this._href = null; this._href = null;
@ -960,21 +954,21 @@ function CssSheet(aCssLogic, aDomSheet, aIndex)
CssSheet.prototype = { CssSheet.prototype = {
_passId: null, _passId: null,
_systemSheet: null, _contentSheet: null,
_mediaMatches: null, _mediaMatches: null,
/** /**
* Tells if the stylesheet is provided by the browser or not. * Tells if the stylesheet is provided by the browser or not.
* *
* @return {boolean} true if this is a browser-provided stylesheet, or false * @return {boolean} false if this is a browser-provided stylesheet, or true
* otherwise. * otherwise.
*/ */
get systemSheet() get contentSheet()
{ {
if (this._systemSheet === null) { if (this._contentSheet === null) {
this._systemSheet = CssLogic.isSystemStyleSheet(this.domSheet); this._contentSheet = CssLogic.isContentStylesheet(this.domSheet);
} }
return this._systemSheet; return this._contentSheet;
}, },
/** /**
@ -1048,7 +1042,7 @@ CssSheet.prototype = {
this._sheetAllowed = true; this._sheetAllowed = true;
let filter = this._cssLogic.sourceFilter; let filter = this._cssLogic.sourceFilter;
if (filter === CssLogic.FILTER.ALL && this.systemSheet) { if (filter === CssLogic.FILTER.ALL && !this.contentSheet) {
this._sheetAllowed = false; this._sheetAllowed = false;
} }
if (filter !== CssLogic.FILTER.ALL && filter !== CssLogic.FILTER.UA) { if (filter !== CssLogic.FILTER.ALL && filter !== CssLogic.FILTER.UA) {
@ -1202,13 +1196,13 @@ function CssRule(aCssSheet, aDomRule, aElement)
this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule); this.line = this._cssSheet._cssLogic.domUtils.getRuleLine(this._domRule);
this.source = this._cssSheet.shortSource + ":" + this.line; this.source = this._cssSheet.shortSource + ":" + this.line;
this.href = this._cssSheet.href; this.href = this._cssSheet.href;
this.systemRule = this._cssSheet.systemSheet; this.contentRule = this._cssSheet.contentSheet;
} else if (aElement) { } else if (aElement) {
this._selectors = [ new CssSelector(this, "@element.style") ]; this._selectors = [ new CssSelector(this, "@element.style") ];
this.line = -1; this.line = -1;
this.source = CssLogic.l10n("rule.sourceElement"); this.source = CssLogic.l10n("rule.sourceElement");
this.href = "#"; this.href = "#";
this.systemRule = false; this.contentRule = true;
this.sourceElement = aElement; this.sourceElement = aElement;
} }
} }
@ -1396,12 +1390,12 @@ CssSelector.prototype = {
/** /**
* Check if the selector comes from a browser-provided stylesheet. * Check if the selector comes from a browser-provided stylesheet.
* *
* @return {boolean} true if the selector comes from a browser-provided * @return {boolean} true if the selector comes from a content-provided
* stylesheet, or false otherwise. * stylesheet, or false otherwise.
*/ */
get systemRule() get contentRule()
{ {
return this._cssRule.systemRule; return this._cssRule.contentRule;
}, },
/** /**
@ -1794,12 +1788,12 @@ function CssSelectorInfo(aSelector, aProperty, aValue, aStatus)
4 important 4 important
5 inline important 5 inline important
*/ */
let scorePrefix = this.systemRule ? 0 : 2; let scorePrefix = this.contentRule ? 2 : 0;
if (this.elementStyle) { if (this.elementStyle) {
scorePrefix++; scorePrefix++;
} }
if (this.important) { if (this.important) {
scorePrefix += this.systemRule ? 1 : 2; scorePrefix += this.contentRule ? 2 : 1;
} }
this.specificityScore = "" + scorePrefix + this.specificity.ids + this.specificityScore = "" + scorePrefix + this.specificity.ids +
@ -1902,9 +1896,9 @@ CssSelectorInfo.prototype = {
* @return {boolean} true if the selector comes from a browser-provided * @return {boolean} true if the selector comes from a browser-provided
* stylesheet, or false otherwise. * stylesheet, or false otherwise.
*/ */
get systemRule() get contentRule()
{ {
return this.selector.systemRule; return this.selector.contentRule;
}, },
/** /**
@ -1916,8 +1910,8 @@ CssSelectorInfo.prototype = {
*/ */
compareTo: function CssSelectorInfo_compareTo(aThat) compareTo: function CssSelectorInfo_compareTo(aThat)
{ {
if (this.systemRule && !aThat.systemRule) return 1; if (!this.contentRule && aThat.contentRule) return 1;
if (!this.systemRule && aThat.systemRule) return -1; if (this.contentRule && !aThat.contentRule) return -1;
if (this.elementStyle && !aThat.elementStyle) { if (this.elementStyle && !aThat.elementStyle) {
if (!this.important && aThat.important) return 1; if (!this.important && aThat.important) return 1;

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

@ -38,7 +38,7 @@
* *
* ***** END LICENSE BLOCK ***** */ * ***** END LICENSE BLOCK ***** */
"use strict" "use strict";
const Cc = Components.classes; const Cc = Components.classes;
const Ci = Components.interfaces; const Ci = Components.interfaces;
@ -181,8 +181,8 @@ ElementStyle.prototype = {
let domRule = domRules.GetElementAt(i); let domRule = domRules.GetElementAt(i);
// XXX: Optionally provide access to system sheets. // XXX: Optionally provide access to system sheets.
let systemSheet = CssLogic.isSystemStyleSheet(domRule.parentStyleSheet); let contentSheet = CssLogic.isContentStylesheet(domRule.parentStyleSheet);
if (systemSheet) { if (!contentSheet) {
continue; continue;
} }
@ -324,7 +324,7 @@ ElementStyle.prototype = {
aProp.overridden = overridden; aProp.overridden = overridden;
return dirty; return dirty;
} }
} };
/** /**
* A single style rule or declaration. * A single style rule or declaration.
@ -358,11 +358,9 @@ Rule.prototype = {
if (this._title) { if (this._title) {
return this._title; return this._title;
} }
let sheet = this.domRule ? this.domRule.parentStyleSheet : null; this._title = CssLogic.shortSource(this.sheet);
this._title = CssLogic.shortSource(sheet);
if (this.domRule) { if (this.domRule) {
let line = this.elementStyle.domUtils.getRuleLine(this.domRule); this._title += ":" + this.ruleLine;
this._title += ":" + line;
} }
if (this.inherited) { if (this.inherited) {
@ -378,6 +376,26 @@ Rule.prototype = {
return this._title; return this._title;
}, },
/**
* The rule's stylesheet.
*/
get sheet()
{
return this.domRule ? this.domRule.parentStyleSheet : null;
},
/**
* The rule's line within a stylesheet
*/
get ruleLine()
{
if (!this.sheet) {
// No stylesheet, no ruleLine
return null;
}
return this.elementStyle.domUtils.getRuleLine(this.domRule);
},
/** /**
* Create a new TextProperty to include in the rule. * Create a new TextProperty to include in the rule.
* *
@ -530,7 +548,7 @@ Rule.prototype = {
this.textProps.push(textProp); this.textProps.push(textProp);
} }
}, },
} };
/** /**
* A single property in a rule's cssText. * A single property in a rule's cssText.
@ -618,7 +636,7 @@ TextProperty.prototype = {
{ {
this.rule.removeProperty(this); this.rule.removeProperty(this);
} }
} };
/** /**
@ -643,7 +661,7 @@ TextProperty.prototype = {
* apply to a given element. After construction, the 'element' * apply to a given element. After construction, the 'element'
* property will be available with the user interface. * property will be available with the user interface.
* *
* @param Document aDocument * @param Document aDoc
* The document that will contain the rule view. * The document that will contain the rule view.
* @param object aStore * @param object aStore
* The CSS rule view can use this object to store metadata * The CSS rule view can use this object to store metadata
@ -655,7 +673,6 @@ function CssRuleView(aDoc, aStore)
{ {
this.doc = aDoc; this.doc = aDoc;
this.store = aStore; this.store = aStore;
this.element = this.doc.createElementNS(XUL_NS, "vbox"); this.element = this.doc.createElementNS(XUL_NS, "vbox");
this.element.setAttribute("tabindex", "0"); this.element.setAttribute("tabindex", "0");
this.element.classList.add("ruleview"); this.element.classList.add("ruleview");
@ -768,6 +785,14 @@ RuleEditor.prototype = {
class: "ruleview-rule-source", class: "ruleview-rule-source",
textContent: this.rule.title textContent: this.rule.title
}); });
source.addEventListener("click", function() {
let rule = this.rule;
let evt = this.doc.createEvent("CustomEvent");
evt.initCustomEvent("CssRuleViewCSSLinkClicked", true, false, {
rule: rule,
});
this.element.dispatchEvent(evt);
}.bind(this));
let code = createChild(this.element, "div", { let code = createChild(this.element, "div", {
class: "ruleview-code" class: "ruleview-code"
@ -1094,8 +1119,6 @@ TextPropertyEditor.prototype = {
_parseValue: function TextPropertyEditor_parseValue(aValue) _parseValue: function TextPropertyEditor_parseValue(aValue)
{ {
let pieces = aValue.split("!", 2); let pieces = aValue.split("!", 2);
let value = pieces[0];
let priority = pieces.length > 1 ? pieces[1] : "";
return { return {
value: pieces[0].trim(), value: pieces[0].trim(),
priority: (pieces.length > 1 ? pieces[1].trim() : "") priority: (pieces.length > 1 ? pieces[1].trim() : "")

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

@ -114,7 +114,7 @@ To visually debug the templates without running firefox, alter the display:none
${selector.humanReadableText(__element)} ${selector.humanReadableText(__element)}
</td> </td>
<td class="rule-link"> <td class="rule-link">
<a target="_blank" href="view-source:${selector.selectorInfo.href}" class="link" <a target="_blank" onclick="${selector.openStyleEditor}" class="link"
title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a> title="${selector.selectorInfo.href}">${selector.selectorInfo.source}</a>
</td> </td>
</tr> </tr>

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

@ -59,11 +59,19 @@ _BROWSER_TEST_FILES = \
browser_ruleview_manipulation.js \ browser_ruleview_manipulation.js \
browser_ruleview_override.js \ browser_ruleview_override.js \
browser_ruleview_ui.js \ browser_ruleview_ui.js \
browser_bug705707_is_content_stylesheet.js \
head.js \ head.js \
$(NULL) $(NULL)
_BROWSER_TEST_PAGES = \ _BROWSER_TEST_PAGES = \
browser_bug683672.html \ browser_bug683672.html \
browser_bug705707_is_content_stylesheet.html \
browser_bug705707_is_content_stylesheet_imported.css \
browser_bug705707_is_content_stylesheet_imported2.css \
browser_bug705707_is_content_stylesheet_linked.css \
browser_bug705707_is_content_stylesheet_script.css \
browser_bug705707_is_content_stylesheet.xul \
browser_bug705707_is_content_stylesheet_xul.css \
$(NULL) $(NULL)
libs:: $(_BROWSER_TEST_FILES) libs:: $(_BROWSER_TEST_FILES)

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

@ -0,0 +1,33 @@
<html>
<head>
<title>test</title>
<link href="./browser_bug705707_is_content_stylesheet_linked.css" rel="stylesheet" type="text/css">
<script>
// Load script.css
function loadCSS() {
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = "./browser_bug705707_is_content_stylesheet_script.css";
document.getElementsByTagName('head')[0].appendChild(link);
}
</script>
<style>
table {
border: 1px solid #000;
}
</style>
</head>
<body onload="loadCSS();">
<table id="target">
<tr>
<td>
<h3>Simple test</h3>
</td>
</tr>
</table>
</body>
</html>

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

@ -0,0 +1,100 @@
/* vim: set ts=2 et sw=2 tw=80: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
// Tests that the correct stylesheets origins are identified in HTML & XUL
// stylesheets
let doc;
const TEST_URI = "http://example.com/browser/browser/devtools/styleinspector/" +
"test/browser_bug705707_is_content_stylesheet.html";
const TEST_URI2 = "http://example.com/browser/browser/devtools/styleinspector/" +
"test/browser_bug705707_is_content_stylesheet.xul";
const XUL_URI = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService)
.newURI(TEST_URI2, null, null);
let tempScope = {};
Cu.import("resource:///modules/devtools/CssLogic.jsm", tempScope);
let CssLogic = tempScope.CssLogic;
function test()
{
waitForExplicitFinish();
addTab(TEST_URI);
browser.addEventListener("load", htmlLoaded, true);
}
function htmlLoaded()
{
browser.removeEventListener("load", htmlLoaded, true);
doc = content.document;
testFromHTML()
}
function testFromHTML()
{
let target = doc.querySelector("#target");
executeSoon(function() {
checkSheets(target);
gBrowser.removeCurrentTab();
openXUL();
});
}
function openXUL()
{
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.ALLOW_ACTION);
addTab(TEST_URI2);
browser.addEventListener("load", xulLoaded, true);
}
function xulLoaded()
{
browser.removeEventListener("load", xulLoaded, true);
doc = content.document;
testFromXUL()
}
function testFromXUL()
{
let target = doc.querySelector("#target");
executeSoon(function() {
checkSheets(target);
finishUp();
});
}
function checkSheets(aTarget)
{
let domUtils = Cc["@mozilla.org/inspector/dom-utils;1"]
.getService(Ci.inIDOMUtils);
let domRules = domUtils.getCSSStyleRules(aTarget);
for (let i = 0, n = domRules.Count(); i < n; i++) {
let domRule = domRules.GetElementAt(i);
let sheet = domRule.parentStyleSheet;
let isContentSheet = CssLogic.isContentStylesheet(sheet);
if (!sheet.href ||
/browser_bug705707_is_content_stylesheet_/.test(sheet.href)) {
ok(isContentSheet, sheet.href + " identified as content stylesheet");
} else {
ok(!isContentSheet, sheet.href + " identified as non-content stylesheet");
}
}
}
function finishUp()
{
info("finishing up");
Cc["@mozilla.org/permissionmanager;1"].getService(Ci.nsIPermissionManager)
.add(XUL_URI, 'allowXULXBL', Ci.nsIPermissionManager.DENY_ACTION);
doc = null;
gBrowser.removeCurrentTab();
finish();
}

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

@ -0,0 +1,9 @@
<?xml version="1.0"?>
<?xml-stylesheet href="chrome://global/skin/xul.css" type="text/css"?>
<?xml-stylesheet href="./browser_bug705707_is_content_stylesheet_xul.css"
type="text/css"?>
<!DOCTYPE window>
<window id="testwindow" xmlns:html="http://www.w3.org/1999/xhtml"
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
<label id="target" value="Simple XUL document" />
</window>

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

@ -0,0 +1,5 @@
@import url("./browser_bug705707_is_content_stylesheet_imported2.css");
#target {
text-decoration: underline;
}

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

@ -0,0 +1,3 @@
#target {
text-decoration: underline;
}

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

@ -0,0 +1,3 @@
table {
border-collapse: collapse;
}

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

@ -0,0 +1,5 @@
@import url("./browser_bug705707_is_content_stylesheet_imported.css");
table {
opacity: 1;
}

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

@ -0,0 +1,3 @@
#target {
font-size: 200px;
}

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

@ -126,6 +126,40 @@ gcli.addCommand({
} }
}); });
/**
* 'edit' command
*/
gcli.addCommand({
name: "edit",
description: gcli.lookup("editDesc"),
manual: gcli.lookup("editManual"),
params: [
{
name: 'resource',
type: {
name: 'resource',
include: 'text/css'
},
description: gcli.lookup("editResourceDesc")
},
{
name: "line",
defaultValue: 1,
type: {
name: "number",
min: 1,
step: 10
},
description: gcli.lookup("editLineToJumpToDesc")
}
],
exec: function(args, context) {
let hud = HUDService.getHudReferenceById(context.environment.hudId);
let StyleEditor = hud.gcliterm.document.defaultView.StyleEditor;
StyleEditor.openChrome(args.resource.element, args.line);
}
});
let breakpoints = []; let breakpoints = [];
/** /**

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

@ -150,9 +150,6 @@
@BINPATH@/components/dom_system_b2g.xpt @BINPATH@/components/dom_system_b2g.xpt
#endif #endif
@BINPATH@/components/dom_battery.xpt @BINPATH@/components/dom_battery.xpt
#ifdef MOZ_B2G_BT
@BINPATH@/components/dom_bluetooth.xpt
#endif
@BINPATH@/components/dom_canvas.xpt @BINPATH@/components/dom_canvas.xpt
@BINPATH@/components/dom_core.xpt @BINPATH@/components/dom_core.xpt
@BINPATH@/components/dom_css.xpt @BINPATH@/components/dom_css.xpt

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

@ -129,3 +129,23 @@ breakdelRemoved=Breakpoint removed
# 'console close' command. This string is designed to be shown in a menu # 'console close' command. This string is designed to be shown in a menu
# alongside the command name, which is why it should be as short as possible. # alongside the command name, which is why it should be as short as possible.
consolecloseDesc=Close the console consolecloseDesc=Close the console
# LOCALIZATION NOTE (editDesc) A very short description of the 'edit'
# command. See editManual for a fuller description of what it does. This
# string is designed to be shown in a menu alongside the command name, which
# is why it should be as short as possible.
editDesc=Tweak a page resource
# LOCALIZATION NOTE (editManual) A fuller description of the 'edit' command,
# displayed when the user asks for help on what it does.
editManual=Edit one of the resources that is part of this page (or maybe any generic web resource?)
# LOCALIZATION NOTE (editResourceDesc) A very short string to describe the
# 'resource' parameter to the 'edit' command, which is displayed in a dialog
# when the user is using this command.
editResourceDesc=URL to edit
# LOCALIZATION NOTE (editLineToJumpToDesc) A very short string to describe the
# 'line' parameter to the 'edit' command, which is displayed in a dialog
# when the user is using this command.
editLineToJumpToDesc=Line to jump to

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

@ -88,6 +88,12 @@ browser/themes/Makefile
$MOZ_BRANDING_DIRECTORY/Makefile $MOZ_BRANDING_DIRECTORY/Makefile
$MOZ_BRANDING_DIRECTORY/content/Makefile $MOZ_BRANDING_DIRECTORY/content/Makefile
$MOZ_BRANDING_DIRECTORY/locales/Makefile $MOZ_BRANDING_DIRECTORY/locales/Makefile
toolkit/locales/Makefile
extensions/spellcheck/locales/Makefile
intl/locales/Makefile
netwerk/locales/Makefile
dom/locales/Makefile
security/manager/locales/Makefile
" "
if [ "$MOZ_SAFE_BROWSING" ]; then if [ "$MOZ_SAFE_BROWSING" ]; then

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

@ -68,6 +68,9 @@
.helplink:visited { .helplink:visited {
text-decoration: none; text-decoration: none;
} }
.link:hover {
text-decoration: underline;
}
.helplink { .helplink {
display: block; display: block;
@ -135,6 +138,7 @@
.rule-link { .rule-link {
text-align: end; text-align: end;
-moz-padding-start: 10px; -moz-padding-start: 10px;
cursor: pointer;
} }
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */ /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -200,7 +204,13 @@
.ruleview-rule-source { .ruleview-rule-source {
background-color: -moz-dialog; background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px; padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
} }
.ruleview-code { .ruleview-code {

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

@ -68,6 +68,9 @@
.helplink:visited { .helplink:visited {
text-decoration: none; text-decoration: none;
} }
.link:hover {
text-decoration: underline;
}
.helplink { .helplink {
display: block; display: block;
@ -137,6 +140,7 @@
.rule-link { .rule-link {
text-align: end; text-align: end;
-moz-padding-start: 10px; -moz-padding-start: 10px;
cursor: pointer;
} }
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */ /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -202,7 +206,13 @@
.ruleview-rule-source { .ruleview-rule-source {
background-color: -moz-dialog; background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px; padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
} }
.ruleview-code { .ruleview-code {

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

@ -67,6 +67,9 @@
.helplink:visited { .helplink:visited {
text-decoration: none; text-decoration: none;
} }
.link:hover {
text-decoration: underline;
}
.helplink { .helplink {
display: block; display: block;
@ -135,6 +138,7 @@
.rule-link { .rule-link {
text-align: end; text-align: end;
-moz-padding-start: 10px; -moz-padding-start: 10px;
cursor: pointer;
} }
/* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */ /* This rule is necessary because Templater.jsm breaks LTR TDs in RTL docs */
@ -200,7 +204,13 @@
.ruleview-rule-source { .ruleview-rule-source {
background-color: -moz-dialog; background-color: -moz-dialog;
color: #0091ff;
padding: 2px 5px; padding: 2px 5px;
cursor: pointer;
}
.ruleview-rule-source:hover {
text-decoration: underline;
} }
.ruleview-code { .ruleview-code {

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

@ -84,7 +84,7 @@ DEFINES += -DGRE_MILESTONE=$(GRE_MILESTONE) -DAPP_BUILDID=$(APP_BUILDID)
DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)" DEFINES += -DMOZ_APP_VERSION="$(MOZ_APP_VERSION)"
APP_INI_DEPS += $(DEPTH)/config/autoconf.mk APP_INI_DEPS += $(DEPTH)/config/autoconf.mk
MOZ_SOURCE_STAMP ?= $(firstword $(shell hg -R $(topsrcdir)/$(MOZ_BUILD_APP)/.. parent --template="{node|short}\n" 2>/dev/null)) MOZ_SOURCE_STAMP := $(firstword $(shell cd $(topsrcdir)/$(MOZ_BUILD_APP)/.. && hg parent --template="{node|short}\n" 2>/dev/null))
ifdef MOZ_SOURCE_STAMP ifdef MOZ_SOURCE_STAMP
DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)" DEFINES += -DMOZ_SOURCE_STAMP="$(MOZ_SOURCE_STAMP)"
endif endif

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

@ -0,0 +1,13 @@
dnl Add compiler specific options
AC_DEFUN([MOZ_COMPILER_OPTS],
[
if test "$CLANG_CXX"; then
## We disable return-type-c-linkage because jsval is defined as a C++ type but is
## returned by C functions. This is possible because we use knowledge about the ABI
## to typedef it to a C type with the same layout when the headers are included
## from C.
_WARNINGS_CXXFLAGS="${_WARNINGS_CXXFLAGS} -Wno-return-type-c-linkage"
fi
])

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

@ -1,5 +1,18 @@
#!/usr/bin/python #!/usr/bin/python
# The directories end up in the debug info, so the easy way of getting
# a reproducible build is to run it in a know absolute directory.
# We use a directory in /builds/slave because the mozilla infrastructure
# cleans it up automatically.
base_dir = "/builds/slave/moz-toolschain"
source_dir = base_dir + "/src"
build_dir = base_dir + "/build"
aux_inst_dir = build_dir + '/aux_inst'
old_make = aux_inst_dir + '/bin/make'
##############################################
import urllib import urllib
import os import os
import os.path import os.path
@ -33,17 +46,21 @@ def patch(patch, plevel, srcdir):
check_run(['patch', '-d', srcdir, '-p%s' % plevel, '-i', patch, '--fuzz=0', check_run(['patch', '-d', srcdir, '-p%s' % plevel, '-i', patch, '--fuzz=0',
'-s']) '-s'])
def build_package(package_source_dir, package_build_dir, configure_args): def build_package(package_source_dir, package_build_dir, configure_args,
make = old_make):
os.mkdir(package_build_dir) os.mkdir(package_build_dir)
run_in(package_build_dir, run_in(package_build_dir,
["%s/configure" % package_source_dir] + configure_args) ["%s/configure" % package_source_dir] + configure_args)
run_in(package_build_dir, ["make", "-j8"]) run_in(package_build_dir, [make, "-j8"])
run_in(package_build_dir, ["make", "install"]) run_in(package_build_dir, [make, "install"])
def build_tar(base_dir, tar_inst_dir): def build_aux_tools(base_dir):
make_build_dir = base_dir + '/make_build'
build_package(make_source_dir, make_build_dir,
["--prefix=%s" % aux_inst_dir], "make")
tar_build_dir = base_dir + '/tar_build' tar_build_dir = base_dir + '/tar_build'
build_package(tar_source_dir, tar_build_dir, build_package(tar_source_dir, tar_build_dir,
["--prefix=%s" % tar_inst_dir]) ["--prefix=%s" % aux_inst_dir])
def with_env(env, f): def with_env(env, f):
old_env = os.environ.copy() old_env = os.environ.copy()
@ -133,21 +150,13 @@ def build_tar_package(tar, name, base, directory):
############################################## ##############################################
# The directories end up in the debug info, so the easy way of getting
# a reproducible build is to run it in a know absolute directory.
# We use a directory in /builds/slave because the mozilla infrastructure
# cleans it up automatically.
base_dir = "/builds/slave/moz-toolschain"
source_dir = base_dir + "/src"
build_dir = base_dir + "/build"
def build_source_dir(prefix, version): def build_source_dir(prefix, version):
return source_dir + '/' + prefix + version return source_dir + '/' + prefix + version
binutils_version = "2.21.1" binutils_version = "2.21.1"
glibc_version = "2.12.2" #FIXME: should probably use 2.5.1 glibc_version = "2.5.1"
tar_version = "1.26" tar_version = "1.26"
make_version = "3.81"
gcc_version = "4.5.2" gcc_version = "4.5.2"
mpfr_version = "2.4.2" mpfr_version = "2.4.2"
gmp_version = "5.0.1" gmp_version = "5.0.1"
@ -159,6 +168,8 @@ glibc_source_uri = "http://ftp.gnu.org/gnu/glibc/glibc-%s.tar.bz2" % \
glibc_version glibc_version
tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \ tar_source_uri = "http://ftp.gnu.org/gnu/tar/tar-%s.tar.bz2" % \
tar_version tar_version
make_source_uri = "http://ftp.gnu.org/gnu/make/make-%s.tar.bz2" % \
make_version
gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \ gcc_source_uri = "http://ftp.gnu.org/gnu/gcc/gcc-%s/gcc-%s.tar.bz2" % \
(gcc_version, gcc_version) (gcc_version, gcc_version)
mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \ mpfr_source_uri = "http://www.mpfr.org/mpfr-%s/mpfr-%s.tar.bz2" % \
@ -170,6 +181,7 @@ mpc_source_uri = "http://www.multiprecision.org/mpc/download/mpc-%s.tar.gz" % \
binutils_source_tar = download_uri(binutils_source_uri) binutils_source_tar = download_uri(binutils_source_uri)
glibc_source_tar = download_uri(glibc_source_uri) glibc_source_tar = download_uri(glibc_source_uri)
tar_source_tar = download_uri(tar_source_uri) tar_source_tar = download_uri(tar_source_uri)
make_source_tar = download_uri(make_source_uri)
mpc_source_tar = download_uri(mpc_source_uri) mpc_source_tar = download_uri(mpc_source_uri)
mpfr_source_tar = download_uri(mpfr_source_uri) mpfr_source_tar = download_uri(mpfr_source_uri)
gmp_source_tar = download_uri(gmp_source_uri) gmp_source_tar = download_uri(gmp_source_uri)
@ -178,6 +190,7 @@ gcc_source_tar = download_uri(gcc_source_uri)
binutils_source_dir = build_source_dir('binutils-', binutils_version) binutils_source_dir = build_source_dir('binutils-', binutils_version)
glibc_source_dir = build_source_dir('glibc-', glibc_version) glibc_source_dir = build_source_dir('glibc-', glibc_version)
tar_source_dir = build_source_dir('tar-', tar_version) tar_source_dir = build_source_dir('tar-', tar_version)
make_source_dir = build_source_dir('make-', make_version)
mpc_source_dir = build_source_dir('mpc-', mpc_version) mpc_source_dir = build_source_dir('mpc-', mpc_version)
mpfr_source_dir = build_source_dir('mpfr-', mpfr_version) mpfr_source_dir = build_source_dir('mpfr-', mpfr_version)
gmp_source_dir = build_source_dir('gmp-', gmp_version) gmp_source_dir = build_source_dir('gmp-', gmp_version)
@ -191,6 +204,7 @@ if not os.path.exists(source_dir):
patch('glibc-deterministic.patch', 1, glibc_source_dir) patch('glibc-deterministic.patch', 1, glibc_source_dir)
run_in(glibc_source_dir, ["autoconf"]) run_in(glibc_source_dir, ["autoconf"])
extract(tar_source_tar, source_dir) extract(tar_source_tar, source_dir)
extract(make_source_tar, source_dir)
extract(mpc_source_tar, source_dir) extract(mpc_source_tar, source_dir)
extract(mpfr_source_tar, source_dir) extract(mpfr_source_tar, source_dir)
extract(gmp_source_tar, source_dir) extract(gmp_source_tar, source_dir)
@ -203,19 +217,18 @@ if os.path.exists(build_dir):
shutil.rmtree(build_dir) shutil.rmtree(build_dir)
os.makedirs(build_dir) os.makedirs(build_dir)
tar_inst_dir = build_dir + '/tar_inst' build_aux_tools(build_dir)
build_tar(build_dir, tar_inst_dir)
stage1_dir = build_dir + '/stage1' stage1_dir = build_dir + '/stage1'
build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True) build_one_stage({"CC": "gcc", "CXX" : "g++"}, stage1_dir, True)
stage1_tool_inst_dir = stage1_dir + '/inst' stage1_tool_inst_dir = stage1_dir + '/inst'
stage2_dir = build_dir + '/stage2' stage2_dir = build_dir + '/stage2'
build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc", build_one_stage({"CC" : stage1_tool_inst_dir + "/bin/gcc -fgnu89-inline",
"CXX" : stage1_tool_inst_dir + "/bin/g++", "CXX" : stage1_tool_inst_dir + "/bin/g++",
"AR" : stage1_tool_inst_dir + "/bin/ar", "AR" : stage1_tool_inst_dir + "/bin/ar",
"RANLIB" : "true" }, "RANLIB" : "true" },
stage2_dir, False) stage2_dir, False)
build_tar_package(tar_inst_dir + "/bin/tar", build_tar_package(aux_inst_dir + "/bin/tar",
"toolchain.tar", stage2_dir, "inst") "toolchain.tar", stage2_dir, "inst")

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

@ -1,7 +1,22 @@
diff -ru a/configure.in b/configure.in diff -ru a/configure.in b/configure.in
--- a/configure.in 2011-01-17 23:34:07.000000000 -0500 --- a/configure.in 2011-01-17 23:34:07.000000000 -0500
+++ b/configure.in 2012-01-25 20:40:27.919485606 -0500 +++ b/configure.in 2012-01-25 20:40:27.919485606 -0500
@@ -2230,6 +2230,7 @@ @@ -841,14 +841,6 @@
LIBC_PROG_BINUTILS
AC_SUBST(MIG)dnl Needed by sysdeps/mach/configure.in
-# Accept binutils 2.13 or newer.
-AC_CHECK_PROG_VER(AS, $AS, --version,
- [GNU assembler.* \([0-9]*\.[0-9.]*\)],
- [2.1[3-9]*], AS=: critic_missing="$critic_missing as")
-AC_CHECK_PROG_VER(LD, $LD, --version,
- [GNU ld.* \([0-9][0-9]*\.[0-9.]*\)],
- [2.1[3-9]*], LD=: critic_missing="$critic_missing ld")
-
# We need the physical current working directory. We cannot use the
# "pwd -P" shell builtin since that's not portable. Instead we try to
# find a pwd binary. Note that assigning to the PWD environment
@@ -2175,6 +2167,7 @@
fi fi
AC_SUBST(old_glibc_headers) AC_SUBST(old_glibc_headers)
@ -12,7 +27,7 @@ diff -ru a/configure.in b/configure.in
diff -ru a/csu/Makefile b/csu/Makefile diff -ru a/csu/Makefile b/csu/Makefile
--- a/csu/Makefile 2011-01-17 23:34:07.000000000 -0500 --- a/csu/Makefile 2011-01-17 23:34:07.000000000 -0500
+++ b/csu/Makefile 2012-01-23 13:58:28.957792633 -0500 +++ b/csu/Makefile 2012-01-23 13:58:28.957792633 -0500
@@ -234,8 +234,7 @@ @@ -223,8 +223,7 @@
if [ -z "$$os" ]; then \ if [ -z "$$os" ]; then \
os=Linux; \ os=Linux; \
fi; \ fi; \
@ -22,10 +37,58 @@ diff -ru a/csu/Makefile b/csu/Makefile
*) ;; \ *) ;; \
esac; \ esac; \
files="$(all-Banner-files)"; \ files="$(all-Banner-files)"; \
diff -ru a/elf/Makefile b/elf/Makefile
--- a/elf/Makefile 2008-10-31 16:35:11.000000000 -0400
+++ b/elf/Makefile 2012-02-16 12:20:00.038593752 -0500
@@ -295,18 +295,11 @@
z-now-yes = -Wl,-z,now
$(objpfx)ld.so: $(objpfx)librtld.os $(ld-map)
- @rm -f $@.lds
- $(LINK.o) -nostdlib -nostartfiles -shared $(z-now-$(bind-now)) \
- $(LDFLAGS-rtld) -Wl,-z,defs -Wl,--verbose 2>&1 | \
- LC_ALL=C \
- sed -e '/^=========/,/^=========/!d;/^=========/d' \
- -e 's/\. = 0 + SIZEOF_HEADERS;/& _begin = . - SIZEOF_HEADERS;/' \
- > $@.lds
$(LINK.o) -nostdlib -nostartfiles -shared -o $@ \
$(LDFLAGS-rtld) -Wl,-z,defs $(z-now-$(bind-now)) \
$(filter-out $(map-file),$^) $(load-map-file) \
- -Wl,-soname=$(rtld-installed-name) -T $@.lds
- rm -f $@.lds
+ -Wl,-soname=$(rtld-installed-name) \
+ -Wl,-defsym=_begin=0
# interp.c exists just to get this string into the libraries.
CFLAGS-interp.c = -D'RUNTIME_LINKER="$(slibdir)/$(rtld-installed-name)"' \
diff -ru a/localedata/Makefile b/localedata/Makefile
--- a/localedata/Makefile 2006-04-26 01:14:03.000000000 -0400
+++ b/localedata/Makefile 2012-02-17 10:31:24.592345047 -0500
@@ -113,7 +113,7 @@
$(make-target-directory)
rm -f $(@:.gz=) $@
$(INSTALL_DATA) $< $(@:.gz=)
- gzip -9 $(@:.gz=)
+ gzip -9n $(@:.gz=)
# Install the locale source files in the appropriate directory.
$(inst_i18ndir)/locales/%: locales/% $(+force); $(do-install)
diff -ru a/Makeconfig b/Makeconfig
--- a/Makeconfig 2006-07-10 17:42:27.000000000 -0400
+++ b/Makeconfig 2012-02-17 08:28:31.859584817 -0500
@@ -674,7 +674,7 @@
$(foreach lib,$(libof-$(basename $(@F))) \
$(libof-$(<F)) $(libof-$(@F)),$(CPPFLAGS-$(lib))) \
$(CPPFLAGS-$(<F)) $(CPPFLAGS-$(@F)) $(CPPFLAGS-$(basename $(@F)))
-override CFLAGS = -std=gnu99 \
+override CFLAGS = -std=gnu99 -fgnu89-inline \
$(filter-out %frame-pointer,$(+cflags)) $(+gccwarn-c) \
$(sysdep-CFLAGS) $(CFLAGS-$(suffix $@)) $(CFLAGS-$(<F)) \
$(CFLAGS-$(@F))
diff -ru a/Makerules b/Makerules diff -ru a/Makerules b/Makerules
--- a/Makerules 2011-01-17 23:34:07.000000000 -0500 --- a/Makerules 2011-01-17 23:34:07.000000000 -0500
+++ b/Makerules 2012-01-30 08:47:56.565068903 -0500 +++ b/Makerules 2012-01-30 08:47:56.565068903 -0500
@@ -992,9 +992,9 @@ @@ -977,9 +977,9 @@
echo ' Use the shared library, but some functions are only in';\ echo ' Use the shared library, but some functions are only in';\
echo ' the static library, so try that secondarily. */';\ echo ' the static library, so try that secondarily. */';\
cat $<; \ cat $<; \

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

@ -57,7 +57,6 @@ MOZ_PROFILE_MIGRATOR = @MOZ_PROFILE_MIGRATOR@
MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@ MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@
MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@ MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
MOZ_APP_VERSION = @MOZ_APP_VERSION@ MOZ_APP_VERSION = @MOZ_APP_VERSION@
MOZ_UA_BUILDID = @MOZ_UA_BUILDID@
MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@ MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@
MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@ MOZ_APP_STATIC_INI = @MOZ_APP_STATIC_INI@
@ -181,6 +180,7 @@ LIBJPEG_TURBO_AS = @LIBJPEG_TURBO_AS@
LIBJPEG_TURBO_ASFLAGS = @LIBJPEG_TURBO_ASFLAGS@ LIBJPEG_TURBO_ASFLAGS = @LIBJPEG_TURBO_ASFLAGS@
LIBJPEG_TURBO_X86_ASM = @LIBJPEG_TURBO_X86_ASM@ LIBJPEG_TURBO_X86_ASM = @LIBJPEG_TURBO_X86_ASM@
LIBJPEG_TURBO_X64_ASM = @LIBJPEG_TURBO_X64_ASM@ LIBJPEG_TURBO_X64_ASM = @LIBJPEG_TURBO_X64_ASM@
LIBJPEG_TURBO_ARM_ASM = @LIBJPEG_TURBO_ARM_ASM@
NS_PRINTING = @NS_PRINTING@ NS_PRINTING = @NS_PRINTING@
MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@ MOZ_PDF_PRINTING = @MOZ_PDF_PRINTING@
MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@ MOZ_CRASHREPORTER = @MOZ_CRASHREPORTER@
@ -293,7 +293,6 @@ MOZ_NATIVE_NSPR = @MOZ_NATIVE_NSPR@
MOZ_NATIVE_NSS = @MOZ_NATIVE_NSS@ MOZ_NATIVE_NSS = @MOZ_NATIVE_NSS@
MOZ_B2G_RIL = @MOZ_B2G_RIL@ MOZ_B2G_RIL = @MOZ_B2G_RIL@
MOZ_B2G_BT = @MOZ_B2G_BT@
BUILD_CTYPES = @BUILD_CTYPES@ BUILD_CTYPES = @BUILD_CTYPES@

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

@ -35,7 +35,7 @@
# #
# ***** END LICENSE BLOCK ***** # ***** END LICENSE BLOCK *****
import sys, os, subprocess, struct import sys, os, subprocess, struct, re
local_file_header = [ local_file_header = [
("signature", "uint32"), ("signature", "uint32"),
@ -329,10 +329,12 @@ if len(sys.argv) != 5:
print "Usage: --optimize|--deoptimize %s JAR_LOG_DIR IN_JAR_DIR OUT_JAR_DIR" % sys.argv[0] print "Usage: --optimize|--deoptimize %s JAR_LOG_DIR IN_JAR_DIR OUT_JAR_DIR" % sys.argv[0]
exit(1) exit(1)
jar_regex = re.compile("\\.jar?$")
def optimize(JAR_LOG_DIR, IN_JAR_DIR, OUT_JAR_DIR): def optimize(JAR_LOG_DIR, IN_JAR_DIR, OUT_JAR_DIR):
ls = os.listdir(IN_JAR_DIR) ls = os.listdir(IN_JAR_DIR)
for jarfile in ls: for jarfile in ls:
if not jarfile.endswith(".jar"): if not re.search(jar_regex, jarfile):
continue continue
injarfile = os.path.join(IN_JAR_DIR, jarfile) injarfile = os.path.join(IN_JAR_DIR, jarfile)
outjarfile = os.path.join(OUT_JAR_DIR, jarfile) outjarfile = os.path.join(OUT_JAR_DIR, jarfile)
@ -347,7 +349,7 @@ def deoptimize(JAR_LOG_DIR, IN_JAR_DIR, OUT_JAR_DIR):
ls = os.listdir(IN_JAR_DIR) ls = os.listdir(IN_JAR_DIR)
for jarfile in ls: for jarfile in ls:
if not jarfile.endswith(".jar"): if not re.search(jar_regex, jarfile):
continue continue
injarfile = os.path.join(IN_JAR_DIR, jarfile) injarfile = os.path.join(IN_JAR_DIR, jarfile)
outjarfile = os.path.join(OUT_JAR_DIR, jarfile) outjarfile = os.path.join(OUT_JAR_DIR, jarfile)

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

@ -3343,6 +3343,7 @@ AC_SUBST(WRAP_SYSTEM_INCLUDES)
AC_SUBST(VISIBILITY_FLAGS) AC_SUBST(VISIBILITY_FLAGS)
MOZ_GCC_PR49911 MOZ_GCC_PR49911
MOZ_COMPILER_OPTS
dnl Check for __force_align_arg_pointer__ for SSE2 on gcc dnl Check for __force_align_arg_pointer__ for SSE2 on gcc
dnl ======================================================== dnl ========================================================
@ -4091,6 +4092,56 @@ if test "$ac_cv_thread_keyword" = yes -a "$MOZ_LINKER" != 1; then
esac esac
fi fi
dnl Using the custom linker on ARMv6 requires 16k alignment of ELF segments.
if test -n "$MOZ_LINKER"; then
if test "$CPU_ARCH" = arm; then
dnl Determine the target ARM architecture (5 for ARMv5, v5T, v5E, etc.; 6 for ARMv6, v6K, etc.)
ARM_ARCH=`${CC-cc} ${CFLAGS} -dM -E - < /dev/null | sed -n 's/.*__ARM_ARCH_\([[0-9]]*\).*/\1/p'`
dnl When building for < ARMv7, we need to ensure 16k alignment of ELF segments
if test -n "$ARM_ARCH" && test "$ARM_ARCH" -lt 7; then
LDFLAGS="$LDFLAGS -Wl,-z,max-page-size=0x4000"
_SUBDIR_LDFLAGS="$_SUBDIR_LDFLAGS -Wl,-z,max-page-size=0x4000"
fi
fi
fi
dnl The custom linker doesn't support text relocations, but NDK >= r6b
dnl creates some (http://code.google.com/p/android/issues/detail?id=23203)
dnl We however want to avoid these text relocations, and this can be done
dnl by making gcc not link crtbegin and crtend. In the broken NDKs, crtend
dnl doesn't contain anything at all, beside placeholders for some sections,
dnl and crtbegin only contains a finalizer function that calls
dnl __cxa_finalize. The custom linker actually takes care of calling
dnl __cxa_finalize when the library doesn't call it itself, which makes it
dnl safe not to link crtbegin. Besides, previous versions of the NDK didn't
dnl link crtbegin and crtend at all.
if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$OS_TARGET" = "Android"; then
AC_CACHE_CHECK([whether the CRT objects have text relocations],
ac_cv_crt_has_text_relocations,
[echo 'int foo() { return 0; }' > conftest.cpp
if AC_TRY_COMMAND(${CXX-g++} -o conftest${DLL_SUFFIX} $CXXFLAGS $DSO_LDOPTS $LDFLAGS conftest.cpp $LIBS 1>&5) &&
test -s conftest${DLL_SUFFIX}; then
if readelf -d conftest${DLL_SUFFIX} | grep TEXTREL > /dev/null; then
ac_cv_crt_has_text_relocations=yes
else
ac_cv_crt_has_text_relocations=no
fi
else
AC_ERROR([couldn't compile a simple C file])
fi
rm -rf conftest*])
if test "$ac_cv_crt_has_text_relocations" = yes; then
dnl While we want libraries to skip the CRT files, we don't want
dnl executables to be treated the same way. We thus set the flag
dnl in DSO_LDOPTS and not LDFLAGS. However, to pass it to nspr,
dnl we need to use LDFLAGS because nspr doesn't inherit DSO_LDOPTS.
dnl Using LDFLAGS in nspr is safe, since we only really build
dnl libraries there.
DSO_LDOPTS="$DSO_LDOPTS -nostartfiles"
NSPR_LDFLAGS=-nostartfiles
fi
fi
dnl Check for the existence of various allocation headers/functions dnl Check for the existence of various allocation headers/functions
MALLOC_H= MALLOC_H=
@ -4612,6 +4663,7 @@ LIBJPEG_TURBO_AS=
LIBJPEG_TURBO_ASFLAGS= LIBJPEG_TURBO_ASFLAGS=
LIBJPEG_TURBO_X86_ASM= LIBJPEG_TURBO_X86_ASM=
LIBJPEG_TURBO_X64_ASM= LIBJPEG_TURBO_X64_ASM=
LIBJPEG_TURBO_ARM_ASM=
MOZ_PANGO=1 MOZ_PANGO=1
MOZ_PERMISSIONS=1 MOZ_PERMISSIONS=1
MOZ_PLACES=1 MOZ_PLACES=1
@ -4927,7 +4979,6 @@ cairo-gonk)
MOZ_PDF_PRINTING=1 MOZ_PDF_PRINTING=1
MOZ_B2G_RIL=1 MOZ_B2G_RIL=1
MOZ_TOUCH=1 MOZ_TOUCH=1
MOZ_B2G_BT=1
;; ;;
esac esac
@ -6171,38 +6222,51 @@ if test -n "$MOZ_LIBJPEG_TURBO"; then
LIBJPEG_TURBO_ASFLAGS="-f win64 -rnasm -pnasm -D__x86_64__ -DPIC -DWIN64 -DMSVC" LIBJPEG_TURBO_ASFLAGS="-f win64 -rnasm -pnasm -D__x86_64__ -DPIC -DWIN64 -DMSVC"
LIBJPEG_TURBO_X64_ASM=1 LIBJPEG_TURBO_X64_ASM=1
;; ;;
*:arm*)
LIBJPEG_TURBO_ASFLAGS="-march=armv7-a -mfpu=neon"
LIBJPEG_TURBO_ARM_ASM=1
;;
esac esac
fi fi
dnl If we're on a system which supports libjpeg-turbo's asm routines and dnl If we're on an x86 or x64 system which supports libjpeg-turbo's asm routines
dnl --disable-libjpeg-turbo wasn't passed, check for yasm, and error out if it dnl and --disable-libjpeg-turbo wasn't passed, check for Yasm, and error out if
dnl doesn't exist or we have too old of a version. dnl it doesn't exist or we have too old of a version.
if test -n "$LIBJPEG_TURBO_X86_ASM" -o -n "$LIBJPEG_TURBO_X64_ASM" ; then if test -n "$LIBJPEG_TURBO_X86_ASM" -o -n "$LIBJPEG_TURBO_X64_ASM" ; then
AC_MSG_CHECKING([for YASM assembler]) AC_MSG_CHECKING([for Yasm assembler])
AC_CHECK_PROGS(LIBJPEG_TURBO_AS, yasm, "") AC_CHECK_PROGS(LIBJPEG_TURBO_AS, yasm, "")
if test -z "$LIBJPEG_TURBO_AS" ; then if test -z "$LIBJPEG_TURBO_AS" ; then
AC_MSG_ERROR([yasm is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you do not appear to have yasm installed. Either install it or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.]) AC_MSG_ERROR([Yasm is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you do not appear to have Yasm installed. Either install it or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.])
fi fi
dnl Check that we have the right yasm version. We require 1.0.1 or newer dnl Check that we have the right yasm version. We require 1.0.1 or newer
dnl on Linux and 1.1 or newer everywhere else. dnl on Linux and 1.1 or newer everywhere else.
if test "$OS_ARCH" = "Linux" ; then if test "$OS_ARCH" = "Linux" ; then
if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -eq "0" -a "$_YASM_RELEASE" -lt "1" \) ; then if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -eq "0" -a "$_YASM_RELEASE" -lt "1" \) ; then
AC_MSG_ERROR([yasm 1.0.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE. Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.]) AC_MSG_ERROR([Yasm 1.0.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION.$_YASM_RELEASE. Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.])
fi fi
else else
if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then if test "$_YASM_MAJOR_VERSION" -lt "1" -o \( "$_YASM_MAJOR_VERSION" -eq "1" -a "$_YASM_MINOR_VERSION" -lt "1" \) ; then
AC_MSG_ERROR([yasm 1.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION. Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.]) AC_MSG_ERROR([Yasm 1.1 or greater is required to build with libjpeg-turbo's optimized JPEG decoding routines, but you appear to have version $_YASM_MAJOR_VERSION.$_YASM_MINOR_VERSION. Upgrade to the newest version or configure with --disable-libjpeg-turbo to use the pure C JPEG decoder. See https://developer.mozilla.org/en/YASM for more details.])
fi fi
fi fi
fi fi
dnl If we're on an ARM system which supports libjpeg-turbo's asm routines and
dnl --disable-libjpeg-turbo wasn't passed, use the C compiler as the assembler.
if test -n "$LIBJPEG_TURBO_ARM_ASM" ; then
echo "Using $AS as the assembler for ARM code."
LIBJPEG_TURBO_AS=$AS
fi
if test -n "$LIBJPEG_TURBO_X86_ASM"; then if test -n "$LIBJPEG_TURBO_X86_ASM"; then
AC_DEFINE(LIBJPEG_TURBO_X86_ASM) AC_DEFINE(LIBJPEG_TURBO_X86_ASM)
elif test -n "$LIBJPEG_TURBO_X64_ASM"; then elif test -n "$LIBJPEG_TURBO_X64_ASM"; then
AC_DEFINE(LIBJPEG_TURBO_X64_ASM) AC_DEFINE(LIBJPEG_TURBO_X64_ASM)
elif test -n "$LIBJPEG_TURBO_ARM_ASM"; then
AC_DEFINE(LIBJPEG_TURBO_ARM_ASM)
elif test -n "$MOZ_LIBJPEG_TURBO"; then elif test -n "$MOZ_LIBJPEG_TURBO"; then
dnl Warn if we're not building the optimized routines, even though the user dnl Warn if we're not building the optimized routines, even though the user
dnl didn't specify --disable-libjpeg-turbo. dnl didn't specify --disable-libjpeg-turbo.
@ -7598,18 +7662,6 @@ if test -n "$MOZ_B2G_RIL"; then
fi fi
AC_SUBST(MOZ_B2G_RIL) AC_SUBST(MOZ_B2G_RIL)
dnl ========================================================
dnl = Enable Bluetooth Interface for B2G (Gonk usually)
dnl ========================================================
MOZ_ARG_ENABLE_BOOL(b2g-bt,
[ --enable-b2g-bt Set compile flags necessary for compiling Bluetooth API for B2G ],
MOZ_B2G_BT=1,
MOZ_B2G_BT= )
if test -n "$MOZ_B2G_BT"; then
AC_DEFINE(MOZ_B2G_BT)
fi
AC_SUBST(MOZ_B2G_BT)
dnl ======================================================== dnl ========================================================
dnl = Support for demangling undefined symbols dnl = Support for demangling undefined symbols
dnl ======================================================== dnl ========================================================
@ -8585,8 +8637,6 @@ AC_SUBST(MOZ_APP_VERSION)
AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION") AC_DEFINE_UNQUOTED(MOZ_UA_FIREFOX_VERSION, "$FIREFOX_VERSION")
AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION) AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
AC_SUBST(FIREFOX_VERSION) AC_SUBST(FIREFOX_VERSION)
AC_DEFINE_UNQUOTED(MOZ_UA_BUILDID, "$MOZ_UA_BUILDID")
AC_SUBST(MOZ_UA_BUILDID)
# We can't use the static application.ini data when building against # We can't use the static application.ini data when building against
# a libxul SDK. # a libxul SDK.
@ -8756,6 +8806,7 @@ AC_SUBST(LIBJPEG_TURBO_AS)
AC_SUBST(LIBJPEG_TURBO_ASFLAGS) AC_SUBST(LIBJPEG_TURBO_ASFLAGS)
AC_SUBST(LIBJPEG_TURBO_X86_ASM) AC_SUBST(LIBJPEG_TURBO_X86_ASM)
AC_SUBST(LIBJPEG_TURBO_X64_ASM) AC_SUBST(LIBJPEG_TURBO_X64_ASM)
AC_SUBST(LIBJPEG_TURBO_ARM_ASM)
AC_MSG_CHECKING([for posix_fallocate]) AC_MSG_CHECKING([for posix_fallocate])
AC_TRY_LINK([#define _XOPEN_SOURCE 600 AC_TRY_LINK([#define _XOPEN_SOURCE 600
@ -9090,7 +9141,11 @@ if test -z "$MOZ_NATIVE_NSPR"; then
_SAVE_CPPFLAGS="$CPPFLAGS" _SAVE_CPPFLAGS="$CPPFLAGS"
export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS" export CPPFLAGS="-include $_topsrcdir/mozglue/linker/dladdr.h $CPPFLAGS"
fi fi
_SAVE_LDFLAGS="$LDFLAGS"
export LDFLAGS="$LDFLAGS $NSPR_LDFLAGS"
AC_OUTPUT_SUBDIRS(nsprpub) AC_OUTPUT_SUBDIRS(nsprpub)
unset LDFLAGS
LDFLAGS="$_SAVE_LDFLAGS"
if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no; then if test -n "$MOZ_LINKER" -a -z "$MOZ_OLD_LINKER" -a "$ac_cv_func_dladdr" = no; then
unset CPPFLAGS unset CPPFLAGS
CPPFLAGS="$_SAVE_CFLAGS" CPPFLAGS="$_SAVE_CFLAGS"

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

@ -1,7 +1,7 @@
onmessage = function(event) { onmessage = function(event) {
var blob = event.data; var blob = event.data;
blob.mozSlice(1, 5); blob.slice(1, 5);
postMessage("done"); postMessage("done");
} }

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

@ -71,9 +71,9 @@ interface nsIDOMBlob : nsISupports
// blob: protocol handler // blob: protocol handler
[noscript] DOMString getInternalUrl(in nsIPrincipal principal); [noscript] DOMString getInternalUrl(in nsIPrincipal principal);
[optional_argc] nsIDOMBlob mozSlice([optional] in long long start, [optional_argc] nsIDOMBlob slice([optional] in long long start,
[optional] in long long end, [optional] in long long end,
[optional] in DOMString contentType); [optional] in DOMString contentType);
// Get internal id of stored file. Returns -1 if it is not a stored file. // Get internal id of stored file. Returns -1 if it is not a stored file.
// Intended only for testing. It can be called on any thread. // Intended only for testing. It can be called on any thread.

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

@ -48,6 +48,7 @@
#include "nsCopySupport.h" #include "nsCopySupport.h"
#include "nsIDOMUIEvent.h" #include "nsIDOMUIEvent.h"
#include "nsISelection.h" #include "nsISelection.h"
#include "nsISelectionController.h"
#include "nsIDOMNode.h" #include "nsIDOMNode.h"
#include "nsIDOMNodeList.h" #include "nsIDOMNodeList.h"
#include "nsIDOMEvent.h" #include "nsIDOMEvent.h"
@ -70,6 +71,7 @@
#include "nsIDocShell.h" #include "nsIDocShell.h"
#include "nsIContent.h" #include "nsIContent.h"
#include "nsIImageLoadingContent.h" #include "nsIImageLoadingContent.h"
#include "nsITextControlElement.h"
#include "nsUnicharUtils.h" #include "nsUnicharUtils.h"
#include "nsIURL.h" #include "nsIURL.h"
#include "nsIDocument.h" #include "nsIDocument.h"
@ -84,37 +86,6 @@
#include "imgIRequest.h" #include "imgIRequest.h"
#include "nsDOMDataTransfer.h" #include "nsDOMDataTransfer.h"
// private clipboard data flavors for html copy, used by editor when pasting
#define kHTMLContext "text/_moz_htmlcontext"
#define kHTMLInfo "text/_moz_htmlinfo"
// if aNode is null, use the selection from the window
static nsresult
GetTransferableForNodeOrSelection(nsIDOMWindow* aWindow,
nsIContent* aNode,
nsITransferable** aTransferable)
{
NS_ENSURE_ARG_POINTER(aWindow);
nsCOMPtr<nsIDOMDocument> domDoc;
aWindow->GetDocument(getter_AddRefs(domDoc));
NS_ENSURE_TRUE(domDoc, NS_ERROR_FAILURE);
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
nsresult rv;
if (aNode) {
rv = nsCopySupport::GetTransferableForNode(aNode, doc, aTransferable);
} else {
nsCOMPtr<nsISelection> selection;
aWindow->GetSelection(getter_AddRefs(selection));
rv = nsCopySupport::GetTransferableForSelection(selection, doc,
aTransferable);
}
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
class NS_STACK_CLASS DragDataProducer class NS_STACK_CLASS DragDataProducer
{ {
public: public:
@ -124,7 +95,7 @@ public:
bool aIsAltKeyPressed); bool aIsAltKeyPressed);
nsresult Produce(nsDOMDataTransfer* aDataTransfer, nsresult Produce(nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag, bool* aCanDrag,
bool* aDragSelection, nsISelection** aSelection,
nsIContent** aDragNode); nsIContent** aDragNode);
private: private:
@ -172,7 +143,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
bool aIsAltKeyPressed, bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag, bool* aCanDrag,
bool* aDragSelection, nsISelection** aSelection,
nsIContent** aDragNode) nsIContent** aDragNode)
{ {
NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG); NS_ENSURE_TRUE(aSelectionTargetNode, NS_ERROR_INVALID_ARG);
@ -181,7 +152,7 @@ nsContentAreaDragDrop::GetDragData(nsIDOMWindow* aWindow,
DragDataProducer DragDataProducer
provider(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed); provider(aWindow, aTarget, aSelectionTargetNode, aIsAltKeyPressed);
return provider.Produce(aDataTransfer, aCanDrag, aDragSelection, aDragNode); return provider.Produce(aDataTransfer, aCanDrag, aSelection, aDragNode);
} }
@ -412,10 +383,10 @@ DragDataProducer::GetNodeString(nsIContent* inNode,
nsresult nsresult
DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer, DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag, bool* aCanDrag,
bool* aDragSelection, nsISelection** aSelection,
nsIContent** aDragNode) nsIContent** aDragNode)
{ {
NS_PRECONDITION(aCanDrag && aDragSelection && aDataTransfer && aDragNode, NS_PRECONDITION(aCanDrag && aSelection && aDataTransfer && aDragNode,
"null pointer passed to Produce"); "null pointer passed to Produce");
NS_ASSERTION(mWindow, "window not set"); NS_ASSERTION(mWindow, "window not set");
NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set"); NS_ASSERTION(mSelectionTargetNode, "selection target node should have been set");
@ -424,33 +395,72 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
nsresult rv; nsresult rv;
nsIContent* dragNode = nsnull; nsIContent* dragNode = nsnull;
*aSelection = nsnull;
// find the selection to see what we could be dragging and if // Find the selection to see what we could be dragging and if what we're
// what we're dragging is in what is selected. // dragging is in what is selected. If this is an editable textbox, use
// the textbox's selection, otherwise use the window's selection.
nsCOMPtr<nsISelection> selection; nsCOMPtr<nsISelection> selection;
mWindow->GetSelection(getter_AddRefs(selection)); nsIContent* editingElement = mSelectionTargetNode->IsEditable() ?
if (!selection) { mSelectionTargetNode->GetEditingHost() : nsnull;
return NS_OK; nsCOMPtr<nsITextControlElement> textControl(do_QueryInterface(editingElement));
} if (textControl) {
nsISelectionController* selcon = textControl->GetSelectionController();
// check if the node is inside a form control. If so, dragging will be if (selcon) {
// handled in editor code (nsPlaintextDataTransfer::DoDrag). Don't set selcon->GetSelection(nsISelectionController::SELECTION_NORMAL, getter_AddRefs(selection));
// aCanDrag to false however, as we still want to allow the drag. if (!selection)
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode; return NS_OK;
nsIContent* findFormParent = findFormNode->GetParent(); }
while (findFormParent) { }
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent)); else {
if (form && !form->AllowDraggableChildren()) { mWindow->GetSelection(getter_AddRefs(selection));
return NS_OK; if (!selection)
return NS_OK;
// Check if the node is inside a form control. Don't set aCanDrag to false
//however, as we still want to allow the drag.
nsCOMPtr<nsIContent> findFormNode = mSelectionTargetNode;
nsIContent* findFormParent = findFormNode->GetParent();
while (findFormParent) {
nsCOMPtr<nsIFormControl> form(do_QueryInterface(findFormParent));
if (form && !form->AllowDraggableChildren()) {
return NS_OK;
}
findFormParent = findFormParent->GetParent();
} }
findFormParent = findFormParent->GetParent();
} }
// if set, serialize the content under this node // if set, serialize the content under this node
nsCOMPtr<nsIContent> nodeToSerialize; nsCOMPtr<nsIContent> nodeToSerialize;
*aDragSelection = false;
{ bool isChromeShell = false;
nsCOMPtr<nsIWebNavigation> webnav = do_GetInterface(mWindow);
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(webnav);
if (dsti) {
PRInt32 type = -1;
if (NS_SUCCEEDED(dsti->GetItemType(&type)) &&
type == nsIDocShellTreeItem::typeChrome) {
isChromeShell = true;
}
}
// In chrome shells, only allow dragging inside editable areas.
if (isChromeShell && !editingElement)
return NS_OK;
if (isChromeShell && textControl) {
// Only use the selection if it isn't collapsed.
bool isCollapsed = false;
selection->GetIsCollapsed(&isCollapsed);
if (!isCollapsed)
selection.swap(*aSelection);
}
else {
// In content shells, a number of checks are made below to determine
// whether an image or a link is being dragged. If so, add additional
// data to the data transfer. This is also done for chrome shells, but
// only when in a non-textbox editor.
bool haveSelectedContent = false; bool haveSelectedContent = false;
// possible parent link node // possible parent link node
@ -490,7 +500,7 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
return NS_OK; return NS_OK;
} }
*aDragSelection = true; selection.swap(*aSelection);
} else if (selectedImageOrLinkNode) { } else if (selectedImageOrLinkNode) {
// an image is selected // an image is selected
image = do_QueryInterface(selectedImageOrLinkNode); image = do_QueryInterface(selectedImageOrLinkNode);
@ -660,20 +670,28 @@ DragDataProducer::Produce(nsDOMDataTransfer* aDataTransfer,
} }
} }
if (nodeToSerialize || *aDragSelection) { if (nodeToSerialize || *aSelection) {
// if we have selected text, use it in preference to the node
if (*aDragSelection) {
nodeToSerialize = nsnull;
}
mHtmlString.Truncate(); mHtmlString.Truncate();
mContextString.Truncate(); mContextString.Truncate();
mInfoString.Truncate(); mInfoString.Truncate();
mTitleString.Truncate(); mTitleString.Truncate();
nsCOMPtr<nsIDOMDocument> domDoc;
mWindow->GetDocument(getter_AddRefs(domDoc));
nsCOMPtr<nsIDocument> doc = do_QueryInterface(domDoc);
NS_ENSURE_TRUE(doc, NS_ERROR_FAILURE);
// if we have selected text, use it in preference to the node
nsCOMPtr<nsITransferable> transferable; nsCOMPtr<nsITransferable> transferable;
rv = ::GetTransferableForNodeOrSelection(mWindow, nodeToSerialize, if (*aSelection) {
getter_AddRefs(transferable)); rv = nsCopySupport::GetTransferableForSelection(*aSelection, doc,
NS_ENSURE_SUCCESS(rv, rv); getter_AddRefs(transferable));
}
else {
rv = nsCopySupport::GetTransferableForNode(nodeToSerialize, doc,
getter_AddRefs(transferable));
}
nsCOMPtr<nsISupportsString> data; nsCOMPtr<nsISupportsString> data;
PRUint32 dataSize; PRUint32 dataSize;
rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize); rv = transferable->GetTransferData(kHTMLMime, getter_AddRefs(data), &dataSize);
@ -747,15 +765,17 @@ DragDataProducer::AddStringsToDataTransfer(nsIContent* aDragNode,
AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal); AddString(aDataTransfer, NS_LITERAL_STRING("text/uri-list"), mUrlString, principal);
} }
// add a special flavor, even if we don't have html context data // add a special flavor for the html context data
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal); if (!mContextString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLContext), mContextString, principal);
// add a special flavor if we have html info data // add a special flavor if we have html info data
if (!mInfoString.IsEmpty()) if (!mInfoString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal); AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLInfo), mInfoString, principal);
// add the full html // add the full html
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal); if (!mHtmlString.IsEmpty())
AddString(aDataTransfer, NS_LITERAL_STRING(kHTMLMime), mHtmlString, principal);
// add the plain text. we use the url for text/plain data if an anchor is // add the plain text. we use the url for text/plain data if an anchor is
// being dragged, rather than the title text of the link or the alt text for // being dragged, rather than the title text of the link or the alt text for

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

@ -78,8 +78,8 @@ public:
* aDataTransfer - the dataTransfer for the drag event. * aDataTransfer - the dataTransfer for the drag event.
* aCanDrag - [out] set to true if the drag may proceed, false to stop the * aCanDrag - [out] set to true if the drag may proceed, false to stop the
* drag entirely * drag entirely
* aDragSelection - [out] set to true to indicate that a selection is being * aSelection - [out] set to the selection being dragged, or null if no
* dragged, rather than a specific node * selection is being dragged.
* aDragNode - [out] the link, image or area being dragged, or null if the * aDragNode - [out] the link, image or area being dragged, or null if the
* drag occurred on another element. * drag occurred on another element.
*/ */
@ -89,7 +89,7 @@ public:
bool aIsAltKeyPressed, bool aIsAltKeyPressed,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
bool* aCanDrag, bool* aCanDrag,
bool* aDragSelection, nsISelection** aSelection,
nsIContent** aDragNode); nsIContent** aDragNode);
}; };

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

@ -91,10 +91,6 @@ static NS_DEFINE_CID(kCClipboardCID, NS_CLIPBOARD_CID);
static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID); static NS_DEFINE_CID(kCTransferableCID, NS_TRANSFERABLE_CID);
static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID); static NS_DEFINE_CID(kHTMLConverterCID, NS_HTMLFORMATCONVERTER_CID);
// private clipboard data flavors for html copy, used by editor when pasting
#define kHTMLContext "text/_moz_htmlcontext"
#define kHTMLInfo "text/_moz_htmlinfo"
// copy string data onto the transferable // copy string data onto the transferable
static nsresult AppendString(nsITransferable *aTransferable, static nsresult AppendString(nsITransferable *aTransferable,
const nsAString& aString, const nsAString& aString,

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

@ -122,9 +122,9 @@ nsDOMMultipartFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
PRUint64 upperBound = NS_MIN<PRUint64>(l - skipStart, length); PRUint64 upperBound = NS_MIN<PRUint64>(l - skipStart, length);
nsCOMPtr<nsIDOMBlob> firstBlob; nsCOMPtr<nsIDOMBlob> firstBlob;
rv = blob->MozSlice(skipStart, skipStart + upperBound, rv = blob->Slice(skipStart, skipStart + upperBound,
aContentType, 3, aContentType, 3,
getter_AddRefs(firstBlob)); getter_AddRefs(firstBlob));
NS_ENSURE_SUCCESS(rv, nsnull); NS_ENSURE_SUCCESS(rv, nsnull);
// Avoid wrapping a single blob inside an nsDOMMultipartFile // Avoid wrapping a single blob inside an nsDOMMultipartFile
@ -150,8 +150,8 @@ nsDOMMultipartFile::CreateSlice(PRUint64 aStart, PRUint64 aLength,
if (length < l) { if (length < l) {
nsCOMPtr<nsIDOMBlob> lastBlob; nsCOMPtr<nsIDOMBlob> lastBlob;
rv = blob->MozSlice(0, length, aContentType, 3, rv = blob->Slice(0, length, aContentType, 3,
getter_AddRefs(lastBlob)); getter_AddRefs(lastBlob));
NS_ENSURE_SUCCESS(rv, nsnull); NS_ENSURE_SUCCESS(rv, nsnull);
blobs.AppendElement(lastBlob); blobs.AppendElement(lastBlob);

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

@ -238,9 +238,9 @@ ParseSize(PRInt64 aSize, PRInt64& aStart, PRInt64& aEnd)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsDOMFileBase::MozSlice(PRInt64 aStart, PRInt64 aEnd, nsDOMFileBase::Slice(PRInt64 aStart, PRInt64 aEnd,
const nsAString& aContentType, PRUint8 optional_argc, const nsAString& aContentType, PRUint8 optional_argc,
nsIDOMBlob **aBlob) nsIDOMBlob **aBlob)
{ {
*aBlob = nsnull; *aBlob = nsnull;

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

@ -1700,9 +1700,29 @@ nsINode::SetExplicitBaseURI(nsIURI* aURI)
//---------------------------------------------------------------------- //----------------------------------------------------------------------
static JSObject*
GetJSObjectChild(nsWrapperCache* aCache)
{
if (aCache->PreservingWrapper()) {
return aCache->GetWrapperPreserveColor();
}
return aCache->GetExpandoObjectPreserveColor();
}
static bool
NeedsScriptTraverse(nsWrapperCache* aCache)
{
JSObject* o = GetJSObjectChild(aCache);
return o && xpc_IsGrayGCThing(o);
}
//----------------------------------------------------------------------
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList) NS_IMPL_CYCLE_COLLECTING_ADDREF(nsChildContentList)
NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList) NS_IMPL_CYCLE_COLLECTING_RELEASE(nsChildContentList)
// If nsChildContentList is changed so that any additional fields are
// traversed by the cycle collector, then CAN_SKIP must be updated.
NS_IMPL_CYCLE_COLLECTION_CLASS(nsChildContentList) NS_IMPL_CYCLE_COLLECTION_CLASS(nsChildContentList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsChildContentList) NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsChildContentList)
NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_UNLINK_PRESERVED_WRAPPER
@ -1714,6 +1734,20 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsChildContentList)
NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER NS_IMPL_CYCLE_COLLECTION_TRACE_PRESERVED_WRAPPER
NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRACE_END
// nsChildContentList only ever has a single child, its wrapper, so if
// the wrapper is black, the list can't be part of a garbage cycle.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_BEGIN(nsChildContentList)
return !NeedsScriptTraverse(tmp);
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_END
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_BEGIN(nsChildContentList)
return !NeedsScriptTraverse(tmp);
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_IN_CC_END
// CanSkipThis returns false to avoid problems with incomplete unlinking.
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_BEGIN(nsChildContentList)
NS_IMPL_CYCLE_COLLECTION_CAN_SKIP_THIS_END
NS_INTERFACE_TABLE_HEAD(nsChildContentList) NS_INTERFACE_TABLE_HEAD(nsChildContentList)
NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY NS_WRAPPERCACHE_INTERFACE_MAP_ENTRY
NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsChildContentList) NS_NODELIST_OFFSET_AND_INTERFACE_TABLE_BEGIN(nsChildContentList)
@ -4405,22 +4439,6 @@ NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(nsGenericElement)
nsINode::Trace(tmp, aCallback, aClosure); nsINode::Trace(tmp, aCallback, aClosure);
NS_IMPL_CYCLE_COLLECTION_TRACE_END NS_IMPL_CYCLE_COLLECTION_TRACE_END
static JSObject*
GetJSObjectChild(nsINode* aNode)
{
if (aNode->PreservingWrapper()) {
return aNode->GetWrapperPreserveColor();
}
return aNode->GetExpandoObjectPreserveColor();
}
static bool
NeedsScriptTraverse(nsINode* aNode)
{
JSObject* o = GetJSObjectChild(aNode);
return o && xpc_IsGrayGCThing(o);
}
void void
nsGenericElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild, nsGenericElement::MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
void* aData) void* aData)

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

@ -102,7 +102,7 @@ public:
} }
NS_DECL_CYCLE_COLLECTING_ISUPPORTS NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS(nsChildContentList) NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
// nsWrapperCache // nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope, virtual JSObject* WrapObject(JSContext *cx, XPCWrappedNativeScope *scope,

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

@ -201,24 +201,24 @@ function testSlice(file, size, type, contents, fileType) {
ok(file instanceof File, fileType + " file is a File"); ok(file instanceof File, fileType + " file is a File");
ok(file instanceof Blob, fileType + " file is also a Blob"); ok(file instanceof Blob, fileType + " file is also a Blob");
var slice = file.mozSlice(0, size); var slice = file.slice(0, size);
ok(slice instanceof Blob, fileType + " fullsize slice is a Blob"); ok(slice instanceof Blob, fileType + " fullsize slice is a Blob");
ok(!(slice instanceof File), fileType + " fullsize slice is not a File"); ok(!(slice instanceof File), fileType + " fullsize slice is not a File");
slice = file.mozSlice(0, 1234); slice = file.slice(0, 1234);
ok(slice instanceof Blob, fileType + " sized slice is a Blob"); ok(slice instanceof Blob, fileType + " sized slice is a Blob");
ok(!(slice instanceof File), fileType + " sized slice is not a File"); ok(!(slice instanceof File), fileType + " sized slice is not a File");
slice = file.mozSlice(0, size, "foo/bar"); slice = file.slice(0, size, "foo/bar");
is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type"); is(slice.type, "foo/bar", fileType + " fullsize slice foo/bar type");
slice = file.mozSlice(0, 5432, "foo/bar"); slice = file.slice(0, 5432, "foo/bar");
is(slice.type, "foo/bar", fileType + " sized slice foo/bar type"); is(slice.type, "foo/bar", fileType + " sized slice foo/bar type");
is(slice.mozSlice(0, 10).type, "", fileType + " slice-slice type"); is(slice.slice(0, 10).type, "", fileType + " slice-slice type");
is(slice.mozSlice(0, 10).size, 10, fileType + " slice-slice size"); is(slice.slice(0, 10).size, 10, fileType + " slice-slice size");
is(slice.mozSlice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type"); is(slice.slice(0, 10, "hello/world").type, "hello/world", fileType + " slice-slice hello/world type");
is(slice.mozSlice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size"); is(slice.slice(0, 10, "hello/world").size, 10, fileType + " slice-slice hello/world size");
// Start, end, expected size // Start, end, expected size
var indexes = [[0, size, size], var indexes = [[0, size, size],
@ -247,17 +247,17 @@ function testSlice(file, size, type, contents, fileType) {
var sliceContents; var sliceContents;
var testName; var testName;
if (indexes[i][0] == undefined) { if (indexes[i][0] == undefined) {
slice = file.mozSlice(); slice = file.slice();
sliceContents = contents.slice(); sliceContents = contents.slice();
testName = fileType + " slice()"; testName = fileType + " slice()";
} }
else if (indexes[i][1] == undefined) { else if (indexes[i][1] == undefined) {
slice = file.mozSlice(indexes[i][0]); slice = file.slice(indexes[i][0]);
sliceContents = contents.slice(indexes[i][0]); sliceContents = contents.slice(indexes[i][0]);
testName = fileType + " slice(" + indexes[i][0] + ")"; testName = fileType + " slice(" + indexes[i][0] + ")";
} }
else { else {
slice = file.mozSlice(indexes[i][0], indexes[i][1]); slice = file.slice(indexes[i][0], indexes[i][1]);
sliceContents = contents.slice(indexes[i][0], indexes[i][1]); sliceContents = contents.slice(indexes[i][0], indexes[i][1]);
testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")"; testName = fileType + " slice(" + indexes[i][0] + ", " + indexes[i][1] + ")";
} }
@ -268,11 +268,11 @@ function testSlice(file, size, type, contents, fileType) {
} }
// Slice of slice // Slice of slice
var slice = file.mozSlice(0, 40000); var slice = file.slice(0, 40000);
testFile(slice.mozSlice(5000, 42000), contents.slice(5000, 40000), "file slice slice"); testFile(slice.slice(5000, 42000), contents.slice(5000, 40000), "file slice slice");
// ...of slice of slice // ...of slice of slice
slice = slice.mozSlice(5000, 42000).mozSlice(400, 700); slice = slice.slice(5000, 42000).slice(400, 700);
SpecialPowers.gc(); SpecialPowers.gc();
testFile(slice, contents.slice(5400, 5700), "file slice slice slice"); testFile(slice, contents.slice(5400, 5700), "file slice slice slice");
} }

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

@ -151,7 +151,7 @@ function doTest(data) {
ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob"); ok(blob instanceof Blob, "Test " + testCounter + " blob is a Blob");
ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File"); ok(!(blob instanceof File), "Test " + testCounter + " blob is not a File");
let slice = blob.mozSlice(test.start, test.start + test.length); let slice = blob.slice(test.start, test.start + test.length);
ok(slice, "Test " + testCounter + " got slice"); ok(slice, "Test " + testCounter + " got slice");
ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob"); ok(slice instanceof Blob, "Test " + testCounter + " slice is a Blob");
ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File"); ok(!(slice instanceof File), "Test " + testCounter + " slice is not a File");

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

@ -104,7 +104,7 @@ function imageLoadHandler(event) {
var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData); var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)"); is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
var img = new Image; var img = new Image;
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size)); img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler; img.onload = imageLoadHandler;
expectedTestCount++; expectedTestCount++;
@ -112,7 +112,7 @@ expectedTestCount++;
var imgfile = createFileWithData(fileData + testBinaryData); var imgfile = createFileWithData(fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length, "correct file size (start)"); is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
var img = new Image; var img = new Image;
img.src = URL.createObjectURL(imgfile.mozSlice(0, size)); img.src = URL.createObjectURL(imgfile.slice(0, size));
img.onload = imageLoadHandler; img.onload = imageLoadHandler;
expectedTestCount++; expectedTestCount++;
@ -120,7 +120,7 @@ expectedTestCount++;
var imgfile = createFileWithData(testBinaryData + fileData); var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size (end)"); is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
var img = new Image; var img = new Image;
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size)); img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size));
img.onload = imageLoadHandler; img.onload = imageLoadHandler;
expectedTestCount++; expectedTestCount++;
@ -128,7 +128,7 @@ expectedTestCount++;
var imgfile = createFileWithData(testBinaryData + fileData); var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size (past end)"); is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
var img = new Image; var img = new Image;
img.src = URL.createObjectURL(imgfile.mozSlice(testBinaryData.length, testBinaryData.length + size + 1000)); img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, testBinaryData.length + size + 1000));
img.onload = imageLoadHandler; img.onload = imageLoadHandler;
expectedTestCount++; expectedTestCount++;

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

@ -1024,7 +1024,7 @@ struct WebGLVertexAttribData {
} }
}; };
class WebGLBuffer class WebGLBuffer MOZ_FINAL
: public nsIWebGLBuffer : public nsIWebGLBuffer
, public WebGLRefCountedObject<WebGLBuffer> , public WebGLRefCountedObject<WebGLBuffer>
, public WebGLContextBoundObject , public WebGLContextBoundObject
@ -1158,7 +1158,7 @@ protected:
void* mData; // in the case of an Element Array Buffer, we keep a copy. void* mData; // in the case of an Element Array Buffer, we keep a copy.
}; };
class WebGLTexture class WebGLTexture MOZ_FINAL
: public nsIWebGLTexture : public nsIWebGLTexture
, public WebGLRefCountedObject<WebGLTexture> , public WebGLRefCountedObject<WebGLTexture>
, public WebGLContextBoundObject , public WebGLContextBoundObject
@ -1608,7 +1608,7 @@ public:
} }
}; };
class WebGLShader class WebGLShader MOZ_FINAL
: public nsIWebGLShader : public nsIWebGLShader
, public WebGLRefCountedObject<WebGLShader> , public WebGLRefCountedObject<WebGLShader>
, public WebGLContextBoundObject , public WebGLContextBoundObject
@ -1673,7 +1673,7 @@ protected:
WebGLMonotonicHandle mMonotonicHandle; WebGLMonotonicHandle mMonotonicHandle;
}; };
class WebGLProgram class WebGLProgram MOZ_FINAL
: public nsIWebGLProgram : public nsIWebGLProgram
, public WebGLRefCountedObject<WebGLProgram> , public WebGLRefCountedObject<WebGLProgram>
, public WebGLContextBoundObject , public WebGLContextBoundObject
@ -1795,7 +1795,7 @@ protected:
WebGLMonotonicHandle mMonotonicHandle; WebGLMonotonicHandle mMonotonicHandle;
}; };
class WebGLRenderbuffer class WebGLRenderbuffer MOZ_FINAL
: public nsIWebGLRenderbuffer : public nsIWebGLRenderbuffer
, public WebGLRefCountedObject<WebGLRenderbuffer> , public WebGLRefCountedObject<WebGLRenderbuffer>
, public WebGLRectangleObject , public WebGLRectangleObject
@ -2001,7 +2001,7 @@ public:
} }
}; };
class WebGLFramebuffer class WebGLFramebuffer MOZ_FINAL
: public nsIWebGLFramebuffer : public nsIWebGLFramebuffer
, public WebGLRefCountedObject<WebGLFramebuffer> , public WebGLRefCountedObject<WebGLFramebuffer>
, public WebGLContextBoundObject , public WebGLContextBoundObject
@ -2296,7 +2296,7 @@ public:
WebGLMonotonicHandle mMonotonicHandle; WebGLMonotonicHandle mMonotonicHandle;
}; };
class WebGLUniformLocation class WebGLUniformLocation MOZ_FINAL
: public nsIWebGLUniformLocation : public nsIWebGLUniformLocation
, public WebGLContextBoundObject , public WebGLContextBoundObject
, public WebGLRefCountedObject<WebGLUniformLocation> , public WebGLRefCountedObject<WebGLUniformLocation>
@ -2337,7 +2337,7 @@ protected:
friend class WebGLProgram; friend class WebGLProgram;
}; };
class WebGLActiveInfo class WebGLActiveInfo MOZ_FINAL
: public nsIWebGLActiveInfo : public nsIWebGLActiveInfo
{ {
public: public:
@ -2356,7 +2356,7 @@ protected:
nsString mName; nsString mName;
}; };
class WebGLShaderPrecisionFormat class WebGLShaderPrecisionFormat MOZ_FINAL
: public nsIWebGLShaderPrecisionFormat : public nsIWebGLShaderPrecisionFormat
{ {
public: public:

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

@ -4377,7 +4377,7 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
// ESSL backend // ESSL backend
compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(), compiler = ShConstructCompiler((ShShaderType) shader->ShaderType(),
SH_WEBGL_SPEC, SH_WEBGL_SPEC,
#ifdef MOZ_WIDGET_ANDROID #ifdef ANDROID
SH_GLSL_OUTPUT, SH_GLSL_OUTPUT,
#else #else
gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT, gl->IsGLES2() ? SH_ESSL_OUTPUT : SH_GLSL_OUTPUT,

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

@ -180,7 +180,7 @@ CopyContext(gfxContext* dest, gfxContext* src)
**/ **/
#define NS_CANVASGRADIENT_PRIVATE_IID \ #define NS_CANVASGRADIENT_PRIVATE_IID \
{ 0x491d39d8, 0x4058, 0x42bd, { 0xac, 0x76, 0x70, 0xd5, 0x62, 0x7f, 0x02, 0x10 } } { 0x491d39d8, 0x4058, 0x42bd, { 0xac, 0x76, 0x70, 0xd5, 0x62, 0x7f, 0x02, 0x10 } }
class nsCanvasGradient : public nsIDOMCanvasGradient class nsCanvasGradient MOZ_FINAL : public nsIDOMCanvasGradient
{ {
public: public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASGRADIENT_PRIVATE_IID)
@ -238,7 +238,7 @@ NS_INTERFACE_MAP_END
**/ **/
#define NS_CANVASPATTERN_PRIVATE_IID \ #define NS_CANVASPATTERN_PRIVATE_IID \
{ 0xb85c6c8a, 0x0624, 0x4530, { 0xb8, 0xee, 0xff, 0xdf, 0x42, 0xe8, 0x21, 0x6d } } { 0xb85c6c8a, 0x0624, 0x4530, { 0xb8, 0xee, 0xff, 0xdf, 0x42, 0xe8, 0x21, 0x6d } }
class nsCanvasPattern : public nsIDOMCanvasPattern class nsCanvasPattern MOZ_FINAL : public nsIDOMCanvasPattern
{ {
public: public:
NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERN_PRIVATE_IID) NS_DECLARE_STATIC_IID_ACCESSOR(NS_CANVASPATTERN_PRIVATE_IID)

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

@ -7,3 +7,5 @@ conformance/more/conformance/quickCheckAPI-S_V.html
conformance/glsl/misc/attrib-location-length-limits.html conformance/glsl/misc/attrib-location-length-limits.html
conformance/glsl/misc/uniform-location-length-limits.html conformance/glsl/misc/uniform-location-length-limits.html
conformance/programs/program-test.html conformance/programs/program-test.html
conformance/textures/texture-mips.html
conformance/textures/texture-npot.html

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

@ -180,8 +180,7 @@ nsDOMEvent::InitPresContextData(nsPresContext* aPresContext)
// Get the explicit original target (if it's anonymous make it null) // Get the explicit original target (if it's anonymous make it null)
{ {
nsCOMPtr<nsIContent> content = GetTargetFromFrame(); nsCOMPtr<nsIContent> content = GetTargetFromFrame();
mTmpRealOriginalTarget = do_QueryInterface(content); mExplicitOriginalTarget = do_QueryInterface(content);
mExplicitOriginalTarget = mTmpRealOriginalTarget;
if (content && content->IsInAnonymousSubtree()) { if (content && content->IsInAnonymousSubtree()) {
mExplicitOriginalTarget = nsnull; mExplicitOriginalTarget = nsnull;
} }
@ -237,10 +236,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMEvent)
} }
} }
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPresContext); NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mPresContext);
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTmpRealOriginalTarget) NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mExplicitOriginalTarget);
// Always set mExplicitOriginalTarget to null, when
// mTmpRealOriginalTarget doesn't point to any object!
tmp->mExplicitOriginalTarget = nsnull;
NS_IMPL_CYCLE_COLLECTION_UNLINK_END NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
@ -275,7 +271,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMEvent)
} }
} }
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mPresContext.get(), nsPresContext) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NATIVE_MEMBER(mPresContext.get(), nsPresContext)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTmpRealOriginalTarget) NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mExplicitOriginalTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
// nsIDOMEventInterface // nsIDOMEventInterface
@ -355,18 +351,6 @@ nsDOMEvent::GetExplicitOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
return GetTarget(aRealEventTarget); return GetTarget(aRealEventTarget);
} }
NS_IMETHODIMP
nsDOMEvent::GetTmpRealOriginalTarget(nsIDOMEventTarget** aRealEventTarget)
{
if (mTmpRealOriginalTarget) {
*aRealEventTarget = mTmpRealOriginalTarget;
NS_ADDREF(*aRealEventTarget);
return NS_OK;
}
return GetOriginalTarget(aRealEventTarget);
}
NS_IMETHODIMP NS_IMETHODIMP
nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget) nsDOMEvent::GetOriginalTarget(nsIDOMEventTarget** aOriginalTarget)
{ {

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

@ -267,8 +267,7 @@ protected:
nsEvent* mEvent; nsEvent* mEvent;
nsRefPtr<nsPresContext> mPresContext; nsRefPtr<nsPresContext> mPresContext;
nsCOMPtr<nsIDOMEventTarget> mTmpRealOriginalTarget; nsCOMPtr<nsIDOMEventTarget> mExplicitOriginalTarget;
nsIDOMEventTarget* mExplicitOriginalTarget;
nsString mCachedType; nsString mCachedType;
bool mEventIsInternal; bool mEventIsInternal;
bool mPrivateDataDuplicated; bool mPrivateDataDuplicated;

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

@ -2081,14 +2081,12 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
if (!dataTransfer) if (!dataTransfer)
return; return;
bool isInEditor = false; nsCOMPtr<nsISelection> selection;
bool isSelection = false;
nsCOMPtr<nsIContent> eventContent, targetContent; nsCOMPtr<nsIContent> eventContent, targetContent;
mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent)); mCurrentTarget->GetContentForEvent(aEvent, getter_AddRefs(eventContent));
if (eventContent) if (eventContent)
DetermineDragTarget(aPresContext, eventContent, dataTransfer, DetermineDragTarget(aPresContext, eventContent, dataTransfer,
&isSelection, &isInEditor, getter_AddRefs(selection), getter_AddRefs(targetContent));
getter_AddRefs(targetContent));
// Stop tracking the drag gesture now. This should stop us from // Stop tracking the drag gesture now. This should stop us from
// reentering GenerateDragGesture inside DOM event processing. // reentering GenerateDragGesture inside DOM event processing.
@ -2129,9 +2127,8 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
// elements in an editor, only fire the draggesture event so that the // elements in an editor, only fire the draggesture event so that the
// editor code can handle it but content doesn't see a dragstart. // editor code can handle it but content doesn't see a dragstart.
nsEventStatus status = nsEventStatus_eIgnore; nsEventStatus status = nsEventStatus_eIgnore;
if (!isInEditor) nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull,
nsEventDispatcher::Dispatch(targetContent, aPresContext, &startEvent, nsnull, &status);
&status);
nsDragEvent* event = &startEvent; nsDragEvent* event = &startEvent;
if (status != nsEventStatus_eConsumeNoDefault) { if (status != nsEventStatus_eConsumeNoDefault) {
@ -2148,7 +2145,7 @@ nsEventStateManager::GenerateDragGesture(nsPresContext* aPresContext,
if (status != nsEventStatus_eConsumeNoDefault) { if (status != nsEventStatus_eConsumeNoDefault) {
bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer, bool dragStarted = DoDefaultDragStart(aPresContext, event, dataTransfer,
targetContent, isSelection); targetContent, selection);
if (dragStarted) { if (dragStarted) {
sActiveESM = nsnull; sActiveESM = nsnull;
aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH; aEvent->flags |= NS_EVENT_FLAG_STOP_DISPATCH;
@ -2173,37 +2170,27 @@ void
nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext, nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* aSelectionTarget, nsIContent* aSelectionTarget,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
bool* aIsSelection, nsISelection** aSelection,
bool* aIsInEditor,
nsIContent** aTargetNode) nsIContent** aTargetNode)
{ {
*aTargetNode = nsnull; *aTargetNode = nsnull;
*aIsInEditor = false;
nsCOMPtr<nsISupports> container = aPresContext->GetContainer(); nsCOMPtr<nsISupports> container = aPresContext->GetContainer();
nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container); nsCOMPtr<nsIDOMWindow> window = do_GetInterface(container);
// GetDragData determines if a selection, link or image in the content // GetDragData determines if a selection, link or image in the content
// should be dragged, and places the data associated with the drag in the // should be dragged, and places the data associated with the drag in the
// data transfer. Skip this check for chrome shells. // data transfer.
// mGestureDownContent is the node where the mousedown event for the drag
// occurred, and aSelectionTarget is the node to use when a selection is used
bool canDrag; bool canDrag;
nsCOMPtr<nsIContent> dragDataNode; nsCOMPtr<nsIContent> dragDataNode;
nsCOMPtr<nsIDocShellTreeItem> dsti = do_QueryInterface(container); nsresult rv = nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
if (dsti) { aSelectionTarget, mGestureDownAlt,
PRInt32 type = -1; aDataTransfer, &canDrag, aSelection,
if (NS_SUCCEEDED(dsti->GetItemType(&type)) && getter_AddRefs(dragDataNode));
type != nsIDocShellTreeItem::typeChrome) { if (NS_FAILED(rv) || !canDrag)
// mGestureDownContent is the node where the mousedown event for the drag return;
// occurred, and aSelectionTarget is the node to use when a selection is used
nsresult rv =
nsContentAreaDragDrop::GetDragData(window, mGestureDownContent,
aSelectionTarget, mGestureDownAlt,
aDataTransfer, &canDrag, aIsSelection,
getter_AddRefs(dragDataNode));
if (NS_FAILED(rv) || !canDrag)
return;
}
}
// if GetDragData returned a node, use that as the node being dragged. // if GetDragData returned a node, use that as the node being dragged.
// Otherwise, if a selection is being dragged, use the node within the // Otherwise, if a selection is being dragged, use the node within the
@ -2211,7 +2198,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* dragContent = mGestureDownContent; nsIContent* dragContent = mGestureDownContent;
if (dragDataNode) if (dragDataNode)
dragContent = dragDataNode; dragContent = dragDataNode;
else if (*aIsSelection) else if (*aSelection)
dragContent = aSelectionTarget; dragContent = aSelectionTarget;
nsIContent* originalDragContent = dragContent; nsIContent* originalDragContent = dragContent;
@ -2220,7 +2207,7 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
// draggable property set. If one is found, use that as the target of the // draggable property set. If one is found, use that as the target of the
// drag instead of the node that was clicked on. If a draggable node wasn't // drag instead of the node that was clicked on. If a draggable node wasn't
// found, just use the clicked node. // found, just use the clicked node.
if (!*aIsSelection) { if (!*aSelection) {
while (dragContent) { while (dragContent) {
nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(dragContent); nsCOMPtr<nsIDOMHTMLElement> htmlElement = do_QueryInterface(dragContent);
if (htmlElement) { if (htmlElement) {
@ -2245,17 +2232,6 @@ nsEventStateManager::DetermineDragTarget(nsPresContext* aPresContext,
// otherwise, it's not an HTML or XUL element, so just keep looking // otherwise, it's not an HTML or XUL element, so just keep looking
} }
dragContent = dragContent->GetParent(); dragContent = dragContent->GetParent();
// if an editable parent is encountered, then we don't look at any
// ancestors. This is used because the editor attaches a draggesture
// listener to the editable element and we want to call it without
// making the editable element draggable. This should be removed once
// the editor is switched over to using the proper drag and drop api.
nsCOMPtr<nsIDOMNSEditableElement> editableElement = do_QueryInterface(dragContent);
if (editableElement) {
*aIsInEditor = true;
break;
}
} }
} }
@ -2279,7 +2255,7 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
nsDragEvent* aDragEvent, nsDragEvent* aDragEvent,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
nsIContent* aDragTarget, nsIContent* aDragTarget,
bool aIsSelection) nsISelection* aSelection)
{ {
nsCOMPtr<nsIDragService> dragService = nsCOMPtr<nsIDragService> dragService =
do_GetService("@mozilla.org/widget/dragservice;1"); do_GetService("@mozilla.org/widget/dragservice;1");
@ -2333,22 +2309,6 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
PRInt32 imageX, imageY; PRInt32 imageX, imageY;
nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY); nsIDOMElement* dragImage = aDataTransfer->GetDragImage(&imageX, &imageY);
// If a selection is being dragged, and no custom drag image was
// set, get the selection so that the drag region can be created
// from the selection area. If a custom image was set, it doesn't
// matter what the selection is since the image will be used instead.
nsISelection* selection = nsnull;
if (aIsSelection && !dragImage) {
nsIDocument* doc = aDragTarget->GetCurrentDoc();
if (doc) {
nsIPresShell* presShell = doc->GetShell();
if (presShell) {
selection = presShell->GetCurrentSelection(
nsISelectionController::SELECTION_NORMAL);
}
}
}
nsCOMPtr<nsISupportsArray> transArray; nsCOMPtr<nsISupportsArray> transArray;
aDataTransfer->GetTransferables(getter_AddRefs(transArray)); aDataTransfer->GetTransferables(getter_AddRefs(transArray));
if (!transArray) if (!transArray)
@ -2363,8 +2323,13 @@ nsEventStateManager::DoDefaultDragStart(nsPresContext* aPresContext,
nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent); nsCOMPtr<nsIDOMDragEvent> domDragEvent = do_QueryInterface(domEvent);
// if creating a drag event failed, starting a drag session will // if creating a drag event failed, starting a drag session will
// just fail. // just fail.
if (selection) {
dragService->InvokeDragSessionWithSelection(selection, transArray, // Use InvokeDragSessionWithSelection if a selection is being dragged,
// such that the image can be generated from the selected text. However,
// use InvokeDragSessionWithImage if a custom image was set or something
// other than a selection is being dragged.
if (!dragImage && aSelection) {
dragService->InvokeDragSessionWithSelection(aSelection, transArray,
action, domDragEvent, action, domDragEvent,
aDataTransfer); aDataTransfer);
} }

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

@ -417,15 +417,13 @@ protected:
* *
* aSelectionTarget - target to check for selection * aSelectionTarget - target to check for selection
* aDataTransfer - data transfer object that will contain the data to drag * aDataTransfer - data transfer object that will contain the data to drag
* aIsSelection - [out] set to true if a selection is being dragged * aSelection - [out] set to the selection to be dragged
* aIsInEditor - [out] set to true if the content is in an editor field
* aTargetNode - [out] the draggable node, or null if there isn't one * aTargetNode - [out] the draggable node, or null if there isn't one
*/ */
void DetermineDragTarget(nsPresContext* aPresContext, void DetermineDragTarget(nsPresContext* aPresContext,
nsIContent* aSelectionTarget, nsIContent* aSelectionTarget,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
bool* aIsSelection, nsISelection** aSelection,
bool* aIsInEditor,
nsIContent** aTargetNode); nsIContent** aTargetNode);
/* /*
@ -436,13 +434,13 @@ protected:
* aDragEvent - the dragstart/draggesture event * aDragEvent - the dragstart/draggesture event
* aDataTransfer - the data transfer that holds the data to be dragged * aDataTransfer - the data transfer that holds the data to be dragged
* aDragTarget - the target of the drag * aDragTarget - the target of the drag
* aIsSelection - true if a selection is being dragged * aSelection - the selection to be dragged
*/ */
bool DoDefaultDragStart(nsPresContext* aPresContext, bool DoDefaultDragStart(nsPresContext* aPresContext,
nsDragEvent* aDragEvent, nsDragEvent* aDragEvent,
nsDOMDataTransfer* aDataTransfer, nsDOMDataTransfer* aDataTransfer,
nsIContent* aDragTarget, nsIContent* aDragTarget,
bool aIsSelection); nsISelection* aSelection);
bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; } bool IsTrackingDragGesture ( ) const { return mGestureDownContent != nsnull; }
/** /**

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

@ -109,7 +109,6 @@ _TEST_FILES = \
test_bug495300.html \ test_bug495300.html \
test_bug686942.html \ test_bug686942.html \
test_can_play_type.html \ test_can_play_type.html \
test_closing_connections.html \
test_constants.html \ test_constants.html \
test_controls.html \ test_controls.html \
test_currentTime.html \ test_currentTime.html \
@ -176,6 +175,8 @@ endif
# test_mixed_principals.html # test_mixed_principals.html
# Disabled since we don't play Wave files standalone, for now # Disabled since we don't play Wave files standalone, for now
# test_audioDocumentTitle.html # test_audioDocumentTitle.html
# Bug 634564:
# test_closing_connections.html \
# sample files # sample files
_TEST_FILES += \ _TEST_FILES += \

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

@ -1486,7 +1486,8 @@ nsSVGElement::GetCtx() const
} }
/* virtual */ gfxMatrix /* virtual */ gfxMatrix
nsSVGElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const nsSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{ {
return aMatrix; return aMatrix;
} }

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

@ -151,11 +151,36 @@ public:
// nsnull for outer <svg> or SVG without an <svg> parent (invalid SVG). // nsnull for outer <svg> or SVG without an <svg> parent (invalid SVG).
nsSVGSVGElement* GetCtx() const; nsSVGSVGElement* GetCtx() const;
enum TransformTypes {
eAllTransforms
,eUserSpaceToParent
,eChildToUserSpace
};
/** /**
* Returns aMatrix post-multiplied by the transform from the userspace * Returns aMatrix pre-multiplied by (explicit or implicit) transforms that
* established by this element to the userspace established by its parent. * are introduced by attributes on this element.
*
* If aWhich is eAllTransforms, then all the transforms from the coordinate
* space established by this element for its children to the coordinate
* space established by this element's parent element for this element, are
* included.
*
* If aWhich is eUserSpaceToParent, then only the transforms from this
* element's userspace to the coordinate space established by its parent is
* included. This includes any transforms introduced by the 'transform'
* attribute, transform animations and animateMotion, but not any offsets
* due to e.g. 'x'/'y' attributes, or any transform due to a 'viewBox'
* attribute. (SVG userspace is defined to be the coordinate space in which
* coordinates on an element apply.)
*
* If aWhich is eChildToUserSpace, then only the transforms from the
* coordinate space established by this element for its childre to this
* elements userspace are included. This includes any offsets due to e.g.
* 'x'/'y' attributes, and any transform due to a 'viewBox' attribute, but
* does not include any transforms due to the 'transform' attribute.
*/ */
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const; virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// Setter for to set the current <animateMotion> transformation // Setter for to set the current <animateMotion> transformation
// Only visible for nsSVGGraphicElement, so it's a no-op here, and that // Only visible for nsSVGGraphicElement, so it's a no-op here, and that

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

@ -112,16 +112,28 @@ NS_IMETHODIMP nsSVGForeignObjectElement::GetHeight(nsIDOMSVGAnimatedLength * *aH
// nsSVGElement methods // nsSVGElement methods
/* virtual */ gfxMatrix /* virtual */ gfxMatrix
nsSVGForeignObjectElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const nsSVGForeignObjectElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{ {
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
// 'transform' attribute: // 'transform' attribute:
gfxMatrix matrix = nsSVGForeignObjectElementBase::PrependLocalTransformTo(aMatrix); gfxMatrix fromUserSpace =
nsSVGForeignObjectElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
// now translate by our 'x' and 'y': if (aWhich == eUserSpaceToParent) {
return fromUserSpace;
}
// our 'x' and 'y' attributes:
float x, y; float x, y;
const_cast<nsSVGForeignObjectElement*>(this)-> const_cast<nsSVGForeignObjectElement*>(this)->
GetAnimatedLengthValues(&x, &y, nsnull); GetAnimatedLengthValues(&x, &y, nsnull);
return gfxMatrix().Translate(gfxPoint(x, y)) * matrix; gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
if (aWhich == eChildToUserSpace) {
return toUserSpace;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
return toUserSpace * fromUserSpace;
} }
//---------------------------------------------------------------------- //----------------------------------------------------------------------

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

@ -69,7 +69,8 @@ public:
NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::) NS_FORWARD_NSIDOMSVGELEMENT(nsSVGForeignObjectElementBase::)
// nsSVGElement specializations: // nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const; virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsIContent interface // nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const; NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* name) const;

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

@ -189,10 +189,25 @@ nsSVGGraphicElement::IsEventName(nsIAtom* aName)
} }
gfxMatrix gfxMatrix
nsSVGGraphicElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const nsSVGGraphicElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{ {
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
gfxMatrix result(aMatrix); gfxMatrix result(aMatrix);
if (aWhich == eChildToUserSpace) {
// We don't have anything to prepend.
// eChildToUserSpace is not the common case, which is why we return
// 'result' to benefit from NRVO rather than returning aMatrix before
// creating 'result'.
return result;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms || aWhich == eUserSpaceToParent,
"Unknown TransformTypes");
// animateMotion's resulting transform is supposed to apply *on top of* // animateMotion's resulting transform is supposed to apply *on top of*
// any transformations from the |transform| attribute. So since we're // any transformations from the |transform| attribute. So since we're
// PRE-multiplying, we need to apply the animateMotion transform *first*. // PRE-multiplying, we need to apply the animateMotion transform *first*.

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

@ -62,7 +62,8 @@ public:
// nsIContent interface // nsIContent interface
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const; NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const;
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const; virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix); virtual void SetAnimateMotionTransform(const gfxMatrix* aMatrix);
virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList(); virtual mozilla::SVGAnimatedTransformList* GetAnimatedTransformList();

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

@ -440,7 +440,7 @@ nsSVGPathElement::GetPathLengthScale(PathLengthScaleForType aFor)
// For textPath, a transform on the referenced path affects the // For textPath, a transform on the referenced path affects the
// textPath layout, so when calculating the actual path length // textPath layout, so when calculating the actual path length
// we need to take that into account. // we need to take that into account.
matrix = PrependLocalTransformTo(matrix); matrix = PrependLocalTransformsTo(matrix);
} }
nsRefPtr<gfxFlattenedPath> path = GetFlattenedPath(matrix); nsRefPtr<gfxFlattenedPath> path = GetFlattenedPath(matrix);
if (path) { if (path) {

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

@ -750,7 +750,16 @@ nsSVGSVGElement::GetCTM(nsIDOMSVGMatrix * *aCTM)
NS_IMETHODIMP NS_IMETHODIMP
nsSVGSVGElement::GetScreenCTM(nsIDOMSVGMatrix **aCTM) nsSVGSVGElement::GetScreenCTM(nsIDOMSVGMatrix **aCTM)
{ {
gfxMatrix m = nsSVGUtils::GetCTM(this, true); gfxMatrix m;
if (IsRoot()) {
// Consistency with other elements would have us return only the
// eFromUserSpace transforms, but this is what we've been doing for
// a while, and it keeps us consistent with WebKit and Opera (if not
// really with the ambiguous spec).
m = PrependLocalTransformsTo(m);
} else {
m = nsSVGUtils::GetCTM(this, true);
}
*aCTM = m.IsSingular() ? nsnull : new DOMSVGMatrix(m); *aCTM = m.IsSingular() ? nsnull : new DOMSVGMatrix(m);
NS_IF_ADDREF(*aCTM); NS_IF_ADDREF(*aCTM);
return NS_OK; return NS_OK;
@ -1180,12 +1189,29 @@ nsSVGSVGElement::GetLength(PRUint8 aCtxType)
// nsSVGElement methods // nsSVGElement methods
/* virtual */ gfxMatrix /* virtual */ gfxMatrix
nsSVGSVGElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const nsSVGSVGElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{ {
NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
"Skipping eUserSpaceToParent transforms makes no sense");
if (IsInner()) { if (IsInner()) {
float x, y; float x, y;
const_cast<nsSVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull); const_cast<nsSVGSVGElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull);
return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix; if (aWhich == eAllTransforms) {
// the common case
return GetViewBoxTransform() * gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
}
if (aWhich == eUserSpaceToParent) {
return gfxMatrix().Translate(gfxPoint(x, y)) * aMatrix;
}
NS_ABORT_IF_FALSE(aWhich == eChildToUserSpace, "Unknown TransformTypes");
return GetViewBoxTransform(); // no need to multiply identity aMatrix
}
if (aWhich == eUserSpaceToParent) {
// only inner-<svg> has eUserSpaceToParent transforms
return aMatrix;
} }
if (IsRoot()) { if (IsRoot()) {

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

@ -186,8 +186,9 @@ public:
virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor); virtual nsresult PreHandleEvent(nsEventChainPreVisitor& aVisitor);
// nsSVGElement specializations: // nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const; virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsSVGSVGElement methods: // nsSVGSVGElement methods:
float GetLength(PRUint8 mCtxType); float GetLength(PRUint8 mCtxType);

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

@ -488,15 +488,27 @@ nsSVGUseElement::UnlinkSource()
// nsSVGElement methods // nsSVGElement methods
/* virtual */ gfxMatrix /* virtual */ gfxMatrix
nsSVGUseElement::PrependLocalTransformTo(const gfxMatrix &aMatrix) const nsSVGUseElement::PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich) const
{ {
// 'transform' attribute: NS_ABORT_IF_FALSE(aWhich != eChildToUserSpace || aMatrix.IsIdentity(),
gfxMatrix matrix = nsSVGUseElementBase::PrependLocalTransformTo(aMatrix); "Skipping eUserSpaceToParent transforms makes no sense");
// now translate by our 'x' and 'y': // 'transform' attribute:
gfxMatrix fromUserSpace =
nsSVGUseElementBase::PrependLocalTransformsTo(aMatrix, aWhich);
if (aWhich == eUserSpaceToParent) {
return fromUserSpace;
}
// our 'x' and 'y' attributes:
float x, y; float x, y;
const_cast<nsSVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull); const_cast<nsSVGUseElement*>(this)->GetAnimatedLengthValues(&x, &y, nsnull);
return matrix.PreMultiply(gfxMatrix().Translate(gfxPoint(x, y))); gfxMatrix toUserSpace = gfxMatrix().Translate(gfxPoint(x, y));
if (aWhich == eChildToUserSpace) {
return toUserSpace;
}
NS_ABORT_IF_FALSE(aWhich == eAllTransforms, "Unknown TransformTypes");
return toUserSpace * fromUserSpace;
} }
nsSVGElement::LengthAttributesInfo nsSVGElement::LengthAttributesInfo

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

@ -103,7 +103,8 @@ public:
void DestroyAnonymousContent(); void DestroyAnonymousContent();
// nsSVGElement specializations: // nsSVGElement specializations:
virtual gfxMatrix PrependLocalTransformTo(const gfxMatrix &aMatrix) const; virtual gfxMatrix PrependLocalTransformsTo(const gfxMatrix &aMatrix,
TransformTypes aWhich = eAllTransforms) const;
// nsIContent interface // nsIContent interface
virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const; virtual nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;

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

@ -1,7 +1,7 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<svg xmlns="http://www.w3.org/2000/svg"> <svg xmlns="http://www.w3.org/2000/svg">
<g transform="scale(0.5)"> <g transform="scale(0.5)">
<foreignObject id="f" width="100" height="100"/> <foreignObject id="fO" x="10" y="10" width="100" height="100"/>
</g> </g>
<text id="b" x="20" y="20">b</text> <text id="b" x="20" y="20">b</text>
<text id="a" x="20" y="30">a</text> <text id="a" x="20" y="30">a</text>

До

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

После

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

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

@ -17,7 +17,7 @@
<svg id="inner" x="30" y="40" width="100" height="100"> <svg id="inner" x="30" y="40" width="100" height="100">
<g id="g1"/> <g id="g1"/>
</svg> </svg>
<foreignObject x="30" y="40" width="100" height="100" transform="translate(1, 1)"> <foreignObject id="fO" x="30" y="40" width="100" height="100" transform="translate(1, 1)">
<!-- current layout implementation ignores x="50" and y="60". <!-- current layout implementation ignores x="50" and y="60".
thus, I made getCTM and getScreenCTM do the same. --> thus, I made getCTM and getScreenCTM do the same. -->
<svg id="outer" x="50" y="60" width="100" height="100"> <svg id="outer" x="50" y="60" width="100" height="100">

До

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

После

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

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

@ -39,7 +39,7 @@ function run()
is(bbox1.height, bbox2.height, id1 + ".getBBox().height"); is(bbox1.height, bbox2.height, id1 + ".getBBox().height");
} }
checkBBox("f", 0, 0, 100, 100); checkBBox("fO", 10, 10, 100, 100);
checkBBoxHeight("a", "b"); checkBBoxHeight("a", "b");
checkBBoxHeight("a", "y"); checkBBoxHeight("a", "y");
checkBBox("v", 95, 45, 10, 155); checkBBox("v", 95, 45, 10, 155);

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