--HG--
rename : content/base/src/nsGenericElement.h => content/base/public/FragmentOrElement.h
rename : content/base/src/nsGenericElement.cpp => content/base/src/FragmentOrElement.cpp
rename : gfx/thebes/nsCoreAnimationSupport.mm => gfx/2d/QuartzSupport.mm
This commit is contained in:
David Anderson 2012-08-01 11:30:00 -07:00
commit bd3a52c3e2
366 changed files with 9374 additions and 4782 deletions

View File

@ -85,7 +85,8 @@ DocAccessible::
mPresShell(aPresShell)
{
mFlags |= eDocAccessible;
mPresShell->SetAccDocument(this);
if (mPresShell)
mPresShell->SetAccDocument(this);
mDependentIDsHash.Init();
// XXX aaronl should we use an algorithm for the initial cache size?

View File

@ -6,6 +6,8 @@ MOZ_APP_BASENAME=B2G
MOZ_APP_VENDOR=Mozilla
MOZ_APP_VERSION=17.0a1
MOZ_UA_OS_AGNOSTIC=1
MOZ_APP_UA_NAME=Firefox
MOZ_BRANDING_DIRECTORY=b2g/branding/unofficial

View File

@ -2494,26 +2494,42 @@ function BrowserOnAboutPageLoad(document) {
/**
* Handle command events bubbling up from error page content
*/
function BrowserOnClick(event) {
if (!event.isTrusted || // Don't trust synthetic events
event.button == 2 || event.target.localName != "button")
let BrowserOnClick = {
handleEvent: function BrowserOnClick_handleEvent(aEvent) {
if (!aEvent.isTrusted || // Don't trust synthetic events
aEvent.button == 2 || aEvent.target.localName != "button") {
return;
}
var ot = event.originalTarget;
var ownerDoc = ot.ownerDocument;
let originalTarget = aEvent.originalTarget;
let ownerDoc = originalTarget.ownerDocument;
// If the event came from an ssl error page, it is probably either the "Add
// Exception…" or "Get me out of here!" button
if (/^about:certerror/.test(ownerDoc.documentURI)) {
if (ot == ownerDoc.getElementById('exceptionDialogButton')) {
var params = { exceptionAdded : false, handlePrivateBrowsing : true };
this.onAboutCertError(originalTarget, ownerDoc);
}
else if (/^about:blocked/.test(ownerDoc.documentURI)) {
this.onAboutBlocked(originalTarget, ownerDoc);
}
else if (/^about:home$/i.test(ownerDoc.documentURI)) {
this.onAboutHome(originalTarget, ownerDoc);
}
},
onAboutCertError: function BrowserOnClick_onAboutCertError(aTargetElm, aOwnerDoc) {
let elmId = aTargetElm.getAttribute("id");
switch (elmId) {
case "exceptionDialogButton":
let params = { exceptionAdded : false, handlePrivateBrowsing : true };
try {
switch (gPrefService.getIntPref("browser.ssl_override_behavior")) {
switch (Services.prefs.getIntPref("browser.ssl_override_behavior")) {
case 2 : // Pre-fetch & pre-populate
params.prefetchCert = true;
case 1 : // Pre-populate
params.location = ownerDoc.location.href;
params.location = aOwnerDoc.location.href;
}
} catch (e) {
Components.utils.reportError("Couldn't get ssl_override pref: " + e);
@ -2523,23 +2539,31 @@ function BrowserOnClick(event) {
'','chrome,centerscreen,modal', params);
// If the user added the exception cert, attempt to reload the page
if (params.exceptionAdded)
ownerDoc.location.reload();
}
else if (ot == ownerDoc.getElementById('getMeOutOfHereButton')) {
getMeOutOfHere();
}
}
else if (/^about:blocked/.test(ownerDoc.documentURI)) {
// The event came from a button on a malware/phishing block page
// First check whether it's malware or phishing, so that we can
// use the right strings/links
var isMalware = /e=malwareBlocked/.test(ownerDoc.documentURI);
if (params.exceptionAdded) {
aOwnerDoc.location.reload();
}
break;
if (ot == ownerDoc.getElementById('getMeOutButton')) {
case "getMeOutOfHereButton":
getMeOutOfHere();
}
else if (ot == ownerDoc.getElementById('reportButton')) {
break;
}
},
onAboutBlocked: function BrowserOnClick_onAboutBlocked(aTargetElm, aOwnerDoc) {
let elmId = aTargetElm.getAttribute("id");
// The event came from a button on a malware/phishing block page
// First check whether it's malware or phishing, so that we can
// use the right strings/links
let isMalware = /e=malwareBlocked/.test(aOwnerDoc.documentURI);
switch (elmId) {
case "getMeOutButton":
getMeOutOfHere();
break;
case "reportButton":
// This is the "Why is this site blocked" button. For malware,
// we can fetch a site-specific report, for phishing, we redirect
// to the generic page describing phishing protection.
@ -2549,7 +2573,7 @@ function BrowserOnClick(event) {
// append the current url, and go there.
try {
let reportURL = formatURL("browser.safebrowsing.malware.reportURL", true);
reportURL += ownerDoc.location.href;
reportURL += aOwnerDoc.location.href;
content.location = reportURL;
} catch (e) {
Components.utils.reportError("Couldn't get malware report URL: " + e);
@ -2562,96 +2586,116 @@ function BrowserOnClick(event) {
Components.utils.reportError("Couldn't get phishing info URL: " + e);
}
}
}
else if (ot == ownerDoc.getElementById('ignoreWarningButton')) {
// Allow users to override and continue through to the site,
// but add a notify bar as a reminder, so that they don't lose
// track after, e.g., tab switching.
gBrowser.loadURIWithFlags(content.location.href,
nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
null, null, null);
break;
Services.perms.add(makeURI(content.location.href), "safe-browsing",
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION);
let buttons = [{
label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
callback: function() { getMeOutOfHere(); }
}];
let title;
if (isMalware) {
title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite");
buttons[1] = {
label: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.accessKey"),
callback: function() {
openUILinkIn(gSafeBrowsing.getReportURL('MalwareError'), 'tab');
}
};
} else {
title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery");
buttons[1] = {
label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.accessKey"),
callback: function() {
openUILinkIn(gSafeBrowsing.getReportURL('Error'), 'tab');
}
};
}
let notificationBox = gBrowser.getNotificationBox();
let value = "blocked-badware-page";
let previousNotification = notificationBox.getNotificationWithValue(value);
if (previousNotification)
notificationBox.removeNotification(previousNotification);
let notification = notificationBox.appendNotification(
title,
value,
"chrome://global/skin/icons/blacklist_favicon.png",
notificationBox.PRIORITY_CRITICAL_HIGH,
buttons
);
// Persist the notification until the user removes so it
// doesn't get removed on redirects.
notification.persistence = -1;
}
case "ignoreWarningButton":
this.ignoreWarningButton(isMalware);
break;
}
else if (/^about:home$/i.test(ownerDoc.documentURI)) {
if (ot == ownerDoc.getElementById("restorePreviousSession")) {
},
ignoreWarningButton: function BrowserOnClick_ignoreWarningButton(aIsMalware) {
// Allow users to override and continue through to the site,
// but add a notify bar as a reminder, so that they don't lose
// track after, e.g., tab switching.
gBrowser.loadURIWithFlags(content.location.href,
nsIWebNavigation.LOAD_FLAGS_BYPASS_CLASSIFIER,
null, null, null);
Services.perms.add(makeURI(content.location.href), "safe-browsing",
Ci.nsIPermissionManager.ALLOW_ACTION,
Ci.nsIPermissionManager.EXPIRE_SESSION);
let buttons = [{
label: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.getMeOutOfHereButton.accessKey"),
callback: function() { getMeOutOfHere(); }
}];
let title;
if (aIsMalware) {
title = gNavigatorBundle.getString("safebrowsing.reportedAttackSite");
buttons[1] = {
label: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.notAnAttackButton.accessKey"),
callback: function() {
openUILinkIn(gSafeBrowsing.getReportURL('MalwareError'), 'tab');
}
};
} else {
title = gNavigatorBundle.getString("safebrowsing.reportedWebForgery");
buttons[1] = {
label: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.label"),
accessKey: gNavigatorBundle.getString("safebrowsing.notAForgeryButton.accessKey"),
callback: function() {
openUILinkIn(gSafeBrowsing.getReportURL('Error'), 'tab');
}
};
}
let notificationBox = gBrowser.getNotificationBox();
let value = "blocked-badware-page";
let previousNotification = notificationBox.getNotificationWithValue(value);
if (previousNotification) {
notificationBox.removeNotification(previousNotification);
}
let notification = notificationBox.appendNotification(
title,
value,
"chrome://global/skin/icons/blacklist_favicon.png",
notificationBox.PRIORITY_CRITICAL_HIGH,
buttons
);
// Persist the notification until the user removes so it
// doesn't get removed on redirects.
notification.persistence = -1;
},
onAboutHome: function BrowserOnClick_onAboutHome(aTargetElm, aOwnerDoc) {
let elmId = aTargetElm.getAttribute("id");
switch (elmId) {
case "restorePreviousSession":
let ss = Cc["@mozilla.org/browser/sessionstore;1"].
getService(Ci.nsISessionStore);
if (ss.canRestoreLastSession)
if (ss.canRestoreLastSession) {
ss.restoreLastSession();
ownerDoc.getElementById("launcher").removeAttribute("session");
}
else if (ot == ownerDoc.getElementById("downloads")) {
}
aOwnerDoc.getElementById("launcher").removeAttribute("session");
break;
case "downloads":
BrowserDownloadsUI();
}
else if (ot == ownerDoc.getElementById("bookmarks")) {
break;
case "bookmarks":
PlacesCommandHook.showPlacesOrganizer("AllBookmarks");
}
else if (ot == ownerDoc.getElementById("history")) {
break;
case "history":
PlacesCommandHook.showPlacesOrganizer("History");
}
else if (ot == ownerDoc.getElementById("apps")) {
break;
case "apps":
openUILinkIn("https://marketplace.mozilla.org/", "tab");
}
else if (ot == ownerDoc.getElementById("addons")) {
break;
case "addons":
BrowserOpenAddonsMgr();
}
else if (ot == ownerDoc.getElementById("sync")) {
break;
case "sync":
openPreferences("paneSync");
}
else if (ot == ownerDoc.getElementById("settings")) {
break;
case "settings":
openPreferences();
}
break;
}
}
},
};
/**
* Re-direct the browser to a known-safe page. This function is

View File

@ -131,6 +131,7 @@ function startTest2() {
"onStateChange",
"onLocationChange",
"onSecurityChange",
"onSecurityChange",
"onStateChange"
];
gFrontNotifications = gAllNotifications;
@ -155,6 +156,7 @@ function startTest4() {
"onStateChange",
"onLocationChange",
"onSecurityChange",
"onSecurityChange",
"onStateChange"
];
gFrontNotifications = [];

View File

@ -6,6 +6,7 @@
// Load DownloadUtils module for convertByteUnits
Components.utils.import("resource://gre/modules/DownloadUtils.jsm");
Components.utils.import("resource://gre/modules/ctypes.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
var gAdvancedPane = {
_inited: false,
@ -39,6 +40,9 @@ var gAdvancedPane = {
#endif
this.updateActualCacheSize("disk");
this.updateActualCacheSize("offline");
// Notify observers that the UI is now ready
Services.obs.notifyObservers(window, "advanced-pane-loaded", null);
},
/**
@ -696,10 +700,15 @@ var gAdvancedPane = {
*/
updateSetDefaultBrowser: function()
{
var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
let shellSvc = getShellService();
let setDefaultPane = document.getElementById("setDefaultPane");
if (!shellSvc) {
setDefaultPane.hidden = true;
document.getElementById("alwaysCheckDefault").disabled = true;
return;
}
let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
setDefaultPane.selectedIndex = selectedIndex;
},
/**
@ -707,8 +716,9 @@ var gAdvancedPane = {
*/
setDefaultBrowser: function()
{
var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
let shellSvc = getShellService();
if (!shellSvc)
return;
shellSvc.setDefaultBrowser(true, false);
document.getElementById("setDefaultPane").selectedIndex = 1;
}

View File

@ -675,10 +675,15 @@ var gAdvancedPane = {
*/
updateSetDefaultBrowser: function()
{
var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
let shellSvc = getShellService();
let setDefaultPane = document.getElementById("setDefaultPane");
if (!shellSvc) {
setDefaultPane.hidden = true;
document.getElementById("alwaysCheckDefault").disabled = true;
return;
}
let selectedIndex = shellSvc.isDefaultBrowser(false) ? 1 : 0;
document.getElementById("setDefaultPane").selectedIndex = selectedIndex;
setDefaultPane.selectedIndex = selectedIndex;
},
/**
@ -686,8 +691,9 @@ var gAdvancedPane = {
*/
setDefaultBrowser: function()
{
var shellSvc = Components.classes["@mozilla.org/browser/shell-service;1"]
.getService(Components.interfaces.nsIShellService);
let shellSvc = getShellService();
if (!shellSvc)
return;
shellSvc.setDefaultBrowser(true, false);
document.getElementById("setDefaultPane").selectedIndex = 1;
}

View File

@ -13,6 +13,7 @@ include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
head.js \
browser_advanced_update.js \
browser_bug410900.js \
browser_bug567487.js \
browser_bug731866.js \

View File

@ -0,0 +1,40 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
function test() {
waitForExplicitFinish();
resetPreferences();
registerCleanupFunction(resetPreferences);
Services.prefs.setBoolPref("browser.search.update", false);
open_preferences(runTest);
}
function runTest(win) {
let doc = win.document;
let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
win.gotoPref("paneAdvanced");
let advancedPrefs = doc.getElementById("advancedPrefs");
let updateTab = doc.getElementById("updateTab");
advancedPrefs.selectedTab = updateTab;
is_element_visible(enableSearchUpdate, "Check search update preference is visible");
// Ensure that the update pref dialog reflects the actual pref value.
ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
Services.prefs.setBoolPref("browser.search.update", true);
ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
gBrowser.removeCurrentTab();
win.close();
finish();
}
function resetPreferences() {
Services.prefs.clearUserPref("browser.search.update");
}

View File

@ -6,11 +6,7 @@ Components.utils.import("resource://gre/modules/NetUtil.jsm");
function test() {
waitForExplicitFinish();
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab = gBrowser.addTab("about:preferences"));
newTabBrowser.addEventListener("load", function () {
newTabBrowser.removeEventListener("load", arguments.callee, true);
runTest(gBrowser.contentWindow);
}, true);
open_preferences(runTest);
}
function runTest(win) {

View File

@ -63,15 +63,11 @@ function test() {
so it has to be opened as a sub dialog of the main pref tab.
Open the main tab here.
*/
gBrowser.selectedTab = gBrowser.addTab("about:preferences");
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("load", function tabLoadListener() {
newTabBrowser.removeEventListener("load", tabLoadListener, true);
open_preferences(function tabOpened(aContentWindow) {
is(gBrowser.currentURI.spec, "about:preferences", "about:preferences loaded");
windowWatcher.registerNotification(observer);
gBrowser.contentWindow.gAdvancedPane.showConnections();
}, true);
});
}
// run a bunch of tests on the window containing connection.xul

View File

@ -23,4 +23,13 @@ function is_element_visible(aElement, aMsg) {
function is_element_hidden(aElement, aMsg) {
isnot(aElement, null, "Element should not be null, when checking visibility");
ok(is_hidden(aElement), aMsg);
}
}
function open_preferences(aCallback) {
gBrowser.selectedTab = gBrowser.addTab("about:preferences");
let newTabBrowser = gBrowser.getBrowserForTab(gBrowser.selectedTab);
newTabBrowser.addEventListener("load", function () {
newTabBrowser.removeEventListener("load", arguments.callee, true);
aCallback(gBrowser.contentWindow);
}, true);
}

View File

@ -12,6 +12,7 @@ include $(DEPTH)/config/autoconf.mk
include $(topsrcdir)/config/rules.mk
_BROWSER_FILES = \
browser_advanced_update.js \
browser_bug410900.js \
browser_bug567487.js \
browser_bug705422.js \

View File

@ -0,0 +1,36 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
resetPreferences();
registerCleanupFunction(resetPreferences);
function observer(win, topic, data) {
Services.obs.removeObserver(observer, "advanced-pane-loaded");
runTest(win);
}
Services.obs.addObserver(observer, "advanced-pane-loaded", false);
Services.prefs.setBoolPref("browser.search.update", false);
openDialog("chrome://browser/content/preferences/preferences.xul", "Preferences",
"chrome,titlebar,toolbar,centerscreen,dialog=no", "paneAdvanced");
}
function runTest(win) {
let doc = win.document;
let enableSearchUpdate = doc.getElementById("enableSearchUpdate");
// Ensure that the update pref dialog reflects the actual pref value.
ok(!enableSearchUpdate.checked, "Ensure search updates are disabled");
Services.prefs.setBoolPref("browser.search.update", true);
ok(enableSearchUpdate.checked, "Ensure search updates are enabled");
win.close();
finish();
}
function resetPreferences() {
Services.prefs.clearUserPref("browser.search.update");
}

View File

@ -36,6 +36,44 @@ const BUTTON_POSITION_SAVE = 0;
const BUTTON_POSITION_CANCEL = 1;
const BUTTON_POSITION_DONT_SAVE = 2;
let keysbundle = Services.strings.createBundle("chrome://global-platform/locale/platformKeys.properties");
function SP_Pretty_Key(aElemKey) {
let elemString = "";
let elemMod = aElemKey.getAttribute("modifiers");
if (elemMod.match("accel")) {
if (navigator.platform.indexOf("Mac") !== -1) {
elemString += keysbundle.GetStringFromName("VK_META") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
} else {
elemString += keysbundle.GetStringFromName("VK_CONTROL") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
}
}
if (elemMod.match("shift")) {
elemString += keysbundle.GetStringFromName("VK_SHIFT") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
}
if (elemMod.match("alt")) {
elemString += keysbundle.GetStringFromName("VK_ALT") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
}
if (elemMod.match("ctrl")) {
elemString += keysbundle.GetStringFromName("VK_CONTROL") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
}
if (elemMod.match("meta")) {
elemString += keysbundle.GetStringFromName("VK_META") +
keysbundle.GetStringFromName("MODIFIER_SEPARATOR");
}
return elemString + aElemKey.getAttribute("key").toUpperCase();
}
/**
* The scratchpad object handles the Scratchpad window functionality.
*/
@ -971,7 +1009,14 @@ var Scratchpad = {
}
let state = null;
let initialText = this.strings.GetStringFromName("scratchpadIntro");
let initialText = this.strings.formatStringFromName(
"scratchpadIntro1",
[SP_Pretty_Key(document.getElementById("sp-key-run")),
SP_Pretty_Key(document.getElementById("sp-key-inspect")),
SP_Pretty_Key(document.getElementById("sp-key-display"))],
3);
if ("arguments" in window &&
window.arguments[0] instanceof Ci.nsIDialogParamBlock) {
state = JSON.parse(window.arguments[0].GetString(0));

View File

@ -25,9 +25,7 @@ function testOpen()
{
openScratchpad(function(win) {
is(win.Scratchpad.filename, undefined, "Default filename is undefined");
is(win.Scratchpad.getText(),
win.Scratchpad.strings.GetStringFromName("scratchpadIntro"),
"Default text is loaded")
isnot(win.Scratchpad.getText(), null, "Default text should not be null");
is(win.Scratchpad.executionContext, win.SCRATCHPAD_CONTEXT_CONTENT,
"Default execution context is content");

View File

@ -57,7 +57,7 @@ confirmClose.title=Unsaved Changes
# LOCALIZATION NOTE (scratchpadIntro): This is a multi-line comment explaining
# how to use the Scratchpad. Note that this should be a valid JavaScript
# comment inside /* and */.
scratchpadIntro=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text,\n * 2. Inspect to bring up an Object Inspector on the result, or,\n * 3. Display to insert the result in a comment after the selection.\n */\n\n
scratchpadIntro1=/*\n * This is a JavaScript Scratchpad.\n *\n * Enter some JavaScript, then Right Click or choose from the Execute Menu:\n * 1. Run to evaluate the selected text (%1$S),\n * 2. Inspect to bring up an Object Inspector on the result (%2$S), or,\n * 3. Display to insert the result in a comment after the selection. (%3$S)\n */\n\n
# LOCALIZATION NOTE (notification.browserContext): This is the message displayed
# over the top of the editor when the user has switched to browser context.

View File

@ -47,8 +47,6 @@ public class RunCmdThread extends Thread
public void run() {
try {
int nIterations = 0;
SvrSocket.setSoTimeout(5000);
while (bListening)
{
@ -61,16 +59,6 @@ public class RunCmdThread extends Thread
}
catch (SocketTimeoutException toe)
{
if (++nIterations > 60)
{
nIterations = 0;
String sRet = SendPing("www.mozilla.org");
if (sRet.contains("3 received"))
handler.post(new doCancelNotification());
else
handler.post(new doSendNotification("SUTAgent - Network Connectivity Error", sRet));
sRet = null;
}
continue;
}
catch (IOException e)

View File

@ -377,6 +377,39 @@ public class SUTAgentAndroid extends Activity
}
}
@Override
public void onLowMemory()
{
System.gc();
DoCommand dc = new DoCommand(getApplication());
if (dc != null)
{
logToFile(dc.GetTestRoot(), dc.GetSystemTime(), "onLowMemory");
logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.GetMemoryInfo());
String procInfo = dc.GetProcessInfo();
if (procInfo != null)
{
String lines[] = procInfo.split("\n");
for (String line : lines)
{
if (line.contains("mozilla"))
{
logToFile(dc.GetTestRoot(), dc.GetSystemTime(), line);
String words[] = line.split("\t");
if ((words != null) && (words.length > 1))
{
logToFile(dc.GetTestRoot(), dc.GetSystemTime(), dc.StatProcess(words[1]));
}
}
}
}
}
else
{
Log.e("SUTAgentAndroid", "onLowMemory: unable to log to file!");
}
}
private void monitorBatteryState()
{
battReceiver = new BroadcastReceiver()

View File

@ -0,0 +1,55 @@
#!/bin/python
import os
import simplejson
import sys
import subprocess
import urllib
import glob
def check_run(args):
r = subprocess.call(args)
assert r == 0
old_files = glob.glob('*.manifest') + ['tooltool.py', 'setup.sh']
for f in old_files:
try:
os.unlink(f)
except:
pass
urllib.urlretrieve('https://raw.github.com/jhford/tooltool/master/tooltool.py',
'tooltool.py')
urllib.urlretrieve('https://hg.mozilla.org/mozilla-central/raw-file/tip/build/unix/build-clang/setup.sh',
'setup.sh')
check_run(['python', 'tooltool.py', '-m', 'linux32.manifest', 'add',
'clang-linux32.tar.bz2', 'setup.sh'])
check_run(['python', 'tooltool.py', '-m', 'linux64.manifest', 'add',
'clang-linux64.tar.bz2', 'setup.sh'])
check_run(['python', 'tooltool.py', '-m', 'darwin.manifest', 'add',
'clang-darwin.tar.bz2', 'setup.sh'])
def key_sort(item):
item = item[0]
if item == 'size':
return 0
if item == 'digest':
return 1
if item == 'algorithm':
return 3
return 4
rev = os.path.basename(os.getcwd()).split('-')[1]
for platform in ['darwin', 'linux32', 'linux64']:
old_name = 'clang-' + platform + '.tar.bz2'
manifest = platform + '.manifest'
data = eval(file(manifest).read())
new_name = data[1]['digest']
data[1]['filename'] = 'clang.tar.bz2'
data = [{'clang_version' : 'r%s' % rev }] + data
out = file(manifest,'w')
simplejson.dump(data, out, indent=0, item_sort_key=key_sort)
out.write('\n')
os.rename(old_name, new_name)

View File

@ -21,7 +21,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSPrincipals(JSPrincipals);
[ptr] native PrincipalArray(nsTArray<nsCOMPtr<nsIPrincipal> >);
[scriptable, uuid(fbb93cc7-9a94-4743-8e89-9e6939cac083)]
[scriptable, uuid(8a74b011-667d-4cfa-b2a2-b27582ba5f38)]
interface nsIPrincipal : nsISerializable
{
/**
@ -245,6 +245,11 @@ interface nsIPrincipal : nsISerializable
* Returns nsIAppsService::NO_APP_ID if this principal isn't part of an app.
*/
readonly attribute unsigned long appId;
/**
* Returns true iif the principal is inside a browser element.
*/
readonly attribute boolean isInBrowserElement;
};
/**

View File

@ -127,6 +127,7 @@ public:
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
NS_IMETHOD GetAppId(PRUint32* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
#ifdef DEBUG
virtual void dumpImpl();
#endif
@ -205,6 +206,7 @@ public:
NS_IMETHOD GetExtendedOrigin(nsACString& aExtendedOrigin);
NS_IMETHOD GetAppStatus(PRUint16* aAppStatus);
NS_IMETHOD GetAppId(PRUint32* aAppStatus);
NS_IMETHOD GetIsInBrowserElement(bool* aIsInBrowserElement);
#ifdef DEBUG
virtual void dumpImpl();
#endif

View File

@ -335,6 +335,13 @@ nsNullPrincipal::GetAppId(PRUint32* aAppId)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = false;
return NS_OK;
}
/**
* nsISerializable implementation
*/

View File

@ -1093,6 +1093,13 @@ nsPrincipal::GetAppId(PRUint32* aAppId)
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = mInMozBrowser;
return NS_OK;
}
NS_IMETHODIMP
nsPrincipal::Read(nsIObjectInputStream* aStream)
{
@ -1476,6 +1483,12 @@ nsExpandedPrincipal::GetAppId(PRUint32* aAppId)
return NS_ERROR_NOT_AVAILABLE;
}
NS_IMETHODIMP
nsExpandedPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
return NS_ERROR_NOT_AVAILABLE;
}
void
nsExpandedPrincipal::GetScriptLocation(nsACString& aStr)
{

View File

@ -258,6 +258,13 @@ nsSystemPrincipal::GetAppId(PRUint32* aAppId)
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::GetIsInBrowserElement(bool* aIsInBrowserElement)
{
*aIsInBrowserElement = false;
return NS_OK;
}
//////////////////////////////////////////
// Methods implementing nsISerializable //
//////////////////////////////////////////

View File

@ -251,6 +251,7 @@ var gData = [
child: {
src: "http://example.org/chrome/",
isapp: false,
inBrowser: true,
},
test: [ "child-has-same-eo" ],
},
@ -310,6 +311,9 @@ function checkIFrame(aFrame, data) {
"extendedOrigin should be the same as the last inserted one");
}
is(principal.isInBrowserElement, !!data.browser,
"check principal.isInBrowserElement");
if (data.child) {
let childPrincipal = aFrame.contentWindow.frames[0].document.nodePrincipal;
@ -318,6 +322,9 @@ function checkIFrame(aFrame, data) {
"child should be an installed app");
}
is(childPrincipal.isInBrowserElement, !!data.child.browser || !!data.child.inBrowser,
"check childPrincipal.isInBrowserElement");
if (data.test.indexOf("child-has-same-eo") != -1) {
is(childPrincipal.extendedOrigin, principal.extendedOrigin,
"child should have the same extendedOrigin as parent");

View File

@ -22,6 +22,7 @@ ACCEPTED_MAR_CHANNEL_IDS = @ACCEPTED_MAR_CHANNEL_IDS@
MOZ_PROFILE_MIGRATOR = @MOZ_PROFILE_MIGRATOR@
MOZ_EXTENSION_MANAGER = @MOZ_EXTENSION_MANAGER@
MOZ_APP_UA_NAME = @MOZ_APP_UA_NAME@
MOZ_UA_OS_AGNOSTIC = @MOZ_UA_OS_AGNOSTIC@
MOZ_APP_VERSION = @MOZ_APP_VERSION@
MOZ_APP_MAXVERSION = @MOZ_APP_MAXVERSION@
MOZ_MACBUNDLE_NAME = @MOZ_MACBUNDLE_NAME@

View File

@ -8411,6 +8411,10 @@ AC_SUBST(MOZ_APP_VERSION)
AC_SUBST(MOZ_APP_MAXVERSION)
AC_DEFINE_UNQUOTED(FIREFOX_VERSION,$FIREFOX_VERSION)
AC_SUBST(FIREFOX_VERSION)
AC_SUBST(MOZ_UA_OS_AGNOSTIC)
if test -n "$MOZ_UA_OS_AGNOSTIC"; then
AC_DEFINE(MOZ_UA_OS_AGNOSTIC)
fi
# We can't use the static application.ini data when building against
# a libxul SDK.

View File

@ -7,7 +7,7 @@
#ifndef mozilla_dom_Element_h__
#define mozilla_dom_Element_h__
#include "nsIContent.h"
#include "mozilla/dom/FragmentOrElement.h"
#include "nsEventStates.h"
class nsEventStateManager;
@ -60,12 +60,12 @@ class Link;
{ 0xc6c049a1, 0x96e8, 0x4580, \
{ 0xa6, 0x93, 0xb9, 0x5f, 0x53, 0xbe, 0xe8, 0x1c } }
class Element : public nsIContent
class Element : public FragmentOrElement
{
public:
#ifdef MOZILLA_INTERNAL_API
Element(already_AddRefed<nsINodeInfo> aNodeInfo) :
nsIContent(aNodeInfo),
FragmentOrElement(aNodeInfo),
mState(NS_EVENT_STATE_MOZ_READONLY)
{}
#endif // MOZILLA_INTERNAL_API
@ -189,6 +189,31 @@ public:
*/
virtual bool IsLabelable() const = 0;
/**
* Is the attribute named stored in the mapped attributes?
*
* // XXXbz we use this method in HasAttributeDependentStyle, so svg
* returns true here even though it stores nothing in the mapped
* attributes.
*/
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const = 0;
/**
* Get a hint that tells the style system what to do when
* an attribute on this node changes, if something needs to happen
* in response to the change *other* than the result of what is
* mapped into style data via any type of style rule.
*/
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const = 0;
/**
* Returns an atom holding the name of the "class" attribute on this
* content node (if applicable). Returns null if there is no
* "class" attribute for this type of content node.
*/
virtual nsIAtom *GetClassAttributeName() const = 0;
protected:
/**
* Method to get the _intrinsic_ content state of this element. This is the

View File

@ -0,0 +1,544 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
/*
* Base class for all element classes as well as nsDocumentFragment. This
* provides an implementation of nsIDOMNode, implements nsIContent, provides
* utility methods for subclasses, and so forth.
*/
#ifndef FragmentOrElement_h___
#define FragmentOrElement_h___
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "nsIContent.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocumentFragment.h"
#include "nsILinkHandler.h"
#include "nsNodeUtils.h"
#include "nsAttrAndChildArray.h"
#include "mozFlushType.h"
#include "nsDOMAttributeMap.h"
#include "nsIWeakReference.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDocument.h"
#include "nsIDOMNodeSelector.h"
#include "nsIDOMXPathNSResolver.h"
#include "nsPresContext.h"
#include "nsIDOMDOMStringMap.h"
#include "nsContentList.h"
#include "nsDOMClassInfoID.h" // DOMCI_DATA
#include "nsIDOMTouchEvent.h"
#include "nsIInlineEventHandlers.h"
#include "mozilla/CORSMode.h"
#include "mozilla/Attributes.h"
#include "nsISMILAttr.h"
class nsIDOMAttr;
class nsIDOMEventListener;
class nsIFrame;
class nsIDOMNamedNodeMap;
class nsICSSDeclaration;
class nsIDOMCSSStyleDeclaration;
class nsIURI;
class nsINodeInfo;
class nsIControllers;
class nsEventListenerManager;
class nsIScrollableFrame;
class nsAttrValueOrString;
class nsContentList;
class nsDOMTokenList;
class ContentUnbinder;
struct nsRect;
typedef PRUptrdiff PtrBits;
/**
* Class that implements the nsIDOMNodeList interface (a list of children of
* the content), by holding a reference to the content and delegating GetLength
* and Item to its existing child list.
* @see nsIDOMNodeList
*/
class nsChildContentList MOZ_FINAL : public nsINodeList
{
public:
nsChildContentList(nsINode* aNode)
: mNode(aNode)
{
SetIsDOMBinding();
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap);
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
// nsINodeList interface
virtual PRInt32 IndexOf(nsIContent* aContent);
void DropReference()
{
mNode = nullptr;
}
virtual nsINode* GetParentObject()
{
return mNode;
}
private:
// The node whose children make up the list (weak reference)
nsINode* mNode;
};
/**
* A tearoff class for FragmentOrElement to implement additional interfaces
*/
class nsNode3Tearoff : public nsIDOMXPathNSResolver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
NS_DECL_NSIDOMXPATHNSRESOLVER
nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
{
}
protected:
virtual ~nsNode3Tearoff() {}
private:
nsCOMPtr<nsINode> mNode;
};
/**
* A class that implements nsIWeakReference
*/
class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
{
public:
nsNodeWeakReference(nsINode* aNode)
: mNode(aNode)
{
}
~nsNodeWeakReference();
// nsISupports
NS_DECL_ISUPPORTS
// nsIWeakReference
NS_DECL_NSIWEAKREFERENCE
void NoticeNodeDestruction()
{
mNode = nullptr;
}
private:
nsINode* mNode;
};
/**
* Tearoff to use for nodes to implement nsISupportsWeakReference
*/
class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
{
public:
nsNodeSupportsWeakRefTearoff(nsINode* aNode)
: mNode(aNode)
{
}
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsISupportsWeakReference
NS_DECL_NSISUPPORTSWEAKREFERENCE
NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
private:
nsCOMPtr<nsINode> mNode;
};
/**
* A tearoff class for FragmentOrElement to implement NodeSelector
*/
class nsNodeSelectorTearoff MOZ_FINAL : public nsIDOMNodeSelector
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIDOMNODESELECTOR
NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSelectorTearoff)
nsNodeSelectorTearoff(nsINode *aNode) : mNode(aNode)
{
}
private:
~nsNodeSelectorTearoff() {}
private:
nsCOMPtr<nsINode> mNode;
};
// Forward declare to allow being a friend
class nsTouchEventReceiverTearoff;
class nsInlineEventHandlersTearoff;
/**
* A generic base class for DOM elements, implementing many nsIContent,
* nsIDOMNode and nsIDOMElement methods.
*/
namespace mozilla {
namespace dom {
class FragmentOrElement : public nsIContent
{
public:
FragmentOrElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~FragmentOrElement();
friend class ::nsTouchEventReceiverTearoff;
friend class ::nsInlineEventHandlersTearoff;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_SIZEOF_EXCLUDING_THIS
/**
* Called during QueryInterface to give the binding manager a chance to
* get an interface for this element.
*/
nsresult PostQueryInterface(REFNSIID aIID, void** aInstancePtr);
// nsINode interface methods
virtual PRUint32 GetChildCount() const;
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
bool aNotify);
virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
NS_IMETHOD GetTextContent(nsAString &aTextContent);
NS_IMETHOD SetTextContent(const nsAString& aTextContent);
// nsIContent interface methods
virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
virtual const nsTextFragment *GetText();
virtual PRUint32 TextLength() const;
virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
bool aNotify);
// Need to implement this here too to avoid hiding.
nsresult SetText(const nsAString& aStr, bool aNotify)
{
return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
}
virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
bool aNotify);
virtual bool TextIsOnlyWhitespace();
virtual void AppendTextTo(nsAString& aResult);
virtual nsIContent *GetBindingParent() const;
virtual bool IsLink(nsIURI** aURI) const;
virtual void DestroyContent();
virtual void SaveSubtreeState();
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
public:
// nsIDOMNode method implementation
NS_IMETHOD GetNodeName(nsAString& aNodeName);
NS_IMETHOD GetLocalName(nsAString& aLocalName);
NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
NS_IMETHOD GetNodeType(PRUint16* aNodeType);
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
NS_IMETHOD GetPrefix(nsAString& aPrefix);
NS_IMETHOD IsSupported(const nsAString& aFeature,
const nsAString& aVersion, bool* aReturn);
NS_IMETHOD HasAttributes(bool* aHasAttributes);
NS_IMETHOD HasChildNodes(bool* aHasChildNodes);
nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn)
{
return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
}
nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn)
{
return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
}
nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return nsINode::RemoveChild(aOldChild, aReturn);
}
nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{
return InsertBefore(aNewChild, nullptr, aReturn);
}
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}
//----------------------------------------
/**
* Check whether a spec feature/version is supported.
* @param aObject the object, which should support the feature,
* for example nsIDOMNode or nsIDOMDOMImplementation
* @param aFeature the feature ("Views", "Core", "HTML", "Range" ...)
* @param aVersion the version ("1.0", "2.0", ...)
* @param aReturn whether the feature is supported or not [OUT]
*/
static nsresult InternalIsSupported(nsISupports* aObject,
const nsAString& aFeature,
const nsAString& aVersion,
bool* aReturn);
/**
* If there are listeners for DOMNodeInserted event, fires the event on all
* aNodes
*/
static void FireNodeInserted(nsIDocument* aDoc,
nsINode* aParent,
nsTArray<nsCOMPtr<nsIContent> >& aNodes);
/**
* Helper methods for implementing querySelector/querySelectorAll
*/
static nsIContent* doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
nsresult *aResult);
static nsresult doQuerySelectorAll(nsINode* aRoot,
const nsAString& aSelector,
nsIDOMNodeList **aReturn);
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(FragmentOrElement)
/**
* Fire a DOMNodeRemoved mutation event for all children of this node
*/
void FireNodeRemovedForChildren();
virtual bool OwnedOnlyByTheDOMTree()
{
PRUint32 rc = mRefCnt.get();
if (GetParent()) {
--rc;
}
rc -= mAttrsAndChildren.ChildCount();
return rc == 0;
}
virtual bool IsPurple()
{
return mRefCnt.IsPurple();
}
virtual void RemovePurple()
{
mRefCnt.RemovePurple();
}
static void ClearContentUnbinder();
static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
static bool CanSkipInCC(nsINode* aNode);
static bool CanSkipThis(nsINode* aNode);
static void MarkNodeChildren(nsINode* aNode);
static void InitCCCallbacks();
static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
void *aData);
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
void* aData);
protected:
/**
* Copy attributes and state to another element
* @param aDest the object to copy to
*/
nsresult CopyInnerTo(FragmentOrElement* aDest);
public:
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
// otherwise nsXULElement::nsXULSlots doesn't compile.
/**
* There are a set of DOM- and scripting-specific instance variables
* that may only be instantiated when a content object is accessed
* through the DOM. Rather than burn actual slots in the content
* objects for each of these instance variables, we put them off
* in a side structure that's only allocated when the content is
* accessed through the DOM.
*/
class nsDOMSlots : public nsINode::nsSlots
{
public:
nsDOMSlots();
virtual ~nsDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
void Unlink(bool aIsXUL);
/**
* The .style attribute (an interface that forwards to the actual
* style rules)
* @see nsGenericHTMLElement::GetStyle
*/
nsCOMPtr<nsICSSDeclaration> mStyle;
/**
* The .dataset attribute.
* @see nsGenericHTMLElement::GetDataset
*/
nsIDOMDOMStringMap* mDataset; // [Weak]
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
* @see nsIContent::GetSMILOverrideStyle
*/
nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
/**
* Holds any SMIL override style rules for this element.
*/
nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
/**
* An object implementing nsIDOMNamedNodeMap for this content (attributes)
* @see FragmentOrElement::GetAttributes
*/
nsRefPtr<nsDOMAttributeMap> mAttributeMap;
union {
/**
* The nearest enclosing content node with a binding that created us.
* @see FragmentOrElement::GetBindingParent
*/
nsIContent* mBindingParent; // [Weak]
/**
* The controllers of the XUL Element.
*/
nsIControllers* mControllers; // [OWNER]
};
/**
* An object implementing the .children property for this element.
*/
nsRefPtr<nsContentList> mChildrenList;
/**
* An object implementing the .classList property for this element.
*/
nsRefPtr<nsDOMTokenList> mClassList;
};
protected:
// Override from nsINode
virtual nsINode::nsSlots* CreateSlots();
nsDOMSlots *DOMSlots()
{
return static_cast<nsDOMSlots*>(GetSlots());
}
nsDOMSlots *GetExistingDOMSlots() const
{
return static_cast<nsDOMSlots*>(GetExistingSlots());
}
friend class ::ContentUnbinder;
/**
* Array containing all attributes and children for this element
*/
nsAttrAndChildArray mAttrsAndChildren;
nsContentList* GetChildrenList();
};
} // namespace dom
} // namespace mozilla
/**
* Tearoff class to implement nsITouchEventReceiver
*/
class nsTouchEventReceiverTearoff MOZ_FINAL : public nsITouchEventReceiver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_FORWARD_NSITOUCHEVENTRECEIVER(mElement->)
NS_DECL_CYCLE_COLLECTION_CLASS(nsTouchEventReceiverTearoff)
nsTouchEventReceiverTearoff(mozilla::dom::FragmentOrElement *aElement) : mElement(aElement)
{
}
private:
nsRefPtr<mozilla::dom::FragmentOrElement> mElement;
};
/**
* Tearoff class to implement nsIInlineEventHandlers
*/
class nsInlineEventHandlersTearoff MOZ_FINAL : public nsIInlineEventHandlers
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_FORWARD_NSIINLINEEVENTHANDLERS(mElement->)
NS_DECL_CYCLE_COLLECTION_CLASS(nsInlineEventHandlersTearoff)
nsInlineEventHandlersTearoff(mozilla::dom::FragmentOrElement *aElement) : mElement(aElement)
{
}
private:
nsRefPtr<mozilla::dom::FragmentOrElement> mElement;
};
#define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
rv = FragmentOrElement::QueryInterface(aIID, aInstancePtr); \
if (NS_SUCCEEDED(rv)) \
return rv; \
\
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
#define NS_ELEMENT_INTERFACE_MAP_END \
{ \
return PostQueryInterface(aIID, aInstancePtr); \
} \
\
NS_ADDREF(foundInterface); \
\
*aInstancePtr = foundInterface; \
\
return NS_OK; \
}
#endif /* FragmentOrElement_h___ */

View File

@ -49,6 +49,7 @@ EXPORTS_NAMESPACES = mozilla/dom mozilla
EXPORTS_mozilla/dom = \
Element.h \
FragmentOrElement.h \
FromParser.h \
$(NULL)

View File

@ -11,6 +11,7 @@
#include "nsChangeHint.h"
#include "nsINode.h"
#include "nsIDocument.h" // for IsInHTMLDocument
#include "nsCSSProperty.h"
// Forward declarations
class nsIAtom;
@ -761,31 +762,6 @@ public:
*/
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker) = 0;
/**
* Is the attribute named stored in the mapped attributes?
*
* // XXXbz we use this method in HasAttributeDependentStyle, so svg
* returns true here even though it stores nothing in the mapped
* attributes.
*/
NS_IMETHOD_(bool) IsAttributeMapped(const nsIAtom* aAttribute) const = 0;
/**
* Get a hint that tells the style system what to do when
* an attribute on this node changes, if something needs to happen
* in response to the change *other* than the result of what is
* mapped into style data via any type of style rule.
*/
virtual nsChangeHint GetAttributeChangeHint(const nsIAtom* aAttribute,
PRInt32 aModType) const = 0;
/**
* Returns an atom holding the name of the "class" attribute on this
* content node (if applicable). Returns null if there is no
* "class" attribute for this type of content node.
*/
virtual nsIAtom *GetClassAttributeName() const = 0;
/**
* Should be called when the node can become editable or when it can stop
* being editable (for example when its contentEditable attribute changes,

View File

@ -1291,6 +1291,8 @@ private:
NodeMayHaveDOMMutationObserver,
// Set if node is Content
NodeIsContent,
// Set if the node has animations or transitions
ElementHasAnimations,
// Guard value
BooleanFlagCount
};
@ -1356,13 +1358,14 @@ public:
bool HasPointerLock() const { return GetBoolFlag(ElementHasPointerLock); }
void SetPointerLock() { SetBoolFlag(ElementHasPointerLock); }
void ClearPointerLock() { ClearBoolFlag(ElementHasPointerLock); }
bool MayHaveAnimations() { return GetBoolFlag(ElementHasAnimations); }
void SetMayHaveAnimations() { SetBoolFlag(ElementHasAnimations); }
protected:
void SetParentIsContent(bool aValue) { SetBoolFlag(ParentIsContent, aValue); }
void SetInDocument() { SetBoolFlag(IsInDocument); }
void SetNodeIsContent() { SetBoolFlag(NodeIsContent); }
void ClearInDocument() { ClearBoolFlag(IsInDocument); }
void SetIsElement() { SetBoolFlag(NodeIsElement); }
void ClearIsElement() { ClearBoolFlag(NodeIsElement); }
void SetHasID() { SetBoolFlag(ElementHasID); }
void ClearHasID() { ClearBoolFlag(ElementHasID); }
void SetMayHaveStyle() { SetBoolFlag(ElementMayHaveStyle); }

File diff suppressed because it is too large Load Diff

View File

@ -125,6 +125,7 @@ CPPSRCS = \
nsXMLContentSerializer.cpp \
nsXMLHttpRequest.cpp \
nsXMLNameSpaceMap.cpp \
FragmentOrElement.cpp \
Link.cpp \
nsBlobProtocolHandler.cpp \
nsFrameMessageManager.cpp \

View File

@ -158,6 +158,7 @@ public:
}
}
#ifdef MOZILLA_INTERNAL_API
void GetPrefix(nsAString& aStr) const
{
if (IsAtom()) {
@ -167,6 +168,7 @@ public:
NodeInfo()->GetPrefix(aStr);
}
}
#endif
PRUint32 HashValue() const
{

View File

@ -12,7 +12,7 @@
#define nsAttrValue_h___
#include "nscore.h"
#include "nsString.h"
#include "nsStringGlue.h"
#include "nsStringBuffer.h"
#include "nsColor.h"
#include "nsCaseTreatment.h"

View File

@ -14,7 +14,7 @@
#include "nsISupports.h"
#include "nsTArray.h"
#include "nsString.h"
#include "nsStringGlue.h"
#include "nsIHTMLCollection.h"
#include "nsIDOMNodeList.h"
#include "nsINodeList.h"

View File

@ -11,7 +11,7 @@
#define nsDOMAttributeMap_h___
#include "nsIDOMNamedNodeMap.h"
#include "nsString.h"
#include "nsStringGlue.h"
#include "nsRefPtrHashtable.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIDOMNode.h"

View File

@ -14,8 +14,10 @@
#include "nsGenericElement.h"
#include "dombindings.h"
using namespace mozilla;
using namespace mozilla::dom;
nsDOMTokenList::nsDOMTokenList(nsGenericElement *aElement, nsIAtom* aAttrAtom)
nsDOMTokenList::nsDOMTokenList(nsGenericElement* aElement, nsIAtom* aAttrAtom)
: mElement(aElement),
mAttrAtom(aAttrAtom)
{

View File

@ -7,10 +7,9 @@
* Implementation of DOM Core's nsIDOMDocumentFragment.
*/
#include "nsISupports.h"
#include "nsIContent.h"
#include "nsIDOMDocumentFragment.h"
#include "nsGenericElement.h"
#include "mozilla/dom/FragmentOrElement.h"
#include "nsGenericElement.h" // for DOMCI_NODE_DATA
#include "nsINameSpaceManager.h"
#include "nsINodeInfo.h"
#include "nsNodeInfoManager.h"
@ -19,15 +18,20 @@
#include "nsDOMString.h"
#include "nsContentUtils.h"
class nsDocumentFragment : public nsGenericElement,
using namespace mozilla;
using namespace mozilla::dom;
class nsDocumentFragment : public FragmentOrElement,
public nsIDOMDocumentFragment
{
public:
using FragmentOrElement::GetFirstChild;
// nsISupports
NS_DECL_ISUPPORTS_INHERITED
// interface nsIDOMNode
NS_FORWARD_NSIDOMNODE(nsGenericElement::)
NS_FORWARD_NSIDOMNODE(FragmentOrElement::)
// interface nsIDOMDocumentFragment
// NS_DECL_NSIDOCUMENTFRAGMENT Empty
@ -38,6 +42,12 @@ public:
}
// nsIContent
virtual already_AddRefed<nsINodeInfo>
GetExistingAttrNameFromQName(const nsAString& aStr) const
{
return nullptr;
}
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString& aValue, bool aNotify)
{
@ -54,6 +64,10 @@ public:
{
return false;
}
virtual bool HasAttr(PRInt32 aNameSpaceID, nsIAtom* aName) const
{
return false;
}
virtual nsresult UnsetAttr(PRInt32 aNameSpaceID, nsIAtom* aAttribute,
bool aNotify)
{
@ -63,6 +77,10 @@ public:
{
return nullptr;
}
virtual PRUint32 GetAttrCount() const
{
return 0;
}
virtual bool IsNodeOfType(PRUint32 aFlags) const;
@ -73,6 +91,30 @@ public:
virtual nsIAtom* DoGetID() const;
virtual nsIAtom *GetIDAttributeName() const;
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
nsIContent* aBindingParent,
bool aCompileEventHandlers)
{
NS_ASSERTION(false, "Trying to bind a fragment to a tree");
return NS_ERROR_NOT_IMPLEMENTED;
}
virtual void UnbindFromTree(bool aDeep, bool aNullParent)
{
NS_ASSERTION(false, "Trying to unbind a fragment from a tree");
return;
}
virtual Element* GetNameSpaceElement()
{
return nullptr;
}
#ifdef DEBUG
virtual void List(FILE* out, PRInt32 aIndent) const;
virtual void DumpContent(FILE* out, PRInt32 aIndent, bool aDumpAll) const;
#endif
protected:
nsresult Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const;
};
@ -100,9 +142,13 @@ NS_NewDocumentFragment(nsIDOMDocumentFragment** aInstancePtrResult,
}
nsDocumentFragment::nsDocumentFragment(already_AddRefed<nsINodeInfo> aNodeInfo)
: nsGenericElement(aNodeInfo)
: FragmentOrElement(aNodeInfo)
{
ClearIsElement();
NS_ABORT_IF_FALSE(mNodeInfo->NodeType() ==
nsIDOMNode::DOCUMENT_FRAGMENT_NODE &&
mNodeInfo->Equals(nsGkAtoms::documentFragmentNodeName,
kNameSpaceID_None),
"Bad NodeType in aNodeInfo");
}
bool
@ -123,6 +169,69 @@ nsDocumentFragment::GetIDAttributeName() const
return nullptr;
}
#ifdef DEBUG
void
nsDocumentFragment::List(FILE* out, PRInt32 aIndent) const
{
PRInt32 indent;
for (indent = aIndent; --indent >= 0; ) {
fputs(" ", out);
}
fprintf(out, "DocumentFragment@%p", (void *)this);
fprintf(out, " flags=[%08x]", static_cast<unsigned int>(GetFlags()));
fprintf(out, " refcount=%d<", mRefCnt.get());
nsIContent* child = GetFirstChild();
if (child) {
fputs("\n", out);
for (; child; child = child->GetNextSibling()) {
child->List(out, aIndent + 1);
}
for (indent = aIndent; --indent >= 0; ) {
fputs(" ", out);
}
}
fputs(">\n", out);
}
void
nsDocumentFragment::DumpContent(FILE* out, PRInt32 aIndent,
bool aDumpAll) const
{
PRInt32 indent;
for (indent = aIndent; --indent >= 0; ) {
fputs(" ", out);
}
fputs("<DocumentFragment>", out);
if(aIndent) {
fputs("\n", out);
}
for (nsIContent* child = GetFirstChild();
child;
child = child->GetNextSibling()) {
PRInt32 indent = aIndent ? aIndent + 1 : 0;
child->DumpContent(out, indent, aDumpAll);
}
for (indent = aIndent; --indent >= 0; ) {
fputs(" ", out);
}
fputs("</DocumentFragment>", out);
if(aIndent) {
fputs("\n", out);
}
}
#endif
DOMCI_NODE_DATA(DocumentFragment, nsDocumentFragment)
// QueryInterface implementation for nsDocumentFragment
@ -146,7 +255,7 @@ NS_INTERFACE_MAP_BEGIN(nsDocumentFragment)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(DocumentFragment)
NS_INTERFACE_MAP_END
NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, nsGenericElement)
NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, nsGenericElement)
NS_IMPL_ADDREF_INHERITED(nsDocumentFragment, FragmentOrElement)
NS_IMPL_RELEASE_INHERITED(nsDocumentFragment, FragmentOrElement)
NS_IMPL_ELEMENT_CLONE(nsDocumentFragment)

File diff suppressed because it is too large Load Diff

View File

@ -14,6 +14,7 @@
#include "nsCOMPtr.h"
#include "nsAutoPtr.h"
#include "mozilla/dom/FragmentOrElement.h"
#include "mozilla/dom/Element.h"
#include "nsIDOMElement.h"
#include "nsIDOMDocumentFragment.h"
@ -57,151 +58,6 @@ struct nsRect;
typedef PRUptrdiff PtrBits;
/**
* Class that implements the nsIDOMNodeList interface (a list of children of
* the content), by holding a reference to the content and delegating GetLength
* and Item to its existing child list.
* @see nsIDOMNodeList
*/
class nsChildContentList MOZ_FINAL : public nsINodeList
{
public:
nsChildContentList(nsINode* aNode)
: mNode(aNode)
{
SetIsDOMBinding();
}
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsChildContentList)
// nsWrapperCache
virtual JSObject* WrapObject(JSContext *cx, JSObject *scope,
bool *triedToWrap);
// nsIDOMNodeList interface
NS_DECL_NSIDOMNODELIST
// nsINodeList interface
virtual PRInt32 IndexOf(nsIContent* aContent);
void DropReference()
{
mNode = nullptr;
}
virtual nsINode* GetParentObject()
{
return mNode;
}
private:
// The node whose children make up the list (weak reference)
nsINode* mNode;
};
/**
* A tearoff class for nsGenericElement to implement additional interfaces
*/
class nsNode3Tearoff : public nsIDOMXPathNSResolver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_CYCLE_COLLECTION_CLASS(nsNode3Tearoff)
NS_DECL_NSIDOMXPATHNSRESOLVER
nsNode3Tearoff(nsINode *aNode) : mNode(aNode)
{
}
protected:
virtual ~nsNode3Tearoff() {}
private:
nsCOMPtr<nsINode> mNode;
};
/**
* A class that implements nsIWeakReference
*/
class nsNodeWeakReference MOZ_FINAL : public nsIWeakReference
{
public:
nsNodeWeakReference(nsINode* aNode)
: mNode(aNode)
{
}
~nsNodeWeakReference();
// nsISupports
NS_DECL_ISUPPORTS
// nsIWeakReference
NS_DECL_NSIWEAKREFERENCE
void NoticeNodeDestruction()
{
mNode = nullptr;
}
private:
nsINode* mNode;
};
/**
* Tearoff to use for nodes to implement nsISupportsWeakReference
*/
class nsNodeSupportsWeakRefTearoff MOZ_FINAL : public nsISupportsWeakReference
{
public:
nsNodeSupportsWeakRefTearoff(nsINode* aNode)
: mNode(aNode)
{
}
// nsISupports
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
// nsISupportsWeakReference
NS_DECL_NSISUPPORTSWEAKREFERENCE
NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSupportsWeakRefTearoff)
private:
nsCOMPtr<nsINode> mNode;
};
/**
* A tearoff class for nsGenericElement to implement NodeSelector
*/
class nsNodeSelectorTearoff MOZ_FINAL : public nsIDOMNodeSelector
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIDOMNODESELECTOR
NS_DECL_CYCLE_COLLECTION_CLASS(nsNodeSelectorTearoff)
nsNodeSelectorTearoff(nsINode *aNode) : mNode(aNode)
{
}
private:
~nsNodeSelectorTearoff() {}
private:
nsCOMPtr<nsINode> mNode;
};
// Forward declare to allow being a friend
class nsTouchEventReceiverTearoff;
class nsInlineEventHandlersTearoff;
/**
* A generic base class for DOM elements, implementing many nsIContent,
* nsIDOMNode and nsIDOMElement methods.
@ -210,33 +66,6 @@ class nsGenericElement : public mozilla::dom::Element
{
public:
nsGenericElement(already_AddRefed<nsINodeInfo> aNodeInfo);
virtual ~nsGenericElement();
friend class nsTouchEventReceiverTearoff;
friend class nsInlineEventHandlersTearoff;
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_SIZEOF_EXCLUDING_THIS
/**
* Called during QueryInterface to give the binding manager a chance to
* get an interface for this element.
*/
nsresult PostQueryInterface(REFNSIID aIID, void** aInstancePtr);
// nsINode interface methods
virtual PRUint32 GetChildCount() const;
virtual nsIContent *GetChildAt(PRUint32 aIndex) const;
virtual nsIContent * const * GetChildArray(PRUint32* aChildCount) const;
virtual PRInt32 IndexOf(nsINode* aPossibleChild) const;
virtual nsresult InsertChildAt(nsIContent* aKid, PRUint32 aIndex,
bool aNotify);
virtual void RemoveChildAt(PRUint32 aIndex, bool aNotify);
NS_IMETHOD GetTextContent(nsAString &aTextContent);
NS_IMETHOD SetTextContent(const nsAString& aTextContent);
// nsIContent interface methods
virtual void UpdateEditableState(bool aNotify);
virtual nsresult BindToTree(nsIDocument* aDocument, nsIContent* aParent,
@ -244,7 +73,6 @@ public:
bool aCompileEventHandlers);
virtual void UnbindFromTree(bool aDeep = true,
bool aNullParent = true);
virtual already_AddRefed<nsINodeList> GetChildren(PRUint32 aFilter);
virtual nsIAtom *GetClassAttributeName() const;
virtual already_AddRefed<nsINodeInfo> GetExistingAttrNameFromQName(const nsAString& aStr) const;
nsresult SetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
@ -295,25 +123,7 @@ public:
bool aNotify);
virtual const nsAttrName* GetAttrNameAt(PRUint32 aIndex) const;
virtual PRUint32 GetAttrCount() const;
virtual const nsTextFragment *GetText();
virtual PRUint32 TextLength() const;
virtual nsresult SetText(const PRUnichar* aBuffer, PRUint32 aLength,
bool aNotify);
// Need to implement this here too to avoid hiding.
nsresult SetText(const nsAString& aStr, bool aNotify)
{
return SetText(aStr.BeginReading(), aStr.Length(), aNotify);
}
virtual nsresult AppendText(const PRUnichar* aBuffer, PRUint32 aLength,
bool aNotify);
virtual bool TextIsOnlyWhitespace();
virtual void AppendTextTo(nsAString& aResult);
virtual nsIContent *GetBindingParent() const;
virtual bool IsNodeOfType(PRUint32 aFlags) const;
virtual bool IsLink(nsIURI** aURI) const;
virtual void DestroyContent();
virtual void SaveSubtreeState();
virtual nsISMILAttr* GetAnimatedAttr(PRInt32 /*aNamespaceID*/, nsIAtom* /*aName*/)
{
@ -335,8 +145,6 @@ public:
void ListAttributes(FILE* out) const;
#endif
virtual const nsAttrValue* DoGetClasses() const;
NS_IMETHOD WalkContentStyleRules(nsRuleWalker* aRuleWalker);
virtual mozilla::css::StyleRule* GetInlineStyleRule();
virtual nsresult SetInlineStyleRule(mozilla::css::StyleRule* aStyleRule,
const nsAString* aSerialized,
@ -373,50 +181,9 @@ private:
PRUint32 aMapCount);
public:
// nsIDOMNode method implementation
NS_IMETHOD GetNodeName(nsAString& aNodeName);
NS_IMETHOD GetLocalName(nsAString& aLocalName);
NS_IMETHOD GetNodeValue(nsAString& aNodeValue);
NS_IMETHOD SetNodeValue(const nsAString& aNodeValue);
NS_IMETHOD GetNodeType(PRUint16* aNodeType);
NS_IMETHOD GetAttributes(nsIDOMNamedNodeMap** aAttributes);
NS_IMETHOD GetNamespaceURI(nsAString& aNamespaceURI);
NS_IMETHOD GetPrefix(nsAString& aPrefix);
NS_IMETHOD IsSupported(const nsAString& aFeature,
const nsAString& aVersion, bool* aReturn);
NS_IMETHOD HasAttributes(bool* aHasAttributes);
NS_IMETHOD HasChildNodes(bool* aHasChildNodes);
nsresult InsertBefore(nsIDOMNode* aNewChild, nsIDOMNode* aRefChild,
nsIDOMNode** aReturn)
{
return ReplaceOrInsertBefore(false, aNewChild, aRefChild, aReturn);
}
nsresult ReplaceChild(nsIDOMNode* aNewChild, nsIDOMNode* aOldChild,
nsIDOMNode** aReturn)
{
return ReplaceOrInsertBefore(true, aNewChild, aOldChild, aReturn);
}
nsresult RemoveChild(nsIDOMNode* aOldChild, nsIDOMNode** aReturn)
{
return nsINode::RemoveChild(aOldChild, aReturn);
}
nsresult AppendChild(nsIDOMNode* aNewChild, nsIDOMNode** aReturn)
{
return InsertBefore(aNewChild, nullptr, aReturn);
}
// nsIDOMElement method implementation
NS_DECL_NSIDOMELEMENT
nsresult CloneNode(bool aDeep, PRUint8 aOptionalArgc, nsIDOMNode **aResult)
{
if (!aOptionalArgc) {
aDeep = true;
}
return nsNodeUtils::CloneNodeImpl(this, aDeep, true, aResult);
}
//----------------------------------------
/**
@ -435,38 +202,8 @@ public:
*/
nsresult LeaveLink(nsPresContext* aPresContext);
/**
* Check whether a spec feature/version is supported.
* @param aObject the object, which should support the feature,
* for example nsIDOMNode or nsIDOMDOMImplementation
* @param aFeature the feature ("Views", "Core", "HTML", "Range" ...)
* @param aVersion the version ("1.0", "2.0", ...)
* @param aReturn whether the feature is supported or not [OUT]
*/
static nsresult InternalIsSupported(nsISupports* aObject,
const nsAString& aFeature,
const nsAString& aVersion,
bool* aReturn);
static bool ShouldBlur(nsIContent *aContent);
/**
* If there are listeners for DOMNodeInserted event, fires the event on all
* aNodes
*/
static void FireNodeInserted(nsIDocument* aDoc,
nsINode* aParent,
nsTArray<nsCOMPtr<nsIContent> >& aNodes);
/**
* Helper methods for implementing querySelector/querySelectorAll
*/
static nsIContent* doQuerySelector(nsINode* aRoot, const nsAString& aSelector,
nsresult *aResult);
static nsresult doQuerySelectorAll(nsINode* aRoot,
const nsAString& aSelector,
nsIDOMNodeList **aReturn);
/**
* Method to create and dispatch a left-click event loosely based on
* aSourceEvent. If aFullDispatch is true, the event will be dispatched
@ -582,48 +319,10 @@ public:
*/
virtual nsAttrInfo GetAttrInfo(PRInt32 aNamespaceID, nsIAtom* aName) const;
NS_DECL_CYCLE_COLLECTION_SKIPPABLE_SCRIPT_HOLDER_CLASS(nsGenericElement)
virtual void NodeInfoChanged(nsINodeInfo* aOldNodeInfo)
{
}
/**
* Fire a DOMNodeRemoved mutation event for all children of this node
*/
void FireNodeRemovedForChildren();
virtual bool OwnedOnlyByTheDOMTree()
{
PRUint32 rc = mRefCnt.get();
if (GetParent()) {
--rc;
}
rc -= mAttrsAndChildren.ChildCount();
return rc == 0;
}
virtual bool IsPurple()
{
return mRefCnt.IsPurple();
}
virtual void RemovePurple()
{
mRefCnt.RemovePurple();
}
static void ClearContentUnbinder();
static bool CanSkip(nsINode* aNode, bool aRemovingAllowed);
static bool CanSkipInCC(nsINode* aNode);
static bool CanSkipThis(nsINode* aNode);
static void MarkNodeChildren(nsINode* aNode);
static void InitCCCallbacks();
static void MarkUserData(void* aObject, nsIAtom* aKey, void* aChild,
void *aData);
static void MarkUserDataHandler(void* aObject, nsIAtom* aKey, void* aChild,
void* aData);
/**
* Parse a string into an nsAttrValue for a CORS attribute. This
* never fails. The resulting value is an enumerated value whose
@ -770,12 +469,6 @@ protected:
virtual nsEventListenerManager*
GetEventListenerManagerForAttr(nsIAtom* aAttrName, bool* aDefer);
/**
* Copy attributes and state to another element
* @param aDest the object to copy to
*/
nsresult CopyInnerTo(nsGenericElement* aDest);
/**
* Internal hook for converting an attribute name-string to an atomized name
*/
@ -808,94 +501,6 @@ protected:
const nsAString& aLocalName,
nsIDOMAttr** aReturn);
public:
// Because of a bug in MS C++ compiler nsDOMSlots must be declared public,
// otherwise nsXULElement::nsXULSlots doesn't compile.
/**
* There are a set of DOM- and scripting-specific instance variables
* that may only be instantiated when a content object is accessed
* through the DOM. Rather than burn actual slots in the content
* objects for each of these instance variables, we put them off
* in a side structure that's only allocated when the content is
* accessed through the DOM.
*/
class nsDOMSlots : public nsINode::nsSlots
{
public:
nsDOMSlots();
virtual ~nsDOMSlots();
void Traverse(nsCycleCollectionTraversalCallback &cb, bool aIsXUL);
void Unlink(bool aIsXUL);
/**
* The .style attribute (an interface that forwards to the actual
* style rules)
* @see nsGenericHTMLElement::GetStyle
*/
nsCOMPtr<nsICSSDeclaration> mStyle;
/**
* The .dataset attribute.
* @see nsGenericHTMLElement::GetDataset
*/
nsIDOMDOMStringMap* mDataset; // [Weak]
/**
* SMIL Overridde style rules (for SMIL animation of CSS properties)
* @see nsIContent::GetSMILOverrideStyle
*/
nsCOMPtr<nsICSSDeclaration> mSMILOverrideStyle;
/**
* Holds any SMIL override style rules for this element.
*/
nsRefPtr<mozilla::css::StyleRule> mSMILOverrideStyleRule;
/**
* An object implementing nsIDOMNamedNodeMap for this content (attributes)
* @see nsGenericElement::GetAttributes
*/
nsRefPtr<nsDOMAttributeMap> mAttributeMap;
union {
/**
* The nearest enclosing content node with a binding that created us.
* @see nsGenericElement::GetBindingParent
*/
nsIContent* mBindingParent; // [Weak]
/**
* The controllers of the XUL Element.
*/
nsIControllers* mControllers; // [OWNER]
};
/**
* An object implementing the .children property for this element.
*/
nsRefPtr<nsContentList> mChildrenList;
/**
* An object implementing the .classList property for this element.
*/
nsRefPtr<nsDOMTokenList> mClassList;
};
protected:
// Override from nsINode
virtual nsINode::nsSlots* CreateSlots();
nsDOMSlots *DOMSlots()
{
return static_cast<nsDOMSlots*>(GetSlots());
}
nsDOMSlots *GetExistingDOMSlots() const
{
return static_cast<nsDOMSlots*>(GetExistingSlots());
}
void RegisterFreezableElement() {
OwnerDoc()->RegisterFreezableElement(this);
}
@ -966,12 +571,6 @@ protected:
*/
virtual void GetLinkTarget(nsAString& aTarget);
friend class ContentUnbinder;
/**
* Array containing all attributes and children for this element
*/
nsAttrAndChildArray mAttrsAndChildren;
private:
/**
* Get this element's client area rect in app units.
@ -980,8 +579,6 @@ private:
nsRect GetClientAreaRect();
nsIScrollableFrame* GetScrollFrame(nsIFrame **aStyledFrame = nullptr);
nsContentList* GetChildrenList();
};
/**
@ -1060,63 +657,4 @@ _elementName::Clone(nsINodeInfo *aNodeInfo, nsINode **aResult) const \
return SetAttr(kNameSpaceID_None, nsGkAtoms::_atom, nullptr, aValue, true); \
}
/**
* Tearoff class to implement nsITouchEventReceiver
*/
class nsTouchEventReceiverTearoff MOZ_FINAL : public nsITouchEventReceiver
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_FORWARD_NSITOUCHEVENTRECEIVER(mElement->)
NS_DECL_CYCLE_COLLECTION_CLASS(nsTouchEventReceiverTearoff)
nsTouchEventReceiverTearoff(nsGenericElement *aElement) : mElement(aElement)
{
}
private:
nsRefPtr<nsGenericElement> mElement;
};
/**
* Tearoff class to implement nsIInlineEventHandlers
*/
class nsInlineEventHandlersTearoff MOZ_FINAL : public nsIInlineEventHandlers
{
public:
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_FORWARD_NSIINLINEEVENTHANDLERS(mElement->)
NS_DECL_CYCLE_COLLECTION_CLASS(nsInlineEventHandlersTearoff)
nsInlineEventHandlersTearoff(nsGenericElement *aElement) : mElement(aElement)
{
}
private:
nsRefPtr<nsGenericElement> mElement;
};
#define NS_ELEMENT_INTERFACE_TABLE_TO_MAP_SEGUE \
rv = nsGenericElement::QueryInterface(aIID, aInstancePtr); \
if (NS_SUCCEEDED(rv)) \
return rv; \
\
NS_OFFSET_AND_INTERFACE_TABLE_TO_MAP_SEGUE
#define NS_ELEMENT_INTERFACE_MAP_END \
{ \
return PostQueryInterface(aIID, aInstancePtr); \
} \
\
NS_ADDREF(foundInterface); \
\
*aInstancePtr = foundInterface; \
\
return NS_OK; \
}
#endif /* nsGenericElement_h___ */

View File

@ -2603,8 +2603,8 @@ GetRequestBody(ArrayBuffer* aArrayBuffer, nsIInputStream** aResult,
aContentType.SetIsVoid(true);
aCharset.Truncate();
PRInt32 length = aArrayBuffer->mLength;
char* data = reinterpret_cast<char*>(aArrayBuffer->mData);
PRInt32 length = aArrayBuffer->Length();
char* data = reinterpret_cast<char*>(aArrayBuffer->Data());
nsCOMPtr<nsIInputStream> stream;
nsresult rv = NS_NewByteInputStream(getter_AddRefs(stream), data, length,

View File

@ -9,6 +9,8 @@
#include "mozilla/dom/ImageData.h"
#include "XPCQuickStubs.h"
static bool
GetImageData(JSContext* cx, JS::Value& imageData,
uint32_t* width, uint32_t* height, JS::Anchor<JSObject*>* array)

View File

@ -892,7 +892,7 @@ public:
WebGLfloat z, WebGLfloat w);
void Uniform1iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
Uniform1iv_base(location, arr.mLength, arr.mData);
Uniform1iv_base(location, arr.Length(), arr.Data());
}
void Uniform1iv(WebGLUniformLocation* location,
const dom::Sequence<WebGLint>& arr) {
@ -902,7 +902,7 @@ public:
const WebGLint* data);
void Uniform2iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
Uniform2iv_base(location, arr.mLength, arr.mData);
Uniform2iv_base(location, arr.Length(), arr.Data());
}
void Uniform2iv(WebGLUniformLocation* location,
const dom::Sequence<WebGLint>& arr) {
@ -912,7 +912,7 @@ public:
const WebGLint* data);
void Uniform3iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
Uniform3iv_base(location, arr.mLength, arr.mData);
Uniform3iv_base(location, arr.Length(), arr.Data());
}
void Uniform3iv(WebGLUniformLocation* location,
const dom::Sequence<WebGLint>& arr) {
@ -922,7 +922,7 @@ public:
const WebGLint* data);
void Uniform4iv(WebGLUniformLocation* location, dom::Int32Array& arr) {
Uniform4iv_base(location, arr.mLength, arr.mData);
Uniform4iv_base(location, arr.Length(), arr.Data());
}
void Uniform4iv(WebGLUniformLocation* location,
const dom::Sequence<WebGLint>& arr) {
@ -932,7 +932,7 @@ public:
const WebGLint* data);
void Uniform1fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
Uniform1fv_base(location, arr.mLength, arr.mData);
Uniform1fv_base(location, arr.Length(), arr.Data());
}
void Uniform1fv(WebGLUniformLocation* location,
const dom::Sequence<WebGLfloat>& arr) {
@ -942,7 +942,7 @@ public:
const WebGLfloat* data);
void Uniform2fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
Uniform2fv_base(location, arr.mLength, arr.mData);
Uniform2fv_base(location, arr.Length(), arr.Data());
}
void Uniform2fv(WebGLUniformLocation* location,
const dom::Sequence<WebGLfloat>& arr) {
@ -952,7 +952,7 @@ public:
const WebGLfloat* data);
void Uniform3fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
Uniform3fv_base(location, arr.mLength, arr.mData);
Uniform3fv_base(location, arr.Length(), arr.Data());
}
void Uniform3fv(WebGLUniformLocation* location,
const dom::Sequence<WebGLfloat>& arr) {
@ -962,7 +962,7 @@ public:
const WebGLfloat* data);
void Uniform4fv(WebGLUniformLocation* location, dom::Float32Array& arr) {
Uniform4fv_base(location, arr.mLength, arr.mData);
Uniform4fv_base(location, arr.Length(), arr.Data());
}
void Uniform4fv(WebGLUniformLocation* location,
const dom::Sequence<WebGLfloat>& arr) {
@ -974,7 +974,7 @@ public:
void UniformMatrix2fv(WebGLUniformLocation* location,
WebGLboolean transpose,
dom::Float32Array &value) {
UniformMatrix2fv_base(location, transpose, value.mLength, value.mData);
UniformMatrix2fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix2fv(WebGLUniformLocation* location,
WebGLboolean transpose,
@ -989,7 +989,7 @@ public:
void UniformMatrix3fv(WebGLUniformLocation* location,
WebGLboolean transpose,
dom::Float32Array &value) {
UniformMatrix3fv_base(location, transpose, value.mLength, value.mData);
UniformMatrix3fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix3fv(WebGLUniformLocation* location,
WebGLboolean transpose,
@ -1004,7 +1004,7 @@ public:
void UniformMatrix4fv(WebGLUniformLocation* location,
WebGLboolean transpose,
dom::Float32Array &value) {
UniformMatrix4fv_base(location, transpose, value.mLength, value.mData);
UniformMatrix4fv_base(location, transpose, value.Length(), value.Data());
}
void UniformMatrix4fv(WebGLUniformLocation* location,
WebGLboolean transpose,
@ -1027,7 +1027,7 @@ public:
WebGLfloat x2, WebGLfloat x3);
void VertexAttrib1fv(WebGLuint idx, dom::Float32Array &arr) {
VertexAttrib1fv_base(idx, arr.mLength, arr.mData);
VertexAttrib1fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib1fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
VertexAttrib1fv_base(idx, arr.Length(), arr.Elements());
@ -1036,7 +1036,7 @@ public:
const WebGLfloat* ptr);
void VertexAttrib2fv(WebGLuint idx, dom::Float32Array &arr) {
VertexAttrib2fv_base(idx, arr.mLength, arr.mData);
VertexAttrib2fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib2fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
VertexAttrib2fv_base(idx, arr.Length(), arr.Elements());
@ -1045,7 +1045,7 @@ public:
const WebGLfloat* ptr);
void VertexAttrib3fv(WebGLuint idx, dom::Float32Array &arr) {
VertexAttrib3fv_base(idx, arr.mLength, arr.mData);
VertexAttrib3fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib3fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
VertexAttrib3fv_base(idx, arr.Length(), arr.Elements());
@ -1054,7 +1054,7 @@ public:
const WebGLfloat* ptr);
void VertexAttrib4fv(WebGLuint idx, dom::Float32Array &arr) {
VertexAttrib4fv_base(idx, arr.mLength, arr.mData);
VertexAttrib4fv_base(idx, arr.Length(), arr.Data());
}
void VertexAttrib4fv(WebGLuint idx, const dom::Sequence<WebGLfloat>& arr) {
VertexAttrib4fv_base(idx, arr.Length(), arr.Elements());

View File

@ -546,16 +546,16 @@ WebGLContext::BufferData(WebGLenum target, ArrayBuffer *data, WebGLenum usage)
MakeContextCurrent();
GLenum error = CheckedBufferData(target, data->mLength, data->mData, usage);
GLenum error = CheckedBufferData(target, data->Length(), data->Data(), usage);
if (error) {
GenerateWarning("bufferData generated error %s", ErrorName(error));
return;
}
boundBuffer->SetByteLength(data->mLength);
boundBuffer->SetByteLength(data->Length());
boundBuffer->InvalidateCachedMaxElements();
if (!boundBuffer->CopyDataIfElementArray(data->mData))
if (!boundBuffer->CopyDataIfElementArray(data->Data()))
return ErrorOutOfMemory("bufferData: out of memory");
}
@ -583,15 +583,15 @@ WebGLContext::BufferData(WebGLenum target, ArrayBufferView& data, WebGLenum usag
MakeContextCurrent();
GLenum error = CheckedBufferData(target, data.mLength, data.mData, usage);
GLenum error = CheckedBufferData(target, data.Length(), data.Data(), usage);
if (error) {
GenerateWarning("bufferData generated error %s", ErrorName(error));
return;
}
boundBuffer->SetByteLength(data.mLength);
boundBuffer->SetByteLength(data.Length());
boundBuffer->InvalidateCachedMaxElements();
if (!boundBuffer->CopyDataIfElementArray(data.mData))
if (!boundBuffer->CopyDataIfElementArray(data.Data()))
return ErrorOutOfMemory("bufferData: out of memory");
}
@ -654,7 +654,7 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->mLength;
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data->Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
@ -664,10 +664,10 @@ WebGLContext::BufferSubData(GLenum target, WebGLsizeiptr byteOffset,
MakeContextCurrent();
boundBuffer->CopySubDataIfElementArray(byteOffset, data->mLength, data->mData);
boundBuffer->CopySubDataIfElementArray(byteOffset, data->Length(), data->Data());
boundBuffer->InvalidateCachedMaxElements();
gl->fBufferSubData(target, byteOffset, data->mLength, data->mData);
gl->fBufferSubData(target, byteOffset, data->Length(), data->Data());
}
void
@ -693,7 +693,7 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
if (!boundBuffer)
return ErrorInvalidOperation("bufferSubData: no buffer bound!");
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.mLength;
CheckedUint32 checked_neededByteLength = CheckedUint32(byteOffset) + data.Length();
if (!checked_neededByteLength.isValid())
return ErrorInvalidOperation("bufferSubData: integer overflow computing the needed byte length");
@ -703,10 +703,10 @@ WebGLContext::BufferSubData(WebGLenum target, WebGLsizeiptr byteOffset,
MakeContextCurrent();
boundBuffer->CopySubDataIfElementArray(byteOffset, data.mLength, data.mData);
boundBuffer->CopySubDataIfElementArray(byteOffset, data.Length(), data.Data());
boundBuffer->InvalidateCachedMaxElements();
gl->fBufferSubData(target, byteOffset, data.mLength, data.mData);
gl->fBufferSubData(target, byteOffset, data.Length(), data.Data());
}
NS_IMETHODIMP
@ -3876,9 +3876,9 @@ WebGLContext::ReadPixels(WebGLint x, WebGLint y, WebGLsizei width,
WebGLsizei framebufferWidth = framebufferRect ? framebufferRect->Width() : 0;
WebGLsizei framebufferHeight = framebufferRect ? framebufferRect->Height() : 0;
void* data = pixels->mData;
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->mObj, NULL);
int dataType = JS_GetTypedArrayType(pixels->mObj, NULL);
void* data = pixels->Data();
uint32_t dataByteLen = JS_GetTypedArrayByteLength(pixels->Obj(), NULL);
int dataType = JS_GetTypedArrayType(pixels->Obj(), NULL);
uint32_t channels = 0;
@ -5146,12 +5146,12 @@ WebGLContext::CompressedTexImage2D(WebGLenum target, WebGLint level, WebGLenum i
return;
}
uint32_t byteLength = view.mLength;
uint32_t byteLength = view.Length();
if (!ValidateCompressedTextureSize(level, internalformat, width, height, byteLength, "compressedTexImage2D")) {
return;
}
gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.mData);
gl->fCompressedTexImage2D(target, level, internalformat, width, height, border, byteLength, view.Data());
tex->SetImageInfo(target, level, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE);
}
@ -5207,7 +5207,7 @@ WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint
return;
}
uint32_t byteLength = view.mLength;
uint32_t byteLength = view.Length();
if (!ValidateCompressedTextureSize(level, format, width, height, byteLength, "compressedTexSubImage2D")) {
return;
}
@ -5252,7 +5252,7 @@ WebGLContext::CompressedTexSubImage2D(WebGLenum target, WebGLint level, WebGLint
}
}
gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.mData);
gl->fCompressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, byteLength, view.Data());
return;
}
@ -5742,9 +5742,9 @@ WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return;
return TexImage2D_base(target, level, internalformat, width, height, 0, border, format, type,
pixels ? pixels->mData : 0,
pixels ? pixels->mLength : 0,
pixels ? (int)JS_GetTypedArrayType(pixels->mObj, cx) : -1,
pixels ? pixels->Data() : 0,
pixels ? pixels->Length() : 0,
pixels ? (int)JS_GetTypedArrayType(pixels->Obj(), cx) : -1,
WebGLTexelConversions::Auto, false);
}
@ -5783,7 +5783,7 @@ WebGLContext::TexImage2D(JSContext* cx, WebGLenum target, WebGLint level,
Uint8ClampedArray arr(cx, pixels->GetDataObject());
return TexImage2D_base(target, level, internalformat, pixels->GetWidth(),
pixels->GetHeight(), 4*pixels->GetWidth(), 0,
format, type, arr.mData, arr.mLength, -1,
format, type, arr.Data(), arr.Length(), -1,
WebGLTexelConversions::RGBA8, false);
}
@ -5948,8 +5948,8 @@ WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return TexSubImage2D_base(target, level, xoffset, yoffset,
width, height, 0, format, type,
pixels->mData, pixels->mLength,
JS_GetTypedArrayType(pixels->mObj, cx),
pixels->Data(), pixels->Length(),
JS_GetTypedArrayType(pixels->Obj(), cx),
WebGLTexelConversions::Auto, false);
}
@ -5994,7 +5994,7 @@ WebGLContext::TexSubImage2D(JSContext* cx, WebGLenum target, WebGLint level,
return TexSubImage2D_base(target, level, xoffset, yoffset,
pixels->GetWidth(), pixels->GetHeight(),
4*pixels->GetWidth(), format, type,
arr.mData, arr.mLength,
arr.Data(), arr.Length(),
-1,
WebGLTexelConversions::RGBA8, false);
}

View File

@ -88,6 +88,9 @@
#include "mozilla/ipc/PDocumentRendererParent.h"
#include "mozilla/unused.h"
#include "CustomQS_Canvas.h"
#include "jsfriendapi.h"
// windows.h (included by chromium code) defines this, in its infinite wisdom
#undef DrawText
@ -4036,12 +4039,62 @@ nsCanvasRenderingContext2D::EnsurePremultiplyTable() {
}
}
// void putImageData (in ImageData d, in float x, in float y);
// void putImageData (in jsval d, in double x, in double y);
// void putImageData (in jsval d, in double x, in double y, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);
NS_IMETHODIMP
nsCanvasRenderingContext2D::PutImageData()
nsCanvasRenderingContext2D::PutImageData(const JS::Value& dataArg,
double xd, double yd,
double dirtyXd, double dirtyYd,
double dirtyWidthd,
double dirtyHeightd,
JSContext* cx,
PRUint8 optional_argc)
{
/* Should never be called -- PutImageData_explicit is the QS entry point */
return NS_ERROR_NOT_IMPLEMENTED;
// GetImageData wants a non-const JS::Value
JS::Value dataVal(dataArg);
// Total copy/paste from the quickstub
uint32_t w, h;
JS::Anchor<JSObject*> darray;
if (!::GetImageData(cx, dataVal, &w, &h, &darray)) {
return NS_ERROR_UNEXPECTED;
}
if (!FloatValidate(xd, yd)) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
int32_t x = JS_DoubleToInt32(xd);
int32_t y = JS_DoubleToInt32(yd);
// The dirty rect is optional
bool hasDirtyRect = false;
int32_t dirtyX = 0, dirtyY = 0, dirtyWidth = w, dirtyHeight = h;
if (optional_argc != 0 && optional_argc != 4) {
// Wrong number of arguments
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
if (optional_argc == 4) {
if (!FloatValidate(dirtyXd, dirtyYd, dirtyWidthd, dirtyHeightd)) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
dirtyX = JS_DoubleToInt32(dirtyXd);
dirtyY = JS_DoubleToInt32(dirtyYd);
dirtyWidth = JS_DoubleToInt32(dirtyWidthd);
dirtyHeight = JS_DoubleToInt32(dirtyHeightd);
hasDirtyRect = true;
}
PRUint8* data =
reinterpret_cast<PRUint8*>(JS_GetArrayBufferViewData(darray.get(), cx));
uint32_t byteLength = JS_GetTypedArrayByteLength(darray.get(), cx);
return PutImageData_explicit(x, y, w, h, data, byteLength, hasDirtyRect,
dirtyX, dirtyY, dirtyWidth, dirtyHeight);
}
NS_IMETHODIMP
@ -4167,11 +4220,76 @@ nsCanvasRenderingContext2D::GetThebesSurface(gfxASurface **surface)
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::CreateImageData()
static nsresult
CreateImageData(JSContext* cx, uint32_t w, uint32_t h,
nsIDOMImageData** retval)
{
/* Should never be called; handled entirely in the quickstub */
return NS_ERROR_NOT_IMPLEMENTED;
using mozilla::CheckedInt;
if (w == 0)
w = 1;
if (h == 0)
h = 1;
CheckedInt<uint32_t> len = CheckedInt<uint32_t>(w) * h * 4;
if (!len.isValid()) {
return NS_ERROR_DOM_INDEX_SIZE_ERR;
}
// Create the fast typed array; it's initialized to 0 by default.
JSObject* darray = JS_NewUint8ClampedArray(cx, len.value());
JS::AutoObjectRooter rd(cx, darray);
if (!darray) {
return NS_ERROR_OUT_OF_MEMORY;
}
nsRefPtr<mozilla::dom::ImageData> imageData =
new mozilla::dom::ImageData(w, h, *darray);
imageData.forget(retval);
return NS_OK;
}
NS_IMETHODIMP
nsCanvasRenderingContext2D::CreateImageData(const JS::Value &a1,
const JS::Value &a2,
JSContext* cx,
PRUint8 optional_argc,
nsIDOMImageData** retval)
{
// GetImageData wants mutable jsvals, so make copies
JS::Value arg1(a1);
JS::Value arg2(a2);
// Forwarding to the quickstub leads to pain and suffering, so
// we'll do this the hard way.
if (optional_argc == 0) {
uint32_t data_width, data_height;
JS::Anchor<JSObject*> darray;
if (!::GetImageData(cx, arg1, &data_width, &data_height, &darray)) {
return NS_ERROR_FAILURE;
}
return ::CreateImageData(cx, data_width, data_height, retval);
}
// This is total copy/paste from the quickstub code
double width, height;
if (!JS_ValueToNumber(cx, arg1, &width) ||
!JS_ValueToNumber(cx, arg2, &height))
return NS_ERROR_FAILURE;
if (!FloatValidate(width, height))
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
if (!width || !height)
return NS_ERROR_DOM_INDEX_SIZE_ERR;
int32_t wi = JS_DoubleToInt32(width);
int32_t hi = JS_DoubleToInt32(height);
uint32_t w = NS_ABS(wi);
uint32_t h = NS_ABS(hi);
return ::CreateImageData(cx, w, h, retval);
}
NS_IMETHODIMP

View File

@ -4352,7 +4352,7 @@ nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData->GetWidth(), imageData->GetHeight(),
arr.mData, arr.mLength, false, 0, 0, 0, 0);
arr.Data(), arr.Length(), false, 0, 0, 0, 0);
}
void
@ -4372,7 +4372,7 @@ nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
error = PutImageData_explicit(JS_DoubleToInt32(dx), JS_DoubleToInt32(dy),
imageData->GetWidth(), imageData->GetHeight(),
arr.mData, arr.mLength, true,
arr.Data(), arr.Length(), true,
JS_DoubleToInt32(dirtyX),
JS_DoubleToInt32(dirtyY),
JS_DoubleToInt32(dirtyWidth),
@ -4380,10 +4380,14 @@ nsCanvasRenderingContext2DAzure::PutImageData(JSContext* cx,
}
// void putImageData (in ImageData d, in float x, in float y);
// void putImageData (in ImageData d, in double x, in double y, in double dirtyX, in double dirtyY, in double dirtyWidth, in double dirtyHeight);
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::PutImageData()
nsCanvasRenderingContext2DAzure::PutImageData(const JS::Value&, double, double,
double, double, double, double,
JSContext*, PRUint8)
{
/* Should never be called -- PutImageData_explicit is the QS entry point */
/* Should never be called -- the new binding code handles it, and
C++ callers should call PutImageData_explicit */
return NS_ERROR_NOT_IMPLEMENTED;
}
@ -4587,9 +4591,13 @@ nsCanvasRenderingContext2DAzure::CreateImageData(JSContext* cx,
}
NS_IMETHODIMP
nsCanvasRenderingContext2DAzure::CreateImageData()
nsCanvasRenderingContext2DAzure::CreateImageData(const JS::Value &arg1,
const JS::Value &arg2,
JSContext* cx,
PRUint8 optional_argc,
nsIDOMImageData** retval)
{
/* Should never be called; handled entirely in the quickstub */
/* Should never be called; handled entirely in new bindings */
return NS_ERROR_NOT_IMPLEMENTED;
}

View File

@ -60,7 +60,6 @@ CPPSRCS = \
nsDOMScrollAreaEvent.cpp \
nsDOMTransitionEvent.cpp \
nsDOMAnimationEvent.cpp \
nsDOMSettingsEvent.cpp \
nsDOMTouchEvent.cpp \
nsDOMCompositionEvent.cpp \
$(NULL)

View File

@ -1,77 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nsDOMClassInfoID.h"
#include "nsDOMSettingsEvent.h"
#include "DictionaryHelpers.h"
NS_IMPL_CYCLE_COLLECTION_CLASS(nsDOMMozSettingsEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsDOMMozSettingsEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSettingValue)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsDOMMozSettingsEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSettingValue)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
DOMCI_DATA(MozSettingsEvent, nsDOMMozSettingsEvent)
NS_INTERFACE_MAP_BEGIN(nsDOMMozSettingsEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMMozSettingsEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(MozSettingsEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
NS_IMPL_ADDREF_INHERITED(nsDOMMozSettingsEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(nsDOMMozSettingsEvent, nsDOMEvent)
NS_IMETHODIMP
nsDOMMozSettingsEvent::GetSettingName(nsAString & aSettingName)
{
aSettingName = mSettingName;
return NS_OK;
}
NS_IMETHODIMP
nsDOMMozSettingsEvent::GetSettingValue(nsIVariant** aSettingValue)
{
NS_IF_ADDREF(*aSettingValue = mSettingValue);
return NS_OK;
}
NS_IMETHODIMP
nsDOMMozSettingsEvent::InitMozSettingsEvent(const nsAString& aType,
bool aCanBubble,
bool aCancelable,
const nsAString &aSettingName,
nsIVariant *aSettingValue)
{
nsresult rv = nsDOMEvent::InitEvent(aType, aCanBubble, aCancelable);
NS_ENSURE_SUCCESS(rv, rv);
mSettingName = aSettingName;
mSettingValue = aSettingValue;
return NS_OK;
}
nsresult
nsDOMMozSettingsEvent::InitFromCtor(const nsAString& aType,
JSContext* aCx, jsval* aVal)
{
mozilla::dom::MozSettingsEventInit d;
nsresult rv = d.Init(aCx, aVal);
NS_ENSURE_SUCCESS(rv, rv);
return InitMozSettingsEvent(aType, d.bubbles, d.cancelable, d.settingName, d.settingValue);
}
nsresult
NS_NewDOMMozSettingsEvent(nsIDOMEvent** aInstancePtrResult,
nsPresContext* aPresContext,
nsEvent* aEvent)
{
nsDOMMozSettingsEvent* e = new nsDOMMozSettingsEvent(aPresContext, aEvent);
return CallQueryInterface(e, aInstancePtrResult);
}

View File

@ -1,33 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef nsDOMSettingsEvent_h__
#define nsDOMSettingsEvent_h__
#include "nsIDOMSettingsManager.h"
#include "nsDOMEvent.h"
class nsDOMMozSettingsEvent : public nsDOMEvent,
public nsIDOMMozSettingsEvent
{
public:
nsDOMMozSettingsEvent(nsPresContext* aPresContext, nsEvent* aEvent)
: nsDOMEvent(aPresContext, aEvent) {}
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(nsDOMMozSettingsEvent, nsDOMEvent)
// Forward to base class
NS_FORWARD_TO_NSDOMEVENT
NS_DECL_NSIDOMMOZSETTINGSEVENT
virtual nsresult InitFromCtor(const nsAString& aType,
JSContext* aCx, jsval* aVal);
private:
nsString mSettingName;
nsCOMPtr<nsIVariant> mSettingValue;
};
#endif // nsDOMSettingsEvent_h__

View File

@ -866,8 +866,7 @@ nsEventDispatcher::CreateEvent(nsPresContext* aPresContext,
if (aEventType.LowerCaseEqualsLiteral("mozsmsevent"))
return NS_NewDOMSmsEvent(aDOMEvent, aPresContext, nullptr);
if (aEventType.LowerCaseEqualsLiteral("storageevent")) {
NS_ADDREF(*aDOMEvent = static_cast<nsDOMEvent*>(new nsDOMStorageEvent()));
return NS_OK;
return NS_NewDOMStorageEvent(aDOMEvent, aPresContext, nsnull);
}

View File

@ -189,7 +189,7 @@ nsHTMLAudioElement::MozCurrentSampleOffset(PRUint64 *aRetVal)
if (position < 0) {
*aRetVal = 0;
} else {
*aRetVal = mAudioStream->GetPositionInFrames() * mChannels;
*aRetVal = position * mChannels;
}
return NS_OK;
}

View File

@ -974,15 +974,27 @@ nsHTMLFormElement::WalkFormElements(nsFormSubmission* aFormSubmission)
nsresult rv = mControls->GetSortedControls(sortedControls);
NS_ENSURE_SUCCESS(rv, rv);
PRUint32 len = sortedControls.Length();
// Hold a reference to the elements so they can't be deleted while
// calling SubmitNamesValues().
for (PRUint32 i = 0; i < len; ++i) {
static_cast<nsGenericHTMLElement*>(sortedControls[i])->AddRef();
}
//
// Walk the list of nodes and call SubmitNamesValues() on the controls
//
PRUint32 len = sortedControls.Length();
for (PRUint32 i = 0; i < len; ++i) {
// Tell the control to submit its name/value pairs to the submission
sortedControls[i]->SubmitNamesValues(aFormSubmission);
}
// Release the references.
for (PRUint32 i = 0; i < len; ++i) {
static_cast<nsGenericHTMLElement*>(sortedControls[i])->Release();
}
return NS_OK;
}

View File

@ -334,8 +334,7 @@ nsHTMLSelectElement::InsertOptionsIntoListRecurse(nsIContent* aOptions,
nsHTMLOptionElement *optElement = nsHTMLOptionElement::FromContent(aOptions);
if (optElement) {
nsresult rv = mOptions->InsertOptionAt(optElement, *aInsertIndex);
NS_ENSURE_SUCCESS(rv, rv);
mOptions->InsertOptionAt(optElement, *aInsertIndex);
(*aInsertIndex)++;
return NS_OK;
}
@ -1809,7 +1808,6 @@ AddOptionsRecurse(nsIContent* aRoot, nsHTMLOptionCollection* aArray)
cur = cur->GetNextSibling()) {
nsHTMLOptionElement* opt = nsHTMLOptionElement::FromContent(cur);
if (opt) {
// If we fail here, then at least we've tried our best
aArray->AppendOption(opt);
} else if (cur->IsHTML(nsGkAtoms::optgroup)) {
AddOptionsRecurse(cur, aArray);

View File

@ -62,9 +62,9 @@ public:
* @param aOption the option to insert
* @param aIndex the index to insert at
*/
bool InsertOptionAt(nsHTMLOptionElement* aOption, PRUint32 aIndex)
void InsertOptionAt(nsHTMLOptionElement* aOption, PRUint32 aIndex)
{
return !!mElements.InsertElementAt(aIndex, aOption);
mElements.InsertElementAt(aIndex, aOption);
}
/**
@ -97,9 +97,9 @@ public:
/**
* Append an option to end of array
*/
bool AppendOption(nsHTMLOptionElement* aOption)
void AppendOption(nsHTMLOptionElement* aOption)
{
return !!mElements.AppendElement(aOption);
mElements.AppendElement(aOption);
}
/**
@ -122,7 +122,8 @@ public:
PRInt32* aIndex);
private:
/** The list of options (holds strong references) */
/** The list of options (holds strong references). This is infallible, so
* various members such as InsertOptionAt are also infallible. */
nsTArray<nsRefPtr<nsHTMLOptionElement> > mElements;
/** The select element that contains this array */
nsHTMLSelectElement* mSelect;

View File

@ -1653,11 +1653,10 @@ nsresult nsOggReader::GetBuffered(nsTimeRanges* aBuffered, PRInt64 aStartTime)
}
else {
// Page is for a stream we don't know about (possibly a chained
// ogg), return an error.
//
// XXX Invalid cast of PageSyncResult to nsresult -- this has numeric
// value 1 and will pass an NS_SUCCEEDED() check (bug 778105)
return (nsresult)PAGE_SYNC_ERROR;
// ogg), return OK to abort the finding any further ranges. This
// prevents us searching through the rest of the media when we
// may not be able to extract timestamps from it.
return NS_OK;
}
}

View File

@ -6,12 +6,13 @@
#ifndef NS_ISMILATTR_H_
#define NS_ISMILATTR_H_
#include "nsStringFwd.h"
#include "nscore.h"
class nsSMILValue;
class nsISMILType;
class nsISMILAnimationElement;
class nsIContent;
class nsAString;
////////////////////////////////////////////////////////////////////////
// nsISMILAttr: A variable targeted by SMIL for animation and can therefore have

View File

@ -26,6 +26,11 @@ public:
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,
double aX2, double aY2);

View File

@ -12,7 +12,7 @@
* types don't need to be exported outside the SVG module.
*/
#include "nsString.h"
#include "nsStringGlue.h"
class nsSVGAngle;
class nsSVGIntegerPair;

View File

@ -2538,7 +2538,8 @@ nsXULDocument::InsertXULOverlayPI(const nsXULPrototypePI* aProtoPI,
// This is needed because the code in ResumeWalk loads the overlays
// by processing the last item of mUnloadedOverlays and removing it
// from the array.
rv = mUnloadedOverlays.InsertObjectAt(uri, 0);
mUnloadedOverlays.InsertElementAt(0, uri);
rv = NS_OK;
} else if (rv == NS_ERROR_MALFORMED_URI) {
// The URL is bad, move along. Don't propagate for now.
// XXX report this to the Error Console (bug 359846)
@ -2585,8 +2586,7 @@ nsXULDocument::AddChromeOverlays()
}
// Same comment as in nsXULDocument::InsertXULOverlayPI
rv = mUnloadedOverlays.InsertObjectAt(uri, 0);
if (NS_FAILED(rv)) break;
mUnloadedOverlays.InsertElementAt(0, uri);
}
return rv;
@ -3052,12 +3052,12 @@ nsXULDocument::ResumeWalk()
mState = eState_Overlay;
// If there are no overlay URIs, then we're done.
PRUint32 count = mUnloadedOverlays.Count();
PRUint32 count = mUnloadedOverlays.Length();
if (! count)
break;
nsCOMPtr<nsIURI> uri = mUnloadedOverlays[count-1];
mUnloadedOverlays.RemoveObjectAt(count-1);
mUnloadedOverlays.RemoveElementAt(count - 1);
bool shouldReturn, failureFromContent;
rv = LoadOverlayInternal(uri, false, &shouldReturn,

View File

@ -345,7 +345,7 @@ protected:
* same order as in the document, then the overlays from the chrome
* registry.
*/
nsCOMArray<nsIURI> mUnloadedOverlays;
nsTArray<nsCOMPtr<nsIURI> > mUnloadedOverlays;
/**
* Load the transcluded script at the specified URI. If the

View File

@ -52,15 +52,15 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_END
static PLDHashOperator
BindingDependenciesTraverser(nsISupports* key,
nsCOMArray<nsXULTemplateResultRDF>* array,
nsXULTemplateQueryProcessorRDF::ResultArray* array,
void* userArg)
{
nsCycleCollectionTraversalCallback *cb =
static_cast<nsCycleCollectionTraversalCallback*>(userArg);
PRInt32 i, count = array->Count();
PRInt32 i, count = array->Length();
for (i = 0; i < count; ++i) {
cb->NoteXPCOMChild(array->ObjectAt(i));
cb->NoteXPCOMChild(array->ElementAt(i));
}
return PL_DHASH_NEXT;
@ -107,7 +107,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsXULTemplateQueryProcessorRDF)
if (tmp->mRuleToBindingsMap.IsInitialized()) {
tmp->mRuleToBindingsMap.EnumerateRead(RuleToBindingTraverser, &cb);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMARRAY(mQueries)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSTARRAY_OF_NSCOMPTR(mQueries)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(nsXULTemplateQueryProcessorRDF)
@ -433,9 +433,7 @@ nsXULTemplateQueryProcessorRDF::CompileQuery(nsIXULTemplateBuilder* aBuilder,
if (NS_FAILED(rv))
return rv;
rv = mQueries.AppendObject(query);
if (NS_FAILED(rv))
return rv;
mQueries.AppendElement(query);
*_retval = query;
NS_ADDREF(*_retval);
@ -472,7 +470,7 @@ nsXULTemplateQueryProcessorRDF::GenerateResults(nsISupports* aDatasource,
}
else {
// clear the cached results
PRInt32 count = mQueries.Count();
PRInt32 count = mQueries.Length();
for (PRInt32 r = 0; r < count; r++) {
mQueries[r]->ClearCachedResults();
}
@ -1013,11 +1011,11 @@ nsXULTemplateQueryProcessorRDF::SynchronizeAll(nsIRDFResource* aSource,
// Get all the matches whose assignments are currently supported
// by aSource and aProperty: we'll need to recompute them.
nsCOMArray<nsXULTemplateResultRDF>* results;
ResultArray* results;
if (!mBindingDependencies.Get(aSource, &results) || !mBuilder)
return NS_OK;
PRUint32 length = results->Count();
PRUint32 length = results->Length();
for (PRUint32 r = 0; r < length; r++) {
nsXULTemplateResultRDF* result = (*results)[r];
@ -1712,38 +1710,32 @@ nsXULTemplateQueryProcessorRDF::GetBindingsForRule(nsIDOMNode* aRuleNode)
return mRuleToBindingsMap.GetWeak(aRuleNode);
}
nsresult
void
nsXULTemplateQueryProcessorRDF::AddBindingDependency(nsXULTemplateResultRDF* aResult,
nsIRDFResource* aResource)
{
nsCOMArray<nsXULTemplateResultRDF>* arr;
ResultArray* arr;
if (!mBindingDependencies.Get(aResource, &arr)) {
arr = new nsCOMArray<nsXULTemplateResultRDF>();
if (!arr)
return NS_ERROR_OUT_OF_MEMORY;
arr = new ResultArray();
mBindingDependencies.Put(aResource, arr);
}
PRInt32 index = arr->IndexOf(aResult);
if (index == -1)
return arr->AppendObject(aResult);
return NS_OK;
arr->AppendElement(aResult);
}
nsresult
void
nsXULTemplateQueryProcessorRDF::RemoveBindingDependency(nsXULTemplateResultRDF* aResult,
nsIRDFResource* aResource)
{
nsCOMArray<nsXULTemplateResultRDF>* arr;
ResultArray* arr;
if (mBindingDependencies.Get(aResource, &arr)) {
PRInt32 index = arr->IndexOf(aResult);
if (index >= 0)
return arr->RemoveObjectAt(index);
arr->RemoveElementAt(index);
}
return NS_OK;
}

View File

@ -47,6 +47,7 @@ class nsXULTemplateQueryProcessorRDF MOZ_FINAL : public nsIXULTemplateQueryProce
public nsIRDFObserver
{
public:
typedef nsTArray<nsCOMPtr<nsXULTemplateResultRDF> > ResultArray;
nsXULTemplateQueryProcessorRDF();
@ -201,14 +202,14 @@ public:
* assertion is added to or removed from the graph involving that
* resource, that result must be recalculated.
*/
nsresult
void
AddBindingDependency(nsXULTemplateResultRDF* aResult,
nsIRDFResource* aResource);
/**
* Remove a dependency a result has on a particular resource.
*/
nsresult
void
RemoveBindingDependency(nsXULTemplateResultRDF* aResult,
nsIRDFResource* aResource);
@ -314,8 +315,7 @@ protected:
* in this binding map. If it exists, the corresponding results must then
* be synchronized.
*/
nsClassHashtable<nsISupportsHashKey,
nsCOMArray<nsXULTemplateResultRDF> > mBindingDependencies;
nsClassHashtable<nsISupportsHashKey, ResultArray> mBindingDependencies;
/**
* A map between memory elements and an array of nsIXULTemplateResults.
@ -333,7 +333,7 @@ protected:
/**
* The queries
*/
nsCOMArray<nsITemplateRDFQuery> mQueries;
nsTArray<nsCOMPtr<nsITemplateRDFQuery> > mQueries;
/**
* All of the RDF tests in the rule network, which are checked when a new

View File

@ -13,7 +13,7 @@ interface nsIAlarmFiredCb : nsISupports
[scriptable, function, uuid(0ca52e84-ba8f-11e1-87e8-63235527db9e)]
interface nsITimezoneChangedCb : nsISupports
{
void onTimezoneChanged(in long aTimezoneOffset);
void onTimezoneChanged(in PRInt32 aTimezoneOffset);
};
%{C++
@ -24,7 +24,7 @@ interface nsITimezoneChangedCb : nsISupports
[scriptable, builtinclass, uuid(057b1ee4-f696-486d-bd55-205e21e88fab)]
interface nsIAlarmHalService : nsISupports
{
bool setAlarm(in long aSeconds, in long aNanoseconds);
bool setAlarm(in PRInt32 aSeconds, in PRInt32 aNanoseconds);
void setAlarmFiredCb(in nsIAlarmFiredCb aAlarmFiredCb);
void setTimezoneChangedCb(in nsITimezoneChangedCb aTimezoneChangedCb);
};

View File

@ -180,8 +180,13 @@ let DOMApplicationRegistry = {
// Read json file into a string
let data = null;
try {
data = JSON.parse(NetUtil.readInputStreamToString(aStream,
aStream.available()) || "");
// Obtain a converter to read from a UTF-8 encoded input stream.
let converter = Cc["@mozilla.org/intl/scriptableunicodeconverter"]
.createInstance(Ci.nsIScriptableUnicodeConverter);
converter.charset = "UTF-8";
data = JSON.parse(converter.ConvertToUnicode(NetUtil.readInputStreamToString(aStream,
aStream.available()) || ""));
aStream.close();
if (aCallback)
aCallback(data);

View File

@ -516,6 +516,7 @@ using mozilla::dom::indexedDB::IDBWrapperCache;
#include "BluetoothAdapter.h"
#include "BluetoothDevice.h"
#include "BluetoothDeviceEvent.h"
#include "BluetoothPropertyEvent.h"
#endif
#include "nsIDOMNavigatorSystemMessages.h"
@ -1370,8 +1371,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
nsIXPCScriptable::WANT_NEWENUMERATE)
NS_DEFINE_CLASSINFO_DATA(StorageItem, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(StorageEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(DOMParser, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
@ -1641,8 +1640,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MutationRecord, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(MozSettingsEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#ifdef MOZ_B2G_RIL
NS_DEFINE_CLASSINFO_DATA(MozWifiStatusChangeEvent, nsDOMGenericSH,
@ -1670,6 +1667,8 @@ static nsDOMClassInfoData sClassInfoData[] = {
EVENTTARGET_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(BluetoothDeviceEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(BluetoothPropertyEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
#endif
NS_DEFINE_CLASSINFO_DATA(CameraManager, nsDOMGenericSH,
@ -1734,7 +1733,6 @@ static const nsContractIDMapData kConstructorMap[] =
}
NS_DEFINE_EVENT_CTOR(Event)
NS_DEFINE_EVENT_CTOR(MozSettingsEvent)
NS_DEFINE_EVENT_CTOR(UIEvent)
NS_DEFINE_EVENT_CTOR(MouseEvent)
#ifdef MOZ_B2G_RIL
@ -1748,13 +1746,6 @@ NS_DEFINE_EVENT_CTOR(MozWifiConnectionInfoEvent)
#include "GeneratedEvents.h"
#undef MOZ_GENERATED_EVENT_LIST
nsresult
NS_DOMStorageEventCtor(nsISupports** aInstancePtrResult)
{
nsDOMStorageEvent* e = new nsDOMStorageEvent();
return CallQueryInterface(e, aInstancePtrResult);
}
nsresult
NS_XMLHttpRequestCtor(nsISupports** aInstancePtrResult)
{
@ -1780,10 +1771,8 @@ static const nsConstructorFuncMapData kConstructorFuncMap[] =
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(File, nsDOMFileFile::NewFile)
NS_DEFINE_CONSTRUCTOR_FUNC_DATA(MozBlobBuilder, NS_NewBlobBuilder)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(Event)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozSettingsEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(UIEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MouseEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(StorageEvent)
#ifdef MOZ_B2G_RIL
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiStatusChangeEvent)
NS_DEFINE_EVENT_CONSTRUCTOR_FUNC_DATA(MozWifiConnectionInfoEvent)
@ -3931,11 +3920,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMToString)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(StorageEvent, nsIDOMStorageEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMStorageEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN_NO_CLASS_IF(DOMParser, nsIDOMParser)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMParser)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMParserJS)
@ -4408,11 +4392,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMutationRecord)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(MozSettingsEvent, nsIDOMMozSettingsEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozSettingsEvent)
DOM_CLASSINFO_EVENT_MAP_ENTRIES
DOM_CLASSINFO_MAP_END
#ifdef MOZ_B2G_RIL
DOM_CLASSINFO_MAP_BEGIN(MozWifiStatusChangeEvent, nsIDOMMozWifiStatusChangeEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMMozWifiStatusChangeEvent)
@ -4467,6 +4446,11 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothDeviceEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(BluetoothPropertyEvent, nsIDOMBluetoothPropertyEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMBluetoothPropertyEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
#endif
DOM_CLASSINFO_MAP_BEGIN(CameraManager, nsIDOMCameraManager)

View File

@ -341,7 +341,6 @@ DOMCI_CLASS(XPathResult)
DOMCI_CLASS(StorageObsolete)
DOMCI_CLASS(Storage)
DOMCI_CLASS(StorageItem)
DOMCI_CLASS(StorageEvent)
// DOMParser, XMLSerializer
DOMCI_CLASS(DOMParser)
@ -507,8 +506,6 @@ DOMCI_CLASS(MediaQueryList)
DOMCI_CLASS(MutationObserver)
DOMCI_CLASS(MutationRecord)
DOMCI_CLASS(MozSettingsEvent)
#ifdef MOZ_B2G_RIL
DOMCI_CLASS(MozWifiStatusChangeEvent)
DOMCI_CLASS(MozWifiConnectionInfoEvent)
@ -524,6 +521,7 @@ DOMCI_CLASS(BluetoothManager)
DOMCI_CLASS(BluetoothAdapter)
DOMCI_CLASS(BluetoothDevice)
DOMCI_CLASS(BluetoothDeviceEvent)
DOMCI_CLASS(BluetoothPropertyEvent)
#endif
DOMCI_CLASS(CameraManager)

View File

@ -197,7 +197,7 @@
#include "nsFrameLoader.h"
#include "nsISupportsPrimitives.h"
#include "nsXPCOMCID.h"
#include "GeneratedEvents.h"
#include "mozilla/FunctionTimer.h"
#include "mozIThirdPartyUtil.h"
@ -9016,7 +9016,8 @@ nsGlobalWindow::CloneStorageEvent(const nsAString& aType,
aEvent->GetUrl(url);
aEvent->GetStorageArea(getter_AddRefs(storageArea));
aEvent = new nsDOMStorageEvent();
NS_NewDOMStorageEvent(getter_AddRefs(domEvent), nsnull, nsnull);
aEvent = do_QueryInterface(domEvent);
return aEvent->InitStorageEvent(aType, canBubble, cancelable,
key, oldValue, newValue,
url, storageArea);

View File

@ -120,7 +120,8 @@ public:
*/
virtual nsresult HandleScriptError(nsScriptErrorEvent *aErrorEvent,
nsEventStatus *aEventStatus) {
return NS_HandleScriptError(this, aErrorEvent, aEventStatus);
NS_ENSURE_STATE(NS_HandleScriptError(this, aErrorEvent, aEventStatus));
return NS_OK;
}
virtual bool IsBlackForCC() { return false; }

View File

@ -110,6 +110,9 @@ static PRLogModuleInfo* gJSDiagnostics;
// Maximum amount of time that should elapse between incremental GC slices
#define NS_INTERSLICE_GC_DELAY 100 // ms
// If we haven't painted in 100ms, we allow for a longer GC budget
#define NS_INTERSLICE_GC_BUDGET 40 // ms
// The amount of time we wait between a request to CC (after GC ran)
// and doing the actual CC.
#define NS_CC_DELAY 6000 // ms
@ -2917,11 +2920,14 @@ void
nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
IsIncremental aIncremental,
IsCompartment aCompartment,
IsShrinking aShrinking)
IsShrinking aShrinking,
int64_t aSliceMillis)
{
NS_TIME_FUNCTION_MIN(1.0);
SAMPLE_LABEL("GC", "GarbageCollectNow");
MOZ_ASSERT_IF(aSliceMillis, aIncremental == IncrementalGC);
KillGCTimer();
KillShrinkGCBuffersTimer();
@ -2941,7 +2947,7 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
if (sCCLockedOut && aIncremental == IncrementalGC) {
// We're in the middle of incremental GC. Do another slice.
js::PrepareForIncrementalGC(nsJSRuntime::sRuntime);
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
return;
}
@ -2962,7 +2968,7 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
}
if (js::IsGCScheduled(nsJSRuntime::sRuntime)) {
if (aIncremental == IncrementalGC) {
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
} else {
js::GCForReason(nsJSRuntime::sRuntime, aReason);
}
@ -2975,7 +2981,7 @@ nsJSContext::GarbageCollectNow(js::gcreason::Reason aReason,
}
js::PrepareForFullGC(nsJSRuntime::sRuntime);
if (aIncremental == IncrementalGC) {
js::IncrementalGC(nsJSRuntime::sRuntime, aReason);
js::IncrementalGC(nsJSRuntime::sRuntime, aReason, aSliceMillis);
} else {
js::GCForReason(nsJSRuntime::sRuntime, aReason);
}
@ -3223,15 +3229,23 @@ nsJSContext::CycleCollectNow(nsICycleCollectorListener *aListener,
sNeedsFullCC = false;
}
// static
void
InterSliceGCTimerFired(nsITimer *aTimer, void *aClosure)
{
NS_RELEASE(sInterSliceGCTimer);
nsJSContext::GarbageCollectNow(js::gcreason::INTER_SLICE_GC,
nsJSContext::IncrementalGC,
nsJSContext::CompartmentGC,
nsJSContext::NonShrinkingGC,
NS_INTERSLICE_GC_BUDGET);
}
// static
void
GCTimerFired(nsITimer *aTimer, void *aClosure)
{
if (aTimer == sGCTimer) {
NS_RELEASE(sGCTimer);
} else {
NS_RELEASE(sInterSliceGCTimer);
}
NS_RELEASE(sGCTimer);
uintptr_t reason = reinterpret_cast<uintptr_t>(aClosure);
nsJSContext::GarbageCollectNow(static_cast<js::gcreason::Reason>(reason),
@ -3554,9 +3568,8 @@ DOMGCSliceCallback(JSRuntime *aRt, js::GCProgress aProgress, const js::GCDescrip
if (aProgress == js::GC_SLICE_END) {
nsJSContext::KillInterSliceGCTimer();
CallCreateInstance("@mozilla.org/timer;1", &sInterSliceGCTimer);
js::gcreason::Reason reason = js::gcreason::INTER_SLICE_GC;
sInterSliceGCTimer->InitWithFuncCallback(GCTimerFired,
reinterpret_cast<void *>(reason),
sInterSliceGCTimer->InitWithFuncCallback(InterSliceGCTimerFired,
NULL,
NS_INTERSLICE_GC_DELAY,
nsITimer::TYPE_ONE_SHOT);
}

View File

@ -164,7 +164,8 @@ public:
static void GarbageCollectNow(js::gcreason::Reason reason,
IsIncremental aIncremental = NonIncrementalGC,
IsCompartment aCompartment = NonCompartmentGC,
IsShrinking aShrinking = NonShrinkingGC);
IsShrinking aShrinking = NonShrinkingGC,
int64_t aSliceMillis = 0);
static void ShrinkGCBuffersNow();
// If aExtraForgetSkippableCalls is -1, forgetSkippable won't be
// called even if the previous collection was GC.

View File

@ -1972,19 +1972,13 @@ for (uint32_t i = 0; i < length; ++i) {
"arraybuffer views because making sure all the "
"objects are properly rooted is hard")
name = type.name
if type.isArrayBuffer():
jsname = "ArrayBufferObject"
elif type.isArrayBufferView():
jsname = "ArrayBufferViewObject"
else:
jsname = type.name
# By default, we use a Maybe<> to hold our typed array. And in the optional
# non-nullable case we want to pass Optional<TypedArray> to consumers, not
# Optional<NonNull<TypedArray> >, so jump though some hoops to do that.
holderType = "Maybe<%s>" % name
constructLoc = "${holderName}"
constructMethod = "construct"
constructInternal = "ref"
if type.nullable():
if isOptional:
declType = "const Optional<" + name + "*>"
@ -1997,15 +1991,16 @@ for (uint32_t i = 0; i < length; ++i) {
holderType = None
constructLoc = "(const_cast<Optional<" + name + ">& >(${declName}))"
constructMethod = "Construct"
constructInternal = "Value"
else:
declType = "NonNull<" + name + ">"
template = (
"if (!JS_Is%s(&${val}.toObject(), cx)) {\n"
"%s.%s(cx, &${val}.toObject());\n"
"if (!%s.%s().inited()) {\n"
"%s" # No newline here because onFailure() handles that
"}\n"
"%s.%s(cx, &${val}.toObject());\n" %
(jsname, CGIndenter(onFailure(failureCode, descriptorProvider.workers)).define(),
constructLoc, constructMethod))
"}\n" %
(constructLoc, constructMethod, constructLoc, constructInternal,
CGIndenter(onFailure(failureCode, descriptorProvider.workers)).define()))
nullableTarget = ""
if type.nullable():
if isOptional:

View File

@ -18,31 +18,50 @@ namespace dom {
* a subclass of the base class that supports creation of a relevant typed array
* or array buffer object.
*/
template<typename T, typename U,
U* GetData(JSObject*, JSContext*),
uint32_t GetLength(JSObject*, JSContext*)>
template<typename T,
JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**)>
struct TypedArray_base {
TypedArray_base(JSContext* cx, JSObject* obj) :
mData(static_cast<T*>(GetData(obj, cx))),
mLength(GetLength(obj, cx)),
mObj(obj)
{}
TypedArray_base(JSContext* cx, JSObject* obj)
{
mObj = UnboxArray(cx, obj, &mLength, &mData);
}
T* const mData;
const uint32_t mLength;
JSObject* const mObj;
private:
T* mData;
uint32_t mLength;
JSObject* mObj;
public:
inline bool inited() const {
return !!mObj;
}
inline T *Data() const {
MOZ_ASSERT(inited());
return mData;
}
inline uint32_t Length() const {
MOZ_ASSERT(inited());
return mLength;
}
inline JSObject *Obj() const {
MOZ_ASSERT(inited());
return mObj;
}
};
template<typename T, typename U,
U* GetData(JSObject*, JSContext*),
uint32_t GetLength(JSObject*, JSContext*),
template<typename T,
T* GetData(JSObject*, JSContext*),
JSObject* UnboxArray(JSContext*, JSObject*, uint32_t*, T**),
JSObject* CreateNew(JSContext*, uint32_t)>
struct TypedArray : public TypedArray_base<T,U,GetData,GetLength> {
struct TypedArray : public TypedArray_base<T,UnboxArray> {
TypedArray(JSContext* cx, JSObject* obj) :
TypedArray_base<T,U,GetData,GetLength>(cx, obj)
TypedArray_base<T,UnboxArray>(cx, obj)
{}
static inline JSObject*
Create(JSContext* cx, nsWrapperCache* creator, uint32_t length,
T* data = NULL) {
@ -65,38 +84,37 @@ struct TypedArray : public TypedArray_base<T,U,GetData,GetLength> {
}
};
typedef TypedArray<int8_t, int8_t, JS_GetInt8ArrayData, JS_GetTypedArrayLength,
typedef TypedArray<int8_t, JS_GetInt8ArrayData, JS_GetObjectAsInt8Array,
JS_NewInt8Array>
Int8Array;
typedef TypedArray<uint8_t, uint8_t, JS_GetUint8ArrayData,
JS_GetTypedArrayLength, JS_NewUint8Array>
typedef TypedArray<uint8_t, JS_GetUint8ArrayData,
JS_GetObjectAsUint8Array, JS_NewUint8Array>
Uint8Array;
typedef TypedArray<uint8_t, uint8_t, JS_GetUint8ClampedArrayData,
JS_GetTypedArrayLength, JS_NewUint8ClampedArray>
typedef TypedArray<uint8_t, JS_GetUint8ClampedArrayData,
JS_GetObjectAsUint8ClampedArray, JS_NewUint8ClampedArray>
Uint8ClampedArray;
typedef TypedArray<int16_t, int16_t, JS_GetInt16ArrayData,
JS_GetTypedArrayLength, JS_NewInt16Array>
typedef TypedArray<int16_t, JS_GetInt16ArrayData,
JS_GetObjectAsInt16Array, JS_NewInt16Array>
Int16Array;
typedef TypedArray<uint16_t, uint16_t, JS_GetUint16ArrayData,
JS_GetTypedArrayLength, JS_NewUint16Array>
typedef TypedArray<uint16_t, JS_GetUint16ArrayData,
JS_GetObjectAsUint16Array, JS_NewUint16Array>
Uint16Array;
typedef TypedArray<int32_t, int32_t, JS_GetInt32ArrayData,
JS_GetTypedArrayLength, JS_NewInt32Array>
typedef TypedArray<int32_t, JS_GetInt32ArrayData,
JS_GetObjectAsInt32Array, JS_NewInt32Array>
Int32Array;
typedef TypedArray<uint32_t, uint32_t, JS_GetUint32ArrayData,
JS_GetTypedArrayLength, JS_NewUint32Array>
typedef TypedArray<uint32_t, JS_GetUint32ArrayData,
JS_GetObjectAsUint32Array, JS_NewUint32Array>
Uint32Array;
typedef TypedArray<float, float, JS_GetFloat32ArrayData, JS_GetTypedArrayLength,
JS_NewFloat32Array>
typedef TypedArray<float, JS_GetFloat32ArrayData,
JS_GetObjectAsFloat32Array, JS_NewFloat32Array>
Float32Array;
typedef TypedArray<double, double, JS_GetFloat64ArrayData,
JS_GetTypedArrayLength, JS_NewFloat64Array>
typedef TypedArray<double, JS_GetFloat64ArrayData,
JS_GetObjectAsFloat64Array, JS_NewFloat64Array>
Float64Array;
typedef TypedArray_base<uint8_t, void, JS_GetArrayBufferViewData,
JS_GetArrayBufferViewByteLength>
typedef TypedArray_base<uint8_t, JS_GetObjectAsArrayBufferView>
ArrayBufferView;
typedef TypedArray<uint8_t, uint8_t, JS_GetArrayBufferData,
JS_GetArrayBufferByteLength, JS_NewArrayBuffer>
typedef TypedArray<uint8_t, JS_GetArrayBufferData,
JS_GetObjectAsArrayBuffer, JS_NewArrayBuffer>
ArrayBuffer;
} // namespace dom

View File

@ -19,32 +19,41 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=775852
<script type="application/javascript">
/** Test for Bug 775852 **/
var gl = $("c").getContext("experimental-webgl");
var setterCalled = false;
function doTest() {
try {
var gl = $("c").getContext("experimental-webgl");
} catch (e) {
// No WebGL support on MacOS 10.5. Just skip this test
todo(false, "WebGL not supported");
return;
}
var setterCalled = false;
extLength = gl.getSupportedExtensions().length;
ok(extLength > 0,
"This test won't work right if we have no supported extensions");
extLength = gl.getSupportedExtensions().length;
ok(extLength > 0,
"This test won't work right if we have no supported extensions");
Object.defineProperty(Array.prototype, "0",
{
set: function(val) {
setterCalled = true;
}
});
Object.defineProperty(Array.prototype, "0",
{
set: function(val) {
setterCalled = true;
}
});
// Test that our property got defined correctly
var arr = []
arr[0] = 5;
is(setterCalled, true, "Setter should be called when setting prop on array");
// Test that our property got defined correctly
var arr = []
arr[0] = 5;
is(setterCalled, true, "Setter should be called when setting prop on array");
setterCalled = false;
setterCalled = false;
is(gl.getSupportedExtensions().length, extLength,
"We should still have the same number of extensions");
is(gl.getSupportedExtensions().length, extLength,
"We should still have the same number of extensions");
is(setterCalled, false,
"Setter should not be called when getting supported extensions");
is(setterCalled, false,
"Setter should not be called when getting supported extensions");
}
doTest();
</script>
</pre>
</body>

View File

@ -8,15 +8,18 @@
#include "BluetoothAdapter.h"
#include "BluetoothDevice.h"
#include "BluetoothDeviceEvent.h"
#include "BluetoothPropertyEvent.h"
#include "BluetoothService.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothUtils.h"
#include "nsDOMClassInfo.h"
#include "nsDOMEvent.h"
#include "nsThreadUtils.h"
#include "nsXPCOMCIDInternal.h"
#include "nsIDOMDOMRequest.h"
#include "nsContentUtils.h"
#include "mozilla/LazyIdleThread.h"
#include "mozilla/Util.h"
@ -29,8 +32,15 @@ DOMCI_DATA(BluetoothAdapter, BluetoothAdapter)
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothAdapter)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsDeviceAddresses)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicefound)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(devicedisappeared)
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
@ -38,6 +48,7 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
tmp->Unroot();
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicefound)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(devicedisappeared)
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(propertychanged)
@ -51,36 +62,15 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothAdapter, nsDOMEventTargetHelper)
class GetPropertiesTask : public BluetoothReplyRunnable
BluetoothAdapter::BluetoothAdapter(nsPIDOMWindow* aOwner, const nsAString& aPath)
: BluetoothPropertyContainer(BluetoothObjectType::TYPE_ADAPTER)
, mJsUuids(nullptr)
, mJsDeviceAddresses(nullptr)
, mIsRooted(false)
{
public:
GetPropertiesTask(BluetoothAdapter* aAdapter, nsIDOMDOMRequest* aReq) :
BluetoothReplyRunnable(aReq),
mAdapterPtr(aAdapter)
{
}
bool
ParseSuccessfulReply(jsval* aValue)
{
const InfallibleTArray<BluetoothNamedValue>& values =
mReply->get_BluetoothReplySuccess().value().get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0; i < values.Length(); ++i) {
mAdapterPtr->SetPropertyByValue(values[i]);
}
*aValue = JSVAL_VOID;
return true;
}
void
ReleaseMembers()
{
BluetoothReplyRunnable::ReleaseMembers();
mAdapterPtr = nullptr;
}
private:
nsRefPtr<BluetoothAdapter> mAdapterPtr;
};
BindToOwner(aOwner);
mPath = aPath;
}
BluetoothAdapter::~BluetoothAdapter()
{
@ -91,6 +81,27 @@ BluetoothAdapter::~BluetoothAdapter()
NS_WARNING("Failed to unregister object with observer!");
}
}
Unroot();
}
void
BluetoothAdapter::Unroot()
{
if (!mIsRooted) {
return;
}
NS_DROP_JS_OBJECTS(this, BluetoothAdapter);
mIsRooted = false;
}
void
BluetoothAdapter::Root()
{
if (mIsRooted) {
return;
}
NS_HOLD_JS_OBJECTS(this, BluetoothAdapter);
mIsRooted = true;
}
void
@ -102,10 +113,14 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
mName = value.get_nsString();
} else if (name.EqualsLiteral("Address")) {
mAddress = value.get_nsString();
} else if (name.EqualsLiteral("Path")) {
mPath = value.get_nsString();
} else if (name.EqualsLiteral("Enabled")) {
mEnabled = value.get_bool();
} else if (name.EqualsLiteral("Discoverable")) {
mDiscoverable = value.get_bool();
} else if (name.EqualsLiteral("Discovering")) {
mDiscovering = value.get_bool();
} else if (name.EqualsLiteral("Pairable")) {
mPairable = value.get_bool();
} else if (name.EqualsLiteral("Powered")) {
@ -118,6 +133,36 @@ BluetoothAdapter::SetPropertyByValue(const BluetoothNamedValue& aValue)
mClass = value.get_uint32_t();
} else if (name.EqualsLiteral("UUIDs")) {
mUuids = value.get_ArrayOfnsString();
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
if (sc) {
rv =
StringArrayToJSArray(sc->GetNativeContext(),
sc->GetNativeGlobal(), mUuids, &mJsUuids);
if (NS_FAILED(rv)) {
NS_WARNING("Cannot set JS UUIDs object!");
return;
}
Root();
} else {
NS_WARNING("Could not get context!");
}
} else if (name.EqualsLiteral("Devices")) {
mDeviceAddresses = value.get_ArrayOfnsString();
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
if (sc) {
rv =
StringArrayToJSArray(sc->GetNativeContext(),
sc->GetNativeGlobal(), mUuids, &mJsDeviceAddresses);
if (NS_FAILED(rv)) {
NS_WARNING("Cannot set JS Devices Addresses object!");
return;
}
Root();
} else {
NS_WARNING("Could not get context!");
}
} else {
#ifdef DEBUG
nsCString warningMsg;
@ -136,11 +181,15 @@ BluetoothAdapter::Create(nsPIDOMWindow* aOwner, const nsAString& aPath)
NS_ASSERTION(!aPath.IsEmpty(), "Adapter created with empty path!");
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return nullptr;
}
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aPath);
adapter->BindToOwner(aOwner);
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(aPath, adapter))) {
nsRefPtr<BluetoothAdapter> adapter = new BluetoothAdapter(aOwner, aPath);
nsString path;
path = adapter->GetPath();
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(path, adapter))) {
NS_WARNING("Failed to register object with observer!");
return nullptr;
}
@ -151,9 +200,21 @@ void
BluetoothAdapter::Notify(const BluetoothSignal& aData)
{
if (aData.name().EqualsLiteral("DeviceFound")) {
nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(GetOwner(), aData);
nsRefPtr<BluetoothDevice> d = BluetoothDevice::Create(GetOwner(), mPath, aData.value());
nsRefPtr<BluetoothDeviceEvent> e = BluetoothDeviceEvent::Create(d);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("devicefound"));
} else if (aData.name().EqualsLiteral("PropertyChanged")) {
// Get BluetoothNamedValue, make sure array length is 1
InfallibleTArray<BluetoothNamedValue> arr = aData.value().get_ArrayOfBluetoothNamedValue();
if (arr.Length() != 1) {
// This really should not happen
NS_ERROR("Got more than one property in a change message!");
return;
}
BluetoothNamedValue v = arr[0];
SetPropertyByValue(v);
nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(v.name());
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
} else {
#ifdef DEBUG
nsCString warningMsg;
@ -168,10 +229,12 @@ nsresult
BluetoothAdapter::StartStopDiscovery(bool aStart, nsIDOMDOMRequest** aRequest)
{
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_WARNING("No DOMRequest Service!");
return NS_ERROR_FAILURE;
@ -268,10 +331,66 @@ BluetoothAdapter::GetDiscoverableTimeout(PRUint32* aDiscoverableTimeout)
NS_IMETHODIMP
BluetoothAdapter::GetDevices(JSContext* aCx, jsval* aDevices)
{
NS_WARNING("GetDevices not yet implemented.");
if (mJsDeviceAddresses) {
aDevices->setObject(*mJsDeviceAddresses);
}
else {
NS_WARNING("UUIDs not yet set!\n");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
nsresult
BluetoothAdapter::GetUuids(JSContext* aCx, jsval* aValue)
{
if (mJsUuids) {
aValue->setObject(*mJsUuids);
}
else {
NS_WARNING("UUIDs not yet set!\n");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMETHODIMP
BluetoothAdapter::SetName(const nsAString& aName,
nsIDOMDOMRequest** aRequest)
{
if (mName.Equals(aName)) {
return NS_OK;
}
nsString name(aName);
BluetoothValue value(name);
BluetoothNamedValue property(NS_LITERAL_STRING("Name"), value);
return SetProperty(GetOwner(), property, aRequest);
}
NS_IMETHODIMP
BluetoothAdapter::SetDiscoverable(const bool aDiscoverable,
nsIDOMDOMRequest** aRequest)
{
if (aDiscoverable == mDiscoverable) {
return NS_OK;
}
BluetoothValue value(aDiscoverable);
BluetoothNamedValue property(NS_LITERAL_STRING("Discoverable"), value);
return SetProperty(GetOwner(), property, aRequest);
}
NS_IMETHODIMP
BluetoothAdapter::SetDiscoverableTimeout(const PRUint32 aDiscoverableTimeout,
nsIDOMDOMRequest** aRequest)
{
if (aDiscoverableTimeout == mDiscoverableTimeout) {
return NS_OK;
}
BluetoothValue value(aDiscoverableTimeout);
BluetoothNamedValue property(NS_LITERAL_STRING("DiscoverableTimeout"), value);
return SetProperty(GetOwner(), property, aRequest);
}
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, propertychanged)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicefound)
NS_IMPL_EVENT_HANDLER(BluetoothAdapter, devicedisappeared)

View File

@ -8,6 +8,7 @@
#define mozilla_dom_bluetooth_bluetoothadapter_h__
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsCOMPtr.h"
#include "nsDOMEventTargetHelper.h"
#include "nsIDOMBluetoothAdapter.h"
@ -23,6 +24,7 @@ class BluetoothNamedValue;
class BluetoothAdapter : public nsDOMEventTargetHelper
, public nsIDOMBluetoothAdapter
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -30,8 +32,9 @@ public:
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(BluetoothAdapter,
nsDOMEventTargetHelper)
static already_AddRefed<BluetoothAdapter>
Create(nsPIDOMWindow* aOwner, const nsAString& name);
@ -50,23 +53,18 @@ public:
return ToIDOMEventTarget();
}
nsresult GetProperties();
void SetPropertyByValue(const BluetoothNamedValue& aValue);
void Unroot();
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue);
private:
BluetoothAdapter(const nsAString& aPath) : mPath(aPath)
{
}
BluetoothAdapter(nsPIDOMWindow* aOwner, const nsAString& aPath);
~BluetoothAdapter();
nsresult SetProperty(const BluetoothNamedValue& aValue,
nsIDOMDOMRequest** aRequest);
void Root();
nsresult StartStopDiscovery(bool aStart, nsIDOMDOMRequest** aRequest);
nsString mAddress;
nsString mName;
nsString mPath;
bool mEnabled;
bool mDiscoverable;
bool mDiscovering;
@ -77,7 +75,10 @@ private:
PRUint32 mClass;
nsTArray<nsString> mDeviceAddresses;
nsTArray<nsString> mUuids;
JSObject* mJsUuids;
JSObject* mJsDeviceAddresses;
bool mIsRooted;
NS_DECL_EVENT_HANDLER(propertychanged)
NS_DECL_EVENT_HANDLER(devicefound)
NS_DECL_EVENT_HANDLER(devicedisappeared)

View File

@ -25,6 +25,15 @@ BEGIN_BLUETOOTH_NAMESPACE
class BluetoothSignal;
typedef mozilla::Observer<BluetoothSignal> BluetoothSignalObserver;
// Enums for object types, currently used for shared function lookups
// (get/setproperty, etc...). Possibly discernable via dbus paths, but this
// method is future-proofed for platform independence.
enum BluetoothObjectType {
TYPE_MANAGER = 0,
TYPE_ADAPTER = 1,
TYPE_DEVICE = 2
};
END_BLUETOOTH_NAMESPACE
#endif // mozilla_dom_bluetooth_bluetoothcommon_h__

View File

@ -6,9 +6,15 @@
#include "base/basictypes.h"
#include "BluetoothDevice.h"
#include "BluetoothPropertyEvent.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
#include "BluetoothService.h"
#include "BluetoothUtils.h"
#include "nsIDOMDOMRequest.h"
#include "nsDOMClassInfo.h"
#include "nsContentUtils.h"
USING_BLUETOOTH_NAMESPACE
@ -16,13 +22,20 @@ DOMCI_DATA(BluetoothDevice, BluetoothDevice)
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothDevice)
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN_INHERITED(BluetoothDevice,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_MEMBER_CALLBACK(mJsUuids)
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothDevice,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_CYCLE_COLLECTION_TRAVERSE_EVENT_HANDLER(propertychanged)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothDevice,
nsDOMEventTargetHelper)
tmp->Unroot();
NS_CYCLE_COLLECTION_UNLINK_EVENT_HANDLER(propertychanged)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
@ -34,15 +47,52 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
NS_IMPL_ADDREF_INHERITED(BluetoothDevice, nsDOMEventTargetHelper)
NS_IMPL_RELEASE_INHERITED(BluetoothDevice, nsDOMEventTargetHelper)
BluetoothDevice::BluetoothDevice(const BluetoothSignal& aSignal)
BluetoothDevice::BluetoothDevice(nsPIDOMWindow* aOwner,
const nsAString& aAdapterPath,
const BluetoothValue& aValue) :
BluetoothPropertyContainer(BluetoothObjectType::TYPE_DEVICE),
mJsUuids(nullptr),
mAdapterPath(aAdapterPath),
mIsRooted(false)
{
BindToOwner(aOwner);
const InfallibleTArray<BluetoothNamedValue>& values =
aSignal.value().get_ArrayOfBluetoothNamedValue();
aValue.get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0; i < values.Length(); ++i) {
SetPropertyByValue(values[i]);
}
}
BluetoothDevice::~BluetoothDevice()
{
BluetoothService* bs = BluetoothService::Get();
// bs can be null on shutdown, where destruction might happen.
if (bs) {
if (NS_FAILED(bs->UnregisterBluetoothSignalHandler(mPath, this))) {
NS_WARNING("Failed to unregister object with observer!");
}
}
Unroot();
}
void
BluetoothDevice::Root()
{
if (!mIsRooted) {
NS_HOLD_JS_OBJECTS(this, BluetoothDevice);
mIsRooted = true;
}
}
void
BluetoothDevice::Unroot()
{
if (mIsRooted) {
NS_DROP_JS_OBJECTS(this, BluetoothDevice);
mIsRooted = false;
}
}
void
BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
{
@ -52,6 +102,13 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
mName = value.get_nsString();
} else if (name.EqualsLiteral("Address")) {
mAddress = value.get_nsString();
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return;
}
// We can't actually set up our path until we know our address
bs->GetDevicePath(mAdapterPath, mAddress, mPath);
} else if (name.EqualsLiteral("Class")) {
mClass = value.get_uint32_t();
} else if (name.EqualsLiteral("Connected")) {
@ -60,8 +117,22 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
mPaired = value.get_bool();
} else if (name.EqualsLiteral("UUIDs")) {
mUuids = value.get_ArrayOfnsString();
} else {
nsresult rv;
nsIScriptContext* sc = GetContextForEventHandlers(&rv);
if (sc) {
rv =
StringArrayToJSArray(sc->GetNativeContext(),
sc->GetNativeGlobal(), mUuids, &mJsUuids);
if (NS_FAILED(rv)) {
NS_WARNING("Cannot set JS UUIDs object!");
return;
}
Root();
} else {
NS_WARNING("Could not get context!");
}
#ifdef DEBUG
} else {
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling device property: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
@ -72,13 +143,46 @@ BluetoothDevice::SetPropertyByValue(const BluetoothNamedValue& aValue)
// static
already_AddRefed<BluetoothDevice>
BluetoothDevice::Create(nsPIDOMWindow* aOwner, const BluetoothSignal& aSignal)
BluetoothDevice::Create(nsPIDOMWindow* aOwner,
const nsAString& aAdapterPath,
const BluetoothValue& aValue)
{
nsRefPtr<BluetoothDevice> device = new BluetoothDevice(aSignal);
device->BindToOwner(device);
// Make sure we at least have a service
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("BluetoothService not available!");
return nullptr;
}
nsRefPtr<BluetoothDevice> device = new BluetoothDevice(aOwner, aAdapterPath,
aValue);
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(device->mPath, device))) {
NS_WARNING("Failed to register object with observer!");
return nullptr;
}
return device.forget();
}
void
BluetoothDevice::Notify(const BluetoothSignal& aData)
{
if (aData.name().EqualsLiteral("PropertyChanged")) {
// Get BluetoothNamedValue, make sure array length is 1
BluetoothNamedValue v = aData.value().get_ArrayOfBluetoothNamedValue()[0];
nsString name = v.name();
SetPropertyByValue(v);
nsRefPtr<BluetoothPropertyEvent> e = BluetoothPropertyEvent::Create(name);
e->Dispatch(ToIDOMEventTarget(), NS_LITERAL_STRING("propertychanged"));
} else {
#ifdef DEBUG
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling device signal: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(aData.name()));
NS_WARNING(warningMsg.get());
#endif
}
}
NS_IMETHODIMP
BluetoothDevice::GetAddress(nsAString& aAddress)
{
@ -114,4 +218,16 @@ BluetoothDevice::GetConnected(bool* aConnected)
return NS_OK;
}
NS_IMETHODIMP
BluetoothDevice::GetUuids(JSContext* aCx, jsval* aUuids)
{
if (mJsUuids) {
aUuids->setObject(*mJsUuids);
} else {
NS_WARNING("UUIDs not yet set!\n");
return NS_ERROR_FAILURE;
}
return NS_OK;
}
NS_IMPL_EVENT_HANDLER(BluetoothDevice, propertychanged)

View File

@ -8,17 +8,23 @@
#define mozilla_dom_bluetooth_bluetoothdevice_h__
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsDOMEventTargetHelper.h"
#include "nsIDOMBluetoothDevice.h"
#include "nsString.h"
class nsIDOMDOMRequest;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothValue;
class BluetoothSignal;
class BluetoothDevice : public nsDOMEventTargetHelper
, public nsIDOMBluetoothDevice
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -26,11 +32,14 @@ public:
NS_FORWARD_NSIDOMEVENTTARGET(nsDOMEventTargetHelper::)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothDevice,
nsDOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(BluetoothDevice,
nsDOMEventTargetHelper)
static already_AddRefed<BluetoothDevice>
Create(nsPIDOMWindow* aOwner, const BluetoothSignal& aSignal);
Create(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
const BluetoothValue& aValue);
void Notify(const BluetoothSignal& aParam);
nsIDOMEventTarget*
ToIDOMEventTarget() const
@ -44,17 +53,25 @@ public:
{
return ToIDOMEventTarget();
}
private:
BluetoothDevice(const BluetoothSignal& aSignal);
~BluetoothDevice() {}
void SetPropertyByValue(const BluetoothNamedValue& aValue);
void Unroot();
private:
BluetoothDevice(nsPIDOMWindow* aOwner, const nsAString& aAdapterPath,
const BluetoothValue& aValue);
~BluetoothDevice();
void Root();
JSObject* mJsUuids;
nsString mAdapterPath;
nsString mAddress;
nsString mName;
PRUint32 mClass;
bool mConnected;
bool mPaired;
bool mIsRooted;
nsTArray<nsString> mUuids;
NS_DECL_EVENT_HANDLER(propertychanged)

View File

@ -8,6 +8,7 @@
#include "BluetoothDeviceEvent.h"
#include "BluetoothTypes.h"
#include "BluetoothDevice.h"
#include "nsIDOMDOMRequest.h"
#include "nsDOMClassInfo.h"

View File

@ -144,10 +144,11 @@ private:
};
BluetoothManager::BluetoothManager(nsPIDOMWindow *aWindow) :
BluetoothPropertyContainer(BluetoothObjectType::TYPE_MANAGER),
mEnabled(false)
{
BindToOwner(aWindow);
mName.AssignLiteral("/");
mPath.AssignLiteral("/");
}
BluetoothManager::~BluetoothManager()
@ -155,20 +156,34 @@ BluetoothManager::~BluetoothManager()
BluetoothService* bs = BluetoothService::Get();
// We can be null on shutdown, where this might happen
if (bs) {
if (NS_FAILED(bs->UnregisterBluetoothSignalHandler(mName, this))) {
if (NS_FAILED(bs->UnregisterBluetoothSignalHandler(mPath, this))) {
NS_WARNING("Failed to unregister object with observer!");
}
}
}
void
BluetoothManager::SetPropertyByValue(const BluetoothNamedValue& aValue)
{
#ifdef DEBUG
const nsString& name = aValue.name();
nsCString warningMsg;
warningMsg.AssignLiteral("Not handling manager property: ");
warningMsg.Append(NS_ConvertUTF16toUTF8(name));
NS_WARNING(warningMsg.get());
#endif
}
NS_IMETHODIMP
BluetoothManager::SetEnabled(bool aEnabled, nsIDOMDOMRequest** aDomRequest)
{
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_WARNING("No DOMRequest Service!");
return NS_ERROR_FAILURE;
@ -208,7 +223,10 @@ NS_IMETHODIMP
BluetoothManager::GetDefaultAdapter(nsIDOMDOMRequest** aAdapter)
{
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
@ -239,7 +257,10 @@ BluetoothManager::Create(nsPIDOMWindow* aWindow) {
nsRefPtr<BluetoothManager> manager = new BluetoothManager(aWindow);
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return nullptr;
}
if (NS_FAILED(bs->RegisterBluetoothSignalHandler(NS_LITERAL_STRING("/"), manager))) {
NS_ERROR("Failed to register object with observer!");

View File

@ -8,6 +8,7 @@
#define mozilla_dom_bluetooth_bluetoothmanager_h__
#include "BluetoothCommon.h"
#include "BluetoothPropertyContainer.h"
#include "nsDOMEventTargetHelper.h"
#include "nsIDOMBluetoothManager.h"
#include "mozilla/Observer.h"
@ -15,9 +16,12 @@
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothManager : public nsDOMEventTargetHelper
, public nsIDOMBluetoothManager
, public BluetoothSignalObserver
, public BluetoothPropertyContainer
{
public:
NS_DECL_ISUPPORTS_INHERITED
@ -34,12 +38,11 @@ public:
static already_AddRefed<BluetoothManager>
Create(nsPIDOMWindow* aWindow);
void Notify(const BluetoothSignal& aData);
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue);
private:
BluetoothManager() {}
BluetoothManager(nsPIDOMWindow* aWindow);
~BluetoothManager();
bool mEnabled;
nsString mName;
NS_DECL_EVENT_HANDLER(enabled)
};

View File

@ -0,0 +1,76 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#include "base/basictypes.h"
#include "BluetoothPropertyContainer.h"
#include "BluetoothService.h"
#include "BluetoothTypes.h"
#include "nsIDOMDOMRequest.h"
USING_BLUETOOTH_NAMESPACE
nsresult
BluetoothPropertyContainer::GetProperties()
{
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("Bluetooth service not available!");
return NS_ERROR_FAILURE;
}
nsRefPtr<BluetoothReplyRunnable> task = new GetPropertiesTask(this, NULL);
return bs->GetProperties(mObjectType, mPath, task);
}
nsresult
BluetoothPropertyContainer::SetProperty(nsIDOMWindow* aOwner,
const BluetoothNamedValue& aProperty,
nsIDOMDOMRequest** aRequest)
{
BluetoothService* bs = BluetoothService::Get();
if (!bs) {
NS_WARNING("Bluetooth service not available!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMRequestService> rs = do_GetService("@mozilla.org/dom/dom-request-service;1");
if (!rs) {
NS_WARNING("No DOMRequest Service!");
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDOMDOMRequest> req;
nsresult rv = rs->CreateRequest(aOwner, getter_AddRefs(req));
if (NS_FAILED(rv)) {
NS_WARNING("Can't create DOMRequest!");
return NS_ERROR_FAILURE;
}
nsRefPtr<BluetoothReplyRunnable> task = new BluetoothVoidReplyRunnable(req);
rv = bs->SetProperty(mObjectType, mPath, aProperty, task);
NS_ENSURE_SUCCESS(rv, rv);
req.forget(aRequest);
return NS_OK;
}
bool
BluetoothPropertyContainer::GetPropertiesTask::ParseSuccessfulReply(jsval* aValue)
{
*aValue = JSVAL_VOID;
BluetoothValue& v = mReply->get_BluetoothReplySuccess().value();
if (v.type() != BluetoothValue::TArrayOfBluetoothNamedValue) {
NS_WARNING("Not a BluetoothNamedValue array!");
return false;
}
const InfallibleTArray<BluetoothNamedValue>& values =
mReply->get_BluetoothReplySuccess().value().get_ArrayOfBluetoothNamedValue();
for (uint32_t i = 0; i < values.Length(); ++i) {
mPropObjPtr->SetPropertyByValue(values[i]);
}
return true;
}

View File

@ -0,0 +1,75 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#ifndef mozilla_dom_bluetooth_bluetoothpropertyobject_h__
#define mozilla_dom_bluetooth_bluetoothpropertyobject_h__
#include "BluetoothCommon.h"
#include "BluetoothReplyRunnable.h"
class nsIDOMDOMRequest;
class nsIDOMWindow;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothNamedValue;
class BluetoothPropertyContainer
{
public:
nsresult GetProperties();
nsresult SetProperty(nsIDOMWindow* aOwner,
const BluetoothNamedValue& aProperty,
nsIDOMDOMRequest** aRequest);
virtual void SetPropertyByValue(const BluetoothNamedValue& aValue) = 0;
nsString GetPath()
{
return mPath;
}
// Compatibility with nsRefPtr to make sure we don't hold a weakptr to
// ourselves
virtual nsrefcnt AddRef() = 0;
virtual nsrefcnt Release() = 0;
protected:
BluetoothPropertyContainer(BluetoothObjectType aType) :
mObjectType(aType)
{}
~BluetoothPropertyContainer()
{}
class GetPropertiesTask : public BluetoothReplyRunnable
{
public:
GetPropertiesTask(BluetoothPropertyContainer* aPropObj, nsIDOMDOMRequest* aReq) :
BluetoothReplyRunnable(aReq),
mPropObjPtr(aPropObj)
{
MOZ_ASSERT(aReq && aPropObj);
}
virtual bool ParseSuccessfulReply(jsval* aValue);
void
ReleaseMembers()
{
BluetoothReplyRunnable::ReleaseMembers();
mPropObjPtr = nullptr;
}
private:
BluetoothPropertyContainer* mPropObjPtr;
};
nsString mPath;
BluetoothObjectType mObjectType;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -0,0 +1,53 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#include "base/basictypes.h"
#include "BluetoothPropertyEvent.h"
#include "BluetoothTypes.h"
#include "nsDOMClassInfo.h"
USING_BLUETOOTH_NAMESPACE
// static
already_AddRefed<BluetoothPropertyEvent>
BluetoothPropertyEvent::Create(const nsAString& aPropertyName)
{
NS_ASSERTION(!aPropertyName.IsEmpty(), "Empty Property String!");
nsRefPtr<BluetoothPropertyEvent> event = new BluetoothPropertyEvent();
event->mPropertyName = aPropertyName;
return event.forget();
}
NS_IMPL_CYCLE_COLLECTION_CLASS(BluetoothPropertyEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(BluetoothPropertyEvent,
nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(BluetoothPropertyEvent,
nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(BluetoothPropertyEvent)
NS_INTERFACE_MAP_ENTRY(nsIDOMBluetoothPropertyEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(BluetoothPropertyEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
NS_IMPL_ADDREF_INHERITED(BluetoothPropertyEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(BluetoothPropertyEvent, nsDOMEvent)
DOMCI_DATA(BluetoothPropertyEvent, BluetoothPropertyEvent)
NS_IMETHODIMP
BluetoothPropertyEvent::GetProperty(nsAString& aPropertyName)
{
aPropertyName = mPropertyName;
return NS_OK;
}

View File

@ -0,0 +1,66 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#ifndef mozilla_dom_bluetooth_propertyevent_h__
#define mozilla_dom_bluetooth_propertyevent_h__
#include "BluetoothCommon.h"
#include "nsIDOMBluetoothPropertyEvent.h"
#include "nsIDOMEventTarget.h"
#include "nsDOMEvent.h"
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothPropertyEvent : public nsDOMEvent
, public nsIDOMBluetoothPropertyEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_TO_NSDOMEVENT
NS_DECL_NSIDOMBLUETOOTHPROPERTYEVENT
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(BluetoothPropertyEvent, nsDOMEvent)
static already_AddRefed<BluetoothPropertyEvent>
Create(const nsAString& aPropertyName);
nsresult
Dispatch(nsIDOMEventTarget* aTarget, const nsAString& aEventType)
{
NS_ASSERTION(aTarget, "Null pointer!");
NS_ASSERTION(!aEventType.IsEmpty(), "Empty event type!");
nsresult rv = InitEvent(aEventType, false, false);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetTrusted(true);
NS_ENSURE_SUCCESS(rv, rv);
nsIDOMEvent* thisEvent =
static_cast<nsDOMEvent*>(const_cast<BluetoothPropertyEvent*>(this));
bool dummy;
rv = aTarget->DispatchEvent(thisEvent, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
private:
BluetoothPropertyEvent()
: nsDOMEvent(nullptr, nullptr)
{ }
~BluetoothPropertyEvent()
{ }
nsString mPropertyName;
};
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -7,8 +7,6 @@
#include "base/basictypes.h"
#include "BluetoothTypes.h"
#include "BluetoothReplyRunnable.h"
#include "nsIDOMDOMRequest.h"
#include "jsapi.h"
USING_BLUETOOTH_NAMESPACE

View File

@ -9,10 +9,9 @@
#include "BluetoothCommon.h"
#include "nsThreadUtils.h"
#include "nsIDOMDOMRequest.h"
#include "jsapi.h"
class nsIDOMDOMRequest;
BEGIN_BLUETOOTH_NAMESPACE
class BluetoothReply;

View File

@ -143,6 +143,50 @@ public:
*/
virtual nsresult StopInternal() = 0;
/**
* Fetches the propertes for the specified object
*
* @param aType Type of the object (see BluetoothObjectType in BluetoothCommon.h)
* @param aPath Path of the object
* @param aRunnable Runnable to return to after receiving callback
*
* @return NS_OK on function run, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
GetProperties(BluetoothObjectType aType,
const nsAString& aPath,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Set a property for the specified object
*
* @param aPath Path to the object
* @param aPropName Name of the property
* @param aValue Boolean value
* @param aRunnable Runnable to run on async reply
*
* @return NS_OK if property is set correctly, NS_ERROR_FAILURE otherwise
*/
virtual nsresult
SetProperty(BluetoothObjectType aType,
const nsAString& aPath,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable) = 0;
/**
* Get the path of a device
*
* @param aAdapterPath Path to the Adapter that's communicating with the device
* @param aDeviceAddress Device address (XX:XX:XX:XX:XX:XX format)
* @param aDevicePath Return value of path
*
* @return True if path set correctly, false otherwise
*/
virtual bool
GetDevicePath(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,
nsAString& aDevicePath) = 0;
protected:
BluetoothService()
{

View File

@ -0,0 +1,61 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#include "BluetoothUtils.h"
#include "jsapi.h"
#include "nsTArray.h"
#include "nsString.h"
#include "mozilla/Scoped.h"
nsresult
mozilla::dom::bluetooth::StringArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
const nsTArray<nsString>& aSourceArray,
JSObject** aResultArray)
{
NS_ASSERTION(aCx, "Null context!");
NS_ASSERTION(aGlobal, "Null global!");
JSAutoRequest ar(aCx);
JSAutoEnterCompartment ac;
if (!ac.enter(aCx, aGlobal)) {
NS_WARNING("Failed to enter compartment!");
return NS_ERROR_FAILURE;
}
JSObject* arrayObj;
if (aSourceArray.IsEmpty()) {
arrayObj = JS_NewArrayObject(aCx, 0, nullptr);
} else {
uint32_t valLength = aSourceArray.Length();
mozilla::ScopedDeleteArray<jsval> valArray(new jsval[valLength]);
JS::AutoArrayRooter tvr(aCx, valLength, valArray);
for (PRUint32 index = 0; index < valLength; index++) {
JSString* s = JS_NewUCStringCopyN(aCx, aSourceArray[index].BeginReading(),
aSourceArray[index].Length());
if(!s) {
NS_WARNING("Memory allocation error!");
return NS_ERROR_OUT_OF_MEMORY;
}
valArray[index] = STRING_TO_JSVAL(s);
}
arrayObj = JS_NewArrayObject(aCx, valLength, valArray);
}
if (!arrayObj) {
return NS_ERROR_OUT_OF_MEMORY;
}
// XXX This is not what Jonas wants. He wants it to be live.
// Followup at bug 717414
if (!JS_FreezeObject(aCx, arrayObj)) {
return NS_ERROR_FAILURE;
}
*aResultArray = arrayObj;
return NS_OK;
}

View File

@ -0,0 +1,24 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#ifndef mozilla_dom_bluetooth_bluetoothutils_h__
#define mozilla_dom_bluetooth_bluetoothutils_h__
#include "BluetoothCommon.h"
class JSContext;
class JSObject;
BEGIN_BLUETOOTH_NAMESPACE
nsresult
StringArrayToJSArray(JSContext* aCx, JSObject* aGlobal,
const nsTArray<nsString>& aSourceArray,
JSObject** aResultArray);
END_BLUETOOTH_NAMESPACE
#endif

View File

@ -33,7 +33,10 @@ CPPSRCS += \
BluetoothAdapter.cpp \
BluetoothDevice.cpp \
BluetoothDeviceEvent.cpp \
BluetoothPropertyEvent.cpp \
BluetoothReplyRunnable.cpp \
BluetoothPropertyContainer.cpp \
BluetoothUtils.cpp \
$(NULL)
XPIDLSRCS = \
@ -42,6 +45,7 @@ XPIDLSRCS = \
nsIDOMBluetoothAdapter.idl \
nsIDOMBluetoothDevice.idl \
nsIDOMBluetoothDeviceEvent.idl \
nsIDOMBluetoothPropertyEvent.idl \
$(NULL)
ifeq (gonk,$(MOZ_WIDGET_TOOLKIT))

View File

@ -57,6 +57,7 @@ USING_BLUETOOTH_NAMESPACE
#define LOG(args...) if (BTDEBUG) printf(args);
#endif
#define DBUS_MANAGER_IFACE BLUEZ_DBUS_BASE_IFC ".Manager"
#define DBUS_ADAPTER_IFACE BLUEZ_DBUS_BASE_IFC ".Adapter"
#define DBUS_DEVICE_IFACE BLUEZ_DBUS_BASE_IFC ".Device"
#define BLUEZ_DBUS_BASE_PATH "/org/bluez"
@ -68,7 +69,7 @@ typedef struct {
int type;
} Properties;
static Properties remote_device_properties[] = {
static Properties sDeviceProperties[] = {
{"Address", DBUS_TYPE_STRING},
{"Name", DBUS_TYPE_STRING},
{"Icon", DBUS_TYPE_STRING},
@ -88,7 +89,7 @@ static Properties remote_device_properties[] = {
{"Broadcaster", DBUS_TYPE_BOOLEAN}
};
static Properties adapter_properties[] = {
static Properties sAdapterProperties[] = {
{"Address", DBUS_TYPE_STRING},
{"Name", DBUS_TYPE_STRING},
{"Class", DBUS_TYPE_UINT32},
@ -102,7 +103,18 @@ static Properties adapter_properties[] = {
{"UUIDs", DBUS_TYPE_ARRAY},
};
static const char* BLUETOOTH_DBUS_SIGNALS[] =
static Properties sManagerProperties[] = {
{"Adapters", DBUS_TYPE_ARRAY},
};
static const char* sBluetoothDBusIfaces[] =
{
DBUS_MANAGER_IFACE,
DBUS_ADAPTER_IFACE,
DBUS_DEVICE_IFACE
};
static const char* sBluetoothDBusSignals[] =
{
"type='signal',interface='org.freedesktop.DBus'",
"type='signal',interface='org.bluez.Adapter'",
@ -128,12 +140,14 @@ public:
{
MOZ_ASSERT(NS_IsMainThread());
BluetoothService* bs = BluetoothService::Get();
MOZ_ASSERT(bs);
if (!bs) {
NS_WARNING("BluetoothService not available!");
return NS_ERROR_FAILURE;
}
return bs->DistributeSignal(mSignal);
}
};
bool
IsDBusMessageError(DBusMessage* aMsg, nsAString& aError)
{
@ -176,24 +190,14 @@ DispatchBluetoothReply(BluetoothReplyRunnable* aRunnable,
NS_WARNING("Failed to dispatch to main thread!");
}
}
void
GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
UnpackObjectPathMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr)
{
MOZ_ASSERT(!NS_IsMainThread());
DBusError err;
dbus_error_init(&err);
nsRefPtr<BluetoothReplyRunnable> replyRunnable =
dont_AddRef(static_cast< BluetoothReplyRunnable* >(aBluetoothReplyRunnable));
NS_ASSERTION(replyRunnable, "Callback reply runnable is null!");
nsString replyError;
nsString replyPath;
nsTArray<BluetoothNamedValue> replyValues;
BluetoothValue v;
if (!IsDBusMessageError(aMsg, replyError)) {
if (!IsDBusMessageError(aMsg, aErrorStr)) {
NS_ASSERTION(dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN,
"Got dbus callback that's not a METHOD_RETURN!");
const char* object_path;
@ -201,22 +205,22 @@ GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
&object_path, DBUS_TYPE_INVALID) ||
!object_path) {
if (dbus_error_is_set(&err)) {
replyError = NS_ConvertUTF8toUTF16(err.message);
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
LOG_AND_FREE_DBUS_ERROR(&err);
}
} else {
v = NS_ConvertUTF8toUTF16(object_path);
aValue = NS_ConvertUTF8toUTF16(object_path);
}
}
DispatchBluetoothReply(replyRunnable, v, replyError);
}
typedef void (*UnpackFunc)(DBusMessage*, BluetoothValue&, nsAString&);
void
GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
RunDBusCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable,
UnpackFunc aFunc)
{
MOZ_ASSERT(!NS_IsMainThread());
DBusError err;
dbus_error_init(&err);
nsRefPtr<BluetoothReplyRunnable> replyRunnable =
dont_AddRef(static_cast< BluetoothReplyRunnable* >(aBluetoothReplyRunnable));
@ -224,20 +228,41 @@ GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
nsString replyError;
BluetoothValue v;
if (!IsDBusMessageError(aMsg, replyError) &&
aFunc(aMsg, v, replyError);
DispatchBluetoothReply(replyRunnable, v, replyError);
}
void
GetObjectPathCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
{
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackObjectPathMessage);
}
void
UnpackVoidMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr)
{
DBusError err;
dbus_error_init(&err);
if (!IsDBusMessageError(aMsg, aErrorStr) &&
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN &&
!dbus_message_get_args(aMsg, &err, DBUS_TYPE_INVALID)) {
if (dbus_error_is_set(&err)) {
replyError = NS_ConvertUTF8toUTF16(err.message);
aErrorStr = NS_ConvertUTF8toUTF16(err.message);
LOG_AND_FREE_DBUS_ERROR(&err);
}
}
DispatchBluetoothReply(replyRunnable, v, replyError);
}
void
GetVoidCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
{
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackVoidMessage);
}
bool
GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
int aPropertiesTypeLen, int* aPropIndex,
int aPropertyTypeLen, int* aPropIndex,
InfallibleTArray<BluetoothNamedValue>& aProperties)
{
DBusMessageIter prop_val, array_val_iter;
@ -256,13 +281,13 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
return false;
}
for (i = 0; i < aPropertiesTypeLen; i++) {
for (i = 0; i < aPropertyTypeLen; i++) {
if (!strncmp(property, aPropertyTypes[i].name, strlen(property))) {
break;
}
}
if (i == aPropertiesTypeLen) {
if (i == aPropertyTypeLen) {
return false;
}
@ -310,6 +335,9 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
} while (dbus_message_iter_next(&array_val_iter));
propertyValue = arr;
} else {
// This happens when the array is 0-length. Apparently we get a
// DBUS_TYPE_INVALID type.
propertyValue = InfallibleTArray<nsString>();
NS_WARNING("Received array type that's not a string array!");
}
break;
@ -321,10 +349,11 @@ GetProperty(DBusMessageIter aIter, Properties* aPropertyTypes,
}
void
ParseProperties(DBusMessageIter* aIter,
ParseProperties(DBusMessageIter* aIter,
BluetoothValue& aValue,
nsAString& aErrorStr,
Properties* aPropertyTypes,
const int aPropertiesTypeLen,
InfallibleTArray<BluetoothNamedValue>& aProperties)
const int aPropertyTypeLen)
{
DBusMessageIter dict_entry, dict;
int prop_index = -1;
@ -333,28 +362,100 @@ ParseProperties(DBusMessageIter* aIter,
"Trying to parse a property from something that's not an array!");
dbus_message_iter_recurse(aIter, &dict);
InfallibleTArray<BluetoothNamedValue> props;
do {
NS_ASSERTION(dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY,
"Trying to parse a property from something that's not an dict!");
dbus_message_iter_recurse(&dict, &dict_entry);
if (!GetProperty(dict_entry, aPropertyTypes, aPropertiesTypeLen, &prop_index,
aProperties)) {
if (!GetProperty(dict_entry, aPropertyTypes, aPropertyTypeLen, &prop_index,
props)) {
aErrorStr.AssignLiteral("Can't Create Property!");
NS_WARNING("Can't create property!");
return;
}
} while (dbus_message_iter_next(&dict));
aValue = props;
}
void UnpackPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr, Properties* aPropertyTypes,
const int aPropertyTypeLen)
{
if (!IsDBusMessageError(aMsg, aErrorStr) &&
dbus_message_get_type(aMsg) == DBUS_MESSAGE_TYPE_METHOD_RETURN) {
DBusMessageIter iter;
if (!dbus_message_iter_init(aMsg, &iter)) {
aErrorStr.AssignLiteral("Cannot create dbus message iter!");
} else {
ParseProperties(&iter, aValue, aErrorStr, aPropertyTypes,
aPropertyTypeLen);
}
}
}
void UnpackAdapterPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr)
{
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
sAdapterProperties,
ArrayLength(sAdapterProperties));
}
void UnpackDevicePropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr)
{
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
sDeviceProperties,
ArrayLength(sDeviceProperties));
}
void UnpackManagerPropertiesMessage(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr)
{
UnpackPropertiesMessage(aMsg, aValue, aErrorStr,
sManagerProperties,
ArrayLength(sManagerProperties));
}
void
ParsePropertyChange(DBusMessage* aMsg, Properties* aPropertyTypes,
const int aPropertiesTypeLen,
InfallibleTArray<BluetoothNamedValue>& aProperties)
GetManagerPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
{
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackManagerPropertiesMessage);
}
void
GetAdapterPropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
{
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackAdapterPropertiesMessage);
}
void
GetDevicePropertiesCallback(DBusMessage* aMsg, void* aBluetoothReplyRunnable)
{
RunDBusCallback(aMsg, aBluetoothReplyRunnable, UnpackDevicePropertiesMessage);
}
static DBusCallback sBluetoothDBusPropCallbacks[] =
{
GetManagerPropertiesCallback,
GetAdapterPropertiesCallback,
GetDevicePropertiesCallback
};
MOZ_STATIC_ASSERT(sizeof(sBluetoothDBusPropCallbacks) == sizeof(sBluetoothDBusIfaces),
"DBus Property callback array and DBus interface array must be same size");
void
ParsePropertyChange(DBusMessage* aMsg, BluetoothValue& aValue,
nsAString& aErrorStr, Properties* aPropertyTypes,
const int aPropertyTypeLen)
{
DBusMessageIter iter;
DBusError err;
int prop_index = -1;
InfallibleTArray<BluetoothNamedValue> props;
dbus_error_init(&err);
if (!dbus_message_iter_init(aMsg, &iter)) {
@ -362,10 +463,13 @@ ParsePropertyChange(DBusMessage* aMsg, Properties* aPropertyTypes,
return;
}
if (!GetProperty(iter, aPropertyTypes, aPropertiesTypeLen,
&prop_index, aProperties)) {
if (!GetProperty(iter, aPropertyTypes, aPropertyTypeLen,
&prop_index, props)) {
NS_WARNING("Can't get property!");
aErrorStr.AssignLiteral("Can't get property!");
return;
}
aValue = props;
}
// Called by dbus during WaitForAndDispatchEventNative()
@ -392,11 +496,8 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
nsString signalName;
dbus_error_init(&err);
signalPath = NS_ConvertUTF8toUTF16(dbus_message_get_path(aMsg));
LOG("%s: Received signal %s:%s from %s\n", __FUNCTION__,
dbus_message_get_interface(aMsg), dbus_message_get_member(aMsg),
dbus_message_get_path(aMsg));
signalName = NS_ConvertUTF8toUTF16(dbus_message_get_member(aMsg));
nsString errorStr;
BluetoothValue v;
if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceFound")) {
@ -408,21 +509,28 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
InfallibleTArray<BluetoothNamedValue> value;
const char* addr;
dbus_message_iter_get_basic(&iter, &addr);
value.AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Address"),
NS_ConvertUTF8toUTF16(addr)));
if (dbus_message_iter_next(&iter)) {
ParseProperties(&iter,
remote_device_properties,
ArrayLength(remote_device_properties),
value);
NS_ASSERTION(value.Length() != 0, "Properties returned empty!");
v = value;
v,
errorStr,
sDeviceProperties,
ArrayLength(sDeviceProperties));
if (v.type() == BluetoothValue::TArrayOfBluetoothNamedValue)
{
// The DBus DeviceFound message actually passes back a key value object
// with the address as the key and the rest of the device properties as
// a dict value. After we parse out the properties, we need to go back
// and add the address to the ipdl dict we've created to make sure we
// have all of the information to correctly build the device.
v.get_ArrayOfBluetoothNamedValue()
.AppendElement(BluetoothNamedValue(NS_LITERAL_STRING("Address"),
NS_ConvertUTF8toUTF16(addr)));
}
} else {
NS_WARNING("DBus iterator not as long as expected!");
errorStr.AssignLiteral("DBus device found message structure not as expected!");
}
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceDisappeared")) {
const char* str;
@ -430,6 +538,7 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
DBUS_TYPE_STRING, &str,
DBUS_TYPE_INVALID)) {
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
errorStr.AssignLiteral("Cannot parse device address!");
}
v = NS_ConvertUTF8toUTF16(str);
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "DeviceCreated")) {
@ -438,16 +547,39 @@ EventFilter(DBusConnection* aConn, DBusMessage* aMsg, void* aData)
DBUS_TYPE_OBJECT_PATH, &str,
DBUS_TYPE_INVALID)) {
LOG_AND_FREE_DBUS_ERROR_WITH_MSG(&err, aMsg);
errorStr.AssignLiteral("Cannot parse device path!");
}
v = NS_ConvertUTF8toUTF16(str);
} else if (dbus_message_is_signal(aMsg, DBUS_ADAPTER_IFACE, "PropertyChanged")) {
InfallibleTArray<BluetoothNamedValue> value;
ParsePropertyChange(aMsg,
(Properties*)&adapter_properties,
ArrayLength(adapter_properties),
value);
NS_ASSERTION(value.Length() != 0, "Properties returned empty!");
v = value;
v,
errorStr,
sAdapterProperties,
ArrayLength(sAdapterProperties));
} else if (dbus_message_is_signal(aMsg, DBUS_DEVICE_IFACE, "PropertyChanged")) {
ParsePropertyChange(aMsg,
v,
errorStr,
sDeviceProperties,
ArrayLength(sDeviceProperties));
} else if (dbus_message_is_signal(aMsg, DBUS_MANAGER_IFACE, "PropertyChanged")) {
ParsePropertyChange(aMsg,
v,
errorStr,
sManagerProperties,
ArrayLength(sManagerProperties));
} else {
#ifdef DEBUG
nsCAutoString signalStr;
signalStr += dbus_message_get_member(aMsg);
signalStr += " Signal not handled!";
NS_WARNING(signalStr.get());
#endif
}
if (!errorStr.IsEmpty()) {
NS_WARNING(NS_ConvertUTF16toUTF8(errorStr).get());
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
BluetoothSignal signal(signalName, signalPath, v);
@ -577,3 +709,131 @@ BluetoothDBusService::StartDiscoveryInternal(const nsAString& aAdapterPath,
{
return SendDiscoveryMessage(aAdapterPath, "StartDiscovery", aRunnable);
}
nsresult
BluetoothDBusService::GetProperties(BluetoothObjectType aType,
const nsAString& aPath,
BluetoothReplyRunnable* aRunnable)
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
MOZ_ASSERT(aType < ArrayLength(sBluetoothDBusIfaces));
MOZ_ASSERT(aType < ArrayLength(sBluetoothDBusPropCallbacks));
const char* interface = sBluetoothDBusIfaces[aType];
DBusCallback callback = sBluetoothDBusPropCallbacks[aType];
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
if (!dbus_func_args_async(mConnection,
1000,
callback,
(void*)aRunnable,
NS_ConvertUTF16toUTF8(aPath).get(),
interface,
"GetProperties",
DBUS_TYPE_INVALID)) {
NS_WARNING("Could not start async function!");
return NS_ERROR_FAILURE;
}
runnable.forget();
return NS_OK;
}
nsresult
BluetoothDBusService::SetProperty(BluetoothObjectType aType,
const nsAString& aPath,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable)
{
NS_ASSERTION(NS_IsMainThread(), "Must be called from main thread!");
MOZ_ASSERT(aType < ArrayLength(sBluetoothDBusIfaces));
const char* interface = sBluetoothDBusIfaces[aType];
/* Compose the command */
DBusMessage* msg = dbus_message_new_method_call("org.bluez",
NS_ConvertUTF16toUTF8(aPath).get(),
interface,
"SetProperty");
if (!msg) {
NS_WARNING("Could not allocate D-Bus message object!");
return NS_ERROR_FAILURE;
}
const char* propName = NS_ConvertUTF16toUTF8(aValue.name()).get();
if (!dbus_message_append_args(msg, DBUS_TYPE_STRING, &propName, DBUS_TYPE_INVALID)) {
NS_WARNING("Couldn't append arguments to dbus message!");
return NS_ERROR_FAILURE;
}
int type;
int tmp_int;
void* val;
nsCString str;
if (aValue.value().type() == BluetoothValue::Tuint32_t) {
tmp_int = aValue.value().get_uint32_t();
val = &tmp_int;
type = DBUS_TYPE_UINT32;
} else if (aValue.value().type() == BluetoothValue::TnsString) {
str = NS_ConvertUTF16toUTF8(aValue.value().get_nsString());
val = (void*)str.get();
type = DBUS_TYPE_STRING;
} else if (aValue.value().type() == BluetoothValue::Tbool) {
tmp_int = aValue.value().get_bool() ? 1 : 0;
val = &(tmp_int);
type = DBUS_TYPE_BOOLEAN;
} else {
NS_WARNING("Property type not handled!");
dbus_message_unref(msg);
return NS_ERROR_FAILURE;
}
DBusMessageIter value_iter, iter;
dbus_message_iter_init_append(msg, &iter);
char var_type[2] = {(char)type, '\0'};
if (!dbus_message_iter_open_container(&iter, DBUS_TYPE_VARIANT, var_type, &value_iter) ||
!dbus_message_iter_append_basic(&value_iter, type, val) ||
!dbus_message_iter_close_container(&iter, &value_iter)) {
NS_WARNING("Could not append argument to method call!");
dbus_message_unref(msg);
return NS_ERROR_FAILURE;
}
nsRefPtr<BluetoothReplyRunnable> runnable = aRunnable;
// msg is unref'd as part of dbus_func_send_async
if (!dbus_func_send_async(mConnection,
msg,
1000,
GetVoidCallback,
(void*)aRunnable)) {
NS_WARNING("Could not start async function!");
return NS_ERROR_FAILURE;
}
runnable.forget();
return NS_OK;
}
nsString
GetObjectPathFromAddress(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress)
{
// The object path would be like /org/bluez/2906/hci0/dev_00_23_7F_CB_B4_F1,
// and the adapter path would be the first part of the object path, accoring
// to the example above, it's /org/bluez/2906/hci0.
nsString devicePath(aAdapterPath);
devicePath.AppendLiteral("/dev_");
devicePath.Append(aDeviceAddress);
devicePath.ReplaceChar(':', '_');
return devicePath;
}
bool
BluetoothDBusService::GetDevicePath(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,
nsAString& aDevicePath)
{
aDevicePath = GetObjectPathFromAddress(aAdapterPath, aDeviceAddress);
return true;
}

View File

@ -16,67 +16,46 @@ class DBusMessage;
BEGIN_BLUETOOTH_NAMESPACE
/**
* BluetoothService functions are used to dispatch messages to Bluetooth DOM
* objects on the main thread, as well as provide platform independent access
* to BT functionality. Tasks for polling for outside messages will usually
* happen on the IO Thread (see ipc/dbus for instance), and these messages will
* be encased in runnables that will then be distributed via observers managed
* here.
* BluetoothDBusService is the implementation of BluetoothService for DBus on
* linux/android/B2G. Function comments are in BluetoothService.h
*/
class BluetoothDBusService : public BluetoothService
, private mozilla::ipc::RawDBusConnection
{
public:
/**
* Set up variables and start the platform specific connection. Must
* be called from outside main thread.
*
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
* otherwise
*/
virtual nsresult StartInternal();
/**
* Stop the platform specific connection. Must be called from outside main
* thread.
*
* @return NS_OK if connection starts successfully, NS_ERROR_FAILURE
* otherwise
*/
virtual nsresult StopInternal();
/**
* Returns the path of the default adapter, implemented via a platform
* specific method.
*
* @return Default adapter path/name on success, NULL otherwise
*/
virtual nsresult GetDefaultAdapterPathInternal(BluetoothReplyRunnable* aRunnable);
/**
* Start device discovery (platform specific implementation)
*
* @param aAdapterPath Adapter to start discovery on
*
* @return NS_OK if discovery stopped correctly, NS_ERROR_FAILURE otherwise
*/
virtual nsresult StartDiscoveryInternal(const nsAString& aAdapterPath,
BluetoothReplyRunnable* aRunnable);
/**
* Stop device discovery (platform specific implementation)
*
* @param aAdapterPath Adapter to stop discovery on
*
* @return NS_OK if discovery stopped correctly, NS_ERROR_FAILURE otherwise
*/
virtual nsresult StopDiscoveryInternal(const nsAString& aAdapterPath,
BluetoothReplyRunnable* aRunnable);
virtual nsresult
GetProperties(BluetoothObjectType aType,
const nsAString& aPath,
BluetoothReplyRunnable* aRunnable);
virtual nsresult
SetProperty(BluetoothObjectType aType,
const nsAString& aPath,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable);
virtual bool
GetDevicePath(const nsAString& aAdapterPath,
const nsAString& aDeviceAddress,
nsAString& aDevicePath);
private:
nsresult SendGetPropertyMessage(const nsAString& aPath,
const char* aInterface,
void (*aCB)(DBusMessage *, void *),
BluetoothReplyRunnable* aRunnable);
nsresult SendDiscoveryMessage(const nsAString& aAdapterPath,
const char* aMessageName,
BluetoothReplyRunnable* aRunnable);
nsresult SendSetPropertyMessage(const nsString& aPath, const char* aInterface,
const BluetoothNamedValue& aValue,
BluetoothReplyRunnable* aRunnable);
};
END_BLUETOOTH_NAMESPACE

View File

@ -170,7 +170,7 @@ EventFilter(DBusConnection *aConn, DBusMessage *aMsg,
nsresult
StartBluetoothConnection()
{
if(sDBusConnection) {
if (sDBusConnection) {
NS_WARNING("DBusConnection already established, skipping");
return NS_OK;
}
@ -193,7 +193,7 @@ StartBluetoothConnection()
nsresult
StopBluetoothConnection()
{
if(!sDBusConnection) {
if (!sDBusConnection) {
NS_WARNING("DBusConnection does not exist, nothing to stop, skipping.");
return NS_OK;
}

View File

@ -9,7 +9,7 @@
interface nsIDOMDOMRequest;
interface nsIDOMBluetoothDevice;
[scriptable, builtinclass, uuid(48df7f05-2bbc-4ac8-aa88-9fecd4c24028)]
[scriptable, builtinclass, uuid(86e9fe78-ce64-476e-a357-333f7d3c8980)]
interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
{
readonly attribute DOMString address;
@ -20,11 +20,17 @@ interface nsIDOMBluetoothAdapter : nsIDOMEventTarget
[implicit_jscontext]
readonly attribute jsval devices;
[implicit_jscontext]
readonly attribute jsval uuids;
readonly attribute DOMString name;
readonly attribute bool discoverable;
// Unit: sec
readonly attribute unsigned long discoverableTimeout;
nsIDOMDOMRequest setName(in DOMString name);
nsIDOMDOMRequest setDiscoverable(in bool discoverable);
nsIDOMDOMRequest setDiscoverableTimeout(in unsigned long timeout);
nsIDOMDOMRequest startDiscovery();
nsIDOMDOMRequest stopDiscovery();
// Fired when discoverying and any device is discovered.

View File

@ -6,13 +6,13 @@
#include "nsIDOMEventTarget.idl"
[scriptable, builtinclass, uuid(2c446123-b5dd-4631-80f6-eda91befd8c9)]
[scriptable, builtinclass, uuid(24c64513-9587-46c6-b718-bb9b9a754b0d)]
interface nsIDOMBluetoothDevice : nsIDOMEventTarget
{
readonly attribute DOMString address;
readonly attribute DOMString name;
[binaryname(DeviceClass)] readonly attribute unsigned long class;
[implicit_jscontext] readonly attribute jsval uuids;
readonly attribute bool connected;
readonly attribute bool paired;
attribute nsIDOMEventListener onpropertychanged;

View File

@ -0,0 +1,13 @@
/* -*- Mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 40 -*- */
/* vim: set ts=2 et sw=2 tw=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/. */
#include "nsIDOMEvent.idl"
[scriptable, builtinclass, uuid(2604ce78-abaa-4af4-b456-daa4c6386a11)]
interface nsIDOMBluetoothPropertyEvent : nsIDOMEvent
{
readonly attribute DOMString property;
};

View File

@ -193,7 +193,9 @@ BrowserElementParent::OpenWindowInProcess(nsIDOMWindow* aOpenerWindow,
NS_ENSURE_TRUE(popupFrameElement, false);
nsCAutoString spec;
aURI->GetSpec(spec);
if (aURI) {
aURI->GetSpec(spec);
}
bool dispatchSucceeded =
DispatchOpenWindowEvent(openerFrameElement, popupFrameElement,
NS_ConvertUTF8toUTF16(spec),

Some files were not shown because too many files have changed in this diff Show More