mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Merge m-c to m-i.
This commit is contained in:
commit
5489c9a378
@ -258,7 +258,7 @@ DocAccessibleWrap::DoInitialUpdate()
|
|||||||
|
|
||||||
a11y::RootAccessible* rootDocument = RootAccessible();
|
a11y::RootAccessible* rootDocument = RootAccessible();
|
||||||
|
|
||||||
mozilla::WindowsHandle nativeData = nsnull;
|
mozilla::WindowsHandle nativeData = NULL;
|
||||||
if (tabChild)
|
if (tabChild)
|
||||||
tabChild->SendGetWidgetNativeData(&nativeData);
|
tabChild->SendGetWidgetNativeData(&nativeData);
|
||||||
else
|
else
|
||||||
|
@ -122,11 +122,14 @@ var shell = {
|
|||||||
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
.sessionHistory = Cc["@mozilla.org/browser/shistory;1"]
|
||||||
.createInstance(Ci.nsISHistory);
|
.createInstance(Ci.nsISHistory);
|
||||||
|
|
||||||
['keydown', 'keypress', 'keyup'].forEach((function listenKey(type) {
|
// Capture all key events so we can filter out hardware buttons
|
||||||
window.addEventListener(type, this, false, true);
|
// And send them to Gaia via mozChromeEvents.
|
||||||
window.addEventListener(type, this, true, true);
|
// Ideally, hardware buttons wouldn't generate key events at all, or
|
||||||
}).bind(this));
|
// if they did, they would use keycodes that conform to DOM 3 Events.
|
||||||
|
// See discussion in https://bugzilla.mozilla.org/show_bug.cgi?id=762362
|
||||||
|
window.addEventListener('keydown', this, true);
|
||||||
|
window.addEventListener('keypress', this, true);
|
||||||
|
window.addEventListener('keyup', this, true);
|
||||||
window.addEventListener('MozApplicationManifest', this);
|
window.addEventListener('MozApplicationManifest', this);
|
||||||
window.addEventListener('mozfullscreenchange', this);
|
window.addEventListener('mozfullscreenchange', this);
|
||||||
window.addEventListener('sizemodechange', this);
|
window.addEventListener('sizemodechange', this);
|
||||||
@ -165,11 +168,9 @@ var shell = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
stop: function shell_stop() {
|
stop: function shell_stop() {
|
||||||
['keydown', 'keypress', 'keyup'].forEach((function unlistenKey(type) {
|
window.removeEventListener('keydown', this, true);
|
||||||
window.removeEventListener(type, this, false, true);
|
window.removeEventListener('keypress', this, true);
|
||||||
window.removeEventListener(type, this, true, true);
|
window.removeEventListener('keyup', this, true);
|
||||||
}).bind(this));
|
|
||||||
|
|
||||||
window.removeEventListener('MozApplicationManifest', this);
|
window.removeEventListener('MozApplicationManifest', this);
|
||||||
window.removeEventListener('mozfullscreenchange', this);
|
window.removeEventListener('mozfullscreenchange', this);
|
||||||
window.removeEventListener('sizemodechange', this);
|
window.removeEventListener('sizemodechange', this);
|
||||||
@ -180,33 +181,75 @@ var shell = {
|
|||||||
#endif
|
#endif
|
||||||
},
|
},
|
||||||
|
|
||||||
forwardKeyToContent: function shell_forwardKeyToContent(evt) {
|
// If this key event actually represents a hardware button, filter it here
|
||||||
let content = shell.contentBrowser.contentWindow;
|
// and send a mozChromeEvent with detail.type set to xxx-button-press or
|
||||||
let generatedEvent = content.document.createEvent('KeyboardEvent');
|
// xxx-button-release instead.
|
||||||
generatedEvent.initKeyEvent(evt.type, true, true, evt.view, evt.ctrlKey,
|
filterHardwareKeys: function shell_filterHardwareKeys(evt) {
|
||||||
evt.altKey, evt.shiftKey, evt.metaKey,
|
var type;
|
||||||
evt.keyCode, evt.charCode);
|
switch (evt.keyCode) {
|
||||||
|
case evt.DOM_VK_HOME: // Home button
|
||||||
|
type = 'home-button';
|
||||||
|
break;
|
||||||
|
case evt.DOM_VK_SLEEP: // Sleep button
|
||||||
|
type = 'sleep-button';
|
||||||
|
break;
|
||||||
|
case evt.DOM_VK_PAGE_UP: // Volume up button
|
||||||
|
type = 'volume-up-button';
|
||||||
|
break;
|
||||||
|
case evt.DOM_VK_PAGE_DOWN: // Volume down button
|
||||||
|
type = 'volume-down-button';
|
||||||
|
break;
|
||||||
|
case evt.DOM_VK_ESCAPE: // Back button (should be disabled)
|
||||||
|
type = 'back-button';
|
||||||
|
break;
|
||||||
|
case evt.DOM_VK_CONTEXT_MENU: // Menu button
|
||||||
|
type = 'menu-button';
|
||||||
|
break;
|
||||||
|
default: // Anything else is a real key
|
||||||
|
return; // Don't filter it at all; let it propagate to Gaia
|
||||||
|
}
|
||||||
|
|
||||||
content.document.documentElement.dispatchEvent(generatedEvent);
|
// If we didn't return, then the key event represents a hardware key
|
||||||
|
// and we need to prevent it from propagating to Gaia
|
||||||
|
evt.stopImmediatePropagation();
|
||||||
|
evt.preventDefault(); // Prevent keypress events (when #501496 is fixed).
|
||||||
|
|
||||||
|
// If it is a key down or key up event, we send a chrome event to Gaia.
|
||||||
|
// If it is a keypress event we just ignore it.
|
||||||
|
switch (evt.type) {
|
||||||
|
case 'keydown':
|
||||||
|
type = type + '-press';
|
||||||
|
break;
|
||||||
|
case 'keyup':
|
||||||
|
type = type + '-release';
|
||||||
|
break;
|
||||||
|
case 'keypress':
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// On my device, the physical hardware buttons (sleep and volume)
|
||||||
|
// send multiple events (press press release release), but the
|
||||||
|
// soft home button just sends one. This hack is to manually
|
||||||
|
// "debounce" the keys. If the type of this event is the same as
|
||||||
|
// the type of the last one, then don't send it. We'll never send
|
||||||
|
// two presses or two releases in a row.
|
||||||
|
// FIXME: https://bugzilla.mozilla.org/show_bug.cgi?id=761067
|
||||||
|
if (type !== this.lastHardwareButtonEventType) {
|
||||||
|
this.lastHardwareButtonEventType = type;
|
||||||
|
this.sendChromeEvent({type: type});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
lastHardwareButtonEventType: null, // property for the hack above
|
||||||
|
|
||||||
handleEvent: function shell_handleEvent(evt) {
|
handleEvent: function shell_handleEvent(evt) {
|
||||||
let content = this.contentBrowser.contentWindow;
|
let content = this.contentBrowser.contentWindow;
|
||||||
switch (evt.type) {
|
switch (evt.type) {
|
||||||
case 'keydown':
|
case 'keydown':
|
||||||
case 'keyup':
|
case 'keyup':
|
||||||
case 'keypress':
|
case 'keypress':
|
||||||
// Redirect the HOME key to System app and stop the applications from
|
this.filterHardwareKeys(evt);
|
||||||
// handling it.
|
|
||||||
let rootContentEvt = (evt.target.ownerDocument.defaultView == content);
|
|
||||||
if (!rootContentEvt && evt.eventPhase == evt.CAPTURING_PHASE &&
|
|
||||||
evt.keyCode == evt.DOM_VK_HOME) {
|
|
||||||
this.forwardKeyToContent(evt);
|
|
||||||
evt.preventDefault();
|
|
||||||
evt.stopImmediatePropagation();
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'mozfullscreenchange':
|
case 'mozfullscreenchange':
|
||||||
// When the screen goes fullscreen make sure to set the focus to the
|
// 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
|
// main window so noboby can prevent the ESC key to get out fullscreen
|
||||||
@ -272,6 +315,9 @@ var shell = {
|
|||||||
let event = content.document.createEvent('CustomEvent');
|
let event = content.document.createEvent('CustomEvent');
|
||||||
event.initCustomEvent(type, true, true, details ? details : {});
|
event.initCustomEvent(type, true, true, details ? details : {});
|
||||||
content.dispatchEvent(event);
|
content.dispatchEvent(event);
|
||||||
|
},
|
||||||
|
sendChromeEvent: function shell_sendChromeEvent(details) {
|
||||||
|
this.sendEvent(getContentWindow(), "mozChromeEvent", details);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -310,7 +356,7 @@ nsBrowserAccess.prototype = {
|
|||||||
Services.obs.addObserver(function onSystemMessage(subject, topic, data) {
|
Services.obs.addObserver(function onSystemMessage(subject, topic, data) {
|
||||||
let msg = JSON.parse(data);
|
let msg = JSON.parse(data);
|
||||||
let origin = Services.io.newURI(msg.manifest, null, null).prePath;
|
let origin = Services.io.newURI(msg.manifest, null, null).prePath;
|
||||||
shell.sendEvent(shell.contentBrowser.contentWindow, 'mozChromeEvent', {
|
shell.sendChromeEvent({
|
||||||
type: 'open-app',
|
type: 'open-app',
|
||||||
url: msg.uri,
|
url: msg.uri,
|
||||||
origin: origin,
|
origin: origin,
|
||||||
@ -415,12 +461,22 @@ var AlertsHelper = {
|
|||||||
return id;
|
return id;
|
||||||
},
|
},
|
||||||
|
|
||||||
showAlertNotification: function alert_showAlertNotification(imageUrl, title, text, textClickable,
|
showAlertNotification: function alert_showAlertNotification(imageUrl,
|
||||||
cookie, alertListener, name) {
|
title,
|
||||||
|
text,
|
||||||
|
textClickable,
|
||||||
|
cookie,
|
||||||
|
alertListener,
|
||||||
|
name)
|
||||||
|
{
|
||||||
let id = this.registerListener(cookie, alertListener);
|
let id = this.registerListener(cookie, alertListener);
|
||||||
let content = shell.contentBrowser.contentWindow;
|
shell.sendChromeEvent({
|
||||||
shell.sendEvent(content, "mozChromeEvent", { type: "desktop-notification", id: id, icon: imageUrl,
|
type: "desktop-notification",
|
||||||
title: title, text: text } );
|
id: id,
|
||||||
|
icon: imageUrl,
|
||||||
|
title: title,
|
||||||
|
text: text
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -456,7 +512,6 @@ var WebappsHelper = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
observe: function webapps_observe(subject, topic, data) {
|
observe: function webapps_observe(subject, topic, data) {
|
||||||
let content = shell.contentBrowser.contentWindow;
|
|
||||||
let json = JSON.parse(data);
|
let json = JSON.parse(data);
|
||||||
switch(topic) {
|
switch(topic) {
|
||||||
case "webapps-launch":
|
case "webapps-launch":
|
||||||
@ -465,7 +520,7 @@ var WebappsHelper = {
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
let manifest = new DOMApplicationManifest(aManifest, json.origin);
|
let manifest = new DOMApplicationManifest(aManifest, json.origin);
|
||||||
shell.sendEvent(content, "mozChromeEvent", {
|
shell.sendChromeEvent({
|
||||||
"type": "webapps-launch",
|
"type": "webapps-launch",
|
||||||
"url": manifest.fullLaunchPath(json.startPoint),
|
"url": manifest.fullLaunchPath(json.startPoint),
|
||||||
"origin": json.origin
|
"origin": json.origin
|
||||||
@ -474,7 +529,11 @@ var WebappsHelper = {
|
|||||||
break;
|
break;
|
||||||
case "webapps-ask-install":
|
case "webapps-ask-install":
|
||||||
let id = this.registerInstaller(json);
|
let id = this.registerInstaller(json);
|
||||||
shell.sendEvent(content, "mozChromeEvent", { type: "webapps-ask-install", id: id, app: json.app } );
|
shell.sendChromeEvent({
|
||||||
|
type: "webapps-ask-install",
|
||||||
|
id: id,
|
||||||
|
app: json.app
|
||||||
|
});
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -529,16 +588,28 @@ window.addEventListener('ContentStart', function ss_onContentStart() {
|
|||||||
context.drawWindow(window, 0, 0, width, height,
|
context.drawWindow(window, 0, 0, width, height,
|
||||||
'rgb(255,255,255)', flags);
|
'rgb(255,255,255)', flags);
|
||||||
|
|
||||||
shell.sendEvent(content, 'mozChromeEvent', {
|
shell.sendChromeEvent({
|
||||||
type: 'take-screenshot-success',
|
type: 'take-screenshot-success',
|
||||||
file: canvas.mozGetAsFile('screenshot', 'image/png')
|
file: canvas.mozGetAsFile('screenshot', 'image/png')
|
||||||
});
|
});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
dump('exception while creating screenshot: ' + e + '\n');
|
dump('exception while creating screenshot: ' + e + '\n');
|
||||||
shell.sendEvent(content, 'mozChromeEvent', {
|
shell.sendChromeEvent({
|
||||||
type: 'take-screenshot-error',
|
type: 'take-screenshot-error',
|
||||||
error: String(e)
|
error: String(e)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
Services.obs.addObserver(function ContentHandler(subject, topic, data) {
|
||||||
|
let handler = JSON.parse(data);
|
||||||
|
new MozActivity({
|
||||||
|
name: 'view',
|
||||||
|
data: {
|
||||||
|
type: handler.type,
|
||||||
|
url: handler.url
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}, 'content-handler', false);
|
||||||
|
|
||||||
|
@ -38,3 +38,8 @@ contract @mozilla.org/dom/activities/ui-glue;1 {70a83123-7467-4389-a309-3e81c74a
|
|||||||
component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js
|
component {1a94c87a-5ece-4d11-91e1-d29c29f21b28} ProcessGlobal.js
|
||||||
contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
|
contract @mozilla.org/b2g-process-global;1 {1a94c87a-5ece-4d11-91e1-d29c29f21b28}
|
||||||
category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1
|
category app-startup ProcessGlobal service,@mozilla.org/b2g-process-global;1
|
||||||
|
|
||||||
|
# ContentHandler.js
|
||||||
|
component {d18d0216-d50c-11e1-ba54-efb18d0ef0ac} ContentHandler.js
|
||||||
|
contract @mozilla.org/uriloader/content-handler;1?type=application/pdf {d18d0216-d50c-11e1-ba54-efb18d0ef0ac}
|
||||||
|
|
||||||
|
48
b2g/components/ContentHandler.js
Normal file
48
b2g/components/ContentHandler.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
/* vim: set shiftwidth=2 tabstop=2 autoindent cindent expandtab: */
|
||||||
|
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cr = Components.results;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
const PDF_CONTENT_TYPE = "application/pdf";
|
||||||
|
|
||||||
|
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||||
|
Cu.import("resource://gre/modules/Services.jsm");
|
||||||
|
|
||||||
|
function log(aMsg) {
|
||||||
|
let msg = "ContentHandler.js: " + (aMsg.join ? aMsg.join("") : aMsg);
|
||||||
|
Cc["@mozilla.org/consoleservice;1"].getService(Ci.nsIConsoleService)
|
||||||
|
.logStringMessage(msg);
|
||||||
|
dump(msg + "\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
const NS_ERROR_WONT_HANDLE_CONTENT = 0x805d0001;
|
||||||
|
function ContentHandler() {
|
||||||
|
}
|
||||||
|
|
||||||
|
ContentHandler.prototype = {
|
||||||
|
handleContent: function handleContent(aMimetype, aContext, aRequest) {
|
||||||
|
if (aMimetype != PDF_CONTENT_TYPE)
|
||||||
|
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||||
|
|
||||||
|
if (!(aRequest instanceof Ci.nsIChannel))
|
||||||
|
throw NS_ERROR_WONT_HANDLE_CONTENT;
|
||||||
|
|
||||||
|
let detail = {
|
||||||
|
"type": aMimetype,
|
||||||
|
"url": aRequest.URI.spec
|
||||||
|
};
|
||||||
|
Services.obs.notifyObservers(this, "content-handler", JSON.stringify(detail));
|
||||||
|
|
||||||
|
aRequest.cancel(Cr.NS_BINDING_ABORTED);
|
||||||
|
},
|
||||||
|
|
||||||
|
classID: Components.ID("{d18d0216-d50c-11e1-ba54-efb18d0ef0ac}"),
|
||||||
|
QueryInterface: XPCOMUtils.generateQI([Ci.nsIContentHandler])
|
||||||
|
};
|
||||||
|
|
||||||
|
var NSGetFactory = XPCOMUtils.generateNSGetFactory([ContentHandler]);
|
@ -22,7 +22,7 @@ DirectoryProvider.prototype = {
|
|||||||
|
|
||||||
getFile: function dp_getFile(prop, persistent) {
|
getFile: function dp_getFile(prop, persistent) {
|
||||||
#ifdef MOZ_WIDGET_GONK
|
#ifdef MOZ_WIDGET_GONK
|
||||||
let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir"];
|
let localProps = ["cachePDir", "webappsDir", "PrefD", "indexedDBPDir", "permissionDBPDir"];
|
||||||
if (localProps.indexOf(prop) != -1) {
|
if (localProps.indexOf(prop) != -1) {
|
||||||
prop.persistent = true;
|
prop.persistent = true;
|
||||||
let file = Cc["@mozilla.org/file/local;1"]
|
let file = Cc["@mozilla.org/file/local;1"]
|
||||||
|
@ -17,14 +17,15 @@ XPIDLSRCS = \
|
|||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
EXTRA_PP_COMPONENTS = \
|
EXTRA_PP_COMPONENTS = \
|
||||||
|
ActivitiesGlue.js \
|
||||||
AlertsService.js \
|
AlertsService.js \
|
||||||
B2GComponents.manifest \
|
B2GComponents.manifest \
|
||||||
CameraContent.js \
|
CameraContent.js \
|
||||||
|
ContentHandler.js \
|
||||||
ContentPermissionPrompt.js \
|
ContentPermissionPrompt.js \
|
||||||
DirectoryProvider.js \
|
DirectoryProvider.js \
|
||||||
MozKeyboard.js \
|
MozKeyboard.js \
|
||||||
ProcessGlobal.js \
|
ProcessGlobal.js \
|
||||||
ActivitiesGlue.js \
|
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifdef MOZ_UPDATER
|
ifdef MOZ_UPDATER
|
||||||
|
@ -684,3 +684,4 @@ bin/components/@DLL_PREFIX@nkgnomevfs@DLL_SUFFIX@
|
|||||||
@BINPATH@/components/DirectoryProvider.js
|
@BINPATH@/components/DirectoryProvider.js
|
||||||
@BINPATH@/components/ActivitiesGlue.js
|
@BINPATH@/components/ActivitiesGlue.js
|
||||||
@BINPATH@/components/ProcessGlobal.js
|
@BINPATH@/components/ProcessGlobal.js
|
||||||
|
@BINPATH@/components/ContentHandler.js
|
||||||
|
@ -43,12 +43,26 @@ static void Output(const char *fmt, ... )
|
|||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, fmt);
|
va_start(ap, fmt);
|
||||||
|
|
||||||
#if defined(XP_WIN) && !MOZ_WINCONSOLE
|
#ifndef XP_WIN
|
||||||
PRUnichar msg[2048];
|
|
||||||
_vsnwprintf(msg, sizeof(msg)/sizeof(msg[0]), NS_ConvertUTF8toUTF16(fmt).get(), ap);
|
|
||||||
MessageBoxW(NULL, msg, L"XULRunner", MB_OK | MB_ICONERROR);
|
|
||||||
#else
|
|
||||||
vfprintf(stderr, fmt, ap);
|
vfprintf(stderr, fmt, ap);
|
||||||
|
#else
|
||||||
|
char msg[2048];
|
||||||
|
vsnprintf_s(msg, _countof(msg), _TRUNCATE, fmt, ap);
|
||||||
|
|
||||||
|
wchar_t wide_msg[2048];
|
||||||
|
MultiByteToWideChar(CP_UTF8,
|
||||||
|
0,
|
||||||
|
msg,
|
||||||
|
-1,
|
||||||
|
wide_msg,
|
||||||
|
_countof(wide_msg));
|
||||||
|
#if MOZ_WINCONSOLE
|
||||||
|
fwprintf_s(stderr, wide_msg);
|
||||||
|
#else
|
||||||
|
MessageBoxW(NULL, wide_msg, L"Firefox", MB_OK
|
||||||
|
| MB_ICONERROR
|
||||||
|
| MB_SETFOREGROUND);
|
||||||
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
|
@ -1186,3 +1186,5 @@ pref("image.mem.max_decoded_image_kb", 256000);
|
|||||||
// Example social provider
|
// Example social provider
|
||||||
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
|
pref("social.manifest.motown", "{\"origin\":\"https://motown-dev.mozillalabs.com\",\"name\":\"MoTown\",\"workerURL\":\"https://motown-dev.mozillalabs.com/social/worker.js\",\"iconURL\":\"https://motown-dev.mozillalabs.com/images/motown-icon.png\",\"sidebarURL\":\"https://motown-dev.mozillalabs.com/social/sidebar\"}");
|
||||||
pref("social.sidebar.open", true);
|
pref("social.sidebar.open", true);
|
||||||
|
pref("browser.social.whitelist", "");
|
||||||
|
pref("social.active", false);
|
||||||
|
@ -332,6 +332,10 @@
|
|||||||
label="&preferencesCmd2.label;"
|
label="&preferencesCmd2.label;"
|
||||||
#endif
|
#endif
|
||||||
oncommand="openPreferences();">
|
oncommand="openPreferences();">
|
||||||
|
<menuitem id="appmenu_socialToggle"
|
||||||
|
type="checkbox"
|
||||||
|
autocheck="false"
|
||||||
|
command="Social:Toggle"/>
|
||||||
<menupopup id="appmenu_customizeMenu"
|
<menupopup id="appmenu_customizeMenu"
|
||||||
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
|
onpopupshowing="onViewToolbarsPopupShowing(event, document.getElementById('appmenu_toggleToolbarsSeparator'));">
|
||||||
<menuitem id="appmenu_preferences"
|
<menuitem id="appmenu_preferences"
|
||||||
|
@ -496,6 +496,10 @@
|
|||||||
accesskey="&addons.accesskey;"
|
accesskey="&addons.accesskey;"
|
||||||
key="key_openAddons"
|
key="key_openAddons"
|
||||||
command="Tools:Addons"/>
|
command="Tools:Addons"/>
|
||||||
|
<menuitem id="menu_socialToggle"
|
||||||
|
type="checkbox"
|
||||||
|
autocheck="false"
|
||||||
|
command="Social:Toggle"/>
|
||||||
#ifdef MOZ_SERVICES_SYNC
|
#ifdef MOZ_SERVICES_SYNC
|
||||||
<!-- only one of sync-setup or sync-menu will be showing at once -->
|
<!-- only one of sync-setup or sync-menu will be showing at once -->
|
||||||
<menuitem id="sync-setup"
|
<menuitem id="sync-setup"
|
||||||
|
@ -108,6 +108,7 @@
|
|||||||
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
|
<command id="Social:SharePage" oncommand="SocialShareButton.sharePage();"/>
|
||||||
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
|
<command id="Social:UnsharePage" oncommand="SocialShareButton.unsharePage();"/>
|
||||||
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
|
<command id="Social:ToggleSidebar" oncommand="Social.toggleSidebar();"/>
|
||||||
|
<command id="Social:Toggle" oncommand="Social.toggle();" hidden="true"/>
|
||||||
</commandset>
|
</commandset>
|
||||||
|
|
||||||
<commandset id="placesCommands">
|
<commandset id="placesCommands">
|
||||||
|
@ -11,6 +11,8 @@ let SocialUI = {
|
|||||||
|
|
||||||
Services.prefs.addObserver("social.sidebar.open", this, false);
|
Services.prefs.addObserver("social.sidebar.open", this, false);
|
||||||
|
|
||||||
|
gBrowser.addEventListener("ActivateSocialFeature", this._activationEventHandler, true, true);
|
||||||
|
|
||||||
Social.init(this._providerReady.bind(this));
|
Social.init(this._providerReady.bind(this));
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -31,6 +33,7 @@ let SocialUI = {
|
|||||||
observe: function SocialUI_observe(subject, topic, data) {
|
observe: function SocialUI_observe(subject, topic, data) {
|
||||||
switch (topic) {
|
switch (topic) {
|
||||||
case "social:pref-changed":
|
case "social:pref-changed":
|
||||||
|
this.updateToggleCommand();
|
||||||
SocialShareButton.updateButtonHiddenState();
|
SocialShareButton.updateButtonHiddenState();
|
||||||
SocialToolbar.updateButtonHiddenState();
|
SocialToolbar.updateButtonHiddenState();
|
||||||
SocialSidebar.updateSidebar();
|
SocialSidebar.updateSidebar();
|
||||||
@ -46,11 +49,103 @@ let SocialUI = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get toggleCommand() {
|
||||||
|
return document.getElementById("Social:Toggle");
|
||||||
|
},
|
||||||
|
|
||||||
// Called once Social.jsm's provider has been set
|
// Called once Social.jsm's provider has been set
|
||||||
_providerReady: function SocialUI_providerReady() {
|
_providerReady: function SocialUI_providerReady() {
|
||||||
|
// If we couldn't find a provider, nothing to do here.
|
||||||
|
if (!Social.provider)
|
||||||
|
return;
|
||||||
|
|
||||||
|
this.updateToggleCommand();
|
||||||
|
|
||||||
|
let toggleCommand = this.toggleCommand;
|
||||||
|
let label = gNavigatorBundle.getFormattedString("social.enable.label",
|
||||||
|
[Social.provider.name]);
|
||||||
|
let accesskey = gNavigatorBundle.getString("social.enable.accesskey");
|
||||||
|
toggleCommand.setAttribute("label", label);
|
||||||
|
toggleCommand.setAttribute("accesskey", accesskey);
|
||||||
|
|
||||||
SocialToolbar.init();
|
SocialToolbar.init();
|
||||||
SocialShareButton.init();
|
SocialShareButton.init();
|
||||||
SocialSidebar.init();
|
SocialSidebar.init();
|
||||||
|
},
|
||||||
|
|
||||||
|
updateToggleCommand: function SocialUI_updateToggleCommand() {
|
||||||
|
let toggleCommand = this.toggleCommand;
|
||||||
|
toggleCommand.setAttribute("checked", Social.enabled);
|
||||||
|
|
||||||
|
// FIXME: bug 772808: menu items don't inherit the "hidden" state properly,
|
||||||
|
// need to update them manually.
|
||||||
|
// This should just be: toggleCommand.hidden = !Social.active;
|
||||||
|
for (let id of ["appmenu_socialToggle", "menu_socialToggle"]) {
|
||||||
|
let el = document.getElementById(id);
|
||||||
|
if (!el)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (Social.active)
|
||||||
|
el.removeAttribute("hidden");
|
||||||
|
else
|
||||||
|
el.setAttribute("hidden", "true");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// This handles "ActivateSocialFeature" events fired against content documents
|
||||||
|
// in this window.
|
||||||
|
_activationEventHandler: function SocialUI_activationHandler(e) {
|
||||||
|
// Nothing to do if Social is already active, or we don't have a provider
|
||||||
|
// to enable yet.
|
||||||
|
if (Social.active || !Social.provider)
|
||||||
|
return;
|
||||||
|
|
||||||
|
let targetDoc = e.target;
|
||||||
|
|
||||||
|
// Event must be fired against the document
|
||||||
|
if (!(targetDoc instanceof HTMLDocument))
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Ignore events fired in background tabs
|
||||||
|
if (targetDoc.defaultView.top != content)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Check that the associated document's origin is in our whitelist
|
||||||
|
let prePath = targetDoc.documentURIObject.prePath;
|
||||||
|
let whitelist = Services.prefs.getCharPref("browser.social.whitelist");
|
||||||
|
if (whitelist.split(",").indexOf(prePath) == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// If the last event was received < 1s ago, ignore this one
|
||||||
|
let now = Date.now();
|
||||||
|
if (now - Social.lastEventReceived < 1000)
|
||||||
|
return;
|
||||||
|
Social.lastEventReceived = now;
|
||||||
|
|
||||||
|
// Enable the social functionality, and indicate that it was activated
|
||||||
|
Social.active = true;
|
||||||
|
|
||||||
|
// Show a warning, allow undoing the activation
|
||||||
|
let description = document.getElementById("social-activation-message");
|
||||||
|
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||||
|
let message = gNavigatorBundle.getFormattedString("social.activated.message",
|
||||||
|
[Social.provider.name, brandShortName]);
|
||||||
|
description.value = message;
|
||||||
|
|
||||||
|
SocialUI.notificationPanel.hidden = false;
|
||||||
|
|
||||||
|
setTimeout(function () {
|
||||||
|
SocialUI.notificationPanel.openPopup(SocialToolbar.button, "bottomcenter topright");
|
||||||
|
}.bind(this), 0);
|
||||||
|
},
|
||||||
|
|
||||||
|
get notificationPanel() {
|
||||||
|
return document.getElementById("socialActivatedNotification")
|
||||||
|
},
|
||||||
|
|
||||||
|
undoActivation: function SocialUI_undoActivation() {
|
||||||
|
Social.active = false;
|
||||||
|
this.notificationPanel.hidePopup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,21 +249,32 @@ var SocialToolbar = {
|
|||||||
init: function SocialToolbar_init() {
|
init: function SocialToolbar_init() {
|
||||||
document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
|
document.getElementById("social-provider-image").setAttribute("image", Social.provider.iconURL);
|
||||||
|
|
||||||
// handle button state
|
let removeItem = document.getElementById("social-remove-menuitem");
|
||||||
document.getElementById("social-statusarea-popup").addEventListener("popupshowing", function(e) {
|
let brandShortName = document.getElementById("bundle_brand").getString("brandShortName");
|
||||||
document.getElementById("social-toolbar-button").setAttribute("open", "true");
|
let label = gNavigatorBundle.getFormattedString("social.remove.label",
|
||||||
}, false);
|
[brandShortName]);
|
||||||
document.getElementById("social-statusarea-popup").addEventListener("popuphiding", function(e) {
|
let accesskey = gNavigatorBundle.getString("social.remove.accesskey");
|
||||||
document.getElementById("social-toolbar-button").removeAttribute("open");
|
removeItem.setAttribute("label", label);
|
||||||
}, false);
|
removeItem.setAttribute("accesskey", accesskey);
|
||||||
|
|
||||||
|
let statusAreaPopup = document.getElementById("social-statusarea-popup");
|
||||||
|
statusAreaPopup.addEventListener("popupshowing", function(e) {
|
||||||
|
this.button.setAttribute("open", "true");
|
||||||
|
}.bind(this));
|
||||||
|
statusAreaPopup.addEventListener("popuphidden", function(e) {
|
||||||
|
this.button.removeAttribute("open");
|
||||||
|
}.bind(this));
|
||||||
|
|
||||||
this.updateButton();
|
this.updateButton();
|
||||||
this.updateProfile();
|
this.updateProfile();
|
||||||
},
|
},
|
||||||
|
|
||||||
|
get button() {
|
||||||
|
return document.getElementById("social-toolbar-button");
|
||||||
|
},
|
||||||
|
|
||||||
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
|
updateButtonHiddenState: function SocialToolbar_updateButtonHiddenState() {
|
||||||
let toolbarbutton = document.getElementById("social-toolbar-button");
|
this.button.hidden = !Social.uiVisible;
|
||||||
toolbarbutton.hidden = !Social.uiVisible;
|
|
||||||
},
|
},
|
||||||
|
|
||||||
updateProfile: function SocialToolbar_updateProfile() {
|
updateProfile: function SocialToolbar_updateProfile() {
|
||||||
@ -233,10 +339,10 @@ var SocialToolbar = {
|
|||||||
panel.hidden = false;
|
panel.hidden = false;
|
||||||
|
|
||||||
function sizePanelToContent() {
|
function sizePanelToContent() {
|
||||||
// XXX Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
|
// FIXME: bug 764787: Maybe we can use nsIDOMWindowUtils.getRootBounds() here?
|
||||||
// XXX need to handle dynamic sizing
|
// Need to handle dynamic sizing
|
||||||
let doc = notifBrowser.contentDocument;
|
let doc = notifBrowser.contentDocument;
|
||||||
// XXX "notif" is an implementation detail that we should get rid of
|
// "notif" is an implementation detail that we should get rid of
|
||||||
// eventually
|
// eventually
|
||||||
let body = doc.getElementById("notif") || doc.body.firstChild;
|
let body = doc.getElementById("notif") || doc.body.firstChild;
|
||||||
if (!body)
|
if (!body)
|
||||||
@ -254,13 +360,13 @@ var SocialToolbar = {
|
|||||||
panel.addEventListener("popuphiding", function onpopuphiding() {
|
panel.addEventListener("popuphiding", function onpopuphiding() {
|
||||||
panel.removeEventListener("popuphiding", onpopuphiding);
|
panel.removeEventListener("popuphiding", onpopuphiding);
|
||||||
// unload the panel
|
// unload the panel
|
||||||
document.getElementById("social-toolbar-button").removeAttribute("open");
|
SocialToolbar.button.removeAttribute("open");
|
||||||
notifBrowser.setAttribute("src", "about:blank");
|
notifBrowser.setAttribute("src", "about:blank");
|
||||||
});
|
});
|
||||||
|
|
||||||
notifBrowser.setAttribute("origin", Social.provider.origin);
|
notifBrowser.setAttribute("origin", Social.provider.origin);
|
||||||
notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
|
notifBrowser.setAttribute("src", iconImage.getAttribute("contentPanel"));
|
||||||
document.getElementById("social-toolbar-button").setAttribute("open", "true");
|
this.button.setAttribute("open", "true");
|
||||||
panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
|
panel.openPopup(iconImage, "bottomcenter topleft", 0, 0, false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -182,6 +182,44 @@
|
|||||||
</hbox>
|
</hbox>
|
||||||
</panel>
|
</panel>
|
||||||
|
|
||||||
|
<panel id="socialActivatedNotification"
|
||||||
|
type="arrow"
|
||||||
|
hidden="true"
|
||||||
|
consumeoutsideclicks="true"
|
||||||
|
align="start"
|
||||||
|
role="alert">
|
||||||
|
<hbox flex="1">
|
||||||
|
<image src="chrome://browser/content/social-icon.png" class="popup-notification-icon"/>
|
||||||
|
<vbox flex="1">
|
||||||
|
<description id="social-activation-message" class="popup-notification-description"/>
|
||||||
|
<spacer flex="1"/>
|
||||||
|
<hbox pack="end" align="center" class="popup-notification-button-container">
|
||||||
|
#ifdef XP_UNIX
|
||||||
|
<button id="social-undoactivation-button"
|
||||||
|
label="&social.activated.button.label;"
|
||||||
|
accesskey="&social.activated.button.accesskey;"
|
||||||
|
onclick="SocialUI.undoActivation();"/>
|
||||||
|
<button default="true"
|
||||||
|
autofocus="autofocus"
|
||||||
|
label="&social.ok.label;"
|
||||||
|
accesskey="&social.ok.accesskey;"
|
||||||
|
oncommand="SocialUI.notificationPanel.hidePopup();"/>
|
||||||
|
#else
|
||||||
|
<button default="true"
|
||||||
|
autofocus="autofocus"
|
||||||
|
label="&social.ok.label;"
|
||||||
|
accesskey="&social.ok.accesskey;"
|
||||||
|
oncommand="SocialUI.notificationPanel.hidePopup();"/>
|
||||||
|
<button id="social-undoactivation-button"
|
||||||
|
label="&social.activated.button.label;"
|
||||||
|
accesskey="&social.activated.button.accesskey;"
|
||||||
|
onclick="SocialUI.undoActivation();"/>
|
||||||
|
#endif
|
||||||
|
</hbox>
|
||||||
|
</vbox>
|
||||||
|
</hbox>
|
||||||
|
</panel>
|
||||||
|
|
||||||
<panel id="editSharePopup"
|
<panel id="editSharePopup"
|
||||||
type="arrow"
|
type="arrow"
|
||||||
orient="vertical"
|
orient="vertical"
|
||||||
@ -214,16 +252,16 @@
|
|||||||
class="editSharePopupBottomButton"
|
class="editSharePopupBottomButton"
|
||||||
default="true"
|
default="true"
|
||||||
autofocus="autofocus"
|
autofocus="autofocus"
|
||||||
label="&social.sharePopup.ok.label;"
|
label="&social.ok.label;"
|
||||||
accesskey="&social.sharePopup.ok.accesskey;"
|
accesskey="&social.ok.accesskey;"
|
||||||
oncommand="SocialShareButton.dismissSharePopup();"/>
|
oncommand="SocialShareButton.dismissSharePopup();"/>
|
||||||
#else
|
#else
|
||||||
<button id="editSharePopupOkButton"
|
<button id="editSharePopupOkButton"
|
||||||
class="editSharePopupBottomButton"
|
class="editSharePopupBottomButton"
|
||||||
default="true"
|
default="true"
|
||||||
autofocus="autofocus"
|
autofocus="autofocus"
|
||||||
label="&social.sharePopup.ok.label;"
|
label="&social.ok.label;"
|
||||||
accesskey="&social.sharePopup.ok.accesskey;"
|
accesskey="&social.ok.accesskey;"
|
||||||
oncommand="SocialShareButton.dismissSharePopup();"/>
|
oncommand="SocialShareButton.dismissSharePopup();"/>
|
||||||
<button id="editSharePopupUndoButton"
|
<button id="editSharePopupUndoButton"
|
||||||
class="editSharePopupBottomButton"
|
class="editSharePopupBottomButton"
|
||||||
@ -638,6 +676,8 @@
|
|||||||
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
|
oncommand="SocialUI.showProfile(); document.getElementById('social-statusarea-popup').hidePopup();"/>
|
||||||
</vbox>
|
</vbox>
|
||||||
</hbox>
|
</hbox>
|
||||||
|
<menuitem id="social-remove-menuitem"
|
||||||
|
oncommand="Social.active = false;"/>
|
||||||
<menuitem id="social-toggle-sidebar-menuitem"
|
<menuitem id="social-toggle-sidebar-menuitem"
|
||||||
type="checkbox"
|
type="checkbox"
|
||||||
autocheck="false"
|
autocheck="false"
|
||||||
|
BIN
browser/base/content/social-icon.png
Normal file
BIN
browser/base/content/social-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -258,6 +258,10 @@ _BROWSER_FILES = \
|
|||||||
browser_bug734076.js \
|
browser_bug734076.js \
|
||||||
browser_social_toolbar.js \
|
browser_social_toolbar.js \
|
||||||
browser_social_sidebar.js \
|
browser_social_sidebar.js \
|
||||||
|
browser_social_mozSocial_API.js \
|
||||||
|
social_panel.html \
|
||||||
|
social_sidebar.html \
|
||||||
|
social_worker.js \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
ifneq (cocoa,$(MOZ_WIDGET_TOOLKIT))
|
||||||
|
87
browser/base/content/test/browser_social_mozSocial_API.js
Normal file
87
browser/base/content/test/browser_social_mozSocial_API.js
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
let SocialService = Cu.import("resource://gre/modules/SocialService.jsm", {}).SocialService;
|
||||||
|
|
||||||
|
function test() {
|
||||||
|
// XXX Bug 775779
|
||||||
|
if (Cc["@mozilla.org/xpcom/debug;1"].getService(Ci.nsIDebug2).isDebugBuild) {
|
||||||
|
ok(true, "can't run social sidebar test in debug builds because they falsely report leaks");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
waitForExplicitFinish();
|
||||||
|
|
||||||
|
let manifest = { // normal provider
|
||||||
|
name: "provider 1",
|
||||||
|
origin: "http://example.com",
|
||||||
|
sidebarURL: "http://example.com/browser/browser/base/content/test/social_sidebar.html",
|
||||||
|
workerURL: "http://example.com/browser/browser/base/content/test/social_worker.js",
|
||||||
|
iconURL: "chrome://branding/content/icon48.png"
|
||||||
|
};
|
||||||
|
runSocialTestWithProvider(manifest, doTest);
|
||||||
|
}
|
||||||
|
|
||||||
|
function doTest() {
|
||||||
|
let iconsReady = false;
|
||||||
|
let gotSidebarMessage = false;
|
||||||
|
|
||||||
|
function checkNext() {
|
||||||
|
if (iconsReady && gotSidebarMessage)
|
||||||
|
triggerIconPanel();
|
||||||
|
}
|
||||||
|
|
||||||
|
function triggerIconPanel() {
|
||||||
|
let statusIcons = document.getElementById("social-status-iconbox");
|
||||||
|
ok(!statusIcons.firstChild.collapsed, "status icon is visible");
|
||||||
|
// Click the button to trigger its contentPanel
|
||||||
|
let panel = document.getElementById("social-notification-panel");
|
||||||
|
EventUtils.synthesizeMouseAtCenter(statusIcons.firstChild, {});
|
||||||
|
}
|
||||||
|
|
||||||
|
let port = Social.provider.port;
|
||||||
|
ok(port, "provider has a port");
|
||||||
|
port.postMessage({topic: "test-init"});
|
||||||
|
Social.provider.port.onmessage = function (e) {
|
||||||
|
let topic = e.data.topic;
|
||||||
|
switch (topic) {
|
||||||
|
case "got-panel-message":
|
||||||
|
ok(true, "got panel message");
|
||||||
|
// Wait for the panel to close before ending the test
|
||||||
|
let panel = document.getElementById("social-notification-panel");
|
||||||
|
panel.addEventListener("popuphidden", function hiddenListener() {
|
||||||
|
panel.removeEventListener("popuphidden", hiddenListener);
|
||||||
|
SocialService.removeProvider(Social.provider.origin, finish);
|
||||||
|
});
|
||||||
|
panel.hidePopup();
|
||||||
|
break;
|
||||||
|
case "got-sidebar-message":
|
||||||
|
// The sidebar message will always come first, since it loads by default
|
||||||
|
ok(true, "got sidebar message");
|
||||||
|
info(topic);
|
||||||
|
gotSidebarMessage = true;
|
||||||
|
checkNext();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Our worker sets up ambient notification at the same time as it responds to
|
||||||
|
// the workerAPI initialization. If it's already initialized, we can
|
||||||
|
// immediately check the icons, otherwise wait for initialization by
|
||||||
|
// observing the topic sent out by the social service.
|
||||||
|
if (Social.provider.workerAPI.initialized) {
|
||||||
|
iconsReady = true;
|
||||||
|
checkNext();
|
||||||
|
} else {
|
||||||
|
Services.obs.addObserver(function obs() {
|
||||||
|
Services.obs.removeObserver(obs, "social:ambient-notification-changed");
|
||||||
|
// Let the other observers (like the one that updates the UI) run before
|
||||||
|
// checking the icons.
|
||||||
|
executeSoon(function () {
|
||||||
|
iconsReady = true;
|
||||||
|
checkNext();
|
||||||
|
});
|
||||||
|
}, "social:ambient-notification-changed", false);
|
||||||
|
}
|
||||||
|
}
|
14
browser/base/content/test/social_panel.html
Normal file
14
browser/base/content/test/social_panel.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script>
|
||||||
|
function pingWorker() {
|
||||||
|
var port = navigator.mozSocial.getWorker().port;
|
||||||
|
port.postMessage({topic: "panel-message", result: "ok"});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="pingWorker();">
|
||||||
|
<p>This is a test social panel.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
14
browser/base/content/test/social_sidebar.html
Normal file
14
browser/base/content/test/social_sidebar.html
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script>
|
||||||
|
function pingWorker() {
|
||||||
|
var port = navigator.mozSocial.getWorker().port;
|
||||||
|
port.postMessage({topic: "sidebar-message", result: "ok"});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="pingWorker();">
|
||||||
|
<p>This is a test social sidebar.</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
40
browser/base/content/test/social_worker.js
Normal file
40
browser/base/content/test/social_worker.js
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
let testPort;
|
||||||
|
|
||||||
|
onconnect = function(e) {
|
||||||
|
let port = e.ports[0];
|
||||||
|
port.onmessage = function onMessage(event) {
|
||||||
|
let topic = event.data.topic;
|
||||||
|
switch (topic) {
|
||||||
|
case "test-init":
|
||||||
|
testPort = port;
|
||||||
|
break;
|
||||||
|
case "sidebar-message":
|
||||||
|
if (testPort && event.data.result == "ok")
|
||||||
|
testPort.postMessage({topic:"got-sidebar-message"});
|
||||||
|
break;
|
||||||
|
case "panel-message":
|
||||||
|
if (testPort && event.data.result == "ok")
|
||||||
|
testPort.postMessage({topic:"got-panel-message"});
|
||||||
|
break;
|
||||||
|
case "social.initialize":
|
||||||
|
// This is the workerAPI port, respond and set up a notification icon.
|
||||||
|
port.postMessage({topic: "social.initialize-response"});
|
||||||
|
let profile = {
|
||||||
|
userName: "foo"
|
||||||
|
};
|
||||||
|
port.postMessage({topic: "social.user-profile", data: profile});
|
||||||
|
let icon = {
|
||||||
|
name: "testIcon",
|
||||||
|
iconURL: "chrome://branding/content/icon48.png",
|
||||||
|
contentPanel: "http://example.com/browser/browser/base/content/test/social_panel.html",
|
||||||
|
counter: 1
|
||||||
|
};
|
||||||
|
port.postMessage({topic: "social.ambient-notification", data: icon});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -101,6 +101,7 @@ browser.jar:
|
|||||||
#ifdef XP_WIN
|
#ifdef XP_WIN
|
||||||
* content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
|
* content/browser/win6BrowserOverlay.xul (content/win6BrowserOverlay.xul)
|
||||||
#endif
|
#endif
|
||||||
|
content/browser/social-icon.png (content/social-icon.png)
|
||||||
# the following files are browser-specific overrides
|
# the following files are browser-specific overrides
|
||||||
* content/browser/license.html (/toolkit/content/license.html)
|
* content/browser/license.html (/toolkit/content/license.html)
|
||||||
% override chrome://global/content/license.html chrome://browser/content/license.html
|
% override chrome://global/content/license.html chrome://browser/content/license.html
|
||||||
|
@ -68,7 +68,7 @@ PlacesViewBase.prototype = {
|
|||||||
if (val) {
|
if (val) {
|
||||||
this._resultNode = val.root;
|
this._resultNode = val.root;
|
||||||
this._rootElt._placesNode = this._resultNode;
|
this._rootElt._placesNode = this._resultNode;
|
||||||
this._domNodes = new WeakMap();
|
this._domNodes = new Map();
|
||||||
this._domNodes.set(this._resultNode, this._rootElt);
|
this._domNodes.set(this._resultNode, this._rootElt);
|
||||||
|
|
||||||
// This calls _rebuild through invalidateContainer.
|
// This calls _rebuild through invalidateContainer.
|
||||||
|
@ -80,7 +80,7 @@ function PlacesController(aView) {
|
|||||||
return Services.dirsvc.get("ProfD", Ci.nsIFile).leafName;
|
return Services.dirsvc.get("ProfD", Ci.nsIFile).leafName;
|
||||||
});
|
});
|
||||||
|
|
||||||
this._cachedLivemarkInfoObjects = new WeakMap();
|
this._cachedLivemarkInfoObjects = new Map();
|
||||||
}
|
}
|
||||||
|
|
||||||
PlacesController.prototype = {
|
PlacesController.prototype = {
|
||||||
|
@ -51,7 +51,7 @@ PlacesTreeView.prototype = {
|
|||||||
// Bug 761494:
|
// Bug 761494:
|
||||||
// ----------
|
// ----------
|
||||||
// Some addons use methods from nsINavHistoryResultObserver and
|
// Some addons use methods from nsINavHistoryResultObserver and
|
||||||
// nsINavHistoryResultTreeViewer, without QIing to these intefaces first.
|
// nsINavHistoryResultTreeViewer, without QIing to these interfaces first.
|
||||||
// That's not a problem when the view is retrieved through the
|
// That's not a problem when the view is retrieved through the
|
||||||
// <tree>.view getter (which returns the wrappedJSObject of this object),
|
// <tree>.view getter (which returns the wrappedJSObject of this object),
|
||||||
// it raises an issue when the view retrieved through the treeBoxObject.view
|
// it raises an issue when the view retrieved through the treeBoxObject.view
|
||||||
@ -153,12 +153,21 @@ PlacesTreeView.prototype = {
|
|||||||
_getRowForNode:
|
_getRowForNode:
|
||||||
function PTV__getRowForNode(aNode, aForceBuild, aParentRow, aNodeIndex) {
|
function PTV__getRowForNode(aNode, aForceBuild, aParentRow, aNodeIndex) {
|
||||||
if (aNode == this._rootNode)
|
if (aNode == this._rootNode)
|
||||||
throw "The root node is never visible";
|
throw new Error("The root node is never visible");
|
||||||
|
|
||||||
let ancestors = PlacesUtils.nodeAncestors(aNode);
|
// A node is removed form the view either if it has no parent or if its
|
||||||
for (let ancestor in ancestors) {
|
// root-ancestor is not the root node (in which case that's the node
|
||||||
|
// for which nodeRemoved was called).
|
||||||
|
let ancestors = [x for each (x in PlacesUtils.nodeAncestors(aNode))];
|
||||||
|
if (ancestors.length == 0 ||
|
||||||
|
ancestors[ancestors.length - 1] != this._rootNode) {
|
||||||
|
throw new Error("Removed node passed to _getRowForNode");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure that the entire chain is open, otherwise that node is invisible.
|
||||||
|
for (let ancestor of ancestors) {
|
||||||
if (!ancestor.containerOpen)
|
if (!ancestor.containerOpen)
|
||||||
throw "Invisible node passed to _getRowForNode";
|
throw new Error("Invisible node passed to _getRowForNode");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Non-plain containers are initially built with their contents.
|
// Non-plain containers are initially built with their contents.
|
||||||
@ -1097,7 +1106,7 @@ PlacesTreeView.prototype = {
|
|||||||
if (val) {
|
if (val) {
|
||||||
this._result = val;
|
this._result = val;
|
||||||
this._rootNode = this._result.root;
|
this._rootNode = this._result.root;
|
||||||
this._cellProperties = new WeakMap();
|
this._cellProperties = new Map();
|
||||||
this._cuttingNodes = new Set();
|
this._cuttingNodes = new Set();
|
||||||
}
|
}
|
||||||
else if (this._result) {
|
else if (this._result) {
|
||||||
|
@ -657,11 +657,21 @@ toolbar button -->
|
|||||||
<!ENTITY socialToolbar.title "Social Toolbar Button">
|
<!ENTITY socialToolbar.title "Social Toolbar Button">
|
||||||
<!ENTITY social.notLoggedIn.label "Not logged in">
|
<!ENTITY social.notLoggedIn.label "Not logged in">
|
||||||
|
|
||||||
|
<!-- LOCALIZATION NOTE (social.ok.label, social.ok.accesskey): this string is
|
||||||
|
used for the "OK" button for two different social panels. One appears when
|
||||||
|
the feature is activated (social.activated.* below), and the other when
|
||||||
|
the user clicks the "Share" button a second time (social.sharePopup.*
|
||||||
|
below). -->
|
||||||
|
<!ENTITY social.ok.label "OK">
|
||||||
|
<!ENTITY social.ok.accesskey "O">
|
||||||
|
|
||||||
<!ENTITY social.sharePopup.undo.label "Unshare">
|
<!ENTITY social.sharePopup.undo.label "Unshare">
|
||||||
<!ENTITY social.sharePopup.undo.accesskey "U">
|
<!ENTITY social.sharePopup.undo.accesskey "U">
|
||||||
<!ENTITY social.sharePopup.ok.label "OK">
|
|
||||||
<!ENTITY social.sharePopup.ok.accesskey "O">
|
|
||||||
<!ENTITY social.sharePopup.shared.label "You shared this page.">
|
<!ENTITY social.sharePopup.shared.label "You shared this page.">
|
||||||
<!ENTITY social.sharePopup.portrait.arialabel "User profile picture">
|
<!ENTITY social.sharePopup.portrait.arialabel "User profile picture">
|
||||||
|
|
||||||
<!ENTITY social.toggleSidebar.label "Show sidebar">
|
<!ENTITY social.toggleSidebar.label "Show sidebar">
|
||||||
<!ENTITY social.toggleSidebar.accesskey "s">
|
<!ENTITY social.toggleSidebar.accesskey "s">
|
||||||
|
|
||||||
|
<!ENTITY social.activated.button.label "Oops, undo">
|
||||||
|
<!ENTITY social.activated.button.accesskey "u">
|
||||||
|
@ -372,3 +372,14 @@ fullscreen.rememberDecision=Remember decision for %S
|
|||||||
social.shareButton.tooltip=Share this
|
social.shareButton.tooltip=Share this
|
||||||
social.shareButton.sharedtooltip=You shared this
|
social.shareButton.sharedtooltip=You shared this
|
||||||
social.pageShared.label=Page shared
|
social.pageShared.label=Page shared
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (social.enable.label): %S = Social networking provider
|
||||||
|
social.enable.label=%S integration
|
||||||
|
social.enable.accesskey=n
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (social.remove.label): %S = brandShortName
|
||||||
|
social.remove.label=Remove from %S
|
||||||
|
social.remove.accesskey=R
|
||||||
|
|
||||||
|
# LOCALIZATION NOTE (social.enabled.message): %1$S is the name of the social provider, %2$S is brandShortName (e.g. Firefox)
|
||||||
|
social.activated.message=%1$S integration with %2$S has been activated.
|
||||||
|
@ -17,6 +17,7 @@ XPCOMUtils.defineLazyModuleGetter(this, "SocialService",
|
|||||||
"resource://gre/modules/SocialService.jsm");
|
"resource://gre/modules/SocialService.jsm");
|
||||||
|
|
||||||
let Social = {
|
let Social = {
|
||||||
|
lastEventReceived: 0,
|
||||||
provider: null,
|
provider: null,
|
||||||
init: function Social_init(callback) {
|
init: function Social_init(callback) {
|
||||||
if (this.provider) {
|
if (this.provider) {
|
||||||
@ -38,6 +39,25 @@ let Social = {
|
|||||||
return this.provider && this.provider.enabled && this.provider.port;
|
return this.provider && this.provider.enabled && this.provider.port;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
set enabled(val) {
|
||||||
|
SocialService.enabled = val;
|
||||||
|
},
|
||||||
|
get enabled() {
|
||||||
|
return SocialService.enabled;
|
||||||
|
},
|
||||||
|
|
||||||
|
get active() {
|
||||||
|
return Services.prefs.getBoolPref("social.active");
|
||||||
|
},
|
||||||
|
set active(val) {
|
||||||
|
Services.prefs.setBoolPref("social.active", !!val);
|
||||||
|
this.enabled = !!val;
|
||||||
|
},
|
||||||
|
|
||||||
|
toggle: function Social_toggle() {
|
||||||
|
this.enabled = !this.enabled;
|
||||||
|
},
|
||||||
|
|
||||||
toggleSidebar: function SocialSidebar_toggle() {
|
toggleSidebar: function SocialSidebar_toggle() {
|
||||||
let prefValue = Services.prefs.getBoolPref("social.sidebar.open");
|
let prefValue = Services.prefs.getBoolPref("social.sidebar.open");
|
||||||
Services.prefs.setBoolPref("social.sidebar.open", !prefValue);
|
Services.prefs.setBoolPref("social.sidebar.open", !prefValue);
|
||||||
|
@ -6,4 +6,6 @@ setup.py:testing/mozbase/mozlog:develop
|
|||||||
setup.py:testing/mozbase/mozprocess:develop
|
setup.py:testing/mozbase/mozprocess:develop
|
||||||
setup.py:testing/mozbase/mozprofile:develop
|
setup.py:testing/mozbase/mozprofile:develop
|
||||||
setup.py:testing/mozbase/mozrunner:develop
|
setup.py:testing/mozbase/mozrunner:develop
|
||||||
setup.py:build/pylib/blessings:develop
|
setup.py:python/blessings:develop
|
||||||
|
mozilla.pth:build
|
||||||
|
mozilla.pth:config
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
# This file contains code for populating the virtualenv environment for
|
# This file contains code for populating the virtualenv environment for
|
||||||
# Mozilla's build system. It is typically called as part of configure.
|
# Mozilla's build system. It is typically called as part of configure.
|
||||||
|
|
||||||
|
from __future__ import with_statement
|
||||||
import os.path
|
import os.path
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
|
import distutils.sysconfig
|
||||||
|
|
||||||
def populate_virtualenv(top_source_directory, manifest_filename):
|
def populate_virtualenv(top_source_directory, manifest_filename):
|
||||||
"""Populate the virtualenv from the contents of a manifest.
|
"""Populate the virtualenv from the contents of a manifest.
|
||||||
@ -38,6 +40,11 @@ def populate_virtualenv(top_source_directory, manifest_filename):
|
|||||||
|
|
||||||
call_setup(os.path.join(top_source_directory, package[1]),
|
call_setup(os.path.join(top_source_directory, package[1]),
|
||||||
package[2:])
|
package[2:])
|
||||||
|
if package[0].endswith('.pth'):
|
||||||
|
assert len(package) == 2
|
||||||
|
|
||||||
|
with open(os.path.join(distutils.sysconfig.get_python_lib(), package[0]), 'a') as f:
|
||||||
|
f.write("%s\n" % os.path.join(top_source_directory, package[1]))
|
||||||
|
|
||||||
def call_setup(directory, arguments):
|
def call_setup(directory, arguments):
|
||||||
"""Calls setup.py in a directory."""
|
"""Calls setup.py in a directory."""
|
||||||
|
@ -161,6 +161,7 @@ PYUNITS := \
|
|||||||
unit-buildlist.py \
|
unit-buildlist.py \
|
||||||
unit-expandlibs.py \
|
unit-expandlibs.py \
|
||||||
unit-writemozinfo.py \
|
unit-writemozinfo.py \
|
||||||
|
unit-mozunit.py \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
check-preqs = \
|
check-preqs = \
|
||||||
|
@ -126,11 +126,13 @@ class Preprocessor:
|
|||||||
'file': self.context['FILE'],
|
'file': self.context['FILE'],
|
||||||
'le': self.LE})
|
'le': self.LE})
|
||||||
self.writtenLines = ln
|
self.writtenLines = ln
|
||||||
aLine = self.applyFilters(aLine)
|
filteredLine = self.applyFilters(aLine)
|
||||||
|
if filteredLine != aLine:
|
||||||
|
self.actionLevel = 2
|
||||||
# ensure our line ending. Only need to handle \n, as we're reading
|
# ensure our line ending. Only need to handle \n, as we're reading
|
||||||
# with universal line ending support, at least for files.
|
# with universal line ending support, at least for files.
|
||||||
aLine = re.sub('\n', self.LE, aLine)
|
filteredLine = re.sub('\n', self.LE, filteredLine)
|
||||||
self.out.write(aLine)
|
self.out.write(filteredLine)
|
||||||
|
|
||||||
def handleCommandLine(self, args, defaultToStdin = False):
|
def handleCommandLine(self, args, defaultToStdin = False):
|
||||||
"""
|
"""
|
||||||
|
@ -3,7 +3,10 @@
|
|||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
|
from unittest import TextTestRunner as _TestRunner, TestResult as _TestResult
|
||||||
|
import unittest
|
||||||
import inspect
|
import inspect
|
||||||
|
from StringIO import StringIO
|
||||||
|
import os
|
||||||
|
|
||||||
'''Helper to make python unit tests report the way that the Mozilla
|
'''Helper to make python unit tests report the way that the Mozilla
|
||||||
unit test infrastructure expects tests to report.
|
unit test infrastructure expects tests to report.
|
||||||
@ -11,10 +14,10 @@ unit test infrastructure expects tests to report.
|
|||||||
Usage:
|
Usage:
|
||||||
|
|
||||||
import unittest
|
import unittest
|
||||||
from mozunit import MozTestRunner
|
import mozunit
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(testRunner=MozTestRunner())
|
mozunit.main()
|
||||||
'''
|
'''
|
||||||
|
|
||||||
class _MozTestResult(_TestResult):
|
class _MozTestResult(_TestResult):
|
||||||
@ -68,3 +71,69 @@ class MozTestRunner(_TestRunner):
|
|||||||
test(result)
|
test(result)
|
||||||
result.printErrorList()
|
result.printErrorList()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
class MockedFile(StringIO):
|
||||||
|
def __init__(self, context, filename, content = ''):
|
||||||
|
self.context = context
|
||||||
|
self.name = filename
|
||||||
|
StringIO.__init__(self, content)
|
||||||
|
|
||||||
|
def close(self):
|
||||||
|
self.context.files[self.name] = self.getvalue()
|
||||||
|
StringIO.close(self)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
class MockedOpen(object):
|
||||||
|
'''
|
||||||
|
Context manager diverting the open builtin such that opening files
|
||||||
|
can open "virtual" file instances given when creating a MockedOpen.
|
||||||
|
|
||||||
|
with MockedOpen({'foo': 'foo', 'bar': 'bar'}):
|
||||||
|
f = open('foo', 'r')
|
||||||
|
|
||||||
|
will thus open the virtual file instance for the file 'foo' to f.
|
||||||
|
|
||||||
|
MockedOpen also masks writes, so that creating or replacing files
|
||||||
|
doesn't touch the file system, while subsequently opening the file
|
||||||
|
will return the recorded content.
|
||||||
|
|
||||||
|
with MockedOpen():
|
||||||
|
f = open('foo', 'w')
|
||||||
|
f.write('foo')
|
||||||
|
self.assertRaises(Exception,f.open('foo', 'r'))
|
||||||
|
'''
|
||||||
|
def __init__(self, files = {}):
|
||||||
|
self.files = {}
|
||||||
|
for name, content in files.iteritems():
|
||||||
|
self.files[os.path.abspath(name)] = content
|
||||||
|
|
||||||
|
def __call__(self, name, mode = 'r'):
|
||||||
|
absname = os.path.abspath(name)
|
||||||
|
if 'w' in mode:
|
||||||
|
file = MockedFile(self, absname)
|
||||||
|
elif absname in self.files:
|
||||||
|
file = MockedFile(self, absname, self.files[absname])
|
||||||
|
elif 'a' in mode:
|
||||||
|
file = MockedFile(self, absname, self.open(name, 'r').read())
|
||||||
|
else:
|
||||||
|
file = self.open(name, mode)
|
||||||
|
if 'a' in mode:
|
||||||
|
file.seek(0, os.SEEK_END)
|
||||||
|
return file
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
import __builtin__
|
||||||
|
self.open = __builtin__.open
|
||||||
|
__builtin__.open = self
|
||||||
|
|
||||||
|
def __exit__(self, type, value, traceback):
|
||||||
|
import __builtin__
|
||||||
|
__builtin__.open = self.open
|
||||||
|
|
||||||
|
def main(*args):
|
||||||
|
unittest.main(testRunner=MozTestRunner(),*args)
|
||||||
|
@ -291,11 +291,9 @@ endif
|
|||||||
ifndef MOZ_AUTO_DEPS
|
ifndef MOZ_AUTO_DEPS
|
||||||
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
ifneq (,$(OBJS)$(XPIDLSRCS)$(SIMPLE_PROGRAMS))
|
||||||
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
|
MDDEPFILES = $(addprefix $(MDDEPDIR)/,$(OBJS:=.pp))
|
||||||
ifndef NO_GEN_XPT
|
|
||||||
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
|
MDDEPFILES += $(addprefix $(MDDEPDIR)/,$(XPIDLSRCS:.idl=.h.pp) $(XPIDLSRCS:.idl=.xpt.pp))
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endif
|
|
||||||
|
|
||||||
ALL_TRASH = \
|
ALL_TRASH = \
|
||||||
$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
|
$(GARBAGE) $(TARGETS) $(OBJS) $(PROGOBJS) LOGS TAGS a.out \
|
||||||
@ -1298,7 +1296,6 @@ $(XPIDL_GEN_DIR)/%.h: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
|
|||||||
@if test -n "$(findstring $*.h, $(EXPORTS))"; \
|
@if test -n "$(findstring $*.h, $(EXPORTS))"; \
|
||||||
then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
|
then echo "*** WARNING: file $*.h generated from $*.idl overrides $(srcdir)/$*.h"; else true; fi
|
||||||
|
|
||||||
ifndef NO_GEN_XPT
|
|
||||||
# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
|
# generate intermediate .xpt files into $(XPIDL_GEN_DIR), then link
|
||||||
# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
|
# into $(XPIDL_MODULE).xpt and export it to $(FINAL_TARGET)/components.
|
||||||
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
|
$(XPIDL_GEN_DIR)/%.xpt: %.idl $(XPIDL_DEPS) $(xpidl-preqs)
|
||||||
@ -1323,8 +1320,6 @@ ifndef NO_INTERFACES_MANIFEST
|
|||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
endif # NO_GEN_XPT
|
|
||||||
|
|
||||||
GARBAGE_DIRS += $(XPIDL_GEN_DIR)
|
GARBAGE_DIRS += $(XPIDL_GEN_DIR)
|
||||||
|
|
||||||
endif #} XPIDLSRCS
|
endif #} XPIDLSRCS
|
||||||
|
@ -2,7 +2,7 @@ import unittest
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
|
|
||||||
from Expression import Expression, Context
|
from Expression import Expression, Context
|
||||||
|
|
||||||
@ -60,4 +60,4 @@ class TestExpression(unittest.TestCase):
|
|||||||
self.assert_(Expression('FAIL != 1').evaluate(self.c))
|
self.assert_(Expression('FAIL != 1').evaluate(self.c))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
@ -5,9 +5,7 @@ from filecmp import dircmp
|
|||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree, copy2
|
from shutil import rmtree, copy2
|
||||||
from zipfile import ZipFile
|
from zipfile import ZipFile
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
|
|
||||||
from mozunit import MozTestRunner
|
|
||||||
from JarMaker import JarMaker
|
from JarMaker import JarMaker
|
||||||
|
|
||||||
if sys.platform == "win32":
|
if sys.platform == "win32":
|
||||||
@ -280,4 +278,4 @@ class TestJarMaker(unittest.TestCase):
|
|||||||
self.assertTrue(not difference, difference)
|
self.assertTrue(not difference, difference)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(testRunner=MozTestRunner())
|
mozunit.main()
|
||||||
|
@ -4,7 +4,7 @@ from StringIO import StringIO
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
|
|
||||||
from Preprocessor import Preprocessor
|
from Preprocessor import Preprocessor
|
||||||
|
|
||||||
@ -43,4 +43,4 @@ class TestLineEndings(unittest.TestCase):
|
|||||||
self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
|
self.assertEquals(self.pp.out.getvalue(), 'a\nb\nc\n')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
@ -5,41 +5,14 @@ from StringIO import StringIO
|
|||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
from mozunit import main, MockedOpen
|
||||||
|
|
||||||
from Preprocessor import Preprocessor
|
from Preprocessor import Preprocessor
|
||||||
|
|
||||||
class NamedIO(StringIO):
|
def NamedIO(name, content):
|
||||||
def __init__(self, name, content):
|
with open(name, 'w') as f:
|
||||||
self.name = name
|
f.write(content)
|
||||||
StringIO.__init__(self, content)
|
return name
|
||||||
|
|
||||||
class MockedOpen(object):
|
|
||||||
"""
|
|
||||||
Context manager diverting the open builtin such that opening files
|
|
||||||
can open NamedIO instances given when creating a MockedOpen.
|
|
||||||
|
|
||||||
with MockedOpen(NamedIO('foo', 'foo'), NamedIO('bar', 'bar')):
|
|
||||||
f = open('foo', 'r')
|
|
||||||
|
|
||||||
will thus assign the NamedIO instance for the file 'foo' to f.
|
|
||||||
"""
|
|
||||||
def __init__(self, *files):
|
|
||||||
self.files = {}
|
|
||||||
for f in files:
|
|
||||||
self.files[os.path.abspath(f.name)] = f
|
|
||||||
def __call__(self, name, args):
|
|
||||||
absname = os.path.abspath(name)
|
|
||||||
if absname in self.files:
|
|
||||||
return self.files[absname]
|
|
||||||
return self.open(name, args)
|
|
||||||
def __enter__(self):
|
|
||||||
import __builtin__
|
|
||||||
self.open = __builtin__.open
|
|
||||||
__builtin__.open = self
|
|
||||||
def __exit__(self, type, value, traceback):
|
|
||||||
import __builtin__
|
|
||||||
__builtin__.open = self.open
|
|
||||||
|
|
||||||
class TestPreprocessor(unittest.TestCase):
|
class TestPreprocessor(unittest.TestCase):
|
||||||
"""
|
"""
|
||||||
@ -539,13 +512,13 @@ octal value is not equal
|
|||||||
self.fail("Expected a Preprocessor.Error")
|
self.fail("Expected a Preprocessor.Error")
|
||||||
|
|
||||||
def test_include(self):
|
def test_include(self):
|
||||||
with MockedOpen(NamedIO("foo/test", """#define foo foobarbaz
|
with MockedOpen({"foo/test": """#define foo foobarbaz
|
||||||
#include @inc@
|
#include @inc@
|
||||||
@bar@
|
@bar@
|
||||||
"""),
|
""",
|
||||||
NamedIO("bar", """#define bar barfoobaz
|
"bar": """#define bar barfoobaz
|
||||||
@foo@
|
@foo@
|
||||||
""")):
|
"""}):
|
||||||
f = NamedIO("include.in", """#filter substitution
|
f = NamedIO("include.in", """#filter substitution
|
||||||
#define inc ../bar
|
#define inc ../bar
|
||||||
#include foo/test""")
|
#include foo/test""")
|
||||||
@ -575,7 +548,7 @@ barfoobaz
|
|||||||
self.fail("Expected a Preprocessor.Error")
|
self.fail("Expected a Preprocessor.Error")
|
||||||
|
|
||||||
def test_include_literal_at(self):
|
def test_include_literal_at(self):
|
||||||
with MockedOpen(NamedIO("@foo@", "#define foo foobarbaz")):
|
with MockedOpen({"@foo@": "#define foo foobarbaz"}):
|
||||||
f = NamedIO("include_literal_at.in", """#include @foo@
|
f = NamedIO("include_literal_at.in", """#include @foo@
|
||||||
#filter substitution
|
#filter substitution
|
||||||
@foo@
|
@foo@
|
||||||
@ -585,11 +558,11 @@ barfoobaz
|
|||||||
""")
|
""")
|
||||||
|
|
||||||
def test_command_line_literal_at(self):
|
def test_command_line_literal_at(self):
|
||||||
with MockedOpen(NamedIO("@foo@.in", """@foo@
|
with MockedOpen({"@foo@.in": """@foo@
|
||||||
""")):
|
"""}):
|
||||||
self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
|
self.pp.handleCommandLine(['-Fsubstitution', '-Dfoo=foobarbaz', '@foo@.in'])
|
||||||
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
|
self.assertEqual(self.pp.out.getvalue(), """foobarbaz
|
||||||
""")
|
""")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
main()
|
||||||
|
@ -3,7 +3,7 @@ import unittest
|
|||||||
import os, sys, os.path, time
|
import os, sys, os.path, time
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
|
|
||||||
from buildlist import addEntriesToListFile
|
from buildlist import addEntriesToListFile
|
||||||
|
|
||||||
@ -77,4 +77,4 @@ class TestBuildList(unittest.TestCase):
|
|||||||
self.assertFileContains(testfile, ["a","b","c"])
|
self.assertFileContains(testfile, ["a","b","c"])
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
@ -6,8 +6,7 @@ import os
|
|||||||
import imp
|
import imp
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
from mozunit import MozTestRunner
|
|
||||||
|
|
||||||
from UserString import UserString
|
from UserString import UserString
|
||||||
# Create a controlled configuration for use by expandlibs
|
# Create a controlled configuration for use by expandlibs
|
||||||
@ -385,4 +384,4 @@ class TestSymbolOrder(unittest.TestCase):
|
|||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(testRunner=MozTestRunner())
|
mozunit.main()
|
||||||
|
75
config/tests/unit-mozunit.py
Normal file
75
config/tests/unit-mozunit.py
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||||
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
|
from __future__ import with_statement
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
from mozunit import main, MockedOpen
|
||||||
|
import unittest
|
||||||
|
from tempfile import mkstemp
|
||||||
|
|
||||||
|
class TestMozUnit(unittest.TestCase):
|
||||||
|
def test_mocked_open(self):
|
||||||
|
# Create a temporary file on the file system.
|
||||||
|
(fd, path) = mkstemp()
|
||||||
|
with os.fdopen(fd, 'w') as file:
|
||||||
|
file.write('foobar');
|
||||||
|
|
||||||
|
with MockedOpen({'file1': 'content1',
|
||||||
|
'file2': 'content2'}):
|
||||||
|
# Check the contents of the files given at MockedOpen creation.
|
||||||
|
self.assertEqual(open('file1', 'r').read(), 'content1')
|
||||||
|
self.assertEqual(open('file2', 'r').read(), 'content2')
|
||||||
|
|
||||||
|
# Check that overwriting these files alters their content.
|
||||||
|
with open('file1', 'w') as file:
|
||||||
|
file.write('foo')
|
||||||
|
self.assertEqual(open('file1', 'r').read(), 'foo')
|
||||||
|
|
||||||
|
# ... but not until the file is closed.
|
||||||
|
file = open('file2', 'w')
|
||||||
|
file.write('bar')
|
||||||
|
self.assertEqual(open('file2', 'r').read(), 'content2')
|
||||||
|
file.close()
|
||||||
|
self.assertEqual(open('file2', 'r').read(), 'bar')
|
||||||
|
|
||||||
|
# Check that appending to a file does append
|
||||||
|
with open('file1', 'a') as file:
|
||||||
|
file.write('bar')
|
||||||
|
self.assertEqual(open('file1', 'r').read(), 'foobar')
|
||||||
|
|
||||||
|
# Opening a non-existing file ought to fail.
|
||||||
|
self.assertRaises(IOError, open, 'file3', 'r')
|
||||||
|
|
||||||
|
# Check that writing a new file does create the file.
|
||||||
|
with open('file3', 'w') as file:
|
||||||
|
file.write('baz')
|
||||||
|
self.assertEqual(open('file3', 'r').read(), 'baz')
|
||||||
|
|
||||||
|
# Check the content of the file created outside MockedOpen.
|
||||||
|
self.assertEqual(open(path, 'r').read(), 'foobar')
|
||||||
|
|
||||||
|
# Check that overwriting a file existing on the file system
|
||||||
|
# does modify its content.
|
||||||
|
with open(path, 'w') as file:
|
||||||
|
file.write('bazqux')
|
||||||
|
self.assertEqual(open(path, 'r').read(), 'bazqux')
|
||||||
|
|
||||||
|
with MockedOpen():
|
||||||
|
# Check that appending to a file existing on the file system
|
||||||
|
# does modify its content.
|
||||||
|
with open(path, 'a') as file:
|
||||||
|
file.write('bazqux')
|
||||||
|
self.assertEqual(open(path, 'r').read(), 'foobarbazqux')
|
||||||
|
|
||||||
|
# Check that the file was not actually modified on the file system.
|
||||||
|
self.assertEqual(open(path, 'r').read(), 'foobar')
|
||||||
|
os.remove(path)
|
||||||
|
|
||||||
|
# Check that the file created inside MockedOpen wasn't actually
|
||||||
|
# created.
|
||||||
|
self.assertRaises(IOError, open, 'file3', 'r')
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
@ -3,7 +3,7 @@ import unittest
|
|||||||
import os, sys, os.path, time
|
import os, sys, os.path, time
|
||||||
from tempfile import mkdtemp
|
from tempfile import mkdtemp
|
||||||
from shutil import rmtree
|
from shutil import rmtree
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
from mozprocess import processhandler
|
from mozprocess import processhandler
|
||||||
|
|
||||||
from nsinstall import nsinstall
|
from nsinstall import nsinstall
|
||||||
@ -170,4 +170,4 @@ class TestNsinstall(unittest.TestCase):
|
|||||||
#TODO: implement -R, -l, -L and test them!
|
#TODO: implement -R, -l, -L and test them!
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
@ -2,7 +2,7 @@ import unittest
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os.path
|
import os.path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
import mozunit
|
||||||
|
|
||||||
from printprereleasesuffix import get_prerelease_suffix
|
from printprereleasesuffix import get_prerelease_suffix
|
||||||
|
|
||||||
@ -77,4 +77,4 @@ class TestGetPreReleaseSuffix(unittest.TestCase):
|
|||||||
self.assertEqual(self.c, '')
|
self.assertEqual(self.c, '')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
@ -3,8 +3,7 @@ from __future__ import with_statement
|
|||||||
import unittest
|
import unittest
|
||||||
import os, sys, time, tempfile
|
import os, sys, time, tempfile
|
||||||
from StringIO import StringIO
|
from StringIO import StringIO
|
||||||
|
import mozunit
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
|
||||||
|
|
||||||
from writemozinfo import build_dict, write_json, JsonValue, jsonify
|
from writemozinfo import build_dict, write_json, JsonValue, jsonify
|
||||||
|
|
||||||
@ -239,5 +238,4 @@ class TestWriteJson(unittest.TestCase):
|
|||||||
self.assertEqual(32, d['bits'])
|
self.assertEqual(32, d['bits'])
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
mozunit.main()
|
||||||
|
|
||||||
|
12
configure.in
12
configure.in
@ -363,6 +363,10 @@ else
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test -n "$MOZ_WINCONSOLE"; then
|
||||||
|
AC_DEFINE(MOZ_WINCONSOLE)
|
||||||
|
fi
|
||||||
|
|
||||||
MOZ_TOOL_VARIABLES
|
MOZ_TOOL_VARIABLES
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
@ -746,6 +750,9 @@ if test -n "$_WIN32_MSVC"; then
|
|||||||
AC_DEFINE(HAVE_IO_H)
|
AC_DEFINE(HAVE_IO_H)
|
||||||
AC_DEFINE(HAVE_SETBUF)
|
AC_DEFINE(HAVE_SETBUF)
|
||||||
AC_DEFINE(HAVE_ISATTY)
|
AC_DEFINE(HAVE_ISATTY)
|
||||||
|
if test $_MSC_VER -ge 1600; then
|
||||||
|
AC_DEFINE(HAVE_NULLPTR)
|
||||||
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
fi # COMPILE_ENVIRONMENT
|
fi # COMPILE_ENVIRONMENT
|
||||||
@ -4206,6 +4213,7 @@ MOZ_ANDROID_HISTORY=
|
|||||||
MOZ_WEBSMS_BACKEND=
|
MOZ_WEBSMS_BACKEND=
|
||||||
MOZ_GRAPHITE=1
|
MOZ_GRAPHITE=1
|
||||||
ACCESSIBILITY=1
|
ACCESSIBILITY=1
|
||||||
|
MOZ_SYS_MSG=
|
||||||
|
|
||||||
case "$target_os" in
|
case "$target_os" in
|
||||||
mingw*)
|
mingw*)
|
||||||
@ -7332,7 +7340,9 @@ AC_SUBST(MOZ_B2G_BT)
|
|||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
dnl = Enable Support for System Messages API
|
dnl = Enable Support for System Messages API
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
if test -n "$MOZ_SYS_MSG"; then
|
||||||
|
AC_DEFINE(MOZ_SYS_MSG)
|
||||||
|
fi
|
||||||
AC_SUBST(MOZ_SYS_MSG)
|
AC_SUBST(MOZ_SYS_MSG)
|
||||||
|
|
||||||
dnl ========================================================
|
dnl ========================================================
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
#include "nsChangeHint.h"
|
#include "nsChangeHint.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsIDocument.h" // for IsInHTMLDocument
|
#include "nsIDocument.h" // for IsInHTMLDocument
|
||||||
|
#include "nsCSSProperty.h"
|
||||||
|
|
||||||
// Forward declarations
|
// Forward declarations
|
||||||
class nsIAtom;
|
class nsIAtom;
|
||||||
|
@ -1291,6 +1291,8 @@ private:
|
|||||||
NodeMayHaveDOMMutationObserver,
|
NodeMayHaveDOMMutationObserver,
|
||||||
// Set if node is Content
|
// Set if node is Content
|
||||||
NodeIsContent,
|
NodeIsContent,
|
||||||
|
// Set if the node has animations or transitions
|
||||||
|
ElementHasAnimations,
|
||||||
// Guard value
|
// Guard value
|
||||||
BooleanFlagCount
|
BooleanFlagCount
|
||||||
};
|
};
|
||||||
@ -1356,6 +1358,8 @@ public:
|
|||||||
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
|
||||||
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
|
||||||
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
|
||||||
|
bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
|
||||||
|
void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
|
||||||
protected:
|
protected:
|
||||||
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
|
||||||
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
void SetInDocument() { SetBoolFlag(IsInDocument); }
|
||||||
|
@ -178,8 +178,6 @@ MOCHITEST_FILES_A = \
|
|||||||
file_bug426646-1.html \
|
file_bug426646-1.html \
|
||||||
file_bug426646-2.html \
|
file_bug426646-2.html \
|
||||||
test_bug429157.html \
|
test_bug429157.html \
|
||||||
test_header.html \
|
|
||||||
header.sjs \
|
|
||||||
test_XHR.html \
|
test_XHR.html \
|
||||||
file_XHR_pass1.xml \
|
file_XHR_pass1.xml \
|
||||||
file_XHR_pass2.txt \
|
file_XHR_pass2.txt \
|
||||||
|
@ -1,8 +0,0 @@
|
|||||||
function handleRequest(request, response) {
|
|
||||||
response.setHeader("Content-Type", "text/plain", false);
|
|
||||||
response.setHeader("Cache-Control", "no-cache", false);
|
|
||||||
|
|
||||||
var value = request.hasHeader("SomeHeader") ? request.getHeader("SomeHeader")
|
|
||||||
: "";
|
|
||||||
response.write("SomeHeader: " + value);
|
|
||||||
}
|
|
@ -1,31 +0,0 @@
|
|||||||
<!DOCTYPE HTML>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<title>Test for XHR header preservation</title>
|
|
||||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
|
||||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p id="display"></p>
|
|
||||||
<div id="content" style="display: none">
|
|
||||||
|
|
||||||
</div>
|
|
||||||
<pre id="test">
|
|
||||||
<script class="testbody" type="text/javascript">
|
|
||||||
/** Test for Bug 421622 **/
|
|
||||||
const SJS_URL = "http://mochi.test:8888/tests/content/base/test/header.sjs";
|
|
||||||
const VALUE = "http://www.mozilla.org/";
|
|
||||||
|
|
||||||
var req = new XMLHttpRequest();
|
|
||||||
req.open("GET", SJS_URL, false);
|
|
||||||
req.setRequestHeader("SomeHeader", VALUE);
|
|
||||||
req.send(null);
|
|
||||||
|
|
||||||
is(req.responseText,
|
|
||||||
"SomeHeader: " + VALUE,
|
|
||||||
"Header received by server does not match what was set");
|
|
||||||
</script>
|
|
||||||
</pre>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -26,6 +26,11 @@ public:
|
|||||||
Init(aX1, aY1, aX2, aY2);
|
Init(aX1, aY1, aX2, aY2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
double X1() const { return mX1; }
|
||||||
|
double Y1() const { return mY1; }
|
||||||
|
double X2() const { return mX2; }
|
||||||
|
double Y2() const { return mY2; }
|
||||||
|
|
||||||
void Init(double aX1, double aY1,
|
void Init(double aX1, double aY1,
|
||||||
double aX2, double aY2);
|
double aX2, double aY2);
|
||||||
|
|
||||||
|
@ -4901,6 +4901,13 @@ nsDocShell::SetParentNativeWindow(nativeWindow parentNativeWindow)
|
|||||||
return NS_ERROR_NOT_IMPLEMENTED;
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDocShell::GetNativeHandle(nsAString& aNativeHandle)
|
||||||
|
{
|
||||||
|
// the nativeHandle should be accessed from nsIXULWindow
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShell::GetVisibility(bool * aVisibility)
|
nsDocShell::GetVisibility(bool * aVisibility)
|
||||||
{
|
{
|
||||||
|
@ -228,8 +228,8 @@ let AlarmService = {
|
|||||||
|
|
||||||
if (this._currentAlarm) {
|
if (this._currentAlarm) {
|
||||||
debug("Fire system intent: " + JSON.stringify(this._currentAlarm));
|
debug("Fire system intent: " + JSON.stringify(this._currentAlarm));
|
||||||
if (this._currentAlarm.manifestURL)
|
let manifestURI = Services.io.newURI(this._currentAlarm.manifestURL, null, null);
|
||||||
messenger.sendMessage("alarm", this._currentAlarm, this._currentAlarm.manifestURL);
|
messenger.sendMessage("alarm", this._currentAlarm, manifestURI);
|
||||||
this._currentAlarm = null;
|
this._currentAlarm = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -244,8 +244,8 @@ let AlarmService = {
|
|||||||
// fire system intent for it instead of setting it
|
// fire system intent for it instead of setting it
|
||||||
if (nextAlarmTime <= nowTime) {
|
if (nextAlarmTime <= nowTime) {
|
||||||
debug("Fire system intent: " + JSON.stringify(nextAlarm));
|
debug("Fire system intent: " + JSON.stringify(nextAlarm));
|
||||||
if (nextAlarm.manifestURL)
|
let manifestURI = Services.io.newURI(nextAlarm.manifestURL, null, null);
|
||||||
messenger.sendMessage("alarm", nextAlarm, nextAlarm.manifestURL);
|
messenger.sendMessage("alarm", nextAlarm, manifestURI);
|
||||||
} else {
|
} else {
|
||||||
this._currentAlarm = nextAlarm;
|
this._currentAlarm = nextAlarm;
|
||||||
break;
|
break;
|
||||||
|
@ -45,6 +45,11 @@ AlarmsManager.prototype = {
|
|||||||
add: function add(aDate, aRespectTimezone, aData) {
|
add: function add(aDate, aRespectTimezone, aData) {
|
||||||
debug("add()");
|
debug("add()");
|
||||||
|
|
||||||
|
if (!this._manifestURL) {
|
||||||
|
debug("Cannot add alarms for non-installed apps.");
|
||||||
|
throw Components.results.NS_ERROR_FAILURE;
|
||||||
|
}
|
||||||
|
|
||||||
let isIgnoreTimezone = true;
|
let isIgnoreTimezone = true;
|
||||||
switch (aRespectTimezone) {
|
switch (aRespectTimezone) {
|
||||||
case "honorTimezone":
|
case "honorTimezone":
|
||||||
@ -150,8 +155,7 @@ AlarmsManager.prototype = {
|
|||||||
|
|
||||||
// Get the manifest URL if this is an installed app
|
// Get the manifest URL if this is an installed app
|
||||||
this._manifestURL = null;
|
this._manifestURL = null;
|
||||||
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
let utils = aWindow.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindowUtils);
|
||||||
.getInterface(Components.interfaces.nsIDOMWindowUtils);
|
|
||||||
let app = utils.getApp();
|
let app = utils.getApp();
|
||||||
if (app)
|
if (app)
|
||||||
this._manifestURL = app.manifestURL;
|
this._manifestURL = app.manifestURL;
|
||||||
|
@ -1298,7 +1298,7 @@ Navigator::GetMozBluetooth(nsIDOMBluetoothManager** aBluetooth)
|
|||||||
// nsNavigator::nsIDOMNavigatorSystemMessages
|
// nsNavigator::nsIDOMNavigatorSystemMessages
|
||||||
//*****************************************************************************
|
//*****************************************************************************
|
||||||
#ifdef MOZ_SYS_MSG
|
#ifdef MOZ_SYS_MSG
|
||||||
NS_IMETHODIMP
|
nsresult
|
||||||
Navigator::EnsureMessagesManager()
|
Navigator::EnsureMessagesManager()
|
||||||
{
|
{
|
||||||
if (mMessagesManager) {
|
if (mMessagesManager) {
|
||||||
|
@ -5973,6 +5973,9 @@ DefineIDBInterfaceConstants(JSContext *cx, JSObject *obj, const nsIID *aIID)
|
|||||||
else if (aIID->Equals(NS_GET_IID(nsIIDBTransaction))) {
|
else if (aIID->Equals(NS_GET_IID(nsIIDBTransaction))) {
|
||||||
interface = IDBConstant::IDBTransaction;
|
interface = IDBConstant::IDBTransaction;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
MOZ_NOT_REACHED("unexpected IID");
|
||||||
|
}
|
||||||
|
|
||||||
for (int8_t i = 0; i < (int8_t)mozilla::ArrayLength(sIDBConstants); ++i) {
|
for (int8_t i = 0; i < (int8_t)mozilla::ArrayLength(sIDBConstants); ++i) {
|
||||||
const IDBConstant& c = sIDBConstants[i];
|
const IDBConstant& c = sIDBConstants[i];
|
||||||
|
@ -9400,9 +9400,7 @@ nsGlobalWindow::SetTimeoutOrInterval(nsIScriptTimeoutHandler *aHandler,
|
|||||||
|
|
||||||
nsRefPtr<nsTimeout> copy = timeout;
|
nsRefPtr<nsTimeout> copy = timeout;
|
||||||
|
|
||||||
rv = timeout->mTimer->InitWithFuncCallback(TimerCallback, timeout,
|
rv = timeout->InitTimer(TimerCallback, realInterval);
|
||||||
realInterval,
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@ -9637,10 +9635,7 @@ nsGlobalWindow::RescheduleTimeout(nsTimeout* aTimeout, const TimeStamp& now,
|
|||||||
// platforms whether delay is positive or negative (which we
|
// platforms whether delay is positive or negative (which we
|
||||||
// know is always positive here, but cast anyways for
|
// know is always positive here, but cast anyways for
|
||||||
// consistency).
|
// consistency).
|
||||||
nsresult rv = aTimeout->mTimer->
|
nsresult rv = aTimeout->InitTimer(TimerCallback, delay.ToMilliseconds());
|
||||||
InitWithFuncCallback(TimerCallback, aTimeout,
|
|
||||||
delay.ToMilliseconds(),
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_ERROR("Error initializing timer for DOM timeout!");
|
NS_ERROR("Error initializing timer for DOM timeout!");
|
||||||
@ -9982,11 +9977,7 @@ nsresult nsGlobalWindow::ResetTimersForNonBackgroundWindow()
|
|||||||
timeout->mFiringDepth = firingDepth;
|
timeout->mFiringDepth = firingDepth;
|
||||||
timeout->Release();
|
timeout->Release();
|
||||||
|
|
||||||
nsresult rv =
|
nsresult rv = timeout->InitTimer(TimerCallback, delay.ToMilliseconds());
|
||||||
timeout->mTimer->InitWithFuncCallback(TimerCallback,
|
|
||||||
timeout,
|
|
||||||
delay.ToMilliseconds(),
|
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
NS_WARNING("Error resetting non background timer for DOM timeout!");
|
NS_WARNING("Error resetting non background timer for DOM timeout!");
|
||||||
@ -10499,8 +10490,7 @@ nsGlobalWindow::ResumeTimeouts(bool aThawChildren)
|
|||||||
t->mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
t->mTimer = do_CreateInstance("@mozilla.org/timer;1");
|
||||||
NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY);
|
NS_ENSURE_TRUE(t->mTimer, NS_ERROR_OUT_OF_MEMORY);
|
||||||
|
|
||||||
rv = t->mTimer->InitWithFuncCallback(TimerCallback, t, delay,
|
rv = t->InitTimer(TimerCallback, delay);
|
||||||
nsITimer::TYPE_ONE_SHOT);
|
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
t->mTimer = nsnull;
|
t->mTimer = nsnull;
|
||||||
return rv;
|
return rv;
|
||||||
|
@ -153,6 +153,11 @@ struct nsTimeout : PRCList
|
|||||||
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
|
return static_cast<nsTimeout*>(PR_PREV_LINK(this));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsresult InitTimer(nsTimerCallbackFunc aFunc, PRUint64 delay) {
|
||||||
|
return mTimer->InitWithFuncCallback(aFunc, this, delay,
|
||||||
|
nsITimer::TYPE_ONE_SHOT);
|
||||||
|
}
|
||||||
|
|
||||||
// Window for which this timeout fires
|
// Window for which this timeout fires
|
||||||
nsRefPtr<nsGlobalWindow> mWindow;
|
nsRefPtr<nsGlobalWindow> mWindow;
|
||||||
|
|
||||||
|
@ -80,8 +80,9 @@ template<>
|
|||||||
struct PrimitiveConversionTraits<bool> {
|
struct PrimitiveConversionTraits<bool> {
|
||||||
typedef JSBool jstype;
|
typedef JSBool jstype;
|
||||||
typedef bool intermediateType;
|
typedef bool intermediateType;
|
||||||
static inline bool converter(JSContext* cx, JS::Value v, jstype* retval) {
|
static inline bool converter(JSContext* /* unused */, JS::Value v, jstype* retval) {
|
||||||
return JS_ValueToBoolean(cx, v, retval);
|
*retval = JS::ToBoolean(v);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -403,8 +403,10 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
|
|||||||
|
|
||||||
DBusMessageIter iter;
|
DBusMessageIter iter;
|
||||||
|
|
||||||
NS_ASSERTION(dbus_message_iter_init(aMsg, &iter),
|
if (!dbus_message_iter_init(aMsg, &iter)) {
|
||||||
"Can't create message iterator!");
|
NS_WARNING("Can't create iterator!");
|
||||||
|
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
|
||||||
|
}
|
||||||
|
|
||||||
InfallibleTArray<BluetoothNamedValue> value;
|
InfallibleTArray<BluetoothNamedValue> value;
|
||||||
const char* addr;
|
const char* addr;
|
||||||
|
@ -13,7 +13,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=717103
|
|||||||
|
|
||||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body onunload="unload()">
|
||||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
|
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=717103">Mozilla Bug 717103</a>
|
||||||
<p id="display"></p>
|
<p id="display"></p>
|
||||||
<div id="content" style="display: none">
|
<div id="content" style="display: none">
|
||||||
@ -22,11 +22,21 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=717103
|
|||||||
<pre id="test">
|
<pre id="test">
|
||||||
<script class="testbody" type="text/javascript">
|
<script class="testbody" type="text/javascript">
|
||||||
|
|
||||||
|
function unload() {
|
||||||
|
delete gDataBlob;
|
||||||
|
gDataBlob = null;
|
||||||
|
|
||||||
|
delete gFileReader;
|
||||||
|
gFileReader = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
devicestorage_setup();
|
devicestorage_setup();
|
||||||
|
|
||||||
var gFileName = "devicestorage/hi";
|
var gFileName = "devicestorage/hi";
|
||||||
var gData = "My name is Doug Turner. My IRC nick is DougT. I like Maple cookies."
|
var gData = "My name is Doug Turner. My IRC nick is DougT. I like Maple cookies."
|
||||||
var gDataBlob = new Blob([gData], {type: 'text/plain'});
|
var gDataBlob = new Blob([gData], {type: 'text/plain'});
|
||||||
|
var gFileReader = new FileReader();
|
||||||
|
|
||||||
function getAfterDeleteSuccess(e) {
|
function getAfterDeleteSuccess(e) {
|
||||||
ok(false, "file was deleted not successfully");
|
ok(false, "file was deleted not successfully");
|
||||||
@ -63,9 +73,8 @@ function getSuccess(e) {
|
|||||||
|
|
||||||
var name = e.target.result.name;
|
var name = e.target.result.name;
|
||||||
|
|
||||||
var reader = new FileReader();
|
gFileReader.readAsArrayBuffer(gDataBlob);
|
||||||
reader.readAsArrayBuffer(gDataBlob);
|
gFileReader.onload = function(e) {
|
||||||
reader.onload = function(e) {
|
|
||||||
readerCallback(e);
|
readerCallback(e);
|
||||||
|
|
||||||
request = storage[0].delete(name)
|
request = storage[0].delete(name)
|
||||||
|
@ -17,7 +17,7 @@ namespace dom {
|
|||||||
void
|
void
|
||||||
CrashReporterParent::ActorDestroy(ActorDestroyReason why)
|
CrashReporterParent::ActorDestroy(ActorDestroyReason why)
|
||||||
{
|
{
|
||||||
#if defined(__ANDROID__) && defined(MOZ_CRASHREPORTER)
|
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
||||||
CrashReporter::RemoveLibraryMappingsForChild(ProcessId(OtherProcess()));
|
CrashReporter::RemoveLibraryMappingsForChild(ProcessId(OtherProcess()));
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ CrashReporterParent::ActorDestroy(ActorDestroyReason why)
|
|||||||
bool
|
bool
|
||||||
CrashReporterParent::RecvAddLibraryMappings(const InfallibleTArray<Mapping>& mappings)
|
CrashReporterParent::RecvAddLibraryMappings(const InfallibleTArray<Mapping>& mappings)
|
||||||
{
|
{
|
||||||
#if defined(__ANDROID__) && defined(MOZ_CRASHREPORTER)
|
#if defined(MOZ_WIDGET_ANDROID) && defined(MOZ_CRASHREPORTER)
|
||||||
for (PRUint32 i = 0; i < mappings.Length(); i++) {
|
for (PRUint32 i = 0; i < mappings.Length(); i++) {
|
||||||
const Mapping& m = mappings[i];
|
const Mapping& m = mappings[i];
|
||||||
CrashReporter::AddLibraryMappingForChild(ProcessId(OtherProcess()),
|
CrashReporter::AddLibraryMappingForChild(ProcessId(OtherProcess()),
|
||||||
|
@ -1947,6 +1947,68 @@ nsPluginHost::IsLiveTag(nsIPluginTag* aPluginTag)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nsPluginTag*
|
||||||
|
nsPluginHost::HaveSamePlugin(const nsPluginTag* aPluginTag)
|
||||||
|
{
|
||||||
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
||||||
|
if (tag->HasSameNameAndMimes(aPluginTag)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
nsPluginTag*
|
||||||
|
nsPluginHost::FirstPluginWithPath(const nsCString& path)
|
||||||
|
{
|
||||||
|
for (nsPluginTag* tag = mPlugins; tag; tag = tag->mNext) {
|
||||||
|
if (tag->mFullPath.Equals(path)) {
|
||||||
|
return tag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nsnull;
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
PRInt64 GetPluginLastModifiedTime(const nsCOMPtr<nsIFile>& localfile)
|
||||||
|
{
|
||||||
|
PRInt64 fileModTime = LL_ZERO;
|
||||||
|
|
||||||
|
#if defined(XP_MACOSX)
|
||||||
|
// On OS X the date of a bundle's "contents" (i.e. of its Info.plist file)
|
||||||
|
// is a much better guide to when it was last modified than the date of
|
||||||
|
// its package directory. See bug 313700.
|
||||||
|
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(localfile);
|
||||||
|
if (localFileMac) {
|
||||||
|
localFileMac->GetBundleContentsLastModifiedTime(&fileModTime);
|
||||||
|
} else {
|
||||||
|
localfile->GetLastModifiedTime(&fileModTime);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
localfile->GetLastModifiedTime(&fileModTime);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
return fileModTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct CompareFilesByTime
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
LessThan(const nsCOMPtr<nsIFile>& a, const nsCOMPtr<nsIFile>& b) const
|
||||||
|
{
|
||||||
|
return LL_CMP(GetPluginLastModifiedTime(a), <, GetPluginLastModifiedTime(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Equals(const nsCOMPtr<nsIFile>& a, const nsCOMPtr<nsIFile>& b) const
|
||||||
|
{
|
||||||
|
return LL_EQ(GetPluginLastModifiedTime(a), GetPluginLastModifiedTime(b));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // anonymous namespace
|
||||||
|
|
||||||
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
typedef NS_NPAPIPLUGIN_CALLBACK(char *, NP_GETMIMEDESCRIPTION)(void);
|
||||||
|
|
||||||
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
||||||
@ -1991,9 +2053,11 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pluginFiles.Sort(CompareFilesByTime());
|
||||||
|
|
||||||
bool warnOutdated = false;
|
bool warnOutdated = false;
|
||||||
|
|
||||||
for (PRUint32 i = 0; i < pluginFiles.Length(); i++) {
|
for (PRInt32 i = (pluginFiles.Length() - 1); i >= 0; i--) {
|
||||||
nsCOMPtr<nsIFile>& localfile = pluginFiles[i];
|
nsCOMPtr<nsIFile>& localfile = pluginFiles[i];
|
||||||
|
|
||||||
nsString utf16FilePath;
|
nsString utf16FilePath;
|
||||||
@ -2001,20 +2065,7 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
|||||||
if (NS_FAILED(rv))
|
if (NS_FAILED(rv))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
PRInt64 fileModTime = LL_ZERO;
|
PRInt64 fileModTime = GetPluginLastModifiedTime(localfile);
|
||||||
#if defined(XP_MACOSX)
|
|
||||||
// On OS X the date of a bundle's "contents" (i.e. of its Info.plist file)
|
|
||||||
// is a much better guide to when it was last modified than the date of
|
|
||||||
// its package directory. See bug 313700.
|
|
||||||
nsCOMPtr<nsILocalFileMac> localFileMac = do_QueryInterface(localfile);
|
|
||||||
if (localFileMac) {
|
|
||||||
localFileMac->GetBundleContentsLastModifiedTime(&fileModTime);
|
|
||||||
} else {
|
|
||||||
localfile->GetLastModifiedTime(&fileModTime);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
localfile->GetLastModifiedTime(&fileModTime);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Look for it in our cache
|
// Look for it in our cache
|
||||||
NS_ConvertUTF16toUTF8 filePath(utf16FilePath);
|
NS_ConvertUTF16toUTF8 filePath(utf16FilePath);
|
||||||
@ -2147,6 +2198,21 @@ nsresult nsPluginHost::ScanPluginsDirectory(nsIFile *pluginsDir,
|
|||||||
*aPluginsChanged = true;
|
*aPluginsChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid adding different versions of the same plugin if they are running
|
||||||
|
// in-process, otherwise we risk undefined behaviour.
|
||||||
|
if (!nsNPAPIPlugin::RunPluginOOP(pluginTag)) {
|
||||||
|
if (nsPluginTag *duplicate = HaveSamePlugin(pluginTag)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Don't add the same plugin again if it hasn't changed
|
||||||
|
if (nsPluginTag* duplicate = FirstPluginWithPath(pluginTag->mFullPath)) {
|
||||||
|
if (LL_EQ(pluginTag->mLastModifiedTime, duplicate->mLastModifiedTime)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// If we're not creating a plugin list, simply looking for changes,
|
// If we're not creating a plugin list, simply looking for changes,
|
||||||
// then we're done.
|
// then we're done.
|
||||||
if (!aCreatePluginList) {
|
if (!aCreatePluginList) {
|
||||||
|
@ -268,6 +268,12 @@ private:
|
|||||||
// Checks to see if a tag object is in our list of live tags.
|
// Checks to see if a tag object is in our list of live tags.
|
||||||
bool IsLiveTag(nsIPluginTag* tag);
|
bool IsLiveTag(nsIPluginTag* tag);
|
||||||
|
|
||||||
|
// Checks our list of live tags for an equivalent tag.
|
||||||
|
nsPluginTag* HaveSamePlugin(const nsPluginTag * aPluginTag);
|
||||||
|
|
||||||
|
// Returns the first plugin at |path|
|
||||||
|
nsPluginTag* FirstPluginWithPath(const nsCString& path);
|
||||||
|
|
||||||
nsresult EnsurePrivateDirServiceProvider();
|
nsresult EnsurePrivateDirServiceProvider();
|
||||||
|
|
||||||
void OnPluginInstanceDestroyed(nsPluginTag* aPluginTag);
|
void OnPluginInstanceDestroyed(nsPluginTag* aPluginTag);
|
||||||
|
@ -379,6 +379,25 @@ bool nsPluginTag::IsEnabled()
|
|||||||
return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
return HasFlag(NS_PLUGIN_FLAG_ENABLED) && !HasFlag(NS_PLUGIN_FLAG_BLOCKLISTED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
nsPluginTag::HasSameNameAndMimes(const nsPluginTag *aPluginTag) const
|
||||||
|
{
|
||||||
|
NS_ENSURE_TRUE(aPluginTag, false);
|
||||||
|
|
||||||
|
if ((!mName.Equals(aPluginTag->mName)) ||
|
||||||
|
(mMimeTypes.Length() != aPluginTag->mMimeTypes.Length())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (PRUint32 i = 0; i < mMimeTypes.Length(); i++) {
|
||||||
|
if (!mMimeTypes[i].Equals(aPluginTag->mMimeTypes[i])) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
void nsPluginTag::TryUnloadPlugin(bool inShutdown)
|
void nsPluginTag::TryUnloadPlugin(bool inShutdown)
|
||||||
{
|
{
|
||||||
// We never want to send NPP_Shutdown to an in-process plugin unless
|
// We never want to send NPP_Shutdown to an in-process plugin unless
|
||||||
|
@ -58,6 +58,7 @@ public:
|
|||||||
void UnMark(PRUint32 mask);
|
void UnMark(PRUint32 mask);
|
||||||
bool HasFlag(PRUint32 flag);
|
bool HasFlag(PRUint32 flag);
|
||||||
PRUint32 Flags();
|
PRUint32 Flags();
|
||||||
|
bool HasSameNameAndMimes(const nsPluginTag *aPluginTag) const;
|
||||||
bool IsEnabled();
|
bool IsEnabled();
|
||||||
|
|
||||||
nsRefPtr<nsPluginTag> mNext;
|
nsRefPtr<nsPluginTag> mNext;
|
||||||
|
@ -1922,7 +1922,7 @@ bool
|
|||||||
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
|
PluginInstanceParent::SharedSurfaceSetWindow(const NPWindow* aWindow,
|
||||||
NPRemoteWindow& aRemoteWindow)
|
NPRemoteWindow& aRemoteWindow)
|
||||||
{
|
{
|
||||||
aRemoteWindow.window = nsnull;
|
aRemoteWindow.window = 0;
|
||||||
aRemoteWindow.x = aWindow->x;
|
aRemoteWindow.x = aWindow->x;
|
||||||
aRemoteWindow.y = aWindow->y;
|
aRemoteWindow.y = aWindow->y;
|
||||||
aRemoteWindow.width = aWindow->width;
|
aRemoteWindow.width = aWindow->width;
|
||||||
|
@ -140,17 +140,17 @@ function RILContentHelper() {
|
|||||||
this.initMessageListener(RIL_IPC_MSG_NAMES);
|
this.initMessageListener(RIL_IPC_MSG_NAMES);
|
||||||
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
Services.obs.addObserver(this, "xpcom-shutdown", false);
|
||||||
|
|
||||||
// Request initial state.
|
// Request initial context.
|
||||||
let radioState = cpmm.QueryInterface(Ci.nsISyncMessageSender)
|
let rilContext = cpmm.QueryInterface(Ci.nsISyncMessageSender)
|
||||||
.sendSyncMessage("RIL:GetRadioState")[0];
|
.sendSyncMessage("RIL:GetRilContext")[0];
|
||||||
|
|
||||||
if (!radioState) {
|
if (!rilContext) {
|
||||||
debug("Received null radioState from chrome process.");
|
debug("Received null rilContext from chrome process.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.cardState = radioState.cardState;
|
this.cardState = rilContext.cardState;
|
||||||
this.updateConnectionInfo(radioState.voice, this.voiceConnectionInfo);
|
this.updateConnectionInfo(rilContext.voice, this.voiceConnectionInfo);
|
||||||
this.updateConnectionInfo(radioState.data, this.dataConnectionInfo);
|
this.updateConnectionInfo(rilContext.data, this.dataConnectionInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
RILContentHelper.prototype = {
|
RILContentHelper.prototype = {
|
||||||
|
@ -60,6 +60,7 @@ let RILQUIRKS_DATACALLSTATE_DOWN_IS_UP = false;
|
|||||||
let RILQUIRKS_V5_LEGACY = true;
|
let RILQUIRKS_V5_LEGACY = true;
|
||||||
let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = false;
|
let RILQUIRKS_REQUEST_USE_DIAL_EMERGENCY_CALL = false;
|
||||||
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = false;
|
let RILQUIRKS_MODEM_DEFAULTS_TO_EMERGENCY_MODE = false;
|
||||||
|
let RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = false;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This object contains helpers buffering incoming data & deconstructing it
|
* This object contains helpers buffering incoming data & deconstructing it
|
||||||
@ -727,6 +728,10 @@ let RIL = {
|
|||||||
case "Qualcomm RIL 1.0":
|
case "Qualcomm RIL 1.0":
|
||||||
let product_model = libcutils.property_get("ro.product.model");
|
let product_model = libcutils.property_get("ro.product.model");
|
||||||
if (DEBUG) debug("Detected product model " + product_model);
|
if (DEBUG) debug("Detected product model " + product_model);
|
||||||
|
if (product_model == "otoro1") {
|
||||||
|
if (DEBUG) debug("Enabling RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS.");
|
||||||
|
RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS = true;
|
||||||
|
}
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
debug("Detected Qualcomm RIL 1.0, " +
|
debug("Detected Qualcomm RIL 1.0, " +
|
||||||
"disabling RILQUIRKS_V5_LEGACY and " +
|
"disabling RILQUIRKS_V5_LEGACY and " +
|
||||||
@ -2825,6 +2830,12 @@ RIL[REQUEST_GET_SIM_STATUS] = function REQUEST_GET_SIM_STATUS(length, options) {
|
|||||||
pin1: Buf.readUint32(),
|
pin1: Buf.readUint32(),
|
||||||
pin2: Buf.readUint32()
|
pin2: Buf.readUint32()
|
||||||
});
|
});
|
||||||
|
if (RILQUIRKS_SIM_APP_STATE_EXTRA_FIELDS) {
|
||||||
|
Buf.readUint32();
|
||||||
|
Buf.readUint32();
|
||||||
|
Buf.readUint32();
|
||||||
|
Buf.readUint32();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (DEBUG) debug("iccStatus: " + JSON.stringify(iccStatus));
|
if (DEBUG) debug("iccStatus: " + JSON.stringify(iccStatus));
|
||||||
|
@ -7,7 +7,9 @@
|
|||||||
#include "nsEditor.h"
|
#include "nsEditor.h"
|
||||||
#include "IMETextTxn.h"
|
#include "IMETextTxn.h"
|
||||||
#include "nsGkAtoms.h"
|
#include "nsGkAtoms.h"
|
||||||
#include "nsISelection.h"
|
#include "mozilla/Selection.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
|
PlaceholderTxn::PlaceholderTxn() : EditAggregateTxn(),
|
||||||
mAbsorb(true),
|
mAbsorb(true),
|
||||||
@ -42,7 +44,9 @@ NS_INTERFACE_MAP_END_INHERITING(EditAggregateTxn)
|
|||||||
NS_IMPL_ADDREF_INHERITED(PlaceholderTxn, EditAggregateTxn)
|
NS_IMPL_ADDREF_INHERITED(PlaceholderTxn, EditAggregateTxn)
|
||||||
NS_IMPL_RELEASE_INHERITED(PlaceholderTxn, EditAggregateTxn)
|
NS_IMPL_RELEASE_INHERITED(PlaceholderTxn, EditAggregateTxn)
|
||||||
|
|
||||||
NS_IMETHODIMP PlaceholderTxn::Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor)
|
NS_IMETHODIMP
|
||||||
|
PlaceholderTxn::Init(nsIAtom* aName, nsSelectionState* aSelState,
|
||||||
|
nsEditor* aEditor)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aEditor && aSelState, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(aEditor && aSelState, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
@ -256,10 +260,9 @@ NS_IMETHODIMP PlaceholderTxn::Commit()
|
|||||||
|
|
||||||
NS_IMETHODIMP PlaceholderTxn::RememberEndingSelection()
|
NS_IMETHODIMP PlaceholderTxn::RememberEndingSelection()
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsRefPtr<Selection> selection = mEditor->GetSelection();
|
||||||
nsresult res = mEditor->GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
return mEndSel.SaveSelection(selection);
|
mEndSel.SaveSelection(selection);
|
||||||
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ public:
|
|||||||
|
|
||||||
// ------------ nsIAbsorbingTransaction -----------------------
|
// ------------ nsIAbsorbingTransaction -----------------------
|
||||||
|
|
||||||
NS_IMETHOD Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor);
|
NS_IMETHOD Init(nsIAtom* aName, nsSelectionState* aSelState,
|
||||||
|
nsEditor* aEditor);
|
||||||
|
|
||||||
NS_IMETHOD GetTxnName(nsIAtom **aName);
|
NS_IMETHOD GetTxnName(nsIAtom **aName);
|
||||||
|
|
||||||
@ -72,7 +73,7 @@ protected:
|
|||||||
// selection properly.
|
// selection properly.
|
||||||
nsAutoPtr<nsSelectionState> mStartSel; // use a pointer because this is constructed before we exist
|
nsAutoPtr<nsSelectionState> mStartSel; // use a pointer because this is constructed before we exist
|
||||||
nsSelectionState mEndSel;
|
nsSelectionState mEndSel;
|
||||||
nsIEditor* mEditor; /** the editor for this transaction */
|
nsEditor* mEditor; /** the editor for this transaction */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
18
editor/libeditor/base/crashtests/776323.html
Normal file
18
editor/libeditor/base/crashtests/776323.html
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html contenteditable="true">
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
function boom()
|
||||||
|
{
|
||||||
|
document.execCommand("inserthtml", false, "b");
|
||||||
|
var myrange = document.createRange();
|
||||||
|
myrange.selectNodeContents(document.getElementsByTagName("img")[0]);
|
||||||
|
window.getSelection().addRange(myrange);
|
||||||
|
document.execCommand("strikethrough", false, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="boom();"><img></body>
|
||||||
|
</html>
|
@ -17,3 +17,4 @@ load 766845.xhtml
|
|||||||
load 768765.html
|
load 768765.html
|
||||||
needs-focus load 771749.html
|
needs-focus load 771749.html
|
||||||
load 772282.html
|
load 772282.html
|
||||||
|
load 776323.html
|
||||||
|
@ -904,9 +904,8 @@ nsEditor::BeginPlaceHolderTransaction(nsIAtom *aName)
|
|||||||
BeginUpdateViewBatch();
|
BeginUpdateViewBatch();
|
||||||
mPlaceHolderTxn = nsnull;
|
mPlaceHolderTxn = nsnull;
|
||||||
mPlaceHolderName = aName;
|
mPlaceHolderName = aName;
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
if (selection) {
|
||||||
if (NS_SUCCEEDED(res)) {
|
|
||||||
mSelState = new nsSelectionState();
|
mSelState = new nsSelectionState();
|
||||||
mSelState->SaveSelection(selection);
|
mSelState->SaveSelection(selection);
|
||||||
}
|
}
|
||||||
@ -1979,7 +1978,7 @@ nsEditor::ArePreservingSelection()
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
nsEditor::PreserveSelectionAcrossActions(nsISelection *aSel)
|
nsEditor::PreserveSelectionAcrossActions(Selection* aSel)
|
||||||
{
|
{
|
||||||
mSavedSel.SaveSelection(aSel);
|
mSavedSel.SaveSelection(aSel);
|
||||||
mRangeUpdater.RegisterSelectionState(mSavedSel);
|
mRangeUpdater.RegisterSelectionState(mSavedSel);
|
||||||
|
@ -425,7 +425,7 @@ public:
|
|||||||
/** routines for managing the preservation of selection across
|
/** routines for managing the preservation of selection across
|
||||||
* various editor actions */
|
* various editor actions */
|
||||||
bool ArePreservingSelection();
|
bool ArePreservingSelection();
|
||||||
void PreserveSelectionAcrossActions(nsISelection *aSel);
|
void PreserveSelectionAcrossActions(mozilla::Selection* aSel);
|
||||||
nsresult RestorePreservedSelection(nsISelection *aSel);
|
nsresult RestorePreservedSelection(nsISelection *aSel);
|
||||||
void StopPreservingSelection();
|
void StopPreservingSelection();
|
||||||
|
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
|
#include "mozilla/Selection.h"
|
||||||
#include "nsCOMArray.h"
|
#include "nsCOMArray.h"
|
||||||
#include "nsComponentManagerUtils.h"
|
#include "nsComponentManagerUtils.h"
|
||||||
#include "nsEditorUtils.h"
|
#include "nsEditorUtils.h"
|
||||||
@ -18,24 +18,23 @@
|
|||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
#include "nsIInterfaceRequestorUtils.h"
|
#include "nsIInterfaceRequestorUtils.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsISelection.h"
|
|
||||||
#include "nsISimpleEnumerator.h"
|
#include "nsISimpleEnumerator.h"
|
||||||
|
|
||||||
class nsIDOMRange;
|
class nsIDOMRange;
|
||||||
class nsISupports;
|
class nsISupports;
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
/******************************************************************************
|
/******************************************************************************
|
||||||
* nsAutoSelectionReset
|
* nsAutoSelectionReset
|
||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
nsAutoSelectionReset::nsAutoSelectionReset(nsISelection *aSel, nsEditor *aEd) :
|
nsAutoSelectionReset::nsAutoSelectionReset(Selection* aSel, nsEditor* aEd)
|
||||||
mSel(nsnull)
|
: mSel(nsnull), mEd(nsnull)
|
||||||
,mEd(nsnull)
|
|
||||||
{
|
{
|
||||||
if (!aSel || !aEd) return; // not much we can do, bail.
|
if (!aSel || !aEd) return; // not much we can do, bail.
|
||||||
if (aEd->ArePreservingSelection()) return; // we already have initted mSavedSel, so this must be nested call.
|
if (aEd->ArePreservingSelection()) return; // we already have initted mSavedSel, so this must be nested call.
|
||||||
mSel = do_QueryInterface(aSel);
|
mSel = aSel;
|
||||||
mEd = aEd;
|
mEd = aEd;
|
||||||
if (mSel)
|
if (mSel)
|
||||||
{
|
{
|
||||||
|
@ -57,12 +57,12 @@ class NS_STACK_CLASS nsAutoSelectionReset
|
|||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
/** ref-counted reference to the selection that we are supposed to restore */
|
/** ref-counted reference to the selection that we are supposed to restore */
|
||||||
nsCOMPtr<nsISelection> mSel;
|
nsRefPtr<mozilla::Selection> mSel;
|
||||||
nsEditor *mEd; // non-owning ref to nsEditor
|
nsEditor *mEd; // non-owning ref to nsEditor
|
||||||
|
|
||||||
public:
|
public:
|
||||||
/** constructor responsible for remembering all state needed to restore aSel */
|
/** constructor responsible for remembering all state needed to restore aSel */
|
||||||
nsAutoSelectionReset(nsISelection *aSel, nsEditor *aEd);
|
nsAutoSelectionReset(mozilla::Selection* aSel, nsEditor* aEd);
|
||||||
|
|
||||||
/** destructor restores mSel to its former state */
|
/** destructor restores mSel to its former state */
|
||||||
~nsAutoSelectionReset();
|
~nsAutoSelectionReset();
|
||||||
|
@ -32,7 +32,8 @@ public:
|
|||||||
|
|
||||||
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IABSORBINGTRANSACTION_IID)
|
NS_DECLARE_STATIC_IID_ACCESSOR(NS_IABSORBINGTRANSACTION_IID)
|
||||||
|
|
||||||
NS_IMETHOD Init(nsIAtom *aName, nsSelectionState *aSelState, nsIEditor *aEditor)=0;
|
NS_IMETHOD Init(nsIAtom* aName, nsSelectionState* aSelState,
|
||||||
|
nsEditor* aEditor) = 0;
|
||||||
|
|
||||||
NS_IMETHOD EndPlaceHolderBatch()=0;
|
NS_IMETHOD EndPlaceHolderBatch()=0;
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
#include "mozilla/Assertions.h" // for MOZ_ASSERT, etc
|
||||||
|
#include "mozilla/Selection.h" // for Selection
|
||||||
#include "nsAString.h" // for nsAString_internal::Length
|
#include "nsAString.h" // for nsAString_internal::Length
|
||||||
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
|
#include "nsAutoPtr.h" // for nsRefPtr, getter_AddRefs, etc
|
||||||
#include "nsCycleCollectionParticipant.h"
|
#include "nsCycleCollectionParticipant.h"
|
||||||
@ -19,6 +20,7 @@
|
|||||||
#include "nsRange.h" // for nsRange
|
#include "nsRange.h" // for nsRange
|
||||||
#include "nsSelectionState.h"
|
#include "nsSelectionState.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* class for recording selection info. stores selection as collection of
|
* class for recording selection info. stores selection as collection of
|
||||||
@ -47,43 +49,30 @@ nsSelectionState::DoTraverse(nsCycleCollectionTraversalCallback &cb)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
void
|
||||||
nsSelectionState::SaveSelection(nsISelection *aSel)
|
nsSelectionState::SaveSelection(Selection* aSel)
|
||||||
{
|
{
|
||||||
NS_ENSURE_TRUE(aSel, NS_ERROR_NULL_POINTER);
|
MOZ_ASSERT(aSel);
|
||||||
PRInt32 i,rangeCount, arrayCount = mArray.Length();
|
PRInt32 arrayCount = mArray.Length();
|
||||||
aSel->GetRangeCount(&rangeCount);
|
PRInt32 rangeCount = aSel->GetRangeCount();
|
||||||
|
|
||||||
// if we need more items in the array, new them
|
// if we need more items in the array, new them
|
||||||
if (arrayCount<rangeCount)
|
if (arrayCount < rangeCount) {
|
||||||
{
|
for (PRInt32 i = arrayCount; i < rangeCount; i++) {
|
||||||
PRInt32 count = rangeCount-arrayCount;
|
|
||||||
for (i=0; i<count; i++)
|
|
||||||
{
|
|
||||||
mArray.AppendElement();
|
mArray.AppendElement();
|
||||||
mArray[i] = new nsRangeStore();
|
mArray[i] = new nsRangeStore();
|
||||||
}
|
}
|
||||||
}
|
} else if (arrayCount > rangeCount) {
|
||||||
|
|
||||||
// else if we have too many, delete them
|
// else if we have too many, delete them
|
||||||
else if (arrayCount>rangeCount)
|
for (PRInt32 i = arrayCount - 1; i >= rangeCount; i--) {
|
||||||
{
|
|
||||||
for (i = arrayCount-1; i >= rangeCount; i--)
|
|
||||||
{
|
|
||||||
mArray.RemoveElementAt(i);
|
mArray.RemoveElementAt(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// now store the selection ranges
|
// now store the selection ranges
|
||||||
nsresult res = NS_OK;
|
for (PRInt32 i = 0; i < rangeCount; i++) {
|
||||||
for (i=0; i<rangeCount; i++)
|
mArray[i]->StoreRange(aSel->GetRangeAt(i));
|
||||||
{
|
|
||||||
nsCOMPtr<nsIDOMRange> range;
|
|
||||||
res = aSel->GetRangeAt(i, getter_AddRefs(range));
|
|
||||||
mArray[i]->StoreRange(range);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -18,6 +18,9 @@ class nsIDOMCharacterData;
|
|||||||
class nsIDOMRange;
|
class nsIDOMRange;
|
||||||
class nsISelection;
|
class nsISelection;
|
||||||
class nsRange;
|
class nsRange;
|
||||||
|
namespace mozilla {
|
||||||
|
class Selection;
|
||||||
|
}
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
* class for recording selection info. stores selection as collection of
|
* class for recording selection info. stores selection as collection of
|
||||||
@ -52,7 +55,7 @@ class nsSelectionState
|
|||||||
void DoTraverse(nsCycleCollectionTraversalCallback &cb);
|
void DoTraverse(nsCycleCollectionTraversalCallback &cb);
|
||||||
void DoUnlink() { MakeEmpty(); }
|
void DoUnlink() { MakeEmpty(); }
|
||||||
|
|
||||||
nsresult SaveSelection(nsISelection *aSel);
|
void SaveSelection(mozilla::Selection *aSel);
|
||||||
nsresult RestoreSelection(nsISelection *aSel);
|
nsresult RestoreSelection(nsISelection *aSel);
|
||||||
bool IsCollapsed();
|
bool IsCollapsed();
|
||||||
bool IsEqual(nsSelectionState *aSelState);
|
bool IsEqual(nsSelectionState *aSelState);
|
||||||
|
@ -2869,7 +2869,7 @@ nsHTMLEditRules::DidDeleteSelection(nsISelection *aSelection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
|
nsHTMLEditRules::WillMakeList(Selection* aSelection,
|
||||||
const nsAString* aListType,
|
const nsAString* aListType,
|
||||||
bool aEntireList,
|
bool aEntireList,
|
||||||
const nsAString* aBulletType,
|
const nsAString* aBulletType,
|
||||||
@ -3159,7 +3159,7 @@ nsHTMLEditRules::WillMakeList(nsISelection* aSelection,
|
|||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillRemoveList(nsISelection *aSelection,
|
nsHTMLEditRules::WillRemoveList(Selection* aSelection,
|
||||||
bool aOrdered,
|
bool aOrdered,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
bool *aHandled)
|
bool *aHandled)
|
||||||
@ -3226,7 +3226,7 @@ nsHTMLEditRules::WillRemoveList(nsISelection *aSelection,
|
|||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillMakeDefListItem(nsISelection *aSelection,
|
nsHTMLEditRules::WillMakeDefListItem(Selection* aSelection,
|
||||||
const nsAString *aItemType,
|
const nsAString *aItemType,
|
||||||
bool aEntireList,
|
bool aEntireList,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
@ -3238,7 +3238,7 @@ nsHTMLEditRules::WillMakeDefListItem(nsISelection *aSelection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillMakeBasicBlock(nsISelection *aSelection,
|
nsHTMLEditRules::WillMakeBasicBlock(Selection* aSelection,
|
||||||
const nsAString *aBlockType,
|
const nsAString *aBlockType,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
bool *aHandled)
|
bool *aHandled)
|
||||||
@ -3395,7 +3395,8 @@ nsHTMLEditRules::DidMakeBasicBlock(nsISelection *aSelection,
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
|
nsHTMLEditRules::WillIndent(Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
nsresult res;
|
nsresult res;
|
||||||
if (mHTMLEditor->IsCSSEnabled()) {
|
if (mHTMLEditor->IsCSSEnabled()) {
|
||||||
@ -3408,7 +3409,8 @@ nsHTMLEditRules::WillIndent(nsISelection *aSelection, bool *aCancel, bool * aHan
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
|
nsHTMLEditRules::WillCSSIndent(Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||||
|
|
||||||
@ -3614,7 +3616,8 @@ nsHTMLEditRules::WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool * a
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool * aHandled)
|
nsHTMLEditRules::WillHTMLIndent(Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||||
nsresult res = WillInsert(aSelection, aCancel);
|
nsresult res = WillInsert(aSelection, aCancel);
|
||||||
@ -3842,7 +3845,8 @@ nsHTMLEditRules::WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *
|
|||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHandled)
|
nsHTMLEditRules::WillOutdent(Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||||
// initialize out param
|
// initialize out param
|
||||||
@ -4412,7 +4416,7 @@ nsHTMLEditRules::IsEmptyBlock(nsIDOMNode *aNode,
|
|||||||
|
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillAlign(nsISelection *aSelection,
|
nsHTMLEditRules::WillAlign(Selection* aSelection,
|
||||||
const nsAString *alignType,
|
const nsAString *alignType,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
bool *aHandled)
|
bool *aHandled)
|
||||||
@ -8570,7 +8574,8 @@ nsHTMLEditRules::RelativeChangeIndentationOfElementNode(nsIDOMNode *aNode, PRInt
|
|||||||
//
|
//
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled)
|
nsHTMLEditRules::WillAbsolutePosition(Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled)
|
||||||
{
|
{
|
||||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||||
nsresult res = WillInsert(aSelection, aCancel);
|
nsresult res = WillInsert(aSelection, aCancel);
|
||||||
@ -8786,8 +8791,8 @@ nsHTMLEditRules::DidAbsolutePosition()
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled)
|
nsHTMLEditRules::WillRemoveAbsolutePosition(Selection* aSelection,
|
||||||
{
|
bool* aCancel, bool* aHandled) {
|
||||||
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
if (!aSelection || !aCancel || !aHandled) { return NS_ERROR_NULL_POINTER; }
|
||||||
nsresult res = WillInsert(aSelection, aCancel);
|
nsresult res = WillInsert(aSelection, aCancel);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
@ -8808,7 +8813,7 @@ nsHTMLEditRules::WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCan
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
nsHTMLEditRules::WillRelativeChangeZIndex(nsISelection *aSelection,
|
nsHTMLEditRules::WillRelativeChangeZIndex(Selection* aSelection,
|
||||||
PRInt32 aChange,
|
PRInt32 aChange,
|
||||||
bool *aCancel,
|
bool *aCancel,
|
||||||
bool * aHandled)
|
bool * aHandled)
|
||||||
|
@ -156,18 +156,38 @@ protected:
|
|||||||
nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
|
nsresult MoveNodeSmart(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
|
||||||
nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
|
nsresult MoveContents(nsIDOMNode *aSource, nsIDOMNode *aDest, PRInt32 *aOffset);
|
||||||
nsresult DeleteNonTableElements(nsINode* aNode);
|
nsresult DeleteNonTableElements(nsINode* aNode);
|
||||||
nsresult WillMakeList(nsISelection *aSelection, const nsAString *aListType, bool aEntireList, const nsAString *aBulletType, bool *aCancel, bool *aHandled, const nsAString *aItemType=nsnull);
|
nsresult WillMakeList(mozilla::Selection* aSelection,
|
||||||
nsresult WillRemoveList(nsISelection *aSelection, bool aOrderd, bool *aCancel, bool *aHandled);
|
const nsAString* aListType,
|
||||||
nsresult WillIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
|
bool aEntireList,
|
||||||
nsresult WillCSSIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
|
const nsAString* aBulletType,
|
||||||
nsresult WillHTMLIndent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
|
bool* aCancel, bool* aHandled,
|
||||||
nsresult WillOutdent(nsISelection *aSelection, bool *aCancel, bool *aHandled);
|
const nsAString* aItemType = nsnull);
|
||||||
nsresult WillAlign(nsISelection *aSelection, const nsAString *alignType, bool *aCancel, bool *aHandled);
|
nsresult WillRemoveList(mozilla::Selection* aSelection,
|
||||||
nsresult WillAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
|
bool aOrdered, bool* aCancel, bool* aHandled);
|
||||||
nsresult WillRemoveAbsolutePosition(nsISelection *aSelection, bool *aCancel, bool * aHandled);
|
nsresult WillIndent(mozilla::Selection* aSelection,
|
||||||
nsresult WillRelativeChangeZIndex(nsISelection *aSelection, PRInt32 aChange, bool *aCancel, bool * aHandled);
|
bool* aCancel, bool* aHandled);
|
||||||
nsresult WillMakeDefListItem(nsISelection *aSelection, const nsAString *aBlockType, bool aEntireList, bool *aCancel, bool *aHandled);
|
nsresult WillCSSIndent(mozilla::Selection* aSelection,
|
||||||
nsresult WillMakeBasicBlock(nsISelection *aSelection, const nsAString *aBlockType, bool *aCancel, bool *aHandled);
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillHTMLIndent(mozilla::Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillOutdent(mozilla::Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillAlign(mozilla::Selection* aSelection,
|
||||||
|
const nsAString* alignType,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillAbsolutePosition(mozilla::Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillRemoveAbsolutePosition(mozilla::Selection* aSelection,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillRelativeChangeZIndex(mozilla::Selection* aSelection,
|
||||||
|
PRInt32 aChange,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillMakeDefListItem(mozilla::Selection* aSelection,
|
||||||
|
const nsAString* aBlockType, bool aEntireList,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
|
nsresult WillMakeBasicBlock(mozilla::Selection* aSelection,
|
||||||
|
const nsAString* aBlockType,
|
||||||
|
bool* aCancel, bool* aHandled);
|
||||||
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
nsresult DidMakeBasicBlock(nsISelection *aSelection, nsRulesInfo *aInfo, nsresult aResult);
|
||||||
nsresult DidAbsolutePosition();
|
nsresult DidAbsolutePosition();
|
||||||
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
|
nsresult AlignInnerBlocks(nsIDOMNode *aNode, const nsAString *alignType);
|
||||||
|
@ -3379,15 +3379,13 @@ SetSelectionAroundHeadChildren(nsISelection* aSelection,
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLEditor::GetHeadContentsAsHTML(nsAString& aOutputString)
|
nsHTMLEditor::GetHeadContentsAsHTML(nsAString& aOutputString)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsISelection> selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
NS_ENSURE_TRUE(selection, NS_ERROR_NULL_POINTER);
|
||||||
|
|
||||||
// Save current selection
|
// Save current selection
|
||||||
nsAutoSelectionReset selectionResetter(selection, this);
|
nsAutoSelectionReset selectionResetter(selection, this);
|
||||||
|
|
||||||
res = SetSelectionAroundHeadChildren(selection, mDocWeak);
|
nsresult res = SetSelectionAroundHeadChildren(selection, mDocWeak);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
|
|
||||||
res = OutputToString(NS_LITERAL_STRING("text/html"),
|
res = OutputToString(NS_LITERAL_STRING("text/html"),
|
||||||
|
@ -1535,11 +1535,8 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
|
|||||||
ForceCompositionEnd();
|
ForceCompositionEnd();
|
||||||
|
|
||||||
// Get the selection
|
// Get the selection
|
||||||
nsCOMPtr<nsISelection>selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||||
nsCOMPtr<nsISelectionPrivate> selPriv(do_QueryInterface(selection));
|
|
||||||
// Is the selection collapsed?
|
// Is the selection collapsed?
|
||||||
// if it's collapsed set typing state
|
// if it's collapsed set typing state
|
||||||
if (selection->Collapsed()) {
|
if (selection->Collapsed()) {
|
||||||
@ -1554,7 +1551,7 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
|
|||||||
NS_ENSURE_TRUE(selectedNode, NS_OK);
|
NS_ENSURE_TRUE(selectedNode, NS_OK);
|
||||||
if (IsTextNode(selectedNode)) {
|
if (IsTextNode(selectedNode)) {
|
||||||
nsCOMPtr<nsIDOMNode> parent;
|
nsCOMPtr<nsIDOMNode> parent;
|
||||||
res = selectedNode->GetParentNode(getter_AddRefs(parent));
|
nsresult res = selectedNode->GetParentNode(getter_AddRefs(parent));
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
selectedNode = parent;
|
selectedNode = parent;
|
||||||
}
|
}
|
||||||
@ -1575,7 +1572,7 @@ nsHTMLEditor::RelativeFontChange( PRInt32 aSizeChange)
|
|||||||
|
|
||||||
// get selection range enumerator
|
// get selection range enumerator
|
||||||
nsCOMPtr<nsIEnumerator> enumerator;
|
nsCOMPtr<nsIEnumerator> enumerator;
|
||||||
res = selPriv->GetEnumerator(getter_AddRefs(enumerator));
|
nsresult res = selection->GetEnumerator(getter_AddRefs(enumerator));
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(enumerator, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
#include "mozilla/Assertions.h"
|
#include "mozilla/Assertions.h"
|
||||||
|
#include "mozilla/Selection.h"
|
||||||
#include "mozilla/dom/Element.h"
|
#include "mozilla/dom/Element.h"
|
||||||
#include "nsAString.h"
|
#include "nsAString.h"
|
||||||
#include "nsAlgorithm.h"
|
#include "nsAlgorithm.h"
|
||||||
@ -28,8 +29,6 @@
|
|||||||
#include "nsIHTMLEditor.h"
|
#include "nsIHTMLEditor.h"
|
||||||
#include "nsINode.h"
|
#include "nsINode.h"
|
||||||
#include "nsIPresShell.h"
|
#include "nsIPresShell.h"
|
||||||
#include "nsISelection.h"
|
|
||||||
#include "nsISelectionPrivate.h" // For nsISelectionPrivate::TABLESELECTION_ defines
|
|
||||||
#include "nsISupportsUtils.h"
|
#include "nsISupportsUtils.h"
|
||||||
#include "nsITableCellLayout.h" // For efficient access to table cell
|
#include "nsITableCellLayout.h" // For efficient access to table cell
|
||||||
#include "nsITableEditor.h"
|
#include "nsITableEditor.h"
|
||||||
@ -1953,9 +1952,7 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
|
|||||||
// Save current selection to restore when done
|
// Save current selection to restore when done
|
||||||
// This is needed so ReplaceContainer can monitor selection
|
// This is needed so ReplaceContainer can monitor selection
|
||||||
// when replacing nodes
|
// when replacing nodes
|
||||||
nsCOMPtr<nsISelection>selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||||
nsAutoSelectionReset selectionResetter(selection, this);
|
nsAutoSelectionReset selectionResetter(selection, this);
|
||||||
|
|
||||||
@ -1965,7 +1962,8 @@ nsHTMLEditor::SwitchTableCellHeaderType(nsIDOMElement *aSourceCell, nsIDOMElemen
|
|||||||
|
|
||||||
// This creates new node, moves children, copies attributes (true)
|
// This creates new node, moves children, copies attributes (true)
|
||||||
// and manages the selection!
|
// and manages the selection!
|
||||||
res = ReplaceContainer(aSourceCell, address_of(newNode), newCellType, nsnull, nsnull, true);
|
nsresult res = ReplaceContainer(aSourceCell, address_of(newNode),
|
||||||
|
newCellType, nsnull, nsnull, true);
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(newNode, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
@ -2491,13 +2489,12 @@ nsHTMLEditor::FixBadColSpan(nsIDOMElement *aTable, PRInt32 aColIndex, PRInt32& a
|
|||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable)
|
nsHTMLEditor::NormalizeTable(nsIDOMElement *aTable)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsISelection>selection;
|
nsRefPtr<Selection> selection = GetSelection();
|
||||||
nsresult res = GetSelection(getter_AddRefs(selection));
|
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
|
||||||
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
NS_ENSURE_TRUE(selection, NS_ERROR_FAILURE);
|
||||||
|
|
||||||
nsCOMPtr<nsIDOMElement> table;
|
nsCOMPtr<nsIDOMElement> table;
|
||||||
res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"), aTable, getter_AddRefs(table));
|
nsresult res = GetElementOrParentByTagName(NS_LITERAL_STRING("table"),
|
||||||
|
aTable, getter_AddRefs(table));
|
||||||
NS_ENSURE_SUCCESS(res, res);
|
NS_ENSURE_SUCCESS(res, res);
|
||||||
// Don't fail if we didn't find a table
|
// Don't fail if we didn't find a table
|
||||||
NS_ENSURE_TRUE(table, NS_OK);
|
NS_ENSURE_TRUE(table, NS_OK);
|
||||||
|
@ -583,6 +583,13 @@ nsDocShellTreeOwner::SetParentNativeWindow(nativeWindow aParentNativeWindow)
|
|||||||
return NS_ERROR_NULL_POINTER;
|
return NS_ERROR_NULL_POINTER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP
|
||||||
|
nsDocShellTreeOwner::GetNativeHandle(nsAString& aNativeHandle)
|
||||||
|
{
|
||||||
|
// the nativeHandle should be accessed from nsIXULWindow
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDocShellTreeOwner::GetVisibility(bool* aVisibility)
|
nsDocShellTreeOwner::GetVisibility(bool* aVisibility)
|
||||||
{
|
{
|
||||||
|
@ -1378,6 +1378,12 @@ NS_IMETHODIMP nsWebBrowser::SetParentNativeWindow(nativeWindow aParentNativeWind
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NS_IMETHODIMP nsWebBrowser::GetNativeHandle(nsAString& aNativeHandle)
|
||||||
|
{
|
||||||
|
// the nativeHandle should be accessed from nsIXULWindow
|
||||||
|
return NS_ERROR_NOT_IMPLEMENTED;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility)
|
NS_IMETHODIMP nsWebBrowser::GetVisibility(bool* visibility)
|
||||||
{
|
{
|
||||||
NS_ENSURE_ARG_POINTER(visibility);
|
NS_ENSURE_ARG_POINTER(visibility);
|
||||||
|
@ -303,11 +303,13 @@ nsresult
|
|||||||
nsPermissionManager::InitDB(bool aRemoveFile)
|
nsPermissionManager::InitDB(bool aRemoveFile)
|
||||||
{
|
{
|
||||||
nsCOMPtr<nsIFile> permissionsFile;
|
nsCOMPtr<nsIFile> permissionsFile;
|
||||||
NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(permissionsFile));
|
nsresult rv = NS_GetSpecialDirectory(NS_APP_PERMISSION_PARENT_DIR, getter_AddRefs(permissionsFile));
|
||||||
if (!permissionsFile)
|
if (NS_FAILED(rv)) {
|
||||||
return NS_ERROR_UNEXPECTED;
|
rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, getter_AddRefs(permissionsFile));
|
||||||
|
}
|
||||||
|
NS_ENSURE_SUCCESS(rv, NS_ERROR_UNEXPECTED);
|
||||||
|
|
||||||
nsresult rv = permissionsFile->AppendNative(NS_LITERAL_CSTRING(kPermissionsFileName));
|
rv = permissionsFile->AppendNative(NS_LITERAL_CSTRING(kPermissionsFileName));
|
||||||
NS_ENSURE_SUCCESS(rv, rv);
|
NS_ENSURE_SUCCESS(rv, rv);
|
||||||
|
|
||||||
if (aRemoveFile) {
|
if (aRemoveFile) {
|
||||||
|
@ -182,6 +182,8 @@ avoid-extend-none.patch: Avoid incorrectly using EXTEND_NONE (bug 751668)
|
|||||||
|
|
||||||
win32-ExtCreatePen-zero-size.patch: Don't pass zero width or dash lengths to ExtCreatePen (bug 768348)
|
win32-ExtCreatePen-zero-size.patch: Don't pass zero width or dash lengths to ExtCreatePen (bug 768348)
|
||||||
|
|
||||||
|
d2d-repeating-gradients.patch: Minimize number of gradient stops added to handle repeating with path fills (bug 768775)
|
||||||
|
|
||||||
==== pixman patches ====
|
==== pixman patches ====
|
||||||
|
|
||||||
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
|
pixman-android-cpu-detect.patch: Add CPU detection support for Android, where we can't reliably access /proc/self/auxv.
|
||||||
|
@ -1416,7 +1416,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
|||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
|
||||||
|
|
||||||
// Find the corner furthest away from the gradient center in pattern space.
|
// Find the corner furthest away from the gradient center in pattern space.
|
||||||
double largest = MAX(_cairo_d2d_point_dist(top_left, gradient_center), _cairo_d2d_point_dist(top_right, gradient_center));
|
double largest = MAX(_cairo_d2d_point_dist(top_left, gradient_center), _cairo_d2d_point_dist(top_right, gradient_center));
|
||||||
@ -1536,6 +1536,7 @@ _cairo_d2d_create_radial_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
|||||||
|
|
||||||
static RefPtr<ID2D1Brush>
|
static RefPtr<ID2D1Brush>
|
||||||
_cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
_cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||||
|
cairo_path_fixed_t *fill_path,
|
||||||
cairo_linear_pattern_t *source_pattern)
|
cairo_linear_pattern_t *source_pattern)
|
||||||
{
|
{
|
||||||
if (source_pattern->p1.x == source_pattern->p2.x &&
|
if (source_pattern->p1.x == source_pattern->p2.x &&
|
||||||
@ -1569,25 +1570,36 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
|||||||
D2D1_GRADIENT_STOP *stops;
|
D2D1_GRADIENT_STOP *stops;
|
||||||
int num_stops = source_pattern->base.n_stops;
|
int num_stops = source_pattern->base.n_stops;
|
||||||
if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
|
if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
|
||||||
|
// Get this when the points are not transformed yet.
|
||||||
|
double gradient_length = _cairo_d2d_point_dist(p1, p2);
|
||||||
|
cairo_point_double_t top_left, top_right, bottom_left, bottom_right;
|
||||||
|
|
||||||
|
if (fill_path) {
|
||||||
|
// Calculate the repeat count needed;
|
||||||
|
cairo_box_t fill_extents;
|
||||||
|
_cairo_path_fixed_extents (fill_path, &fill_extents);
|
||||||
|
|
||||||
|
top_left.x = bottom_left.x = _cairo_fixed_to_double (fill_extents.p1.x);
|
||||||
|
top_left.y = top_right.y = _cairo_fixed_to_double (fill_extents.p1.y);
|
||||||
|
top_right.x = bottom_right.x = _cairo_fixed_to_double (fill_extents.p2.x);
|
||||||
|
bottom_right.y = bottom_left.y = _cairo_fixed_to_double (fill_extents.p2.y);
|
||||||
|
} else {
|
||||||
RefPtr<IDXGISurface> surf;
|
RefPtr<IDXGISurface> surf;
|
||||||
d2dsurf->surface->QueryInterface(&surf);
|
d2dsurf->surface->QueryInterface(&surf);
|
||||||
DXGI_SURFACE_DESC desc;
|
DXGI_SURFACE_DESC desc;
|
||||||
surf->GetDesc(&desc);
|
surf->GetDesc(&desc);
|
||||||
|
|
||||||
// Get this when the points are not transformed yet.
|
top_left.x = bottom_left.x = 0;
|
||||||
double gradient_length = _cairo_d2d_point_dist(p1, p2);
|
top_left.y = top_right.y = 0;
|
||||||
|
|
||||||
// Calculate the repeat count needed;
|
|
||||||
cairo_point_double_t top_left, top_right, bottom_left, bottom_right;
|
|
||||||
top_left.x = bottom_left.x = top_left.y = top_right.y = 0;
|
|
||||||
top_right.x = bottom_right.x = desc.Width;
|
top_right.x = bottom_right.x = desc.Width;
|
||||||
bottom_right.y = bottom_left.y = desc.Height;
|
bottom_right.y = bottom_left.y = desc.Height;
|
||||||
|
}
|
||||||
|
|
||||||
// Transform the corners of our surface to pattern space.
|
// Transform the corners of our surface to pattern space.
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
||||||
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y);
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
|
||||||
|
|
||||||
cairo_point_double_t u;
|
cairo_point_double_t u;
|
||||||
// Unit vector of the gradient direction.
|
// Unit vector of the gradient direction.
|
||||||
@ -1707,6 +1719,7 @@ _cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
|||||||
*/
|
*/
|
||||||
static RefPtr<ID2D1Brush>
|
static RefPtr<ID2D1Brush>
|
||||||
_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
||||||
|
cairo_path_fixed_t *fill_path,
|
||||||
const cairo_pattern_t *pattern,
|
const cairo_pattern_t *pattern,
|
||||||
bool unique = false)
|
bool unique = false)
|
||||||
{
|
{
|
||||||
@ -1734,7 +1747,7 @@ _cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
|||||||
} else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
|
} else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
|
||||||
cairo_linear_pattern_t *source_pattern =
|
cairo_linear_pattern_t *source_pattern =
|
||||||
(cairo_linear_pattern_t*)pattern;
|
(cairo_linear_pattern_t*)pattern;
|
||||||
return _cairo_d2d_create_linear_gradient_brush(d2dsurf, source_pattern);
|
return _cairo_d2d_create_linear_gradient_brush(d2dsurf, fill_path, source_pattern);
|
||||||
} else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
|
} else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
|
||||||
cairo_radial_pattern_t *source_pattern =
|
cairo_radial_pattern_t *source_pattern =
|
||||||
(cairo_radial_pattern_t*)pattern;
|
(cairo_radial_pattern_t*)pattern;
|
||||||
@ -3233,7 +3246,7 @@ _cairo_d2d_paint(void *surface,
|
|||||||
|
|
||||||
target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
|
||||||
source);
|
source);
|
||||||
|
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
@ -3354,7 +3367,7 @@ _cairo_d2d_mask(void *surface,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source);
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, source);
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@ -3394,7 +3407,7 @@ _cairo_d2d_mask(void *surface,
|
|||||||
return CAIRO_INT_STATUS_SUCCESS;
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, true);
|
RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, mask, true);
|
||||||
if (!opacityBrush) {
|
if (!opacityBrush) {
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@ -3480,7 +3493,7 @@ _cairo_d2d_stroke(void *surface,
|
|||||||
transformed = false;
|
transformed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
|
||||||
source);
|
source);
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
@ -3607,7 +3620,7 @@ _cairo_d2d_fill(void *surface,
|
|||||||
float x2 = _cairo_fixed_to_float(box.p2.x);
|
float x2 = _cairo_fixed_to_float(box.p2.x);
|
||||||
float y2 = _cairo_fixed_to_float(box.p2.y);
|
float y2 = _cairo_fixed_to_float(box.p2.y);
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
source);
|
path, source);
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@ -3621,7 +3634,7 @@ _cairo_d2d_fill(void *surface,
|
|||||||
RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
|
RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
source);
|
path, source);
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
return CAIRO_INT_STATUS_UNSUPPORTED;
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
}
|
}
|
||||||
@ -4143,7 +4156,7 @@ _cairo_dwrite_show_glyphs_on_d2d_surface(void *surface,
|
|||||||
fontArea.height = bounds.bottom - bounds.top;
|
fontArea.height = bounds.bottom - bounds.top;
|
||||||
}
|
}
|
||||||
|
|
||||||
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst,
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst, NULL,
|
||||||
source);
|
source);
|
||||||
|
|
||||||
if (!brush) {
|
if (!brush) {
|
||||||
|
271
gfx/cairo/d2d-repeating-gradients.patch
Normal file
271
gfx/cairo/d2d-repeating-gradients.patch
Normal file
@ -0,0 +1,271 @@
|
|||||||
|
From: Robert O'Callahan <robert@ocallahan.org>
|
||||||
|
Bug 768775. Improve the precision of the calculation of the number of stops that need to be added to handle 'repeat' and 'reflect', when we're filling a path. r=bas
|
||||||
|
|
||||||
|
diff --git a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
|
||||||
|
--- a/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
|
||||||
|
+++ b/gfx/cairo/cairo/src/cairo-d2d-surface.cpp
|
||||||
|
@@ -1411,17 +1411,17 @@ static RefPtr<ID2D1Brush>
|
||||||
|
|
||||||
|
gradient_center.x = _cairo_fixed_to_float(source_pattern->c1.x);
|
||||||
|
gradient_center.y = _cairo_fixed_to_float(source_pattern->c1.y);
|
||||||
|
|
||||||
|
// Transform surface corners into pattern coordinates.
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
||||||
|
- cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y);
|
||||||
|
+ cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
|
||||||
|
|
||||||
|
// Find the corner furthest away from the gradient center in pattern space.
|
||||||
|
double largest = MAX(_cairo_d2d_point_dist(top_left, gradient_center), _cairo_d2d_point_dist(top_right, gradient_center));
|
||||||
|
largest = MAX(largest, _cairo_d2d_point_dist(bottom_left, gradient_center));
|
||||||
|
largest = MAX(largest, _cairo_d2d_point_dist(bottom_right, gradient_center));
|
||||||
|
|
||||||
|
unsigned int minSize = (unsigned int)ceil(largest);
|
||||||
|
|
||||||
|
@@ -1531,16 +1531,17 @@ static RefPtr<ID2D1Brush>
|
||||||
|
stopCollection,
|
||||||
|
&brush);
|
||||||
|
delete [] stops;
|
||||||
|
return brush;
|
||||||
|
}
|
||||||
|
|
||||||
|
static RefPtr<ID2D1Brush>
|
||||||
|
_cairo_d2d_create_linear_gradient_brush(cairo_d2d_surface_t *d2dsurf,
|
||||||
|
+ cairo_path_fixed_t *fill_path,
|
||||||
|
cairo_linear_pattern_t *source_pattern)
|
||||||
|
{
|
||||||
|
if (source_pattern->p1.x == source_pattern->p2.x &&
|
||||||
|
source_pattern->p1.y == source_pattern->p2.y) {
|
||||||
|
// Cairo behavior in this situation is to draw a solid color the size of the last stop.
|
||||||
|
RefPtr<ID2D1SolidColorBrush> brush;
|
||||||
|
d2dsurf->rt->CreateSolidColorBrush(
|
||||||
|
_cairo_d2d_color_from_cairo_color_stop(source_pattern->base.stops[source_pattern->base.n_stops - 1].color),
|
||||||
|
@@ -1564,35 +1565,46 @@ static RefPtr<ID2D1Brush>
|
||||||
|
p1.x = _cairo_fixed_to_float(source_pattern->p1.x);
|
||||||
|
p1.y = _cairo_fixed_to_float(source_pattern->p1.y);
|
||||||
|
p2.x = _cairo_fixed_to_float(source_pattern->p2.x);
|
||||||
|
p2.y = _cairo_fixed_to_float(source_pattern->p2.y);
|
||||||
|
|
||||||
|
D2D1_GRADIENT_STOP *stops;
|
||||||
|
int num_stops = source_pattern->base.n_stops;
|
||||||
|
if (source_pattern->base.base.extend == CAIRO_EXTEND_REPEAT || source_pattern->base.base.extend == CAIRO_EXTEND_REFLECT) {
|
||||||
|
-
|
||||||
|
- RefPtr<IDXGISurface> surf;
|
||||||
|
- d2dsurf->surface->QueryInterface(&surf);
|
||||||
|
- DXGI_SURFACE_DESC desc;
|
||||||
|
- surf->GetDesc(&desc);
|
||||||
|
-
|
||||||
|
// Get this when the points are not transformed yet.
|
||||||
|
double gradient_length = _cairo_d2d_point_dist(p1, p2);
|
||||||
|
-
|
||||||
|
- // Calculate the repeat count needed;
|
||||||
|
- cairo_point_double_t top_left, top_right, bottom_left, bottom_right;
|
||||||
|
- top_left.x = bottom_left.x = top_left.y = top_right.y = 0;
|
||||||
|
- top_right.x = bottom_right.x = desc.Width;
|
||||||
|
- bottom_right.y = bottom_left.y = desc.Height;
|
||||||
|
+ cairo_point_double_t top_left, top_right, bottom_left, bottom_right;
|
||||||
|
+
|
||||||
|
+ if (fill_path) {
|
||||||
|
+ // Calculate the repeat count needed;
|
||||||
|
+ cairo_box_t fill_extents;
|
||||||
|
+ _cairo_path_fixed_extents (fill_path, &fill_extents);
|
||||||
|
+
|
||||||
|
+ top_left.x = bottom_left.x = _cairo_fixed_to_double (fill_extents.p1.x);
|
||||||
|
+ top_left.y = top_right.y = _cairo_fixed_to_double (fill_extents.p1.y);
|
||||||
|
+ top_right.x = bottom_right.x = _cairo_fixed_to_double (fill_extents.p2.x);
|
||||||
|
+ bottom_right.y = bottom_left.y = _cairo_fixed_to_double (fill_extents.p2.y);
|
||||||
|
+ } else {
|
||||||
|
+ RefPtr<IDXGISurface> surf;
|
||||||
|
+ d2dsurf->surface->QueryInterface(&surf);
|
||||||
|
+ DXGI_SURFACE_DESC desc;
|
||||||
|
+ surf->GetDesc(&desc);
|
||||||
|
+
|
||||||
|
+ top_left.x = bottom_left.x = 0;
|
||||||
|
+ top_left.y = top_right.y = 0;
|
||||||
|
+ top_right.x = bottom_right.x = desc.Width;
|
||||||
|
+ bottom_right.y = bottom_left.y = desc.Height;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
// Transform the corners of our surface to pattern space.
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_left.x, &top_left.y);
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &top_right.x, &top_right.y);
|
||||||
|
cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_left.x, &bottom_left.y);
|
||||||
|
- cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &top_left.y);
|
||||||
|
+ cairo_matrix_transform_point(&source_pattern->base.base.matrix, &bottom_right.x, &bottom_right.y);
|
||||||
|
|
||||||
|
cairo_point_double_t u;
|
||||||
|
// Unit vector of the gradient direction.
|
||||||
|
u = _cairo_d2d_subtract_point(p2, p1);
|
||||||
|
_cairo_d2d_normalize_point(&u);
|
||||||
|
|
||||||
|
// (corner - p1) . u = |corner - p1| cos(a) where a is the angle between the two vectors.
|
||||||
|
// Coincidentally |corner - p1| cos(a) is actually also the distance our gradient needs to cover since
|
||||||
|
@@ -1701,17 +1713,18 @@ static RefPtr<ID2D1Brush>
|
||||||
|
* \param d2dsurf Surface to create a brush for
|
||||||
|
* \param pattern The pattern to create a brush for
|
||||||
|
* \param unique We cache the bitmap/color brush for speed. If this
|
||||||
|
* needs a brush that is unique (i.e. when more than one is needed),
|
||||||
|
* this will make the function return a seperate brush.
|
||||||
|
* \return A brush object
|
||||||
|
*/
|
||||||
|
static RefPtr<ID2D1Brush>
|
||||||
|
-_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
||||||
|
+_cairo_d2d_create_brush_for_pattern(cairo_d2d_surface_t *d2dsurf,
|
||||||
|
+ cairo_path_fixed_t *fill_path,
|
||||||
|
const cairo_pattern_t *pattern,
|
||||||
|
bool unique = false)
|
||||||
|
{
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (pattern->type == CAIRO_PATTERN_TYPE_SOLID) {
|
||||||
|
cairo_solid_pattern_t *sourcePattern =
|
||||||
|
(cairo_solid_pattern_t*)pattern;
|
||||||
|
@@ -1729,17 +1742,17 @@ static RefPtr<ID2D1Brush>
|
||||||
|
d2dsurf->solidColorBrush->SetColor(color);
|
||||||
|
}
|
||||||
|
return d2dsurf->solidColorBrush;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else if (pattern->type == CAIRO_PATTERN_TYPE_LINEAR) {
|
||||||
|
cairo_linear_pattern_t *source_pattern =
|
||||||
|
(cairo_linear_pattern_t*)pattern;
|
||||||
|
- return _cairo_d2d_create_linear_gradient_brush(d2dsurf, source_pattern);
|
||||||
|
+ return _cairo_d2d_create_linear_gradient_brush(d2dsurf, fill_path, source_pattern);
|
||||||
|
} else if (pattern->type == CAIRO_PATTERN_TYPE_RADIAL) {
|
||||||
|
cairo_radial_pattern_t *source_pattern =
|
||||||
|
(cairo_radial_pattern_t*)pattern;
|
||||||
|
return _cairo_d2d_create_radial_gradient_brush(d2dsurf, source_pattern);
|
||||||
|
} else if (pattern->type == CAIRO_PATTERN_TYPE_SURFACE) {
|
||||||
|
cairo_matrix_t mat = pattern->matrix;
|
||||||
|
cairo_matrix_invert(&mat);
|
||||||
|
|
||||||
|
@@ -3228,17 +3241,17 @@ static cairo_int_status_t
|
||||||
|
|
||||||
|
if (unlikely(status))
|
||||||
|
return status;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
target_rt->SetAntialiasMode(D2D1_ANTIALIAS_MODE_ALIASED);
|
||||||
|
|
||||||
|
- RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
|
+ RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
|
||||||
|
source);
|
||||||
|
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
D2D1_SIZE_F size = target_rt->GetSize();
|
||||||
|
target_rt->FillRectangle(D2D1::RectF((FLOAT)0,
|
||||||
|
@@ -3349,17 +3362,17 @@ static cairo_int_status_t
|
||||||
|
source->filter,
|
||||||
|
solidAlphaValue);
|
||||||
|
if (rv != CAIRO_INT_STATUS_UNSUPPORTED) {
|
||||||
|
return rv;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, source);
|
||||||
|
+ RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, source);
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefPtr<ID2D1RenderTarget> target_rt = d2dsurf->rt;
|
||||||
|
#ifndef ALWAYS_MANUAL_COMPOSITE
|
||||||
|
if (op != CAIRO_OPERATOR_OVER) {
|
||||||
|
#endif
|
||||||
|
@@ -3389,17 +3402,17 @@ static cairo_int_status_t
|
||||||
|
brush->SetOpacity(1.0);
|
||||||
|
|
||||||
|
if (target_rt.get() != d2dsurf->rt.get()) {
|
||||||
|
return _cairo_d2d_blend_temp_surface(d2dsurf, op, target_rt, clip);
|
||||||
|
}
|
||||||
|
return CAIRO_INT_STATUS_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
- RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, mask, true);
|
||||||
|
+ RefPtr<ID2D1Brush> opacityBrush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL, mask, true);
|
||||||
|
if (!opacityBrush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!d2dsurf->maskLayer) {
|
||||||
|
d2dsurf->rt->CreateLayer(&d2dsurf->maskLayer);
|
||||||
|
}
|
||||||
|
target_rt->PushLayer(D2D1::LayerParameters(D2D1::InfiniteRect(),
|
||||||
|
@@ -3475,17 +3488,17 @@ static cairo_int_status_t
|
||||||
|
D2D1_FIGURE_BEGIN_FILLED);
|
||||||
|
|
||||||
|
bool transformed = true;
|
||||||
|
|
||||||
|
if (_cairo_matrix_is_identity(ctm)) {
|
||||||
|
transformed = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
- RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
|
+ RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf, NULL,
|
||||||
|
source);
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
D2D1::Matrix3x2F mat;
|
||||||
|
if (transformed) {
|
||||||
|
// If we are transformed we will draw the geometry multiplied by the
|
||||||
|
@@ -3602,31 +3615,31 @@ static cairo_int_status_t
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_box) {
|
||||||
|
float x1 = _cairo_fixed_to_float(box.p1.x);
|
||||||
|
float y1 = _cairo_fixed_to_float(box.p1.y);
|
||||||
|
float x2 = _cairo_fixed_to_float(box.p2.x);
|
||||||
|
float y2 = _cairo_fixed_to_float(box.p2.y);
|
||||||
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
|
- source);
|
||||||
|
+ path, source);
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
target_rt->FillRectangle(D2D1::RectF(x1,
|
||||||
|
y1,
|
||||||
|
x2,
|
||||||
|
y2),
|
||||||
|
brush);
|
||||||
|
} else {
|
||||||
|
RefPtr<ID2D1Geometry> d2dpath = _cairo_d2d_create_path_geometry_for_path(path, fill_rule, D2D1_FIGURE_BEGIN_FILLED);
|
||||||
|
|
||||||
|
RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(d2dsurf,
|
||||||
|
- source);
|
||||||
|
+ path, source);
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
target_rt->FillGeometry(d2dpath, brush);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (target_rt.get() != d2dsurf->rt.get()) {
|
||||||
|
double x1, y1, x2, y2;
|
||||||
|
@@ -4138,17 +4151,17 @@ static cairo_int_status_t
|
||||||
|
DWRITE_TEXTURE_ALIASED_1x1 : DWRITE_TEXTURE_CLEARTYPE_3x1,
|
||||||
|
&bounds);
|
||||||
|
fontArea.x = bounds.left;
|
||||||
|
fontArea.y = bounds.top;
|
||||||
|
fontArea.width = bounds.right - bounds.left;
|
||||||
|
fontArea.height = bounds.bottom - bounds.top;
|
||||||
|
}
|
||||||
|
|
||||||
|
- RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst,
|
||||||
|
+ RefPtr<ID2D1Brush> brush = _cairo_d2d_create_brush_for_pattern(dst, NULL,
|
||||||
|
source);
|
||||||
|
|
||||||
|
if (!brush) {
|
||||||
|
return CAIRO_INT_STATUS_UNSUPPORTED;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (transform) {
|
||||||
|
D2D1::Matrix3x2F mat_inverse = _cairo_d2d_matrix_from_matrix(&dwritesf->mat_inverse);
|
@ -888,10 +888,10 @@ SharedTextureHandle
|
|||||||
GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType)
|
GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType)
|
||||||
{
|
{
|
||||||
if (aType != TextureImage::ThreadShared)
|
if (aType != TextureImage::ThreadShared)
|
||||||
return nsnull;
|
return 0;
|
||||||
|
|
||||||
if (!mShareWithEGLImage)
|
if (!mShareWithEGLImage)
|
||||||
return nsnull;
|
return 0;
|
||||||
|
|
||||||
MakeCurrent();
|
MakeCurrent();
|
||||||
GLuint texture = 0;
|
GLuint texture = 0;
|
||||||
@ -903,7 +903,7 @@ GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType)
|
|||||||
if (!tex->CreateEGLImage()) {
|
if (!tex->CreateEGLImage()) {
|
||||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||||
ReleaseSharedHandle(aType, (SharedTextureHandle)tex);
|
ReleaseSharedHandle(aType, (SharedTextureHandle)tex);
|
||||||
return nsnull;
|
return 0;
|
||||||
}
|
}
|
||||||
// Raw pointer shared across threads
|
// Raw pointer shared across threads
|
||||||
return (SharedTextureHandle)tex;
|
return (SharedTextureHandle)tex;
|
||||||
@ -917,35 +917,35 @@ GLContextEGL::CreateSharedHandle(TextureImage::TextureShareType aType,
|
|||||||
// Both EGLImage and SurfaceTexture only support ThreadShared currently, but
|
// Both EGLImage and SurfaceTexture only support ThreadShared currently, but
|
||||||
// it's possible to make SurfaceTexture work across processes. We should do that.
|
// it's possible to make SurfaceTexture work across processes. We should do that.
|
||||||
if (aType != TextureImage::ThreadShared)
|
if (aType != TextureImage::ThreadShared)
|
||||||
return nsnull;
|
return 0;
|
||||||
|
|
||||||
switch (aBufferType) {
|
switch (aBufferType) {
|
||||||
#ifdef MOZ_WIDGET_ANDROID
|
#ifdef MOZ_WIDGET_ANDROID
|
||||||
case SharedTextureBufferType::SurfaceTexture:
|
case SharedTextureBufferType::SurfaceTexture:
|
||||||
if (!IsExtensionSupported(GLContext::OES_EGL_image_external)) {
|
if (!IsExtensionSupported(GLContext::OES_EGL_image_external)) {
|
||||||
NS_WARNING("Missing GL_OES_EGL_image_external");
|
NS_WARNING("Missing GL_OES_EGL_image_external");
|
||||||
return nsnull;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast<nsSurfaceTexture*>(aBuffer));
|
return (SharedTextureHandle) new SurfaceTextureWrapper(reinterpret_cast<nsSurfaceTexture*>(aBuffer));
|
||||||
#endif
|
#endif
|
||||||
case SharedTextureBufferType::TextureID: {
|
case SharedTextureBufferType::TextureID: {
|
||||||
if (!mShareWithEGLImage)
|
if (!mShareWithEGLImage)
|
||||||
return nsnull;
|
return 0;
|
||||||
|
|
||||||
GLuint texture = (GLuint)aBuffer;
|
GLuint texture = (GLuint)aBuffer;
|
||||||
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture, false);
|
EGLTextureWrapper* tex = new EGLTextureWrapper(this, texture, false);
|
||||||
if (!tex->CreateEGLImage()) {
|
if (!tex->CreateEGLImage()) {
|
||||||
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
NS_ERROR("EGLImage creation for EGLTextureWrapper failed");
|
||||||
delete tex;
|
delete tex;
|
||||||
return nsnull;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (SharedTextureHandle)tex;
|
return (SharedTextureHandle)tex;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
NS_ERROR("Unknown shared texture buffer type");
|
NS_ERROR("Unknown shared texture buffer type");
|
||||||
return nsnull;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
#include "nsPrintfCString.h"
|
#include "nsPrintfCString.h"
|
||||||
#include "mozilla/Util.h"
|
#include "mozilla/Util.h"
|
||||||
#include "LayerSorter.h"
|
#include "LayerSorter.h"
|
||||||
|
#include "AnimationCommon.h"
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
@ -220,6 +221,245 @@ LayerManager::CreateAsynchronousImageContainer()
|
|||||||
//--------------------------------------------------
|
//--------------------------------------------------
|
||||||
// Layer
|
// Layer
|
||||||
|
|
||||||
|
Layer::Layer(LayerManager* aManager, void* aImplData) :
|
||||||
|
mManager(aManager),
|
||||||
|
mParent(nsnull),
|
||||||
|
mNextSibling(nsnull),
|
||||||
|
mPrevSibling(nsnull),
|
||||||
|
mImplData(aImplData),
|
||||||
|
mMaskLayer(nsnull),
|
||||||
|
mXScale(1.0f),
|
||||||
|
mYScale(1.0f),
|
||||||
|
mOpacity(1.0),
|
||||||
|
mContentFlags(0),
|
||||||
|
mUseClipRect(false),
|
||||||
|
mUseTileSourceRect(false),
|
||||||
|
mIsFixedPosition(false),
|
||||||
|
mDebugColorIndex(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
Layer::~Layer()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::AddAnimation(const Animation& aAnimation)
|
||||||
|
{
|
||||||
|
if (!AsShadowableLayer() || !AsShadowableLayer()->HasShadow())
|
||||||
|
return;
|
||||||
|
|
||||||
|
MOZ_ASSERT(aAnimation.segments().Length() >= 1);
|
||||||
|
|
||||||
|
mAnimations.AppendElement(aAnimation);
|
||||||
|
Mutated();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::ClearAnimations()
|
||||||
|
{
|
||||||
|
mAnimations.Clear();
|
||||||
|
mAnimationData.Clear();
|
||||||
|
Mutated();
|
||||||
|
}
|
||||||
|
|
||||||
|
static nsCSSValueList*
|
||||||
|
CreateCSSValueList(const InfallibleTArray<TransformFunction>& aFunctions)
|
||||||
|
{
|
||||||
|
nsAutoPtr<nsCSSValueList> result;
|
||||||
|
nsCSSValueList** resultTail = getter_Transfers(result);
|
||||||
|
for (PRUint32 i = 0; i < aFunctions.Length(); i++) {
|
||||||
|
nsRefPtr<nsCSSValue::Array> arr;
|
||||||
|
switch (aFunctions[i].type()) {
|
||||||
|
case TransformFunction::TRotationX:
|
||||||
|
{
|
||||||
|
float theta = aFunctions[i].get_RotationX().radians();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatex, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TRotationY:
|
||||||
|
{
|
||||||
|
float theta = aFunctions[i].get_RotationY().radians();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatey, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TRotationZ:
|
||||||
|
{
|
||||||
|
float theta = aFunctions[i].get_RotationZ().radians();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotatez, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TRotation:
|
||||||
|
{
|
||||||
|
float theta = aFunctions[i].get_Rotation().radians();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(theta, eCSSUnit_Radian);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TRotation3D:
|
||||||
|
{
|
||||||
|
float x = aFunctions[i].get_Rotation3D().x();
|
||||||
|
float y = aFunctions[i].get_Rotation3D().y();
|
||||||
|
float z = aFunctions[i].get_Rotation3D().z();
|
||||||
|
float theta = aFunctions[i].get_Rotation3D().radians();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_rotate3d, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
|
||||||
|
arr->Item(2).SetFloatValue(y, eCSSUnit_Number);
|
||||||
|
arr->Item(3).SetFloatValue(z, eCSSUnit_Number);
|
||||||
|
arr->Item(4).SetFloatValue(theta, eCSSUnit_Radian);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TScale:
|
||||||
|
{
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_scale3d, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(aFunctions[i].get_Scale().x(), eCSSUnit_Number);
|
||||||
|
arr->Item(2).SetFloatValue(aFunctions[i].get_Scale().y(), eCSSUnit_Number);
|
||||||
|
arr->Item(3).SetFloatValue(aFunctions[i].get_Scale().z(), eCSSUnit_Number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TTranslation:
|
||||||
|
{
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_translate3d, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(aFunctions[i].get_Translation().x(), eCSSUnit_Pixel);
|
||||||
|
arr->Item(2).SetFloatValue(aFunctions[i].get_Translation().y(), eCSSUnit_Pixel);
|
||||||
|
arr->Item(3).SetFloatValue(aFunctions[i].get_Translation().z(), eCSSUnit_Pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TSkewX:
|
||||||
|
{
|
||||||
|
float x = aFunctions[i].get_SkewX().x();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewx, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(x, eCSSUnit_Number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TSkewY:
|
||||||
|
{
|
||||||
|
float y = aFunctions[i].get_SkewY().y();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_skewy, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(y, eCSSUnit_Number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TTransformMatrix:
|
||||||
|
{
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_matrix3d, resultTail);
|
||||||
|
const gfx3DMatrix& matrix = aFunctions[i].get_TransformMatrix().value();
|
||||||
|
arr->Item(1).SetFloatValue(matrix._11, eCSSUnit_Number);
|
||||||
|
arr->Item(2).SetFloatValue(matrix._12, eCSSUnit_Number);
|
||||||
|
arr->Item(3).SetFloatValue(matrix._13, eCSSUnit_Number);
|
||||||
|
arr->Item(4).SetFloatValue(matrix._14, eCSSUnit_Number);
|
||||||
|
arr->Item(5).SetFloatValue(matrix._21, eCSSUnit_Number);
|
||||||
|
arr->Item(6).SetFloatValue(matrix._22, eCSSUnit_Number);
|
||||||
|
arr->Item(7).SetFloatValue(matrix._23, eCSSUnit_Number);
|
||||||
|
arr->Item(8).SetFloatValue(matrix._24, eCSSUnit_Number);
|
||||||
|
arr->Item(9).SetFloatValue(matrix._31, eCSSUnit_Number);
|
||||||
|
arr->Item(10).SetFloatValue(matrix._32, eCSSUnit_Number);
|
||||||
|
arr->Item(11).SetFloatValue(matrix._33, eCSSUnit_Number);
|
||||||
|
arr->Item(12).SetFloatValue(matrix._34, eCSSUnit_Number);
|
||||||
|
arr->Item(13).SetFloatValue(matrix._41, eCSSUnit_Number);
|
||||||
|
arr->Item(14).SetFloatValue(matrix._42, eCSSUnit_Number);
|
||||||
|
arr->Item(15).SetFloatValue(matrix._43, eCSSUnit_Number);
|
||||||
|
arr->Item(16).SetFloatValue(matrix._44, eCSSUnit_Number);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case TransformFunction::TPerspective:
|
||||||
|
{
|
||||||
|
float perspective = aFunctions[i].get_Perspective().value();
|
||||||
|
arr = nsStyleAnimation::AppendTransformFunction(eCSSKeyword_perspective, resultTail);
|
||||||
|
arr->Item(1).SetFloatValue(perspective, eCSSUnit_Pixel);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NS_ASSERTION(false, "All functions should be implemented?");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result.forget();
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Layer::SetAnimations(const AnimationArray& aAnimations)
|
||||||
|
{
|
||||||
|
mAnimations = aAnimations;
|
||||||
|
mAnimationData.Clear();
|
||||||
|
for (PRUint32 i = 0; i < mAnimations.Length(); i++) {
|
||||||
|
AnimData data;
|
||||||
|
InfallibleTArray<css::ComputedTimingFunction*>* functions =
|
||||||
|
&data.mFunctions;
|
||||||
|
nsTArray<AnimationSegment> segments = mAnimations.ElementAt(i).segments();
|
||||||
|
for (PRUint32 j = 0; j < segments.Length(); j++) {
|
||||||
|
TimingFunction tf = segments.ElementAt(j).sampleFn();
|
||||||
|
css::ComputedTimingFunction* ctf = new css::ComputedTimingFunction();
|
||||||
|
switch (tf.type()) {
|
||||||
|
case TimingFunction::TCubicBezierFunction: {
|
||||||
|
CubicBezierFunction cbf = tf.get_CubicBezierFunction();
|
||||||
|
ctf->Init(nsTimingFunction(cbf.x1(), cbf.y1(), cbf.x2(), cbf.y2()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
NS_ASSERTION(tf.type() == TimingFunction::TStepFunction,
|
||||||
|
"Function must be bezier or step");
|
||||||
|
StepFunction sf = tf.get_StepFunction();
|
||||||
|
nsTimingFunction::Type type = sf.type() == 1 ? nsTimingFunction::StepStart
|
||||||
|
: nsTimingFunction::StepEnd;
|
||||||
|
ctf->Init(nsTimingFunction(type, sf.steps()));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
functions->AppendElement(ctf);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Precompute the nsStyleAnimation::Values that we need if this is a transform
|
||||||
|
// animation.
|
||||||
|
InfallibleTArray<nsStyleAnimation::Value>* startValues =
|
||||||
|
&data.mStartValues;
|
||||||
|
InfallibleTArray<nsStyleAnimation::Value>* endValues =
|
||||||
|
&data.mEndValues;
|
||||||
|
for (PRUint32 j = 0; j < mAnimations[i].segments().Length(); j++) {
|
||||||
|
const AnimationSegment& segment = mAnimations[i].segments()[j];
|
||||||
|
if (segment.endState().type() == Animatable::TArrayOfTransformFunction) {
|
||||||
|
const InfallibleTArray<TransformFunction>& startFunctions =
|
||||||
|
segment.startState().get_ArrayOfTransformFunction();
|
||||||
|
nsStyleAnimation::Value startValue;
|
||||||
|
nsCSSValueList* startList;
|
||||||
|
if (startFunctions.Length() > 0) {
|
||||||
|
startList = CreateCSSValueList(startFunctions);
|
||||||
|
} else {
|
||||||
|
startList = new nsCSSValueList();
|
||||||
|
startList->mValue.SetNoneValue();
|
||||||
|
}
|
||||||
|
startValue.SetAndAdoptCSSValueListValue(startList, nsStyleAnimation::eUnit_Transform);
|
||||||
|
startValues->AppendElement(startValue);
|
||||||
|
|
||||||
|
const InfallibleTArray<TransformFunction>& endFunctions =
|
||||||
|
segment.endState().get_ArrayOfTransformFunction();
|
||||||
|
nsStyleAnimation::Value endValue;
|
||||||
|
nsCSSValueList* endList;
|
||||||
|
if (endFunctions.Length() > 0) {
|
||||||
|
endList = CreateCSSValueList(endFunctions);
|
||||||
|
} else {
|
||||||
|
endList = new nsCSSValueList();
|
||||||
|
endList->mValue.SetNoneValue();
|
||||||
|
}
|
||||||
|
endValue.SetAndAdoptCSSValueListValue(endList, nsStyleAnimation::eUnit_Transform);
|
||||||
|
endValues->AppendElement(endValue);
|
||||||
|
} else {
|
||||||
|
NS_ASSERTION(segment.endState().type() == Animatable::TOpacity,
|
||||||
|
"Unknown Animatable type");
|
||||||
|
nsStyleAnimation::Value startValue;
|
||||||
|
startValue.SetFloatValue(segment.startState().get_Opacity().value());
|
||||||
|
startValues->AppendElement(startValue);
|
||||||
|
|
||||||
|
nsStyleAnimation::Value endValue;
|
||||||
|
endValue.SetFloatValue(segment.endState().get_Opacity().value());
|
||||||
|
endValues->AppendElement(endValue);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
mAnimationData.AppendElement(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
Mutated();
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Layer::CanUseOpaqueSurface()
|
Layer::CanUseOpaqueSurface()
|
||||||
{
|
{
|
||||||
@ -361,21 +601,42 @@ Layer::CalculateScissorRect(const nsIntRect& aCurrentScissorRect,
|
|||||||
return currentClip.Intersect(scissor);
|
return currentClip.Intersect(scissor);
|
||||||
}
|
}
|
||||||
|
|
||||||
const gfx3DMatrix&
|
const gfx3DMatrix
|
||||||
|
Layer::GetTransform()
|
||||||
|
{
|
||||||
|
gfx3DMatrix transform = mTransform;
|
||||||
|
transform.Scale(mXScale, mYScale, 1);
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gfx3DMatrix
|
||||||
Layer::GetLocalTransform()
|
Layer::GetLocalTransform()
|
||||||
|
{
|
||||||
|
gfx3DMatrix transform;
|
||||||
|
if (ShadowLayer* shadow = AsShadowLayer()) {
|
||||||
|
transform = shadow->GetShadowTransform();
|
||||||
|
} else {
|
||||||
|
transform = mTransform;
|
||||||
|
}
|
||||||
|
transform.Scale(mXScale, mYScale, 1);
|
||||||
|
return transform;
|
||||||
|
}
|
||||||
|
|
||||||
|
const float
|
||||||
|
Layer::GetLocalOpacity()
|
||||||
{
|
{
|
||||||
if (ShadowLayer* shadow = AsShadowLayer())
|
if (ShadowLayer* shadow = AsShadowLayer())
|
||||||
return shadow->GetShadowTransform();
|
return shadow->GetShadowOpacity();
|
||||||
return mTransform;
|
return mOpacity;
|
||||||
}
|
}
|
||||||
|
|
||||||
float
|
float
|
||||||
Layer::GetEffectiveOpacity()
|
Layer::GetEffectiveOpacity()
|
||||||
{
|
{
|
||||||
float opacity = GetOpacity();
|
float opacity = GetLocalOpacity();
|
||||||
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
for (ContainerLayer* c = GetParent(); c && !c->UseIntermediateSurface();
|
||||||
c = c->GetParent()) {
|
c = c->GetParent()) {
|
||||||
opacity *= c->GetOpacity();
|
opacity *= c->GetLocalOpacity();
|
||||||
}
|
}
|
||||||
return opacity;
|
return opacity;
|
||||||
}
|
}
|
||||||
@ -387,6 +648,7 @@ Layer::ComputeEffectiveTransformForMaskLayer(const gfx3DMatrix& aTransformToSurf
|
|||||||
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
mMaskLayer->mEffectiveTransform = aTransformToSurface;
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
|
|
||||||
gfxMatrix maskTranslation;
|
gfxMatrix maskTranslation;
|
||||||
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
bool maskIs2D = mMaskLayer->GetTransform().CanDraw2D(&maskTranslation);
|
||||||
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
NS_ASSERTION(maskIs2D, "How did we end up with a 3D transform here?!");
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
#include "gfxPattern.h"
|
#include "gfxPattern.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
#include "nsStyleAnimation.h"
|
||||||
#include "LayersBackend.h"
|
#include "LayersBackend.h"
|
||||||
#include "mozilla/gfx/2D.h"
|
#include "mozilla/gfx/2D.h"
|
||||||
#include "mozilla/TimeStamp.h"
|
#include "mozilla/TimeStamp.h"
|
||||||
@ -43,8 +44,14 @@ namespace gl {
|
|||||||
class GLContext;
|
class GLContext;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace css {
|
||||||
|
class ComputedTimingFunction;
|
||||||
|
}
|
||||||
|
|
||||||
namespace layers {
|
namespace layers {
|
||||||
|
|
||||||
|
class Animation;
|
||||||
|
class CommonLayerAttributes;
|
||||||
class Layer;
|
class Layer;
|
||||||
class ThebesLayer;
|
class ThebesLayer;
|
||||||
class ContainerLayer;
|
class ContainerLayer;
|
||||||
@ -530,6 +537,13 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
class ThebesLayer;
|
class ThebesLayer;
|
||||||
|
typedef InfallibleTArray<Animation> AnimationArray;
|
||||||
|
|
||||||
|
struct AnimData {
|
||||||
|
InfallibleTArray<nsStyleAnimation::Value> mStartValues;
|
||||||
|
InfallibleTArray<nsStyleAnimation::Value> mEndValues;
|
||||||
|
InfallibleTArray<mozilla::css::ComputedTimingFunction*> mFunctions;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A Layer represents anything that can be rendered onto a destination
|
* A Layer represents anything that can be rendered onto a destination
|
||||||
@ -551,7 +565,7 @@ public:
|
|||||||
TYPE_THEBES
|
TYPE_THEBES
|
||||||
};
|
};
|
||||||
|
|
||||||
virtual ~Layer() {}
|
virtual ~Layer();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the LayerManager this Layer belongs to. Note that the layer
|
* Returns the LayerManager this Layer belongs to. Note that the layer
|
||||||
@ -702,12 +716,19 @@ public:
|
|||||||
* XXX Currently only transformations corresponding to 2D affine transforms
|
* XXX Currently only transformations corresponding to 2D affine transforms
|
||||||
* are supported.
|
* are supported.
|
||||||
*/
|
*/
|
||||||
void SetTransform(const gfx3DMatrix& aMatrix)
|
void SetBaseTransform(const gfx3DMatrix& aMatrix)
|
||||||
{
|
{
|
||||||
mTransform = aMatrix;
|
mTransform = aMatrix;
|
||||||
Mutated();
|
Mutated();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SetScale(float aXScale, float aYScale)
|
||||||
|
{
|
||||||
|
mXScale = aXScale;
|
||||||
|
mYScale = aYScale;
|
||||||
|
Mutated();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CONSTRUCTION PHASE ONLY
|
* CONSTRUCTION PHASE ONLY
|
||||||
* A layer is "fixed position" when it draws content from a content
|
* A layer is "fixed position" when it draws content from a content
|
||||||
@ -716,6 +737,14 @@ public:
|
|||||||
*/
|
*/
|
||||||
void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; }
|
void SetIsFixedPosition(bool aFixedPosition) { mIsFixedPosition = aFixedPosition; }
|
||||||
|
|
||||||
|
// Call AddAnimation to add an animation to this layer from layout code.
|
||||||
|
void AddAnimation(const Animation& aAnimation);
|
||||||
|
// ClearAnimations clears animations on this layer.
|
||||||
|
void ClearAnimations();
|
||||||
|
// This is only called when the layer tree is updated. Do not call this from
|
||||||
|
// layout code. To add an animation to this layer, use AddAnimation.
|
||||||
|
void SetAnimations(const AnimationArray& aAnimations);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* CONSTRUCTION PHASE ONLY
|
* CONSTRUCTION PHASE ONLY
|
||||||
* If a layer is "fixed position", this determines which point on the layer
|
* If a layer is "fixed position", this determines which point on the layer
|
||||||
@ -735,11 +764,15 @@ public:
|
|||||||
Layer* GetPrevSibling() { return mPrevSibling; }
|
Layer* GetPrevSibling() { return mPrevSibling; }
|
||||||
virtual Layer* GetFirstChild() { return nsnull; }
|
virtual Layer* GetFirstChild() { return nsnull; }
|
||||||
virtual Layer* GetLastChild() { return nsnull; }
|
virtual Layer* GetLastChild() { return nsnull; }
|
||||||
const gfx3DMatrix& GetTransform() { return mTransform; }
|
const gfx3DMatrix GetTransform();
|
||||||
|
const gfx3DMatrix& GetBaseTransform() { return mTransform; }
|
||||||
|
float GetXScale() { return mXScale; }
|
||||||
|
float GetYScale() { return mYScale; }
|
||||||
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
bool GetIsFixedPosition() { return mIsFixedPosition; }
|
||||||
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
gfxPoint GetFixedPositionAnchor() { return mAnchor; }
|
||||||
Layer* GetMaskLayer() { return mMaskLayer; }
|
Layer* GetMaskLayer() { return mMaskLayer; }
|
||||||
|
AnimationArray& GetAnimations() { return mAnimations; }
|
||||||
|
InfallibleTArray<AnimData>& GetAnimationData() { return mAnimationData; }
|
||||||
/**
|
/**
|
||||||
* DRAWING PHASE ONLY
|
* DRAWING PHASE ONLY
|
||||||
*
|
*
|
||||||
@ -940,20 +973,7 @@ public:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Layer(LayerManager* aManager, void* aImplData) :
|
Layer(LayerManager* aManager, void* aImplData);
|
||||||
mManager(aManager),
|
|
||||||
mParent(nsnull),
|
|
||||||
mNextSibling(nsnull),
|
|
||||||
mPrevSibling(nsnull),
|
|
||||||
mImplData(aImplData),
|
|
||||||
mMaskLayer(nsnull),
|
|
||||||
mOpacity(1.0),
|
|
||||||
mContentFlags(0),
|
|
||||||
mUseClipRect(false),
|
|
||||||
mUseTileSourceRect(false),
|
|
||||||
mIsFixedPosition(false),
|
|
||||||
mDebugColorIndex(0)
|
|
||||||
{}
|
|
||||||
|
|
||||||
void Mutated() { mManager->Mutated(this); }
|
void Mutated() { mManager->Mutated(this); }
|
||||||
|
|
||||||
@ -968,7 +988,13 @@ protected:
|
|||||||
* Returns the local transform for this layer: either mTransform or,
|
* Returns the local transform for this layer: either mTransform or,
|
||||||
* for shadow layers, GetShadowTransform()
|
* for shadow layers, GetShadowTransform()
|
||||||
*/
|
*/
|
||||||
const gfx3DMatrix& GetLocalTransform();
|
const gfx3DMatrix GetLocalTransform();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the local opacity for this layer: either mOpacity or,
|
||||||
|
* for shadow layers, GetShadowOpacity()
|
||||||
|
*/
|
||||||
|
const float GetLocalOpacity();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
* Computes a tweaked version of aTransform that snaps a point or a rectangle
|
||||||
@ -994,7 +1020,11 @@ protected:
|
|||||||
gfx::UserData mUserData;
|
gfx::UserData mUserData;
|
||||||
nsIntRegion mVisibleRegion;
|
nsIntRegion mVisibleRegion;
|
||||||
gfx3DMatrix mTransform;
|
gfx3DMatrix mTransform;
|
||||||
|
float mXScale;
|
||||||
|
float mYScale;
|
||||||
gfx3DMatrix mEffectiveTransform;
|
gfx3DMatrix mEffectiveTransform;
|
||||||
|
AnimationArray mAnimations;
|
||||||
|
InfallibleTArray<AnimData> mAnimationData;
|
||||||
float mOpacity;
|
float mOpacity;
|
||||||
nsIntRect mClipRect;
|
nsIntRect mClipRect;
|
||||||
nsIntRect mTileSourceRect;
|
nsIntRect mTileSourceRect;
|
||||||
|
@ -31,16 +31,18 @@ EXPORTS = \
|
|||||||
BasicLayers.h \
|
BasicLayers.h \
|
||||||
BasicTiledThebesLayer.h \
|
BasicTiledThebesLayer.h \
|
||||||
BasicImplData.h \
|
BasicImplData.h \
|
||||||
|
CompositorParent.h \
|
||||||
ImageLayers.h \
|
ImageLayers.h \
|
||||||
Layers.h \
|
Layers.h \
|
||||||
LayersBackend.h \
|
LayersBackend.h \
|
||||||
LayerManagerOGLShaders.h \
|
LayerManagerOGLShaders.h \
|
||||||
LayerManagerOGL.h \
|
LayerManagerOGL.h \
|
||||||
LayerManagerOGLProgram.h \
|
LayerManagerOGLProgram.h \
|
||||||
ReadbackLayer.h \
|
|
||||||
LayerSorter.h \
|
LayerSorter.h \
|
||||||
TexturePoolOGL.h \
|
ReadbackLayer.h \
|
||||||
|
ShadowLayersManager.h \
|
||||||
SharedTextureImage.h \
|
SharedTextureImage.h \
|
||||||
|
TexturePoolOGL.h \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
||||||
CPPSRCS = \
|
CPPSRCS = \
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "BasicThebesLayer.h"
|
#include "BasicThebesLayer.h"
|
||||||
#include "BasicContainerLayer.h"
|
#include "BasicContainerLayer.h"
|
||||||
#include "mozilla/Preferences.h"
|
#include "mozilla/Preferences.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
|
||||||
using namespace mozilla::gfx;
|
using namespace mozilla::gfx;
|
||||||
|
|
||||||
@ -132,7 +133,8 @@ BasicLayerManager::~BasicLayerManager()
|
|||||||
|
|
||||||
void
|
void
|
||||||
BasicLayerManager::SetDefaultTarget(gfxContext* aContext,
|
BasicLayerManager::SetDefaultTarget(gfxContext* aContext,
|
||||||
BufferMode aDoubleBuffering)
|
BufferMode aDoubleBuffering,
|
||||||
|
ScreenRotation aRotation)
|
||||||
{
|
{
|
||||||
NS_ASSERTION(!InTransaction(),
|
NS_ASSERTION(!InTransaction(),
|
||||||
"Must set default target outside transaction");
|
"Must set default target outside transaction");
|
||||||
@ -922,7 +924,7 @@ BasicLayerManager::CreateReadbackLayer()
|
|||||||
}
|
}
|
||||||
|
|
||||||
BasicShadowLayerManager::BasicShadowLayerManager(nsIWidget* aWidget) :
|
BasicShadowLayerManager::BasicShadowLayerManager(nsIWidget* aWidget) :
|
||||||
BasicLayerManager(aWidget)
|
BasicLayerManager(aWidget), mTargetRotation(ROTATION_0)
|
||||||
{
|
{
|
||||||
MOZ_COUNT_CTOR(BasicShadowLayerManager);
|
MOZ_COUNT_CTOR(BasicShadowLayerManager);
|
||||||
}
|
}
|
||||||
@ -942,6 +944,18 @@ BasicShadowLayerManager::GetMaxTextureSize() const
|
|||||||
return PR_INT32_MAX;
|
return PR_INT32_MAX;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
BasicShadowLayerManager::SetDefaultTarget(gfxContext* aContext,
|
||||||
|
BufferMode aDoubleBuffering,
|
||||||
|
ScreenRotation aRotation)
|
||||||
|
{
|
||||||
|
BasicLayerManager::SetDefaultTarget(aContext, aDoubleBuffering, aRotation);
|
||||||
|
mTargetRotation = aRotation;
|
||||||
|
if (mWidget) {
|
||||||
|
mTargetBounds = mWidget->GetNaturalBounds();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
BasicShadowLayerManager::SetRoot(Layer* aLayer)
|
BasicShadowLayerManager::SetRoot(Layer* aLayer)
|
||||||
{
|
{
|
||||||
@ -981,7 +995,7 @@ BasicShadowLayerManager::BeginTransactionWithTarget(gfxContext* aTarget)
|
|||||||
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
|
// don't signal a new transaction to ShadowLayerForwarder. Carry on adding
|
||||||
// to the previous transaction.
|
// to the previous transaction.
|
||||||
if (HasShadowManager()) {
|
if (HasShadowManager()) {
|
||||||
ShadowLayerForwarder::BeginTransaction();
|
ShadowLayerForwarder::BeginTransaction(mTargetBounds, mTargetRotation);
|
||||||
|
|
||||||
// If we have a non-default target, we need to let our shadow manager draw
|
// If we have a non-default target, we need to let our shadow manager draw
|
||||||
// to it. This will happen at the end of the transaction.
|
// to it. This will happen at the end of the transaction.
|
||||||
|
@ -10,11 +10,11 @@
|
|||||||
|
|
||||||
#include "gfxContext.h"
|
#include "gfxContext.h"
|
||||||
#include "gfxCachedTempSurface.h"
|
#include "gfxCachedTempSurface.h"
|
||||||
|
#include "mozilla/layers/ShadowLayers.h"
|
||||||
|
#include "mozilla/WidgetUtils.h"
|
||||||
#include "nsAutoRef.h"
|
#include "nsAutoRef.h"
|
||||||
#include "nsThreadUtils.h"
|
#include "nsThreadUtils.h"
|
||||||
|
|
||||||
#include "mozilla/layers/ShadowLayers.h"
|
|
||||||
|
|
||||||
class nsIWidget;
|
class nsIWidget;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
@ -80,7 +80,8 @@ public:
|
|||||||
BUFFER_NONE,
|
BUFFER_NONE,
|
||||||
BUFFER_BUFFERED
|
BUFFER_BUFFERED
|
||||||
};
|
};
|
||||||
void SetDefaultTarget(gfxContext* aContext, BufferMode aDoubleBuffering);
|
virtual void SetDefaultTarget(gfxContext* aContext, BufferMode aDoubleBuffering,
|
||||||
|
ScreenRotation aRotation);
|
||||||
gfxContext* GetDefaultTarget() { return mDefaultTarget; }
|
gfxContext* GetDefaultTarget() { return mDefaultTarget; }
|
||||||
|
|
||||||
nsIWidget* GetRetainerWidget() { return mWidget; }
|
nsIWidget* GetRetainerWidget() { return mWidget; }
|
||||||
@ -221,6 +222,8 @@ public:
|
|||||||
|
|
||||||
virtual PRInt32 GetMaxTextureSize() const;
|
virtual PRInt32 GetMaxTextureSize() const;
|
||||||
|
|
||||||
|
virtual void SetDefaultTarget(gfxContext* aContext, BufferMode aDoubleBuffering,
|
||||||
|
ScreenRotation aRotation) MOZ_OVERRIDE;
|
||||||
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
virtual void BeginTransactionWithTarget(gfxContext* aTarget);
|
||||||
virtual bool EndEmptyTransaction();
|
virtual bool EndEmptyTransaction();
|
||||||
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
virtual void EndTransaction(DrawThebesLayerCallback aCallback,
|
||||||
@ -261,11 +264,20 @@ private:
|
|||||||
*/
|
*/
|
||||||
void ForwardTransaction();
|
void ForwardTransaction();
|
||||||
|
|
||||||
|
// The bounds of |mTarget| in device pixels.
|
||||||
|
nsIntRect mTargetBounds;
|
||||||
|
|
||||||
|
LayerRefArray mKeepAlive;
|
||||||
|
|
||||||
|
// Sometimes we draw to targets that don't natively support
|
||||||
|
// landscape/portrait orientation. When we need to implement that
|
||||||
|
// ourselves, |mTargetRotation| describes the induced transform we
|
||||||
|
// need to apply when compositing content to our target.
|
||||||
|
ScreenRotation mTargetRotation;
|
||||||
|
|
||||||
// Used to repeat the transaction right away (to avoid rebuilding
|
// Used to repeat the transaction right away (to avoid rebuilding
|
||||||
// a display list) to support progressive drawing.
|
// a display list) to support progressive drawing.
|
||||||
bool mRepeatTransaction;
|
bool mRepeatTransaction;
|
||||||
|
|
||||||
LayerRefArray mKeepAlive;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class BasicShadowableThebesLayer;
|
class BasicShadowableThebesLayer;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#include "ReadbackLayerD3D10.h"
|
#include "ReadbackLayerD3D10.h"
|
||||||
#include "ImageLayerD3D10.h"
|
#include "ImageLayerD3D10.h"
|
||||||
#include "mozilla/layers/PLayerChild.h"
|
#include "mozilla/layers/PLayerChild.h"
|
||||||
|
#include "mozilla/WidgetUtils.h"
|
||||||
|
|
||||||
#include "../d3d9/Nv3DVUtils.h"
|
#include "../d3d9/Nv3DVUtils.h"
|
||||||
|
|
||||||
@ -448,7 +449,6 @@ LayerManagerD3D10::CreateOptimalSurface(const gfxIntSize &aSize,
|
|||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
||||||
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
|
|
||||||
|
|
||||||
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(texture));
|
HRESULT hr = device()->CreateTexture2D(&desc, NULL, getter_AddRefs(texture));
|
||||||
|
|
||||||
@ -729,7 +729,8 @@ LayerManagerD3D10::Render()
|
|||||||
if (mTarget) {
|
if (mTarget) {
|
||||||
PaintToTarget();
|
PaintToTarget();
|
||||||
} else if (mBackBuffer) {
|
} else if (mBackBuffer) {
|
||||||
ShadowLayerForwarder::BeginTransaction();
|
ShadowLayerForwarder::BeginTransaction(mWidget->GetNaturalBounds(),
|
||||||
|
ROTATION_0);
|
||||||
|
|
||||||
nsIntRect contentRect = nsIntRect(0, 0, rect.width, rect.height);
|
nsIntRect contentRect = nsIntRect(0, 0, rect.width, rect.height);
|
||||||
if (!mRootForShadowTree) {
|
if (!mRootForShadowTree) {
|
||||||
|
@ -470,7 +470,6 @@ ThebesLayerD3D10::CreateNewTextures(const gfxIntSize &aSize, SurfaceMode aMode)
|
|||||||
|
|
||||||
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
CD3D10_TEXTURE2D_DESC desc(DXGI_FORMAT_B8G8R8A8_UNORM, aSize.width, aSize.height, 1, 1);
|
||||||
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
desc.BindFlags = D3D10_BIND_RENDER_TARGET | D3D10_BIND_SHADER_RESOURCE;
|
||||||
desc.MiscFlags = D3D10_RESOURCE_MISC_GDI_COMPATIBLE;
|
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
|
|
||||||
if (!mTexture) {
|
if (!mTexture) {
|
||||||
|
@ -21,6 +21,15 @@
|
|||||||
#include "nsIWidget.h"
|
#include "nsIWidget.h"
|
||||||
#include "RenderTrace.h"
|
#include "RenderTrace.h"
|
||||||
#include "ShadowLayersParent.h"
|
#include "ShadowLayersParent.h"
|
||||||
|
#include "BasicLayers.h"
|
||||||
|
#include "LayerManagerOGL.h"
|
||||||
|
#include "nsIWidget.h"
|
||||||
|
#include "nsGkAtoms.h"
|
||||||
|
#include "RenderTrace.h"
|
||||||
|
#include "nsStyleAnimation.h"
|
||||||
|
#include "nsDisplayList.h"
|
||||||
|
#include "AnimationCommon.h"
|
||||||
|
#include "nsAnimationManager.h"
|
||||||
|
|
||||||
using namespace base;
|
using namespace base;
|
||||||
using namespace mozilla::ipc;
|
using namespace mozilla::ipc;
|
||||||
@ -412,16 +421,23 @@ CompositorParent::Composite()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Layer* aLayer = mLayerManager->GetRoot();
|
Layer* layer = mLayerManager->GetRoot();
|
||||||
AutoResolveRefLayers resolve(aLayer);
|
AutoResolveRefLayers resolve(layer);
|
||||||
|
|
||||||
bool requestNextFrame = TransformShadowTree(mLastCompose);
|
bool requestNextFrame = TransformShadowTree(mLastCompose);
|
||||||
if (requestNextFrame) {
|
if (requestNextFrame) {
|
||||||
ScheduleComposition();
|
ScheduleComposition();
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderTraceLayers(aLayer, "0000");
|
RenderTraceLayers(layer, "0000");
|
||||||
|
|
||||||
|
if (LAYERS_OPENGL == mLayerManager->GetBackendType() &&
|
||||||
|
!mTargetConfig.naturalBounds().IsEmpty()) {
|
||||||
|
LayerManagerOGL* lm = static_cast<LayerManagerOGL*>(mLayerManager.get());
|
||||||
|
lm->SetWorldTransform(
|
||||||
|
ComputeGLTransformForRotation(mTargetConfig.naturalBounds(),
|
||||||
|
mTargetConfig.rotation()));
|
||||||
|
}
|
||||||
mLayerManager->EndEmptyTransaction();
|
mLayerManager->EndEmptyTransaction();
|
||||||
|
|
||||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||||
@ -510,9 +526,10 @@ SetShadowProperties(Layer* aLayer)
|
|||||||
{
|
{
|
||||||
// FIXME: Bug 717688 -- Do these updates in ShadowLayersParent::RecvUpdate.
|
// FIXME: Bug 717688 -- Do these updates in ShadowLayersParent::RecvUpdate.
|
||||||
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||||
shadow->SetShadowTransform(aLayer->GetTransform());
|
shadow->SetShadowTransform(aLayer->GetBaseTransform());
|
||||||
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
shadow->SetShadowVisibleRegion(aLayer->GetVisibleRegion());
|
||||||
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
shadow->SetShadowClipRect(aLayer->GetClipRect());
|
||||||
|
shadow->SetShadowOpacity(aLayer->GetOpacity());
|
||||||
|
|
||||||
for (Layer* child = aLayer->GetFirstChild();
|
for (Layer* child = aLayer->GetFirstChild();
|
||||||
child; child = child->GetNextSibling()) {
|
child; child = child->GetNextSibling()) {
|
||||||
@ -520,6 +537,114 @@ SetShadowProperties(Layer* aLayer)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// SampleValue should eventually take the CSS property as an argument. This
|
||||||
|
// will be needed if we ever animate two values with the same type but different
|
||||||
|
// interpolation rules.
|
||||||
|
static void
|
||||||
|
SampleValue(float aPortion, Animation& aAnimation, nsStyleAnimation::Value& aStart,
|
||||||
|
nsStyleAnimation::Value& aEnd, Animatable* aValue)
|
||||||
|
{
|
||||||
|
nsStyleAnimation::Value interpolatedValue;
|
||||||
|
NS_ASSERTION(aStart.GetUnit() == aEnd.GetUnit() ||
|
||||||
|
aStart.GetUnit() == nsStyleAnimation::eUnit_None ||
|
||||||
|
aEnd.GetUnit() == nsStyleAnimation::eUnit_None, "Must have same unit");
|
||||||
|
if (aStart.GetUnit() == nsStyleAnimation::eUnit_Transform ||
|
||||||
|
aEnd.GetUnit() == nsStyleAnimation::eUnit_Transform) {
|
||||||
|
nsStyleAnimation::Interpolate(eCSSProperty_transform, aStart, aEnd,
|
||||||
|
aPortion, interpolatedValue);
|
||||||
|
nsCSSValueList* interpolatedList = interpolatedValue.GetCSSValueListValue();
|
||||||
|
|
||||||
|
TransformData& data = aAnimation.data().get_TransformData();
|
||||||
|
gfx3DMatrix transform =
|
||||||
|
nsDisplayTransform::GetResultingTransformMatrix(nsnull, data.origin(), nsDeviceContext::AppUnitsPerCSSPixel(),
|
||||||
|
&data.bounds(), interpolatedList, &data.mozOrigin(),
|
||||||
|
&data.perspectiveOrigin(), &data.perspective());
|
||||||
|
|
||||||
|
InfallibleTArray<TransformFunction>* functions = new InfallibleTArray<TransformFunction>();
|
||||||
|
functions->AppendElement(TransformMatrix(transform));
|
||||||
|
*aValue = *functions;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ASSERTION(aStart.GetUnit() == nsStyleAnimation::eUnit_Float, "Should be opacity");
|
||||||
|
nsStyleAnimation::Interpolate(eCSSProperty_opacity, aStart, aEnd,
|
||||||
|
aPortion, interpolatedValue);
|
||||||
|
*aValue = interpolatedValue.GetFloatValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
SampleAnimations(Layer* aLayer, TimeStamp aPoint)
|
||||||
|
{
|
||||||
|
AnimationArray& animations = aLayer->GetAnimations();
|
||||||
|
InfallibleTArray<AnimData>& animationData = aLayer->GetAnimationData();
|
||||||
|
|
||||||
|
bool activeAnimations = false;
|
||||||
|
|
||||||
|
for (PRUint32 i = animations.Length(); i-- !=0; ) {
|
||||||
|
Animation& animation = animations[i];
|
||||||
|
AnimData& animData = animationData[i];
|
||||||
|
|
||||||
|
double numIterations = animation.numIterations() != -1 ?
|
||||||
|
animation.numIterations() : NS_IEEEPositiveInfinity();
|
||||||
|
double positionInIteration =
|
||||||
|
ElementAnimations::GetPositionInIteration(animation.startTime(),
|
||||||
|
aPoint,
|
||||||
|
animation.duration(),
|
||||||
|
numIterations,
|
||||||
|
animation.direction());
|
||||||
|
|
||||||
|
if (positionInIteration == -1) {
|
||||||
|
animations.RemoveElementAt(i);
|
||||||
|
animationData.RemoveElementAt(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
NS_ABORT_IF_FALSE(0.0 <= positionInIteration &&
|
||||||
|
positionInIteration <= 1.0,
|
||||||
|
"position should be in [0-1]");
|
||||||
|
|
||||||
|
int segmentIndex = 0;
|
||||||
|
AnimationSegment* segment = animation.segments().Elements();
|
||||||
|
while (segment->endPortion() < positionInIteration) {
|
||||||
|
++segment;
|
||||||
|
++segmentIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
double positionInSegment = (positionInIteration - segment->startPortion()) /
|
||||||
|
(segment->endPortion() - segment->startPortion());
|
||||||
|
|
||||||
|
double portion = animData.mFunctions[segmentIndex]->GetValue(positionInSegment);
|
||||||
|
|
||||||
|
activeAnimations = true;
|
||||||
|
|
||||||
|
// interpolate the property
|
||||||
|
Animatable interpolatedValue;
|
||||||
|
SampleValue(portion, animation, animData.mStartValues[segmentIndex],
|
||||||
|
animData.mEndValues[segmentIndex], &interpolatedValue);
|
||||||
|
ShadowLayer* shadow = aLayer->AsShadowLayer();
|
||||||
|
switch (interpolatedValue.type()) {
|
||||||
|
case Animatable::TOpacity:
|
||||||
|
shadow->SetShadowOpacity(interpolatedValue.get_Opacity().value());
|
||||||
|
break;
|
||||||
|
case Animatable::TArrayOfTransformFunction: {
|
||||||
|
gfx3DMatrix matrix = interpolatedValue.get_ArrayOfTransformFunction()[0].get_TransformMatrix().value();
|
||||||
|
shadow->SetShadowTransform(matrix);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
NS_WARNING("Unhandled animated property");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (Layer* child = aLayer->GetFirstChild(); child;
|
||||||
|
child = child->GetNextSibling()) {
|
||||||
|
activeAnimations |= SampleAnimations(child, aPoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
return activeAnimations;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
CompositorParent::ApplyAsyncContentTransformToTree(TimeStamp aCurrentFrame,
|
||||||
Layer *aLayer,
|
Layer *aLayer,
|
||||||
@ -565,9 +690,13 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||||||
ContainerLayer* container = layer->AsContainerLayer();
|
ContainerLayer* container = layer->AsContainerLayer();
|
||||||
Layer* root = mLayerManager->GetRoot();
|
Layer* root = mLayerManager->GetRoot();
|
||||||
|
|
||||||
|
// NB: we must sample animations *before* sampling pan/zoom
|
||||||
|
// transforms.
|
||||||
|
wantNextFrame |= SampleAnimations(layer, mLastCompose);
|
||||||
|
|
||||||
const FrameMetrics& metrics = container->GetFrameMetrics();
|
const FrameMetrics& metrics = container->GetFrameMetrics();
|
||||||
const gfx3DMatrix& rootTransform = root->GetTransform();
|
const gfx3DMatrix& rootTransform = root->GetTransform();
|
||||||
const gfx3DMatrix& currentTransform = layer->GetTransform();
|
const gfx3DMatrix& currentTransform = layer->GetBaseTransform();
|
||||||
|
|
||||||
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
// FIXME/bug 775437: unify this interface with the ~native-fennec
|
||||||
// derived code
|
// derived code
|
||||||
@ -660,7 +789,6 @@ CompositorParent::TransformShadowTree(TimeStamp aCurrentFrame)
|
|||||||
shadow->SetShadowTransform(treeTransform * currentTransform);
|
shadow->SetShadowTransform(treeTransform * currentTransform);
|
||||||
TransformFixedLayers(layer, offset, scaleDiff);
|
TransformFixedLayers(layer, offset, scaleDiff);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wantNextFrame;
|
return wantNextFrame;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -694,8 +822,10 @@ CompositorParent::SyncViewportInfo(const nsIntRect& aDisplayPort,
|
|||||||
|
|
||||||
void
|
void
|
||||||
CompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
CompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
||||||
|
const TargetConfig& aTargetConfig,
|
||||||
bool isFirstPaint)
|
bool isFirstPaint)
|
||||||
{
|
{
|
||||||
|
mTargetConfig = aTargetConfig;
|
||||||
mIsFirstPaint = mIsFirstPaint || isFirstPaint;
|
mIsFirstPaint = mIsFirstPaint || isFirstPaint;
|
||||||
mLayersUpdated = true;
|
mLayersUpdated = true;
|
||||||
Layer* root = aLayerTree->GetRoot();
|
Layer* root = aLayerTree->GetRoot();
|
||||||
@ -898,6 +1028,7 @@ public:
|
|||||||
virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
|
virtual bool DeallocPLayers(PLayersParent* aLayers) MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual void ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
virtual void ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
||||||
|
const TargetConfig& aTargetConfig,
|
||||||
bool isFirstPaint) MOZ_OVERRIDE;
|
bool isFirstPaint) MOZ_OVERRIDE;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -997,7 +1128,9 @@ CrossProcessCompositorParent::DeallocPLayers(PLayersParent* aLayers)
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
CrossProcessCompositorParent::ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
CrossProcessCompositorParent::ShadowLayersUpdated(
|
||||||
|
ShadowLayersParent* aLayerTree,
|
||||||
|
const TargetConfig& aTargetConfig,
|
||||||
bool isFirstPaint)
|
bool isFirstPaint)
|
||||||
{
|
{
|
||||||
uint64_t id = aLayerTree->GetId();
|
uint64_t id = aLayerTree->GetId();
|
||||||
|
@ -70,6 +70,7 @@ public:
|
|||||||
virtual bool RecvResume() MOZ_OVERRIDE;
|
virtual bool RecvResume() MOZ_OVERRIDE;
|
||||||
|
|
||||||
virtual void ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
virtual void ShadowLayersUpdated(ShadowLayersParent* aLayerTree,
|
||||||
|
const TargetConfig& aTargetConfig,
|
||||||
bool isFirstPaint) MOZ_OVERRIDE;
|
bool isFirstPaint) MOZ_OVERRIDE;
|
||||||
void Destroy();
|
void Destroy();
|
||||||
|
|
||||||
@ -227,6 +228,7 @@ private:
|
|||||||
|
|
||||||
nsRefPtr<LayerManager> mLayerManager;
|
nsRefPtr<LayerManager> mLayerManager;
|
||||||
nsIWidget* mWidget;
|
nsIWidget* mWidget;
|
||||||
|
TargetConfig mTargetConfig;
|
||||||
CancelableTask *mCurrentCompositeTask;
|
CancelableTask *mCurrentCompositeTask;
|
||||||
TimeStamp mLastCompose;
|
TimeStamp mLastCompose;
|
||||||
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
#ifdef COMPOSITOR_PERFORMANCE_WARNING
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user