зеркало из https://github.com/mozilla/gecko-dev.git
Merge m-c to elm
This commit is contained in:
Коммит
2c8842b2b6
|
@ -227,7 +227,7 @@ endif
|
|||
|
||||
ifdef MOZ_PSEUDO_DERECURSE
|
||||
# Interdependencies for parallel export.
|
||||
js/xpconnect/src/export: config/makefiles/precompile/export
|
||||
accessible/src/xpcom/export: config/makefiles/precompile/export
|
||||
js/xpconnect/src/export: dom/bindings/export
|
||||
accessible/src/xpcom/export: xpcom/xpidl/export
|
||||
js/src/export: mfbt/export
|
||||
endif
|
||||
|
|
|
@ -229,6 +229,9 @@ public:
|
|||
|
||||
NS_IMETHODIMP Notify(nsITimer* aTimer) MOZ_FINAL
|
||||
{
|
||||
if (!mContent->IsInDoc())
|
||||
return NS_OK;
|
||||
|
||||
nsIPresShell* ps = mContent->OwnerDoc()->GetShell();
|
||||
if (ps) {
|
||||
DocAccessible* doc = ps->GetDocAccessible();
|
||||
|
@ -1022,8 +1025,11 @@ nsAccessibilityService::GetOrCreateAccessible(nsINode* aNode,
|
|||
} else if (content->Tag() == nsGkAtoms::svg) {
|
||||
newAcc = new EnumRoleAccessible(content, document, roles::DIAGRAM);
|
||||
}
|
||||
} else if (content->IsMathML(nsGkAtoms::math)) {
|
||||
} else if (content->IsMathML()){
|
||||
if (content->Tag() == nsGkAtoms::math)
|
||||
newAcc = new EnumRoleAccessible(content, document, roles::EQUATION);
|
||||
else
|
||||
newAcc = new HyperTextAccessible(content, document);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -285,7 +285,7 @@ this.OutputGenerator = {
|
|||
'calendar': INCLUDE_DESC | INCLUDE_NAME,
|
||||
'combobox list': INCLUDE_DESC,
|
||||
'combobox option': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
|
||||
'listbox option': NAME_FROM_SUBTREE_RULE,
|
||||
'listbox option': INCLUDE_DESC | NAME_FROM_SUBTREE_RULE,
|
||||
'listbox rich option': NAME_FROM_SUBTREE_RULE,
|
||||
'gridcell': NAME_FROM_SUBTREE_RULE,
|
||||
'check rich option': NAME_FROM_SUBTREE_RULE,
|
||||
|
|
|
@ -38,6 +38,7 @@ const ROLE_DEFINITION_LIST = Ci.nsIAccessibleRole.ROLE_DEFINITION_LIST;
|
|||
const ROLE_LISTITEM = Ci.nsIAccessibleRole.ROLE_LISTITEM;
|
||||
const ROLE_BUTTONDROPDOWNGRID = Ci.nsIAccessibleRole.ROLE_BUTTONDROPDOWNGRID;
|
||||
const ROLE_LISTBOX = Ci.nsIAccessibleRole.ROLE_LISTBOX;
|
||||
const ROLE_OPTION = Ci.nsIAccessibleRole.ROLE_OPTION;
|
||||
const ROLE_SLIDER = Ci.nsIAccessibleRole.ROLE_SLIDER;
|
||||
const ROLE_HEADING = Ci.nsIAccessibleRole.ROLE_HEADING;
|
||||
const ROLE_HEADER = Ci.nsIAccessibleRole.ROLE_HEADER;
|
||||
|
@ -110,6 +111,7 @@ var gSimpleTraversalRoles =
|
|||
ROLE_HEADING,
|
||||
ROLE_SLIDER,
|
||||
ROLE_SPINBUTTON,
|
||||
ROLE_OPTION,
|
||||
// Used for traversing in to child OOP frames.
|
||||
ROLE_INTERNAL_FRAME];
|
||||
|
||||
|
|
|
@ -9,10 +9,8 @@
|
|||
<![CDATA[
|
||||
function doTest()
|
||||
{
|
||||
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
|
||||
|
||||
var accRetrieval = Components.classes["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(Components.interfaces.nsIAccessibleRetrieval);
|
||||
var accRetrieval = SpecialPowers.Cc["@mozilla.org/accessibleRetrieval;1"].
|
||||
getService(SpecialPowers.Ci.nsIAccessibleRetrieval);
|
||||
|
||||
var treecol = document.getElementById("col");
|
||||
var x = treecol.boxObject.screenX;
|
||||
|
|
|
@ -1 +1,2 @@
|
|||
load 471493.xul
|
||||
# Disabled because it causes assertions/crashes in later crashtests, see bug 918246
|
||||
skip load 471493.xul
|
||||
|
|
|
@ -330,9 +330,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
|
|||
// The number of random entries to send with a gethash request.
|
||||
pref("urlclassifier.gethashnoise", 4);
|
||||
|
||||
// The list of tables that use the gethash request to confirm partial results.
|
||||
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
|
||||
|
||||
// If an urlclassifier table has not been updated in this number of seconds,
|
||||
// a gethash request will be forced to check that the result is still in
|
||||
// the database.
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
{
|
||||
"config_version": 2,
|
||||
"tooltool_manifest": "releng-emulator-ics.tt",
|
||||
"mock_target": "mozilla-centos6-x86_64",
|
||||
"mock_packages": ["ccache", "make", "bison", "flex", "gcc", "g++", "mpfr", "zlib-devel", "ncurses-devel", "zip", "autoconf213", "glibc-static", "perl-Digest-SHA", "wget", "alsa-lib", "atk", "cairo", "dbus-glib", "fontconfig", "freetype", "glib2", "gtk2", "libXRender", "libXt", "pango", "mozilla-python27-mercurial", "openssh-clients", "nss-devel", "glibc-devel.i686", "libstdc++.i686", "zlib-devel.i686", "ncurses-devel.i686", "libX11-devel.i686", "mesa-libGL-devel.i686", "mesa-libGL-devel", "libX11-devel", "git"],
|
||||
"mock_files": [["/home/cltbld/.ssh", "/home/mock_mozilla/.ssh"]],
|
||||
"build_targets": ["droid", "package-emulator", "package-tests"],
|
||||
"upload_files": [
|
||||
"{workdir}/out/target/product/generic/*.tar.bz2",
|
||||
"{workdir}/out/target/product/generic/tests/*.zip",
|
||||
"{workdir}/out/emulator.tar.gz",
|
||||
"{objdir}/dist/b2g-*.crashreporter-symbols.zip",
|
||||
"{workdir}/sources.xml"
|
||||
],
|
||||
"upload_platform": "emulator-ics",
|
||||
"gecko_l10n_root": "http://hg.mozilla.org/l10n-central",
|
||||
"gaia": {
|
||||
"l10n": {
|
||||
"vcs": "hgtool",
|
||||
"root": "http://hg.mozilla.org/gaia-l10n"
|
||||
}
|
||||
},
|
||||
"b2g_manifest": "emulator.xml",
|
||||
"b2g_manifest_branch": "master"
|
||||
}
|
|
@ -0,0 +1,2 @@
|
|||
[
|
||||
]
|
|
@ -1,4 +1,4 @@
|
|||
{
|
||||
"revision": "43bc58df001f2b870fd2d1eb80723cfdccdc7b67",
|
||||
"revision": "6b82ab58ac7e7cbce89a6718659311a1ce6b7436",
|
||||
"repo_path": "/integration/gaia-central"
|
||||
}
|
||||
|
|
|
@ -803,9 +803,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
|
|||
// The number of random entries to send with a gethash request.
|
||||
pref("urlclassifier.gethashnoise", 4);
|
||||
|
||||
// The list of tables that use the gethash request to confirm partial results.
|
||||
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
|
||||
|
||||
// If an urlclassifier table has not been updated in this number of seconds,
|
||||
// a gethash request will be forced to check that the result is still in
|
||||
// the database.
|
||||
|
|
|
@ -804,7 +804,9 @@ var gPluginHandler = {
|
|||
let contentDoc = aBrowser.contentDocument;
|
||||
let cwu = contentWindow.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
let plugins = cwu.plugins;
|
||||
// cwu.plugins may contain non-plugin <object>s, filter them out
|
||||
let plugins = cwu.plugins.filter((plugin) =>
|
||||
plugin.getContentTypeForMIMEType(plugin.actualType) == Ci.nsIObjectLoadingContent.TYPE_PLUGIN);
|
||||
if (plugins.length == 0) {
|
||||
if (notification) {
|
||||
PopupNotifications.remove(notification);
|
||||
|
|
|
@ -874,18 +874,27 @@ SocialToolbar = {
|
|||
let toggleNotificationsCommand = document.getElementById("Social:ToggleNotifications");
|
||||
toggleNotificationsCommand.setAttribute("hidden", !socialEnabled);
|
||||
|
||||
let parent = document.getElementById("social-notification-panel");
|
||||
while (parent.hasChildNodes()) {
|
||||
let frame = parent.firstChild;
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
parent.removeChild(frame);
|
||||
}
|
||||
|
||||
// we need to remove buttons and frames if !socialEnabled or the provider
|
||||
// has changed (frame origin does not match current provider). We only
|
||||
// remove frames that are "attached" to buttons in this toolbar button since
|
||||
// other buttons may also be using grouped frames.
|
||||
let tbi = document.getElementById("social-provider-button");
|
||||
if (tbi) {
|
||||
// buttons after social-provider-button are ambient icons
|
||||
while (tbi.nextSibling) {
|
||||
tbi.parentNode.removeChild(tbi.nextSibling);
|
||||
let next = tbi.nextSibling;
|
||||
let currentOrigin = Social.provider ? Social.provider.origin : null;
|
||||
|
||||
while (next) {
|
||||
let button = next;
|
||||
next = next.nextSibling;
|
||||
// get the frame for this button
|
||||
let frameId = button.getAttribute("notificationFrameId");
|
||||
let frame = document.getElementById(frameId);
|
||||
if (!socialEnabled || frame.getAttribute("origin") != currentOrigin) {
|
||||
SharedFrame.forgetGroup(frame.id);
|
||||
frame.parentNode.removeChild(frame);
|
||||
button.parentNode.removeChild(button);
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
|
|
@ -259,7 +259,7 @@ panel[noactions] > richlistbox > richlistitem[type~="action"] > .ac-url-box > .a
|
|||
|
||||
#wrapper-urlbar-container > #urlbar-container > #urlbar {
|
||||
-moz-user-input: disabled;
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
#PopupAutoComplete {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
#placesTreechildren::-moz-tree-cell(grippyRow),
|
||||
#placesTreechildren::-moz-tree-cell-text(grippyRow),
|
||||
#placesTreechildren::-moz-tree-image(grippyRow) {
|
||||
cursor: -moz-grab;
|
||||
cursor: grab;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -194,6 +194,7 @@ MOCHITEST_BROWSER_FILES = \
|
|||
browser_contextSearchTabPosition.js \
|
||||
browser_CTP_drag_drop.js \
|
||||
browser_CTP_data_urls.js \
|
||||
browser_CTP_nonplugins.js \
|
||||
browser_CTP_resize.js \
|
||||
browser_ctrlTab.js \
|
||||
browser_customize_popupNotification.js \
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
var rootDir = getRootDirectory(gTestPath);
|
||||
const gTestRoot = rootDir;
|
||||
const gHttpTestRoot = rootDir.replace("chrome://mochitests/content/", "http://127.0.0.1:8888/");
|
||||
|
||||
var gTestBrowser = null;
|
||||
var gNextTest = null;
|
||||
var gPluginHost = Components.classes["@mozilla.org/plugin/host;1"].getService(Components.interfaces.nsIPluginHost);
|
||||
var gRunNextTestAfterPluginRemoved = false;
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// This listens for the next opened tab and checks it is of the right url.
|
||||
// opencallback is called when the new tab is fully loaded
|
||||
// closecallback is called when the tab is closed
|
||||
function TabOpenListener(url, opencallback, closecallback) {
|
||||
this.url = url;
|
||||
this.opencallback = opencallback;
|
||||
this.closecallback = closecallback;
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabOpen", this, false);
|
||||
}
|
||||
|
||||
TabOpenListener.prototype = {
|
||||
url: null,
|
||||
opencallback: null,
|
||||
closecallback: null,
|
||||
tab: null,
|
||||
browser: null,
|
||||
|
||||
handleEvent: function(event) {
|
||||
if (event.type == "TabOpen") {
|
||||
gBrowser.tabContainer.removeEventListener("TabOpen", this, false);
|
||||
this.tab = event.originalTarget;
|
||||
this.browser = this.tab.linkedBrowser;
|
||||
gBrowser.addEventListener("pageshow", this, false);
|
||||
} else if (event.type == "pageshow") {
|
||||
if (event.target.location.href != this.url)
|
||||
return;
|
||||
gBrowser.removeEventListener("pageshow", this, false);
|
||||
this.tab.addEventListener("TabClose", this, false);
|
||||
var url = this.browser.contentDocument.location.href;
|
||||
is(url, this.url, "Should have opened the correct tab");
|
||||
this.opencallback(this.tab, this.browser.contentWindow);
|
||||
} else if (event.type == "TabClose") {
|
||||
if (event.originalTarget != this.tab)
|
||||
return;
|
||||
this.tab.removeEventListener("TabClose", this, false);
|
||||
this.opencallback = null;
|
||||
this.tab = null;
|
||||
this.browser = null;
|
||||
// Let the window close complete
|
||||
executeSoon(this.closecallback);
|
||||
this.closecallback = null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
registerCleanupFunction(function() {
|
||||
clearAllPluginPermissions();
|
||||
Services.prefs.clearUserPref("extensions.blocklist.suppressUI");
|
||||
gTestBrowser.removeEventListener("PluginRemoved", handlePluginRemoved, true, true);
|
||||
});
|
||||
Services.prefs.setBoolPref("extensions.blocklist.suppressUI", true);
|
||||
|
||||
var newTab = gBrowser.addTab();
|
||||
gBrowser.selectedTab = newTab;
|
||||
gTestBrowser = gBrowser.selectedBrowser;
|
||||
gTestBrowser.addEventListener("load", pageLoad, true);
|
||||
gTestBrowser.addEventListener("PluginRemoved", handlePluginRemoved, true, true);
|
||||
|
||||
Services.prefs.setBoolPref("plugins.click_to_play", true);
|
||||
setTestPluginEnabledState(Ci.nsIPluginTag.STATE_CLICKTOPLAY);
|
||||
|
||||
prepareTest(runAfterPluginBindingAttached(test1), gHttpTestRoot + "plugin_two_types.html");
|
||||
}
|
||||
|
||||
function finishTest() {
|
||||
clearAllPluginPermissions();
|
||||
gTestBrowser.removeEventListener("load", pageLoad, true);
|
||||
gBrowser.removeCurrentTab();
|
||||
window.focus();
|
||||
finish();
|
||||
}
|
||||
|
||||
function pageLoad() {
|
||||
// The plugin events are async dispatched and can come after the load event
|
||||
// This just allows the events to fire before we then go on to test the states
|
||||
executeSoon(gNextTest);
|
||||
}
|
||||
|
||||
function prepareTest(nextTest, url) {
|
||||
gNextTest = nextTest;
|
||||
gTestBrowser.contentWindow.location = url;
|
||||
}
|
||||
|
||||
// Due to layout being async, "PluginBindAttached" may trigger later.
|
||||
// This wraps a function to force a layout flush, thus triggering it,
|
||||
// and schedules the function execution so they're definitely executed
|
||||
// afterwards.
|
||||
function runAfterPluginBindingAttached(func) {
|
||||
return function() {
|
||||
let doc = gTestBrowser.contentDocument;
|
||||
let elems = doc.getElementsByTagName('embed');
|
||||
if (elems.length < 1) {
|
||||
elems = doc.getElementsByTagName('object');
|
||||
}
|
||||
elems[0].clientTop;
|
||||
executeSoon(func);
|
||||
};
|
||||
}
|
||||
|
||||
function handlePluginRemoved() {
|
||||
if (gRunNextTestAfterPluginRemoved) {
|
||||
executeSoon(gNextTest);
|
||||
gRunNextTestAfterPluginRemoved = false;
|
||||
}
|
||||
}
|
||||
|
||||
function runAfterPluginRemoved(func) {
|
||||
gNextTest = func;
|
||||
gRunNextTestAfterPluginRemoved = true;
|
||||
}
|
||||
|
||||
// Test that the click-to-play notification is not shown for non-plugin object elements
|
||||
|
||||
function test1() {
|
||||
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(popupNotification, "Test 1, Should have a click-to-play notification");
|
||||
|
||||
let plugin = gTestBrowser.contentDocument.getElementById("secondtestA");
|
||||
plugin.parentNode.removeChild(plugin);
|
||||
plugin = gTestBrowser.contentDocument.getElementById("secondtestB");
|
||||
plugin.parentNode.removeChild(plugin);
|
||||
|
||||
let image = gTestBrowser.contentDocument.createElement("object");
|
||||
image.type = "image/png";
|
||||
image.data = "moz.png";
|
||||
gTestBrowser.contentDocument.body.appendChild(image);
|
||||
|
||||
runAfterPluginRemoved(test2);
|
||||
}
|
||||
|
||||
function test2() {
|
||||
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(popupNotification, "Test 2, Should have a click-to-play notification");
|
||||
|
||||
let plugin = gTestBrowser.contentDocument.getElementById("test");
|
||||
plugin.parentNode.removeChild(plugin);
|
||||
|
||||
runAfterPluginRemoved(() => executeSoon(test3));
|
||||
}
|
||||
|
||||
function test3() {
|
||||
let popupNotification = PopupNotifications.getNotification("click-to-play-plugins", gTestBrowser);
|
||||
ok(!popupNotification, "Test 3, Should not have a click-to-play notification");
|
||||
|
||||
finishTest();
|
||||
}
|
|
@ -1499,7 +1499,7 @@
|
|||
</binding>
|
||||
|
||||
<binding id="click-to-play-plugins-notification" extends="chrome://global/content/bindings/notification.xml#popup-notification">
|
||||
<content align="start" class="click-to-play-plugins-notification-content">
|
||||
<content align="start" style="width: &pluginNotification.width;;">
|
||||
<xul:vbox flex="1" align="stretch" class="popup-notification-main-box"
|
||||
xbl:inherits="popupid">
|
||||
<xul:hbox class="click-to-play-plugins-notification-description-box" flex="1" align="start">
|
||||
|
|
|
@ -68,6 +68,23 @@ const IDB = {
|
|||
return deferred.promise;
|
||||
},
|
||||
|
||||
update: function(project) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
var transaction = IDB._db.transaction(["projects"], "readwrite");
|
||||
var objectStore = transaction.objectStore("projects");
|
||||
var request = objectStore.put(project);
|
||||
request.onerror = function(event) {
|
||||
deferred.reject("Unable to update project to the AppProjects indexedDB: " +
|
||||
this.error.name + " - " + this.error.message );
|
||||
};
|
||||
request.onsuccess = function() {
|
||||
deferred.resolve();
|
||||
};
|
||||
|
||||
return deferred.promise;
|
||||
},
|
||||
|
||||
remove: function(location) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
|
@ -110,6 +127,8 @@ const AppProjects = {
|
|||
// The packaged app local path is a valid id, but only on the client.
|
||||
// This origin will be used to generate the true id of an app:
|
||||
// its manifest URL.
|
||||
// If the app ends up specifying an explicit origin in its manifest,
|
||||
// we will override this random UUID on app install.
|
||||
packagedAppOrigin: generateUUID().toString().slice(1, -1)
|
||||
};
|
||||
return IDB.add(project).then(function () {
|
||||
|
@ -131,6 +150,14 @@ const AppProjects = {
|
|||
});
|
||||
},
|
||||
|
||||
update: function (project) {
|
||||
return IDB.update({
|
||||
type: project.type,
|
||||
location: project.location,
|
||||
packagedAppOrigin: project.packagedAppOrigin
|
||||
}).then(() => project);
|
||||
},
|
||||
|
||||
remove: function(location) {
|
||||
return IDB.remove(location).then(function () {
|
||||
let projects = store.object.projects;
|
||||
|
|
|
@ -208,9 +208,15 @@ let UI = {
|
|||
},
|
||||
|
||||
install: function(project) {
|
||||
let install;
|
||||
if (project.type == "packaged") {
|
||||
install = installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin);
|
||||
return installPackaged(this.connection.client, this.listTabsResponse.webappsActor, project.location, project.packagedAppOrigin)
|
||||
.then(({ appId }) => {
|
||||
// If the packaged app specified a custom origin override,
|
||||
// we need to update the local project origin
|
||||
project.packagedAppOrigin = appId;
|
||||
// And ensure the indexed db on disk is also updated
|
||||
AppProjects.update(project);
|
||||
});
|
||||
} else {
|
||||
let manifestURLObject = Services.io.newURI(project.location, null, null);
|
||||
let origin = Services.io.newURI(manifestURLObject.prePath, null, null);
|
||||
|
@ -219,9 +225,8 @@ let UI = {
|
|||
origin: origin.spec,
|
||||
manifestURL: project.location
|
||||
};
|
||||
install = installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
|
||||
return installHosted(this.connection.client, this.listTabsResponse.webappsActor, appId, metadata, project.manifest);
|
||||
}
|
||||
return install;
|
||||
},
|
||||
|
||||
start: function(project) {
|
||||
|
|
|
@ -116,6 +116,7 @@ function ResponsiveUI(aWindow, aTab)
|
|||
this.container = aWindow.gBrowser.getBrowserContainer(this.browser);
|
||||
this.stack = this.container.querySelector(".browserStack");
|
||||
this._telemetry = new Telemetry();
|
||||
this._floatingScrollbars = !this.mainWindow.matchMedia("(-moz-overlay-scrollbars)").matches;
|
||||
|
||||
|
||||
// Try to load presets from prefs
|
||||
|
@ -210,7 +211,6 @@ function ResponsiveUI(aWindow, aTab)
|
|||
|
||||
ResponsiveUI.prototype = {
|
||||
_transitionsEnabled: true,
|
||||
_floatingScrollbars: Services.appinfo.OS != "Darwin",
|
||||
get transitionsEnabled() this._transitionsEnabled,
|
||||
set transitionsEnabled(aValue) {
|
||||
this._transitionsEnabled = aValue;
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
winUtils.loadSheet(newThemeUrl, winUtils.AUTHOR_SHEET);
|
||||
|
||||
// Floating scrollbars à la osx
|
||||
if (Services.appinfo.OS != "Darwin") {
|
||||
if (!window.matchMedia("(-moz-overlay-scrollbars)").matches) {
|
||||
let scrollbarsUrl = Services.io.newURI(
|
||||
DEVTOOLS_SKIN_URL + "floating-scrollbars-light.css", null, null);
|
||||
|
||||
|
|
|
@ -52,8 +52,12 @@ MOCHITEST_BROWSER_FILES += \
|
|||
browser_bug705707_is_content_stylesheet_xul.css \
|
||||
browser_bug722196_identify_media_queries.html \
|
||||
browser_styleinspector_bug_677930_urls_clickable.html \
|
||||
browser_styleinspector_bug_677930_urls_clickable \
|
||||
browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \
|
||||
test-image.png \
|
||||
browser_ruleview_pseudoelement.html \
|
||||
$(NULL)
|
||||
|
||||
MOCHITEST_BUG_677940_DATA_FILES = \
|
||||
browser_styleinspector_bug_677930_urls_clickable/browser_styleinspector_bug_677930_urls_clickable.css \
|
||||
$(NULL)
|
||||
MOCHITEST_BUG_677940_DATA_DEST = $(MOCHITEST_BROWSER_DEST)/browser_styleinspector_bug_677930_urls_clickable
|
||||
INSTALL_TARGETS += MOCHITEST_BUG_677940_DATA
|
||||
|
|
|
@ -4522,6 +4522,7 @@ var Utils = {
|
|||
case "CSP":
|
||||
case "Invalid HSTS Headers":
|
||||
case "Insecure Password Field":
|
||||
case "SSL":
|
||||
return CATEGORY_SECURITY;
|
||||
|
||||
default:
|
||||
|
|
|
@ -341,7 +341,7 @@ Section "-Application" APP_IDX
|
|||
${AddDisabledDDEHandlerValues} "FirefoxHTML" "$2" "$8,1" \
|
||||
"${AppRegName} Document" ""
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
|
||||
"delete"
|
||||
"true"
|
||||
|
||||
; For pre win8, the following keys should only be set if we can write to HKLM.
|
||||
; For post win8, the keys below get set in both HKLM and HKCU.
|
||||
|
|
|
@ -415,7 +415,7 @@ FunctionEnd
|
|||
"${AppRegName} HTML Document" ""
|
||||
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" "${AppRegName} URL" \
|
||||
"delete"
|
||||
"true"
|
||||
Call RegisterCEH
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
|
@ -653,7 +653,7 @@ FunctionEnd
|
|||
${IsHandlerForInstallDir} "FirefoxURL" $R9
|
||||
${If} "$R9" == "true"
|
||||
${AddDisabledDDEHandlerValues} "FirefoxURL" "$2" "$8,1" \
|
||||
"${AppRegName} URL" "delete"
|
||||
"${AppRegName} URL" "true"
|
||||
${EndIf}
|
||||
|
||||
; An empty string is used for the 4th & 5th params because the following
|
||||
|
|
|
@ -672,6 +672,13 @@ just addresses the organization to follow, e.g. "This site is run by " -->
|
|||
<!ENTITY pluginActivateAlways.label "Allow and Remember">
|
||||
<!ENTITY pluginBlockNow.label "Block Plugin">
|
||||
|
||||
<!-- LOCALIZATION NOTE: (pluginNotification.width): This is used to determine the
|
||||
width of the plugin popup notification that can appear if a plugin has been
|
||||
blocked on a page. Should be wide enough to fit the pluginActivateNow.label
|
||||
and pluginActivateAlways.label strings above on a single line. This must be
|
||||
a CSS length value. -->
|
||||
<!ENTITY pluginNotification.width "28em">
|
||||
|
||||
<!ENTITY tabCrashed.header "Tab crashed">
|
||||
<!ENTITY tabCrashed.message "Well, this is embarrassing. We tried to display this Web page, but it's not responding.">
|
||||
<!ENTITY tabCrashed.checkSendReport "Tell &vendorShortName; about this crash so they can fix it.">
|
||||
|
|
|
@ -607,9 +607,6 @@ pref("urlclassifier.alternate_error_page", "blocked");
|
|||
// The number of random entries to send with a gethash request.
|
||||
pref("urlclassifier.gethashnoise", 4);
|
||||
|
||||
// The list of tables that use the gethash request to confirm partial results.
|
||||
pref("urlclassifier.gethashtables", "goog-phish-shavar,goog-malware-shavar");
|
||||
|
||||
// If an urlclassifier table has not been updated in this number of seconds,
|
||||
// a gethash request will be forced to check that the result is still in
|
||||
// the database.
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
/* vim:set ts=2 sw=2 sts=2 et: */
|
||||
/* 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/. */
|
||||
|
||||
@import url("floating-scrollbars.css");
|
||||
|
||||
scrollbar thumb {
|
||||
background-color: rgba(170,170,170,0.2) !important;
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
scrollbar {
|
||||
-moz-appearance: none;
|
||||
position: relative;
|
||||
background-color: transparent;
|
||||
background-image: none;
|
||||
border: 0px solid transparent;
|
||||
z-index: 2147483647;
|
||||
-moz-box-align: start;
|
||||
padding: 2px;
|
||||
}
|
||||
|
||||
scrollbar[orient="vertical"] {
|
||||
-moz-margin-start: -8px;
|
||||
min-width: 8px;
|
||||
max-width: 8px;
|
||||
}
|
||||
|
||||
scrollbar[orient="horizontal"] {
|
||||
margin-top: -8px;
|
||||
min-height: 8px;
|
||||
max-height: 8px;
|
||||
}
|
||||
|
||||
thumb {
|
||||
-moz-appearance: none !important;
|
||||
background-color: rgba(0,0,0,0.2);
|
||||
border-radius: 3px;
|
||||
}
|
|
@ -288,6 +288,8 @@ browser.jar:
|
|||
skin/classic/browser/devtools/debugger-step-in.png (devtools/debugger-step-in.png)
|
||||
skin/classic/browser/devtools/debugger-step-out.png (devtools/debugger-step-out.png)
|
||||
skin/classic/browser/devtools/debugger-step-over.png (devtools/debugger-step-over.png)
|
||||
skin/classic/browser/devtools/floating-scrollbars.css (devtools/floating-scrollbars.css)
|
||||
skin/classic/browser/devtools/floating-scrollbars-light.css (devtools/floating-scrollbars-light.css)
|
||||
skin/classic/browser/devtools/responsive-se-resizer.png (devtools/responsive-se-resizer.png)
|
||||
skin/classic/browser/devtools/responsive-vertical-resizer.png (devtools/responsive-vertical-resizer.png)
|
||||
skin/classic/browser/devtools/responsive-horizontal-resizer.png (devtools/responsive-horizontal-resizer.png)
|
||||
|
|
|
@ -2,10 +2,6 @@
|
|||
padding: 0px;
|
||||
}
|
||||
|
||||
.click-to-play-plugins-notification-content {
|
||||
width: 28em;
|
||||
}
|
||||
|
||||
.click-to-play-plugins-notification-center-box {
|
||||
border: 1px solid ThreeDShadow;
|
||||
margin: 10px;
|
||||
|
|
|
@ -171,6 +171,12 @@ AC_DEFUN([MOZ_COMPILER_OPTS],
|
|||
|
||||
AC_SUBST(DEVELOPER_OPTIONS)
|
||||
|
||||
if test -n "$DEVELOPER_OPTIONS" -a "${MOZ_PSEUDO_DERECURSE-unset}" = unset; then
|
||||
dnl Don't enable on pymake, because of bug 918652. Bug 912979 is an annoyance
|
||||
dnl with pymake, too.
|
||||
MOZ_PSEUDO_DERECURSE=no-parallel-export,no-pymake
|
||||
fi
|
||||
|
||||
MOZ_DEBUGGING_OPTS
|
||||
MOZ_RTTI
|
||||
if test "$CLANG_CXX"; then
|
||||
|
@ -194,7 +200,17 @@ if test -z "$GNU_CC"; then
|
|||
esac
|
||||
fi
|
||||
|
||||
if test "$GNU_CC" -a -n "$DEVELOPER_OPTIONS"; then
|
||||
if test -n "$DEVELOPER_OPTIONS"; then
|
||||
MOZ_FORCE_GOLD=1
|
||||
fi
|
||||
|
||||
MOZ_ARG_ENABLE_BOOL(gold,
|
||||
[ --enable-gold Enable GNU Gold Linker when it is not already the default],
|
||||
MOZ_FORCE_GOLD=1,
|
||||
MOZ_FORCE_GOLD=
|
||||
)
|
||||
|
||||
if test "$GNU_CC" -a -n "$MOZ_FORCE_GOLD"; then
|
||||
dnl if the default linker is BFD ld, check if gold is available and try to use it
|
||||
dnl for local builds only.
|
||||
if $CC -Wl,--version 2>&1 | grep -q "GNU ld"; then
|
||||
|
@ -208,6 +224,7 @@ if test "$GNU_CC" -a -n "$DEVELOPER_OPTIONS"; then
|
|||
esac
|
||||
if test -n "$GOLD"; then
|
||||
mkdir -p $_objdir/build/unix/gold
|
||||
rm -f $_objdir/build/unix/gold/ld
|
||||
ln -s "$GOLD" $_objdir/build/unix/gold/ld
|
||||
if $CC -B $_objdir/build/unix/gold -Wl,--version 2>&1 | grep -q "GNU gold"; then
|
||||
LDFLAGS="$LDFLAGS -B $_objdir/build/unix/gold"
|
||||
|
|
|
@ -74,5 +74,12 @@ if test "$?" != 0; then
|
|||
AC_MSG_ERROR([Python environment does not appear to be sane.])
|
||||
fi
|
||||
AC_MSG_RESULT([yes])
|
||||
|
||||
PYTHON_SITE_PACKAGES=`$PYTHON -c "import distutils.sysconfig; print distutils.sysconfig.get_python_lib()"`
|
||||
if test -z "$PYTHON_SITE_PACKAGES"; then
|
||||
AC_MSG_ERROR([Could not determine python site packages directory.])
|
||||
fi
|
||||
AC_SUBST([PYTHON_SITE_PACKAGES])
|
||||
|
||||
])
|
||||
|
||||
|
|
|
@ -7,4 +7,7 @@ Vagrant::Config.run do |config|
|
|||
config.vm.box = "precise64"
|
||||
config.vm.box_url = "http://files.vagrantup.com/precise64.box"
|
||||
config.vm.share_folder("gecko", "/gecko", "../..")
|
||||
# Doxygen needs more than the default memory or it will swap and be
|
||||
# extremely slow.
|
||||
config.vm.customize ["modifyvm", :id, "--memory", 1024]
|
||||
end
|
||||
|
|
|
@ -26,7 +26,7 @@ source_suffix = '.rst'
|
|||
master_doc = 'index'
|
||||
project = u'Mozilla Build System'
|
||||
year = datetime.now().year
|
||||
copyright = u'%s, Mozilla Foundation, CC BY-SA 3.0' % year
|
||||
copyright = u'%s, Mozilla Foundation, CC BY-SA 3.0 or any later version' % year
|
||||
|
||||
# Grab the version from the source tree's milestone.
|
||||
with open(os.path.join(mozilla_dir, 'config', 'milestone.txt'), 'rt') as fh:
|
||||
|
|
|
@ -10,12 +10,20 @@ def measure_vsize_threadfunc(proc, output_file):
|
|||
"""
|
||||
Measure the virtual memory usage of |proc| at regular intervals
|
||||
until it exits, then print the maximum value and write it to
|
||||
|output_file|.
|
||||
|output_file|. Also, print something to the console every
|
||||
half an hour to prevent the build job from getting killed when
|
||||
linking a large PGOed binary.
|
||||
"""
|
||||
maxvsize = 0
|
||||
idleTime = 0
|
||||
while proc.returncode is None:
|
||||
maxvsize, vsize = procmem.get_vmsize(proc._handle)
|
||||
time.sleep(0.5)
|
||||
idleTime += 0.5
|
||||
if idleTime > 30 * 60:
|
||||
print "Still linking, 30 minutes passed..."
|
||||
sys.stdout.flush()
|
||||
idleTime = 0
|
||||
print "TinderboxPrint: linker max vsize: %d" % maxvsize
|
||||
with open(output_file, "w") as f:
|
||||
f.write("%d\n" % maxvsize)
|
||||
|
|
|
@ -19,8 +19,10 @@ if __name__ == '__main__':
|
|||
|
||||
# This is meant as a temporary workaround until issues with many targets
|
||||
# and prerequisites is addressed. Bug 874210 tracks.
|
||||
#
|
||||
# The default recursion limit for CPython is 1000.
|
||||
try:
|
||||
sys.setrecursionlimit(2 * sys.getrecursionlimit())
|
||||
sys.setrecursionlimit(10000)
|
||||
except Exception:
|
||||
print >>sys.stderr, 'Unable to increase Python recursion limit.'
|
||||
|
||||
|
|
|
@ -171,8 +171,8 @@ class Rule(Statement):
|
|||
# Skip targets with no rules and no dependencies
|
||||
if not deps:
|
||||
return
|
||||
targets = self.targetexp.resolvesplit(makefile, makefile.variables)
|
||||
rule = data.Rule(deps, self.doublecolon, loc=self.targetexp.loc, weakdeps=True)
|
||||
targets = data.stripdotslashes(self.targetexp.resolvesplit(makefile, makefile.variables))
|
||||
rule = data.Rule(list(data.stripdotslashes(deps)), self.doublecolon, loc=self.targetexp.loc, weakdeps=True)
|
||||
for target in targets:
|
||||
makefile.gettarget(target).addrule(rule)
|
||||
makefile.foundtarget(target)
|
||||
|
|
|
@ -6,6 +6,7 @@ parsing command lines into argv and making sure that no shell magic is being use
|
|||
#TODO: ship pyprocessing?
|
||||
import multiprocessing
|
||||
import subprocess, shlex, re, logging, sys, traceback, os, imp, glob
|
||||
import site
|
||||
from collections import deque
|
||||
# XXXkhuey Work around http://bugs.python.org/issue1731717
|
||||
subprocess._cleanup = lambda: None
|
||||
|
@ -347,24 +348,15 @@ class PythonException(Exception):
|
|||
|
||||
def load_module_recursive(module, path):
|
||||
"""
|
||||
Emulate the behavior of __import__, but allow
|
||||
passing a custom path to search for modules.
|
||||
Like __import__, but allow passing a custom path to search for modules.
|
||||
"""
|
||||
bits = module.split('.')
|
||||
oldsyspath = sys.path
|
||||
for i, bit in enumerate(bits):
|
||||
dotname = '.'.join(bits[:i+1])
|
||||
sys.path = []
|
||||
for p in path:
|
||||
site.addsitedir(p)
|
||||
sys.path.extend(oldsyspath)
|
||||
try:
|
||||
f, path, desc = imp.find_module(bit, path)
|
||||
# Add the directory the module was found in to sys.path
|
||||
if path != '':
|
||||
abspath = os.path.abspath(path)
|
||||
if not os.path.isdir(abspath):
|
||||
abspath = os.path.dirname(path)
|
||||
sys.path = [abspath] + sys.path
|
||||
m = imp.load_module(dotname, f, path, desc)
|
||||
if f is None:
|
||||
path = m.__path__
|
||||
__import__(module)
|
||||
except ImportError:
|
||||
return
|
||||
finally:
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
./test: TEST-PASS
|
|
@ -0,0 +1,8 @@
|
|||
#T gmake skip
|
||||
|
||||
test:
|
||||
@echo $<
|
||||
|
||||
includedeps $(TESTPATH)/includedeps-stripdotslash.deps
|
||||
|
||||
TEST-PASS:
|
|
@ -99,6 +99,15 @@ endif
|
|||
CONFIG_TOOLS = $(MOZ_BUILD_ROOT)/config
|
||||
AUTOCONF_TOOLS = $(topsrcdir)/build/autoconf
|
||||
|
||||
# Disable MOZ_PSEUDO_DERECURSE when it contains no-pymake and we're running
|
||||
# pymake. This can be removed when no-pymake is removed from the default in
|
||||
# build/autoconf/compiler-opts.m4.
|
||||
ifdef .PYMAKE
|
||||
comma = ,
|
||||
ifneq (,$(filter no-pymake,$(subst $(comma), ,$(MOZ_PSEUDO_DERECURSE))))
|
||||
MOZ_PSEUDO_DERECURSE :=
|
||||
endif
|
||||
endif
|
||||
#
|
||||
# Strip off the excessively long version numbers on these platforms,
|
||||
# but save the version to allow multiple versions of the same base
|
||||
|
@ -132,7 +141,7 @@ SLEEP ?= sleep
|
|||
TOUCH ?= touch
|
||||
|
||||
ifdef .PYMAKE
|
||||
PYCOMMANDPATH += $(topsrcdir)/config
|
||||
PYCOMMANDPATH += $(PYTHON_SITE_PACKAGES)
|
||||
endif
|
||||
|
||||
PYTHON_PATH = $(PYTHON) $(topsrcdir)/config/pythonpath.py
|
||||
|
|
|
@ -68,6 +68,13 @@ def isObject(path):
|
|||
ends with OBJ_SUFFIX or .i_o'''
|
||||
return os.path.splitext(path)[1] in [conf.OBJ_SUFFIX, '.i_o']
|
||||
|
||||
def isDynamicLib(path):
|
||||
'''Returns whether the given path points to a dynamic library, that is,
|
||||
ends with DLL_SUFFIX.'''
|
||||
# On mac, the xul library is named XUL, instead of libxul.dylib. Assume any
|
||||
# file by that name is a dynamic library.
|
||||
return os.path.splitext(path)[1] == conf.DLL_SUFFIX or os.path.basename(path) == 'XUL'
|
||||
|
||||
class LibDescriptor(dict):
|
||||
KEYS = ['OBJS', 'LIBS']
|
||||
|
||||
|
|
|
@ -23,7 +23,14 @@ symbols appear in the resulting binary. Only works for ELF targets.
|
|||
from __future__ import with_statement
|
||||
import sys
|
||||
import os
|
||||
from expandlibs import ExpandArgs, relativize, isObject, ensureParentDir, ExpandLibsDeps
|
||||
from expandlibs import (
|
||||
ExpandArgs,
|
||||
relativize,
|
||||
isDynamicLib,
|
||||
isObject,
|
||||
ensureParentDir,
|
||||
ExpandLibsDeps,
|
||||
)
|
||||
import expandlibs_config as conf
|
||||
from optparse import OptionParser
|
||||
import subprocess
|
||||
|
@ -31,6 +38,7 @@ import tempfile
|
|||
import shutil
|
||||
import subprocess
|
||||
import re
|
||||
from mozbuild.makeutil import Makefile
|
||||
|
||||
# The are the insert points for a GNU ld linker script, assuming a more
|
||||
# or less "standard" default linker script. This is not a dict because
|
||||
|
@ -318,7 +326,11 @@ def main():
|
|||
|
||||
if options.verbose:
|
||||
print_command(sys.stderr, args)
|
||||
try:
|
||||
proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
|
||||
except Exception, e:
|
||||
print >>sys.stderr, 'error: Launching', args, ':', e
|
||||
raise e
|
||||
(stdout, stderr) = proc.communicate()
|
||||
if proc.returncode and not options.verbose:
|
||||
print_command(sys.stderr, args)
|
||||
|
@ -329,12 +341,15 @@ def main():
|
|||
if not options.depend:
|
||||
return
|
||||
ensureParentDir(options.depend)
|
||||
with open(options.depend, 'w') as depfile:
|
||||
depfile.write("%s : %s\n" % (options.target, ' '.join(dep for dep in deps if os.path.isfile(dep) and dep != options.target)))
|
||||
mk = Makefile()
|
||||
deps = [dep for dep in deps if os.path.isfile(dep) and dep != options.target]
|
||||
no_dynamic_lib = [dep for dep in deps if not isDynamicLib(dep)]
|
||||
mk.create_rule([options.target]).add_dependencies(no_dynamic_lib)
|
||||
if len(deps) != len(no_dynamic_lib):
|
||||
mk.create_rule(['%s_order_only' % options.target]).add_dependencies(dep for dep in deps if isDynamicLib(dep))
|
||||
|
||||
for dep in deps:
|
||||
if os.path.isfile(dep) and dep != options.target:
|
||||
depfile.write("%s :\n" % dep)
|
||||
with open(options.depend, 'w') as depfile:
|
||||
mk.dump(depfile, removal_guard=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
|
@ -1254,9 +1254,6 @@ $(DEPTH)/config/autoconf.mk: $(topsrcdir)/config/autoconf.mk.in
|
|||
# Bunch of things that extend the 'export' rule (in order):
|
||||
###############################################################################
|
||||
|
||||
################################################################################
|
||||
# Copy each element of EXPORTS to $(DIST)/include
|
||||
|
||||
ifneq ($(XPI_NAME),)
|
||||
$(FINAL_TARGET):
|
||||
$(NSINSTALL) -D $@
|
||||
|
@ -1264,26 +1261,6 @@ $(FINAL_TARGET):
|
|||
export:: $(FINAL_TARGET)
|
||||
endif
|
||||
|
||||
ifndef NO_DIST_INSTALL
|
||||
ifneq (,$(EXPORTS))
|
||||
EXPORTS_FILES := $(EXPORTS)
|
||||
EXPORTS_DEST := $(DIST)/include
|
||||
EXPORTS_TARGET := export
|
||||
INSTALL_TARGETS += EXPORTS
|
||||
endif
|
||||
endif # NO_DIST_INSTALL
|
||||
|
||||
define EXPORT_NAMESPACE_RULE
|
||||
ifndef NO_DIST_INSTALL
|
||||
EXPORTS_$(namespace)_FILES := $$(EXPORTS_$(namespace))
|
||||
EXPORTS_$(namespace)_DEST := $$(DIST)/include/$(namespace)
|
||||
EXPORTS_$(namespace)_TARGET := export
|
||||
INSTALL_TARGETS += EXPORTS_$(namespace)
|
||||
endif # NO_DIST_INSTALL
|
||||
endef
|
||||
|
||||
$(foreach namespace,$(EXPORTS_NAMESPACES),$(eval $(EXPORT_NAMESPACE_RULE)))
|
||||
|
||||
################################################################################
|
||||
# Copy each element of PREF_JS_EXPORTS
|
||||
|
||||
|
|
40
configure.in
40
configure.in
|
@ -51,7 +51,7 @@ _SUBDIR_CONFIG_ARGS="$ac_configure_args"
|
|||
dnl Set the version number of the libs included with mozilla
|
||||
dnl ========================================================
|
||||
MOZJPEG=62
|
||||
MOZPNG=10517
|
||||
MOZPNG=10606
|
||||
NSPR_VERSION=4
|
||||
NSS_VERSION=3
|
||||
|
||||
|
@ -71,7 +71,7 @@ GCONF_VERSION=1.2.1
|
|||
GIO_VERSION=2.20
|
||||
STARTUP_NOTIFICATION_VERSION=0.8
|
||||
DBUS_VERSION=0.60
|
||||
SQLITE_VERSION=3.7.17
|
||||
SQLITE_VERSION=3.8.0.2
|
||||
|
||||
MSMANIFEST_TOOL=
|
||||
|
||||
|
@ -490,30 +490,14 @@ case "$target" in
|
|||
|
||||
INCREMENTAL_LINKER=1
|
||||
|
||||
# Check midl version
|
||||
_MIDL_FULL_VERSION=`"${MIDL}" -v 2>&1 | sed -nre "$_MSVC_VER_FILTER"`
|
||||
_MIDL_MAJOR_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $1 }'`
|
||||
_MIDL_MINOR_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $2 }'`
|
||||
_MIDL_REV_VERSION=`echo ${_MIDL_FULL_VERSION} | $AWK -F\. '{ print $3 }'`
|
||||
# Add flags if necessary
|
||||
AC_MSG_CHECKING([for midl flags])
|
||||
# Set midl environment
|
||||
case "$target" in
|
||||
i*86-*)
|
||||
if test \( "$_MIDL_MAJOR_VERSION" = "7" -a "$_MIDL_MINOR_VERSION" = "00" -a "$_MIDL_REV_VERSION" = "0499" \); then
|
||||
# MIDL version 7.00.0499 defaults /env win64 on x64 platforms.
|
||||
# MIDL version 7.00.0500 or later has no problem.
|
||||
MIDL_FLAGS="${MIDL_FLAGS} -env win32"
|
||||
AC_MSG_RESULT([need -env win32])
|
||||
else
|
||||
AC_MSG_RESULT([none needed])
|
||||
fi
|
||||
;;
|
||||
x86_64-*)
|
||||
MIDL_FLAGS="${MIDL_FLAGS} -env x64"
|
||||
;;
|
||||
*)
|
||||
AC_MSG_RESULT([none needed])
|
||||
;;
|
||||
esac
|
||||
|
||||
unset _MSVC_VER_FILTER
|
||||
|
@ -910,9 +894,8 @@ MOZ_PNG_LIBS='$(call EXPAND_LIBNAME_PATH,mozpng,$(DEPTH)/media/libpng)'
|
|||
|
||||
MOZ_JS_STATIC_LIBS='$(call EXPAND_LIBNAME_PATH,js_static,$(LIBXUL_DIST)/lib)'
|
||||
MOZ_JS_SHARED_LIBS='$(call EXPAND_LIBNAME_PATH,mozjs,$(LIBXUL_DIST)/lib)'
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/bin -lxul -lxpcom_core -lmozalloc'
|
||||
MOZ_FIX_LINK_PATHS='-Wl,-rpath-link,$(LIBXUL_DIST)/bin -Wl,-rpath-link,$(prefix)/lib'
|
||||
XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/bin -lxul -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/bin)'
|
||||
LIBXUL_LIBS='$(XPCOM_FROZEN_LDOPTS)'
|
||||
XPCOM_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue_s.$(LIB_SUFFIX) $(XPCOM_FROZEN_LDOPTS)'
|
||||
XPCOM_STANDALONE_GLUE_LDOPTS='$(LIBXUL_DIST)/lib/$(LIB_PREFIX)xpcomglue.$(LIB_SUFFIX)'
|
||||
|
@ -1994,6 +1977,7 @@ ia64*-hpux*)
|
|||
MC=mc.exe
|
||||
# certain versions of cygwin's makedepend barf on the
|
||||
# #include <string> vs -I./dist/include/string issue so don't use it
|
||||
XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/lib)'
|
||||
if test -n "$GNU_CC" -o -n "$CLANG_CC"; then
|
||||
CC="$CC -mwindows"
|
||||
CXX="$CXX -mwindows"
|
||||
|
@ -2012,8 +1996,6 @@ ia64*-hpux*)
|
|||
# mingw doesn't require kernel32, user32, and advapi32 explicitly
|
||||
LIBS="$LIBS -luuid -lgdi32 -lwinmm -lwsock32 -luserenv -lsecur32 -lnetapi32"
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib -lxul -lxpcom_core -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='-L$(LIBXUL_DIST)/lib -lxul -lmozalloc'
|
||||
DLL_PREFIX=
|
||||
IMPORT_LIB_SUFFIX=dll.a
|
||||
|
||||
|
@ -2088,9 +2070,6 @@ ia64*-hpux*)
|
|||
WARNINGS_AS_ERRORS='-WX'
|
||||
MOZ_OPTIMIZE_FLAGS='-O1'
|
||||
MOZ_FIX_LINK_PATHS=
|
||||
DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||
XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||
LIBXUL_LIBS='$(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||
MOZ_COMPONENT_NSPR_LIBS='$(NSPR_LIBS)'
|
||||
LDFLAGS="$LDFLAGS -LARGEADDRESSAWARE -NXCOMPAT"
|
||||
if test -z "$DEVELOPER_OPTIONS"; then
|
||||
|
@ -2262,7 +2241,6 @@ ia64*-hpux*)
|
|||
MOZ_DEBUG_FLAGS="-g -fno-inline"
|
||||
MOZ_OPTIMIZE_FLAGS="-O2"
|
||||
MOZ_OPTIMIZE_LDFLAGS="-s -Zlinker /EXEPACK:2 -Zlinker /PACKCODE -Zlinker /PACKDATA"
|
||||
DYNAMIC_XPCOM_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/xpcom_core.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||
LIBXUL_LIBS='-L$(LIBXUL_DIST)/lib $(LIBXUL_DIST)/lib/xul.lib $(LIBXUL_DIST)/lib/mozalloc.lib'
|
||||
TARGET_MD_ARCH=os2
|
||||
_PLATFORM_DEFAULT_TOOLKIT="cairo-os2"
|
||||
|
@ -3214,7 +3192,6 @@ AC_CACHE_CHECK(
|
|||
)
|
||||
if test "$ac_cv_func_iconv" = "yes"; then
|
||||
AC_DEFINE(HAVE_ICONV)
|
||||
DYNAMIC_XPCOM_LIBS="$DYNAMIC_XPCOM_LIBS $_ICONV_LIBS"
|
||||
LIBXUL_LIBS="$LIBXUL_LIBS $_ICONV_LIBS"
|
||||
LIBICONV="$_ICONV_LIBS"
|
||||
AC_CACHE_CHECK(
|
||||
|
@ -4445,8 +4422,7 @@ cairo-cocoa)
|
|||
TK_CFLAGS="-DNO_X11"
|
||||
CFLAGS="$CFLAGS $TK_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
|
||||
DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/bin/XUL -lxpcom_core -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL $(call EXPAND_LIBNAME_PATH,mozalloc,$(LIBXUL_DIST)/bin)'
|
||||
MOZ_USER_DIR="Mozilla"
|
||||
MOZ_FS_LAYOUT=bundle
|
||||
MOZ_WEBGL=1
|
||||
|
@ -4461,8 +4437,7 @@ cairo-uikit)
|
|||
TK_LIBS='-framework Foundation -framework CoreFoundation -framework CoreGraphics -framework CoreText'
|
||||
CFLAGS="$CFLAGS $TK_CFLAGS"
|
||||
CXXFLAGS="$CXXFLAGS $TK_CFLAGS"
|
||||
DYNAMIC_XPCOM_LIBS='$(LIBXUL_DIST)/bin/XUL -lxpcom_core -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL -lmozalloc'
|
||||
XPCOM_FROZEN_LDOPTS='$(LIBXUL_DIST)/bin/XUL $(call EXPAND_LIBNAME_PATH,mozalloc,$(LIBXUL_DIST)/bin)'
|
||||
MOZ_USER_DIR="Mozilla"
|
||||
MOZ_FS_LAYOUT=bundle
|
||||
;;
|
||||
|
@ -4478,6 +4453,7 @@ cairo-android)
|
|||
;;
|
||||
|
||||
cairo-gonk)
|
||||
XPCOM_FROZEN_LDOPTS='$(call EXPAND_LIBNAME_PATH,xul mozalloc,$(LIBXUL_DIST)/lib)'
|
||||
AC_DEFINE(MOZ_WIDGET_GONK)
|
||||
AC_DEFINE(MOZ_TOUCH)
|
||||
MOZ_WIDGET_TOOLKIT=gonk
|
||||
|
|
|
@ -737,6 +737,14 @@ public:
|
|||
return sXPConnect;
|
||||
}
|
||||
|
||||
/**
|
||||
* Report simple error message to the browser console
|
||||
* @param aErrorText the error message
|
||||
* @param classification Name of the module reporting error
|
||||
*/
|
||||
static void LogSimpleConsoleError(const nsAString& aErrorText,
|
||||
const char * classification);
|
||||
|
||||
/**
|
||||
* Report a non-localized error message to the error console.
|
||||
* @param aErrorText the error message
|
||||
|
|
|
@ -3014,6 +3014,24 @@ nsresult nsContentUtils::FormatLocalizedString(PropertiesFile aFile,
|
|||
getter_Copies(aResult));
|
||||
}
|
||||
|
||||
/* static */ void
|
||||
nsContentUtils::LogSimpleConsoleError(const nsAString& aErrorText,
|
||||
const char * classification)
|
||||
{
|
||||
nsCOMPtr<nsIScriptError> scriptError =
|
||||
do_CreateInstance(NS_SCRIPTERROR_CONTRACTID);
|
||||
if (scriptError) {
|
||||
nsCOMPtr<nsIConsoleService> console =
|
||||
do_GetService(NS_CONSOLESERVICE_CONTRACTID);
|
||||
if (console && NS_SUCCEEDED(scriptError->Init(aErrorText, EmptyString(),
|
||||
EmptyString(), 0, 0,
|
||||
nsIScriptError::errorFlag,
|
||||
classification))) {
|
||||
console->LogMessage(scriptError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* static */ nsresult
|
||||
nsContentUtils::ReportToConsole(uint32_t aErrorFlags,
|
||||
const nsACString& aCategory,
|
||||
|
|
|
@ -900,7 +900,9 @@ nsEventListenerManager::CompileEventHandlerInternal(nsListenerStruct *aListenerS
|
|||
JS::Rooted<JSObject*> boundHandler(cx);
|
||||
JS::Rooted<JSObject*> scope(cx, listener->GetEventScope());
|
||||
context->BindCompiledEventHandler(mTarget, scope, handler, &boundHandler);
|
||||
if (listener->EventName() == nsGkAtoms::onerror && win) {
|
||||
if (!boundHandler) {
|
||||
listener->ForgetHandler();
|
||||
} else if (listener->EventName() == nsGkAtoms::onerror && win) {
|
||||
nsRefPtr<OnErrorEventHandlerNonNull> handlerCallback =
|
||||
new OnErrorEventHandlerNonNull(boundHandler);
|
||||
listener->SetHandler(handlerCallback);
|
||||
|
@ -1034,7 +1036,7 @@ nsEventListenerManager::HandleEventInternal(nsPresContext* aPresContext,
|
|||
|
||||
aEvent->currentTarget = nullptr;
|
||||
|
||||
if (!hasListener) {
|
||||
if (mIsMainThreadELM && !hasListener) {
|
||||
mNoListenerForEvent = aEvent->message;
|
||||
mNoListenerForEventAtom = aEvent->userType;
|
||||
}
|
||||
|
|
|
@ -65,9 +65,20 @@ HTMLTemplateElement::~HTMLTemplateElement()
|
|||
NS_IMPL_ADDREF_INHERITED(HTMLTemplateElement, Element)
|
||||
NS_IMPL_RELEASE_INHERITED(HTMLTemplateElement, Element)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_INHERITED_1(HTMLTemplateElement,
|
||||
nsGenericHTMLElement,
|
||||
mContent)
|
||||
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLTemplateElement)
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLTemplateElement,
|
||||
nsGenericHTMLElement)
|
||||
if (tmp->mContent) {
|
||||
tmp->mContent->SetHost(nullptr);
|
||||
tmp->mContent = nullptr;
|
||||
}
|
||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLTemplateElement,
|
||||
nsGenericHTMLElement)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mContent)
|
||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||
|
||||
// QueryInterface implementation for HTMLTemplateElement
|
||||
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(HTMLTemplateElement)
|
||||
|
|
|
@ -30,99 +30,293 @@ NS_INTERFACE_MAP_END_INHERITING(nsDOMEventTargetHelper)
|
|||
NS_IMPL_ADDREF_INHERITED(MediaRecorder, nsDOMEventTargetHelper)
|
||||
NS_IMPL_RELEASE_INHERITED(MediaRecorder, nsDOMEventTargetHelper)
|
||||
|
||||
// This task is used for triggering the creating blob object and it runs at main thread.
|
||||
class MediaRecorder::PushBlobTask : public nsRunnable
|
||||
/**
|
||||
* Session is an object to represent a single recording event.
|
||||
* In original design, all recording context is stored in MediaRecorder, which causes
|
||||
* a problem if someone calls MediaRecoder::Stop and MedaiRecorder::Start quickly.
|
||||
* To prevent blocking main thread, media encoding is executed in a second thread,
|
||||
* named as Read Thread. For the same reason, we do not wait Read Thread shutdown in
|
||||
* MediaRecorder::Stop. If someone call MediaRecoder::Start before Read Thread shutdown,
|
||||
* the same recording context in MediaRecoder might be access by two Reading Threads,
|
||||
* which cause a problem.
|
||||
* In the new design, we put recording context into Session object, including Read
|
||||
* Thread. Each Session has its own recording context and Read Thread, problem is been
|
||||
* resolved.
|
||||
*
|
||||
* Life cycle of a Session object.
|
||||
* 1) Initialization Stage (in main thread)
|
||||
* Setup media streams in MSG, and bind MediaEncoder with Source Stream.
|
||||
* Resource allocation, such as encoded data cache buffer and MediaEncoder.
|
||||
* Create read thread.
|
||||
* Automatically switch to Extract stage in the end of this stage.
|
||||
* 2) Extract Stage (in Read Thread)
|
||||
* Pull encoded A/V frames from MediaEncoder, dispatch to OnDataAvailable handler.
|
||||
* Unless a client calls Session::Stop, Session object keeps stay in this stage.
|
||||
* 3) Destroy Stage (in main thread)
|
||||
* Switch from Extract stage to Destroy stage by calling Session::Stop.
|
||||
* Release session resource and remove associated streams from MSG.
|
||||
*
|
||||
* Lifetime of a Session object.
|
||||
* 1) MediaRecorder creates a Session in MediaRecorder::Start function.
|
||||
* 2) A Session is destroyed in DestroyRunnable after MediaRecorder::Stop being called
|
||||
* _and_ all encoded media data been passed to OnDataAvailable handler.
|
||||
*/
|
||||
class MediaRecorder::Session
|
||||
{
|
||||
public:
|
||||
PushBlobTask(MediaRecorder* recorder)
|
||||
: mRecorder(recorder) {}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
nsresult rv = mRecorder->CreateAndDispatchBlobEvent();
|
||||
if (NS_FAILED(rv)) {
|
||||
mRecorder->NotifyError(rv);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
MediaRecorder* mRecorder;
|
||||
};
|
||||
|
||||
// This task is for firing the error message from encoder and it runs in main thread
|
||||
class MediaRecorder::PushErrorMessageTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
PushErrorMessageTask(MediaRecorder* recorder, nsresult aError)
|
||||
: mRecorder(recorder),
|
||||
mError(aError) { }
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mRecorder->NotifyError(mError);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
MediaRecorder* mRecorder;
|
||||
nsresult mError;
|
||||
};
|
||||
|
||||
// This class is used for avoiding abort by directly use the NS_NewRunnableMethod and invoke ExtractEncodedData function
|
||||
// The abort is checking if the destructor runs at main thread during the cycle-collect step in nsDOMEventTargetHelper
|
||||
class MediaRecorder::ExtractEncodedDataTask : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ExtractEncodedDataTask(MediaRecorder* aRecorder, MediaEncoder* aEncoder)
|
||||
: mRecorder(aRecorder),
|
||||
mEncoder(aEncoder) {}
|
||||
|
||||
class ReleaseEncoderThreadTask : public nsRunnable
|
||||
// Main thread task.
|
||||
// Create a blob event and send back to client.
|
||||
class PushBlobRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ReleaseEncoderThreadTask(already_AddRefed<MediaRecorder> recorder)
|
||||
: mRecorder(recorder) {}
|
||||
PushBlobRunnable(Session* aSession)
|
||||
: mSession(aSession)
|
||||
{ }
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
mRecorder->mReadThread->Shutdown();
|
||||
mRecorder->mReadThread = nullptr;
|
||||
|
||||
// Setting mState to Inactive here is for the case where SourceStream
|
||||
// ends itself, thus the recorder should stop itself too.
|
||||
mRecorder->mState = RecordingState::Inactive;
|
||||
mRecorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop"));
|
||||
MediaRecorder *recorder = mSession->mRecorder;
|
||||
nsresult rv = recorder->CreateAndDispatchBlobEvent(mSession);
|
||||
if (NS_FAILED(rv)) {
|
||||
recorder->NotifyError(rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<MediaRecorder> mRecorder;
|
||||
Session *mSession;
|
||||
};
|
||||
|
||||
// Record thread task.
|
||||
// Fetch encoded Audio/Video data from MediaEncoder.
|
||||
class ExtractRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ExtractRunnable(Session *aSession)
|
||||
: mSession(aSession) {}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
mRecorder->ExtractEncodedData();
|
||||
NS_DispatchToMainThread(new ReleaseEncoderThreadTask(mRecorder.forget()));
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mSession->mReadThread);
|
||||
|
||||
mSession->Extract();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
Session *mSession;
|
||||
};
|
||||
|
||||
// Main thread task.
|
||||
// To delete RecordingSession object.
|
||||
class DestroyRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
DestroyRunnable(Session *aSession)
|
||||
: mSession(aSession) {}
|
||||
|
||||
NS_IMETHODIMP Run()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread() && mSession.get());
|
||||
MediaRecorder *recorder = mSession->mRecorder;
|
||||
|
||||
// If MediaRecoder is not in Inactive mode, call MediaRecoder::Stop
|
||||
// and dispatch DestroyRunnable again.
|
||||
if (recorder->mState != RecordingState::Inactive) {
|
||||
ErrorResult result;
|
||||
recorder->Stop(result);
|
||||
NS_DispatchToMainThread(new DestroyRunnable(mSession.forget()));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// Dispatch stop event and clear MIME type.
|
||||
recorder->DispatchSimpleEvent(NS_LITERAL_STRING("stop"));
|
||||
recorder->SetMimeType(NS_LITERAL_STRING(""));
|
||||
|
||||
// Delete session object.
|
||||
mSession = nullptr;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsAutoPtr<Session> mSession;
|
||||
};
|
||||
|
||||
friend class PushBlobRunnable;
|
||||
friend class ExtractRunnable;
|
||||
friend class DestroyRunnable;
|
||||
|
||||
public:
|
||||
Session(MediaRecorder* aRecorder, int32_t aTimeSlice)
|
||||
: mRecorder(aRecorder),
|
||||
mTimeSlice(aTimeSlice)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER);
|
||||
}
|
||||
|
||||
// Only DestroyRunnable is allowed to delete Session object.
|
||||
~Session()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (mInputPort.get()) {
|
||||
mInputPort->Destroy();
|
||||
}
|
||||
|
||||
if (mTrackUnionStream.get()) {
|
||||
mTrackUnionStream->Destroy();
|
||||
}
|
||||
}
|
||||
|
||||
void Start()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
SetupStreams();
|
||||
|
||||
// Create a thread to read encode media data from MediaEncoder.
|
||||
if (!mReadThread) {
|
||||
nsresult rv = NS_NewNamedThread("Media Encoder", getter_AddRefs(mReadThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
mRecorder->NotifyError(rv);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
mReadThread->Dispatch(new ExtractRunnable(this), NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
void Stop()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// Shutdown mEncoder to stop Session::Extract
|
||||
if (mInputPort.get())
|
||||
{
|
||||
mInputPort->Destroy();
|
||||
mInputPort = nullptr;
|
||||
}
|
||||
|
||||
if (mTrackUnionStream.get())
|
||||
{
|
||||
mTrackUnionStream->Destroy();
|
||||
mTrackUnionStream = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Pause()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
|
||||
|
||||
mTrackUnionStream->ChangeExplicitBlockerCount(-1);
|
||||
}
|
||||
|
||||
void Resume()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread() && mTrackUnionStream);
|
||||
|
||||
mTrackUnionStream->ChangeExplicitBlockerCount(1);
|
||||
}
|
||||
|
||||
already_AddRefed<nsIDOMBlob> GetEncodedData()
|
||||
{
|
||||
nsString mimeType;
|
||||
mRecorder->GetMimeType(mimeType);
|
||||
return mEncodedBufferCache->ExtractBlob(mimeType);
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Pull encoded meida data from MediaEncoder and put into EncodedBufferCache.
|
||||
// Destroy this session object in the end of this function.
|
||||
void Extract()
|
||||
{
|
||||
MOZ_ASSERT(NS_GetCurrentThread() == mReadThread);
|
||||
|
||||
TimeStamp lastBlobTimeStamp = TimeStamp::Now();
|
||||
// Whether push encoded data back to onDataAvailable automatically.
|
||||
const bool pushBlob = (mTimeSlice > 0) ? true : false;
|
||||
|
||||
do {
|
||||
// Pull encoded media data from MediaEncoder
|
||||
nsTArray<nsTArray<uint8_t> > encodedBuf;
|
||||
nsString mimeType;
|
||||
mEncoder->GetEncodedData(&encodedBuf, mimeType);
|
||||
|
||||
mRecorder->SetMimeType(mimeType);
|
||||
|
||||
// Append pulled data into cache buffer.
|
||||
for (uint32_t i = 0; i < encodedBuf.Length(); i++) {
|
||||
mEncodedBufferCache->AppendBuffer(encodedBuf[i]);
|
||||
}
|
||||
|
||||
if (pushBlob) {
|
||||
if ((TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
|
||||
NS_DispatchToMainThread(new PushBlobRunnable(this));
|
||||
lastBlobTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
}
|
||||
} while (!mEncoder->IsShutdown());
|
||||
|
||||
// Flush out remainding encoded data.
|
||||
NS_DispatchToMainThread(new PushBlobRunnable(this));
|
||||
|
||||
// Destroy this session object in main thread.
|
||||
NS_DispatchToMainThread(new DestroyRunnable(this));
|
||||
}
|
||||
|
||||
// Bind media source with MediaEncoder to receive raw media data.
|
||||
void SetupStreams()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
MediaStreamGraph* gm = mRecorder->mStream->GetStream()->Graph();
|
||||
mTrackUnionStream = gm->CreateTrackUnionStream(nullptr);
|
||||
MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");
|
||||
|
||||
mTrackUnionStream->SetAutofinish(true);
|
||||
|
||||
mInputPort = mTrackUnionStream->AllocateInputPort(mRecorder->mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
|
||||
|
||||
// Allocate encoder and bind with union stream.
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""));
|
||||
MOZ_ASSERT(mEncoder, "CreateEncoder failed");
|
||||
|
||||
if (mEncoder) {
|
||||
mTrackUnionStream->AddListener(mEncoder);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
// Hold a reference to MediaRecoder to make sure MediaRecoder be
|
||||
// destroyed after all session object dead.
|
||||
nsRefPtr<MediaRecorder> mRecorder;
|
||||
|
||||
// Pause/ Resume controller.
|
||||
nsRefPtr<ProcessedMediaStream> mTrackUnionStream;
|
||||
nsRefPtr<MediaInputPort> mInputPort;
|
||||
|
||||
// Runnable thread for read data from MediaEncode.
|
||||
nsCOMPtr<nsIThread> mReadThread;
|
||||
// MediaEncoder pipeline.
|
||||
nsRefPtr<MediaEncoder> mEncoder;
|
||||
// A buffer to cache encoded meda data.
|
||||
nsAutoPtr<EncodedBufferCache> mEncodedBufferCache;
|
||||
// The interval of passing encoded data from EncodedBufferCache to onDataAvailable
|
||||
// handler. "mTimeSlice < 0" means Session object does not push encoded data to
|
||||
// onDataAvailable, instead, it passive wait the client side pull encoded data
|
||||
// by calling requestData API.
|
||||
const int32_t mTimeSlice;
|
||||
};
|
||||
|
||||
MediaRecorder::~MediaRecorder()
|
||||
{
|
||||
if (mStreamPort) {
|
||||
mStreamPort->Destroy();
|
||||
}
|
||||
if (mTrackUnionStream) {
|
||||
mTrackUnionStream->Destroy();
|
||||
}
|
||||
MOZ_ASSERT(mSession == nullptr);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -134,31 +328,26 @@ MediaRecorder::Init(nsPIDOMWindow* aOwnerWindow)
|
|||
}
|
||||
|
||||
MediaRecorder::MediaRecorder(DOMMediaStream& aStream)
|
||||
: mTimeSlice(0),
|
||||
mState(RecordingState::Inactive)
|
||||
: mState(RecordingState::Inactive),
|
||||
mSession(nullptr),
|
||||
mMutex("Session.Data.Mutex")
|
||||
{
|
||||
mStream = &aStream;
|
||||
SetIsDOMBinding();
|
||||
}
|
||||
|
||||
void
|
||||
MediaRecorder::ExtractEncodedData()
|
||||
MediaRecorder::SetMimeType(const nsString &aMimeType)
|
||||
{
|
||||
TimeStamp lastBlobTimeStamp = TimeStamp::Now();
|
||||
do {
|
||||
nsTArray<nsTArray<uint8_t> > outputBufs;
|
||||
mEncoder->GetEncodedData(&outputBufs, mMimeType);
|
||||
for (uint32_t i = 0; i < outputBufs.Length(); i++) {
|
||||
mEncodedBufferCache->AppendBuffer(outputBufs[i]);
|
||||
}
|
||||
MutexAutoLock lock(mMutex);
|
||||
mMimeType = aMimeType;
|
||||
}
|
||||
|
||||
if (mTimeSlice > 0 && (TimeStamp::Now() - lastBlobTimeStamp).ToMilliseconds() > mTimeSlice) {
|
||||
NS_DispatchToMainThread(new PushBlobTask(this));
|
||||
lastBlobTimeStamp = TimeStamp::Now();
|
||||
}
|
||||
} while (!mEncoder->IsShutdown());
|
||||
|
||||
NS_DispatchToMainThread(new PushBlobTask(this));
|
||||
void
|
||||
MediaRecorder::GetMimeType(nsString &aMimeType)
|
||||
{
|
||||
MutexAutoLock lock(mMutex);
|
||||
aMimeType = mMimeType;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -174,53 +363,25 @@ MediaRecorder::Start(const Optional<int32_t>& aTimeSlice, ErrorResult& aResult)
|
|||
return;
|
||||
}
|
||||
|
||||
int32_t timeSlice = 0;
|
||||
if (aTimeSlice.WasPassed()) {
|
||||
if (aTimeSlice.Value() < 0) {
|
||||
aResult.Throw(NS_ERROR_INVALID_ARG);
|
||||
return;
|
||||
}
|
||||
mTimeSlice = aTimeSlice.Value();
|
||||
} else {
|
||||
mTimeSlice = 0;
|
||||
}
|
||||
|
||||
// Create a TrackUnionStream to support Pause/Resume by using ChangeExplicitBlockerCount
|
||||
MediaStreamGraph* gm = mStream->GetStream()->Graph();
|
||||
mTrackUnionStream = gm->CreateTrackUnionStream(nullptr);
|
||||
MOZ_ASSERT(mTrackUnionStream, "CreateTrackUnionStream failed");
|
||||
timeSlice = aTimeSlice.Value();
|
||||
}
|
||||
|
||||
if (!CheckPrincipal()) {
|
||||
aResult.Throw(NS_ERROR_DOM_SECURITY_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
if (mEncodedBufferCache == nullptr) {
|
||||
mEncodedBufferCache = new EncodedBufferCache(MAX_ALLOW_MEMORY_BUFFER);
|
||||
}
|
||||
|
||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""));
|
||||
MOZ_ASSERT(mEncoder, "CreateEncoder failed");
|
||||
|
||||
mTrackUnionStream->SetAutofinish(true);
|
||||
mStreamPort = mTrackUnionStream->AllocateInputPort(mStream->GetStream(), MediaInputPort::FLAG_BLOCK_OUTPUT);
|
||||
|
||||
if (mEncoder) {
|
||||
mTrackUnionStream->AddListener(mEncoder);
|
||||
} else {
|
||||
aResult.Throw(NS_ERROR_DOM_ABORT_ERR);
|
||||
}
|
||||
|
||||
if (!mReadThread) {
|
||||
nsresult rv = NS_NewNamedThread("Media Encoder",
|
||||
getter_AddRefs(mReadThread));
|
||||
if (NS_FAILED(rv)) {
|
||||
aResult.Throw(rv);
|
||||
return;
|
||||
}
|
||||
nsRefPtr<ExtractEncodedDataTask> event = new ExtractEncodedDataTask(this, mEncoder);
|
||||
mReadThread->Dispatch(event, NS_DISPATCH_NORMAL);
|
||||
mState = RecordingState::Recording;
|
||||
}
|
||||
// Start a session
|
||||
mSession = new Session(this, timeSlice);
|
||||
mSession->Start();
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -230,13 +391,11 @@ MediaRecorder::Stop(ErrorResult& aResult)
|
|||
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
|
||||
mSession->Stop();
|
||||
mSession = nullptr;
|
||||
|
||||
mState = RecordingState::Inactive;
|
||||
|
||||
mStreamPort->Destroy();
|
||||
mStreamPort = nullptr;
|
||||
|
||||
mTrackUnionStream->Destroy();
|
||||
mTrackUnionStream = nullptr;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -246,9 +405,14 @@ MediaRecorder::Pause(ErrorResult& aResult)
|
|||
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
mTrackUnionStream->ChangeExplicitBlockerCount(-1);
|
||||
|
||||
mState = RecordingState::Paused;
|
||||
|
||||
MOZ_ASSERT(mSession != nullptr);
|
||||
if (mSession) {
|
||||
mSession->Pause();
|
||||
mState = RecordingState::Paused;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -258,8 +422,12 @@ MediaRecorder::Resume(ErrorResult& aResult)
|
|||
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
mTrackUnionStream->ChangeExplicitBlockerCount(1);
|
||||
|
||||
MOZ_ASSERT(mSession != nullptr);
|
||||
if (mSession) {
|
||||
mSession->Resume();
|
||||
mState = RecordingState::Recording;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -269,7 +437,10 @@ MediaRecorder::RequestData(ErrorResult& aResult)
|
|||
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
|
||||
return;
|
||||
}
|
||||
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &MediaRecorder::CreateAndDispatchBlobEvent),
|
||||
|
||||
NS_DispatchToMainThread(
|
||||
NS_NewRunnableMethodWithArg<Session *>(this,
|
||||
&MediaRecorder::CreateAndDispatchBlobEvent, mSession),
|
||||
NS_DISPATCH_NORMAL);
|
||||
}
|
||||
|
||||
|
@ -301,7 +472,7 @@ MediaRecorder::Constructor(const GlobalObject& aGlobal,
|
|||
}
|
||||
|
||||
nsresult
|
||||
MediaRecorder::CreateAndDispatchBlobEvent()
|
||||
MediaRecorder::CreateAndDispatchBlobEvent(Session *aSession)
|
||||
{
|
||||
NS_ABORT_IF_FALSE(NS_IsMainThread(), "Not running on main thread");
|
||||
|
||||
|
@ -313,7 +484,7 @@ MediaRecorder::CreateAndDispatchBlobEvent()
|
|||
BlobEventInitInitializer init;
|
||||
init.mBubbles = false;
|
||||
init.mCancelable = false;
|
||||
init.mData = mEncodedBufferCache->ExtractBlob(mMimeType);
|
||||
init.mData = aSession->GetEncodedData();
|
||||
nsRefPtr<BlobEvent> event =
|
||||
BlobEvent::Constructor(this,
|
||||
NS_LITERAL_STRING("dataavailable"),
|
||||
|
|
|
@ -36,9 +36,8 @@ namespace dom {
|
|||
|
||||
class MediaRecorder : public nsDOMEventTargetHelper
|
||||
{
|
||||
class ExtractEncodedDataTask;
|
||||
class PushBlobTask;
|
||||
class PushErrorMessageTask;
|
||||
class Session;
|
||||
|
||||
public:
|
||||
MediaRecorder(DOMMediaStream&);
|
||||
virtual ~MediaRecorder();
|
||||
|
@ -71,7 +70,7 @@ public:
|
|||
// The current state of the MediaRecorder object.
|
||||
RecordingState State() const { return mState; }
|
||||
// Return the current encoding MIME type selected by the MediaEncoder.
|
||||
void GetMimeType(nsString &aMimeType) { aMimeType = mMimeType; }
|
||||
void GetMimeType(nsString &aMimeType);
|
||||
|
||||
static already_AddRefed<MediaRecorder>
|
||||
Constructor(const GlobalObject& aGlobal,
|
||||
|
@ -83,45 +82,33 @@ public:
|
|||
IMPL_EVENT_HANDLER(stop)
|
||||
IMPL_EVENT_HANDLER(warning)
|
||||
|
||||
friend class ExtractEncodedData;
|
||||
|
||||
protected:
|
||||
void Init(nsPIDOMWindow* aOwnerWindow);
|
||||
// Copy encoded data from encoder to EncodedBufferCache. This function runs in the Media Encoder Thread.
|
||||
void ExtractEncodedData();
|
||||
|
||||
MediaRecorder& operator = (const MediaRecorder& x) MOZ_DELETE;
|
||||
// Create dataavailable event with Blob data and it runs in main thread
|
||||
nsresult CreateAndDispatchBlobEvent();
|
||||
nsresult CreateAndDispatchBlobEvent(Session *session);
|
||||
// Creating a simple event to notify UA simple event.
|
||||
void DispatchSimpleEvent(const nsAString & aStr);
|
||||
// Creating a error event with message.
|
||||
void NotifyError(nsresult aRv);
|
||||
// Check if the recorder's principal is the subsume of mediaStream
|
||||
bool CheckPrincipal();
|
||||
// Set encoded MIME type.
|
||||
void SetMimeType(const nsString &aMimeType);
|
||||
|
||||
MediaRecorder(const MediaRecorder& x) MOZ_DELETE; // prevent bad usage
|
||||
|
||||
|
||||
// Runnable thread for read data from mediaEncoder. It starts at MediaRecorder::Start() and stops at MediaRecorder::Stop().
|
||||
nsCOMPtr<nsIThread> mReadThread;
|
||||
// The MediaEncoder object initializes on start() and destroys in ~MediaRecorder.
|
||||
nsRefPtr<MediaEncoder> mEncoder;
|
||||
// MediaStream passed from js context
|
||||
nsRefPtr<DOMMediaStream> mStream;
|
||||
// This media stream is used for notifying raw data to encoder and can be blocked.
|
||||
nsRefPtr<ProcessedMediaStream> mTrackUnionStream;
|
||||
// This is used for destroing the inputport when destroy the mediaRecorder
|
||||
nsRefPtr<MediaInputPort> mStreamPort;
|
||||
// This object creates on start() and destroys in ~MediaRecorder.
|
||||
nsAutoPtr<EncodedBufferCache> mEncodedBufferCache;
|
||||
// It specifies the container format as well as the audio and video capture formats.
|
||||
nsString mMimeType;
|
||||
// The interval of timer passed from Start(). On every mTimeSlice milliseconds, if there are buffers store in the EncodedBufferCache,
|
||||
// a dataavailable event will be fired.
|
||||
int32_t mTimeSlice;
|
||||
// The current state of the MediaRecorder object.
|
||||
RecordingState mState;
|
||||
// Current recording session.
|
||||
Session *mSession;
|
||||
// Thread safe for mMimeType.
|
||||
Mutex mMutex;
|
||||
// It specifies the container format as well as the audio and video capture formats.
|
||||
nsString mMimeType;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
#include "nsIFrame.h"
|
||||
#include "nsVideoFrame.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
|
||||
// Alternate value for the 'auto' keyword.
|
||||
#define WEBVTT_AUTO -1
|
||||
|
@ -162,6 +163,7 @@ TextTrackCue::GetCueAsHTML()
|
|||
return mDocument->CreateDocumentFragment();
|
||||
}
|
||||
sParserWrapper = parserWrapper;
|
||||
ClearOnShutdown(&sParserWrapper);
|
||||
}
|
||||
|
||||
nsPIDOMWindow* window = mDocument->GetWindow();
|
||||
|
|
|
@ -64,10 +64,16 @@ MOCHITEST_FILES = \
|
|||
test_audio1.html \
|
||||
test_audio2.html \
|
||||
test_autoplay.html \
|
||||
test_bug448534.html \
|
||||
test_bug463162.xhtml \
|
||||
test_bug495145.html \
|
||||
test_bug495300.html \
|
||||
test_bug654550.html \
|
||||
test_bug686942.html \
|
||||
test_bug883173.html \
|
||||
test_bug895305.html \
|
||||
test_bug895091.html \
|
||||
test_bug919265.html \
|
||||
test_can_play_type.html \
|
||||
test_can_play_type_mpeg.html \
|
||||
test_closing_connections.html \
|
||||
|
@ -118,12 +124,11 @@ MOCHITEST_FILES = \
|
|||
test_mozHasAudio.html \
|
||||
test_source_media.html \
|
||||
test_autoplay_contentEditable.html \
|
||||
test_bug448534.html \
|
||||
test_bug463162.xhtml \
|
||||
test_decoder_disable.html \
|
||||
test_mediarecorder_record_no_timeslice.html \
|
||||
test_mediarecorder_reload_crash.html \
|
||||
test_mediarecorder_record_immediate_stop.html \
|
||||
test_mediarecorder_record_session.html \
|
||||
test_media_selection.html \
|
||||
test_playback.html \
|
||||
test_seekLies.html \
|
||||
|
@ -146,9 +151,6 @@ MOCHITEST_FILES = \
|
|||
test_VideoPlaybackQuality.html \
|
||||
test_VideoPlaybackQuality_disabled.html \
|
||||
test_webvtt_disabled.html \
|
||||
test_bug895305.html \
|
||||
test_bug895091.html \
|
||||
test_bug883173.html \
|
||||
$(NULL)
|
||||
|
||||
# Don't run in suite
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
<html>
|
||||
<head>
|
||||
<script>
|
||||
var o0 = new TextTrackCue(0.000, 1.000, 'Bug882549');
|
||||
var o1 = o0.getCueAsHTML(0);
|
||||
var o0 = new VTTCue(0.000, 1.000, 'Bug882549');
|
||||
var o1 = o0.getCueAsHTML();
|
||||
</script>
|
||||
</head>
|
||||
<body>
|
||||
|
|
|
@ -8,9 +8,9 @@ function boom()
|
|||
{
|
||||
var frame = document.getElementById("f");
|
||||
var frameWin = frame.contentWindow;
|
||||
frameWin.TextTrackCue;
|
||||
frameWin.VTTCue;
|
||||
document.body.removeChild(frame);
|
||||
frameWin.TextTrackCue(0, 1, "Bug 894104").getCueAsHTML();
|
||||
frameWin.VTTCue(0, 1, "Bug 894104").getCueAsHTML();
|
||||
}
|
||||
|
||||
</script>
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=919265
|
||||
-->
|
||||
<head>
|
||||
<meta charset='utf-8'>
|
||||
<title>Regression test for bug 919265 - Leak on VTTCue::GetCueAsHTML()</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
</head>
|
||||
<body>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
SimpleTest.waitForExplicitFinish();
|
||||
SpecialPowers.pushPrefEnv({"set": [["media.webvtt.enabled", true]]},
|
||||
function() {
|
||||
// We shouldn't leak upon shutdown.
|
||||
(new VTTCue(0, 0, "")).getCueAsHTML();
|
||||
// We need to assert something for Mochitest to be happy.
|
||||
ok(true);
|
||||
SimpleTest.finish();
|
||||
}
|
||||
);
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,72 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=909670
|
||||
-->
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Test for Media Recoder recording session</title>
|
||||
<script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
<script type="text/javascript" src="manifest.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
var manager = new MediaTestManager;
|
||||
|
||||
function startTest(test, token) {
|
||||
var element = document.createElement('audio');
|
||||
|
||||
element.token = token;
|
||||
manager.started(token);
|
||||
|
||||
element.src = test.name;
|
||||
element.test = test;
|
||||
element.stream = element.mozCaptureStream();
|
||||
|
||||
var mStopCount = 0;
|
||||
// Start and stop recording session three times continuously.
|
||||
var mExpectStopCount = 3;
|
||||
var mediaRecorder = new MediaRecorder(element.stream);
|
||||
|
||||
// Stop callback.
|
||||
// Suppose to receive mExpectStopCount
|
||||
mediaRecorder.onstop = function stopCallback() {
|
||||
mStopCount++;
|
||||
|
||||
info("MediaRecorder.onstop callback: (" + mStopCount + ")");
|
||||
|
||||
if (mExpectStopCount === mStopCount)
|
||||
{
|
||||
manager.finished(token);
|
||||
}
|
||||
}
|
||||
|
||||
// data avaliable.
|
||||
mediaRecorder.ondataavailable = function(evt) {}
|
||||
|
||||
mediaRecorder.onerror = function(err) {
|
||||
ok(false, 'Unexpected error fired with:' + err);
|
||||
}
|
||||
|
||||
mediaRecorder.onwarning = function() {
|
||||
ok(false, 'Unexpected warning fired');
|
||||
}
|
||||
|
||||
element.oncanplaythrough = function () {
|
||||
for (var i = 0; i < mExpectStopCount; i++) {
|
||||
mediaRecorder.start(1000);
|
||||
mediaRecorder.stop();
|
||||
}
|
||||
}
|
||||
|
||||
element.play();
|
||||
}
|
||||
|
||||
manager.runTests(gMediaRecorderTests, startTest);
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
|
@ -21,6 +21,8 @@
|
|||
<g id="e">
|
||||
<!-- empty container should not affect parent's bbox -->
|
||||
<g/>
|
||||
<!-- nor should an empty text element -->
|
||||
<text x="185" y="25"/>
|
||||
<circle cx="100" cy="100" r="5"/>
|
||||
<g/>
|
||||
<circle cx="100" cy="100" r="5"/>
|
||||
|
|
До Ширина: | Высота: | Размер: 782 B После Ширина: | Высота: | Размер: 855 B |
|
@ -27,5 +27,10 @@ text { font: 20px monospace; }
|
|||
<rect id="rect4" x="150" y="50" width="50" height="50" fill="yellow"/>
|
||||
<rect id="rect4a" x="150" y="50" width="50" height="50" fill="none" stroke-width="4" stroke="blue"/>
|
||||
</g>
|
||||
<text id="text4" x="185" y="25"/>
|
||||
<g id="g2">
|
||||
<rect x="100" y="100" width="50" height="50" fill="pink"/>
|
||||
<text x="200" y="200"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
|
До Ширина: | Высота: | Размер: 1.5 KiB После Ширина: | Высота: | Размер: 1.7 KiB |
|
@ -141,6 +141,18 @@ function runTest()
|
|||
is(iBounds.width, 200, "i.getBoundingClientRect().width");
|
||||
is(iBounds.height, 200, "i.getBoundingClientRect().height");
|
||||
|
||||
var text4Bounds = doc.getElementById("text4").getBoundingClientRect();
|
||||
is(text4Bounds.left, 0, "text4.getBoundingClientRect().left");
|
||||
is(text4Bounds.top, 0, "text4.getBoundingClientRect().top");
|
||||
is(text4Bounds.width, 0, "text4.getBoundingClientRect().width");
|
||||
is(text4Bounds.height, 0, "text4.getBoundingClientRect().height");
|
||||
|
||||
var gBounds = doc.getElementById("g2").getBoundingClientRect();
|
||||
is(gBounds.left, 100, "g2.getBoundingClientRect().left");
|
||||
is(gBounds.top, 100, "g2.getBoundingClientRect().top");
|
||||
is(gBounds.width, 50, "g2.getBoundingClientRect().width");
|
||||
is(gBounds.height, 50, "g2.getBoundingClientRect().height");
|
||||
|
||||
SimpleTest.finish();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
This is sqlite 3.7.17
|
||||
This is sqlite 3.8.0.2
|
||||
|
||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 05/2013
|
||||
-- Ryan VanderMeulen <ryanvm@gmail.com>, 09/2013
|
||||
|
||||
See http://www.sqlite.org/ for more info.
|
||||
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -107,9 +107,9 @@ extern "C" {
|
|||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||
** [sqlite_version()] and [sqlite_source_id()].
|
||||
*/
|
||||
#define SQLITE_VERSION "3.7.17"
|
||||
#define SQLITE_VERSION_NUMBER 3007017
|
||||
#define SQLITE_SOURCE_ID "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
|
||||
#define SQLITE_VERSION "3.8.0.2"
|
||||
#define SQLITE_VERSION_NUMBER 3008000
|
||||
#define SQLITE_SOURCE_ID "2013-09-03 17:11:13 7dd4968f235d6e1ca9547cda9cf3bd570e1609ef"
|
||||
|
||||
/*
|
||||
** CAPI3REF: Run-Time Library Version Numbers
|
||||
|
@ -478,8 +478,10 @@ SQLITE_API int sqlite3_exec(
|
|||
#define SQLITE_IOERR_SEEK (SQLITE_IOERR | (22<<8))
|
||||
#define SQLITE_IOERR_DELETE_NOENT (SQLITE_IOERR | (23<<8))
|
||||
#define SQLITE_IOERR_MMAP (SQLITE_IOERR | (24<<8))
|
||||
#define SQLITE_IOERR_GETTEMPPATH (SQLITE_IOERR | (25<<8))
|
||||
#define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))
|
||||
#define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8))
|
||||
#define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8))
|
||||
#define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))
|
||||
#define SQLITE_CANTOPEN_ISDIR (SQLITE_CANTOPEN | (2<<8))
|
||||
#define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8))
|
||||
|
@ -499,6 +501,7 @@ SQLITE_API int sqlite3_exec(
|
|||
#define SQLITE_CONSTRAINT_VTAB (SQLITE_CONSTRAINT | (9<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_WAL (SQLITE_NOTICE | (1<<8))
|
||||
#define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
|
||||
#define SQLITE_WARNING_AUTOINDEX (SQLITE_WARNING | (1<<8))
|
||||
|
||||
/*
|
||||
** CAPI3REF: Flags For File Open Operations
|
||||
|
@ -2557,9 +2560,10 @@ SQLITE_API SQLITE_EXPERIMENTAL void *sqlite3_profile(sqlite3*,
|
|||
** interface is to keep a GUI updated during a large query.
|
||||
**
|
||||
** ^The parameter P is passed through as the only parameter to the
|
||||
** callback function X. ^The parameter N is the number of
|
||||
** callback function X. ^The parameter N is the approximate number of
|
||||
** [virtual machine instructions] that are evaluated between successive
|
||||
** invocations of the callback X.
|
||||
** invocations of the callback X. ^If N is less than one then the progress
|
||||
** handler is disabled.
|
||||
**
|
||||
** ^Only a single progress handler may be defined at one time per
|
||||
** [database connection]; setting a new progress handler cancels the
|
||||
|
@ -4179,41 +4183,49 @@ SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
|
|||
/*
|
||||
** CAPI3REF: Function Auxiliary Data
|
||||
**
|
||||
** The following two functions may be used by scalar SQL functions to
|
||||
** These functions may be used by (non-aggregate) SQL functions to
|
||||
** associate metadata with argument values. If the same value is passed to
|
||||
** multiple invocations of the same SQL function during query execution, under
|
||||
** some circumstances the associated metadata may be preserved. This may
|
||||
** be used, for example, to add a regular-expression matching scalar
|
||||
** function. The compiled version of the regular expression is stored as
|
||||
** metadata associated with the SQL value passed as the regular expression
|
||||
** pattern. The compiled regular expression can be reused on multiple
|
||||
** invocations of the same function so that the original pattern string
|
||||
** does not need to be recompiled on each invocation.
|
||||
** some circumstances the associated metadata may be preserved. An example
|
||||
** of where this might be useful is in a regular-expression matching
|
||||
** function. The compiled version of the regular expression can be stored as
|
||||
** metadata associated with the pattern string.
|
||||
** Then as long as the pattern string remains the same,
|
||||
** the compiled regular expression can be reused on multiple
|
||||
** invocations of the same function.
|
||||
**
|
||||
** ^The sqlite3_get_auxdata() interface returns a pointer to the metadata
|
||||
** associated by the sqlite3_set_auxdata() function with the Nth argument
|
||||
** value to the application-defined function. ^If no metadata has been ever
|
||||
** been set for the Nth argument of the function, or if the corresponding
|
||||
** function parameter has changed since the meta-data was set,
|
||||
** then sqlite3_get_auxdata() returns a NULL pointer.
|
||||
** value to the application-defined function. ^If there is no metadata
|
||||
** associated with the function argument, this sqlite3_get_auxdata() interface
|
||||
** returns a NULL pointer.
|
||||
**
|
||||
** ^The sqlite3_set_auxdata() interface saves the metadata
|
||||
** pointed to by its 3rd parameter as the metadata for the N-th
|
||||
** argument of the application-defined function. Subsequent
|
||||
** calls to sqlite3_get_auxdata() might return this data, if it has
|
||||
** not been destroyed.
|
||||
** ^If it is not NULL, SQLite will invoke the destructor
|
||||
** function given by the 4th parameter to sqlite3_set_auxdata() on
|
||||
** the metadata when the corresponding function parameter changes
|
||||
** or when the SQL statement completes, whichever comes first.
|
||||
** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th
|
||||
** argument of the application-defined function. ^Subsequent
|
||||
** calls to sqlite3_get_auxdata(C,N) return P from the most recent
|
||||
** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or
|
||||
** NULL if the metadata has been discarded.
|
||||
** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL,
|
||||
** SQLite will invoke the destructor function X with parameter P exactly
|
||||
** once, when the metadata is discarded.
|
||||
** SQLite is free to discard the metadata at any time, including: <ul>
|
||||
** <li> when the corresponding function parameter changes, or
|
||||
** <li> when [sqlite3_reset()] or [sqlite3_finalize()] is called for the
|
||||
** SQL statement, or
|
||||
** <li> when sqlite3_set_auxdata() is invoked again on the same parameter, or
|
||||
** <li> during the original sqlite3_set_auxdata() call when a memory
|
||||
** allocation error occurs. </ul>)^
|
||||
**
|
||||
** SQLite is free to call the destructor and drop metadata on any
|
||||
** parameter of any function at any time. ^The only guarantee is that
|
||||
** the destructor will be called before the metadata is dropped.
|
||||
** Note the last bullet in particular. The destructor X in
|
||||
** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the
|
||||
** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata()
|
||||
** should be called near the end of the function implementation and the
|
||||
** function implementation should not make any use of P after
|
||||
** sqlite3_set_auxdata() has been called.
|
||||
**
|
||||
** ^(In practice, metadata is preserved between function calls for
|
||||
** expressions that are constant at compile time. This includes literal
|
||||
** values and [parameters].)^
|
||||
** function parameters that are compile-time constants, including literal
|
||||
** values and [parameters] and expressions composed from the same.)^
|
||||
**
|
||||
** These routines must be called from the same thread in which
|
||||
** the SQL function is running.
|
||||
|
@ -4518,6 +4530,11 @@ SQLITE_API int sqlite3_key(
|
|||
sqlite3 *db, /* Database to be rekeyed */
|
||||
const void *pKey, int nKey /* The key */
|
||||
);
|
||||
SQLITE_API int sqlite3_key_v2(
|
||||
sqlite3 *db, /* Database to be rekeyed */
|
||||
const char *zDbName, /* Name of the database */
|
||||
const void *pKey, int nKey /* The key */
|
||||
);
|
||||
|
||||
/*
|
||||
** Change the key on an open database. If the current database is not
|
||||
|
@ -4531,6 +4548,11 @@ SQLITE_API int sqlite3_rekey(
|
|||
sqlite3 *db, /* Database to be rekeyed */
|
||||
const void *pKey, int nKey /* The new key */
|
||||
);
|
||||
SQLITE_API int sqlite3_rekey_v2(
|
||||
sqlite3 *db, /* Database to be rekeyed */
|
||||
const char *zDbName, /* Name of the database */
|
||||
const void *pKey, int nKey /* The new key */
|
||||
);
|
||||
|
||||
/*
|
||||
** Specify the activation key for a SEE database. Unless
|
||||
|
@ -5116,10 +5138,23 @@ SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
|
|||
** on the list of automatic extensions is a harmless no-op. ^No entry point
|
||||
** will be called more than once for each database connection that is opened.
|
||||
**
|
||||
** See also: [sqlite3_reset_auto_extension()].
|
||||
** See also: [sqlite3_reset_auto_extension()]
|
||||
** and [sqlite3_cancel_auto_extension()]
|
||||
*/
|
||||
SQLITE_API int sqlite3_auto_extension(void (*xEntryPoint)(void));
|
||||
|
||||
/*
|
||||
** CAPI3REF: Cancel Automatic Extension Loading
|
||||
**
|
||||
** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the
|
||||
** initialization routine X that was registered using a prior call to
|
||||
** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)]
|
||||
** routine returns 1 if initialization routine X was successfully
|
||||
** unregistered and it returns 0 if X was not on the list of initialization
|
||||
** routines.
|
||||
*/
|
||||
SQLITE_API int sqlite3_cancel_auto_extension(void (*xEntryPoint)(void));
|
||||
|
||||
/*
|
||||
** CAPI3REF: Reset Automatic Extension Loading
|
||||
**
|
||||
|
@ -6232,6 +6267,12 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
|
|||
** on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined.)^ ^The
|
||||
** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0.
|
||||
** </dd>
|
||||
**
|
||||
** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt>
|
||||
** <dd>This parameter returns zero for the current value if and only if
|
||||
** all foreign key constraints (deferred or immediate) have been
|
||||
** resolved.)^ ^The highwater mark is always 0.
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_DBSTATUS_LOOKASIDE_USED 0
|
||||
|
@ -6244,7 +6285,8 @@ SQLITE_API int sqlite3_db_status(sqlite3*, int op, int *pCur, int *pHiwtr, int r
|
|||
#define SQLITE_DBSTATUS_CACHE_HIT 7
|
||||
#define SQLITE_DBSTATUS_CACHE_MISS 8
|
||||
#define SQLITE_DBSTATUS_CACHE_WRITE 9
|
||||
#define SQLITE_DBSTATUS_MAX 9 /* Largest defined DBSTATUS */
|
||||
#define SQLITE_DBSTATUS_DEFERRED_FKS 10
|
||||
#define SQLITE_DBSTATUS_MAX 10 /* Largest defined DBSTATUS */
|
||||
|
||||
|
||||
/*
|
||||
|
@ -6298,11 +6340,21 @@ SQLITE_API int sqlite3_stmt_status(sqlite3_stmt*, int op,int resetFlg);
|
|||
** A non-zero value in this counter may indicate an opportunity to
|
||||
** improvement performance by adding permanent indices that do not
|
||||
** need to be reinitialized each time the statement is run.</dd>
|
||||
**
|
||||
** [[SQLITE_STMTSTATUS_VM_STEP]] <dt>SQLITE_STMTSTATUS_VM_STEP</dt>
|
||||
** <dd>^This is the number of virtual machine operations executed
|
||||
** by the prepared statement if that number is less than or equal
|
||||
** to 2147483647. The number of virtual machine operations can be
|
||||
** used as a proxy for the total work done by the prepared statement.
|
||||
** If the number of virtual machine operations exceeds 2147483647
|
||||
** then the value returned by this statement status code is undefined.
|
||||
** </dd>
|
||||
** </dl>
|
||||
*/
|
||||
#define SQLITE_STMTSTATUS_FULLSCAN_STEP 1
|
||||
#define SQLITE_STMTSTATUS_SORT 2
|
||||
#define SQLITE_STMTSTATUS_AUTOINDEX 3
|
||||
#define SQLITE_STMTSTATUS_VM_STEP 4
|
||||
|
||||
/*
|
||||
** CAPI3REF: Custom Page Cache Object
|
||||
|
@ -7181,7 +7233,7 @@ SQLITE_API int sqlite3_vtab_on_conflict(sqlite3 *);
|
|||
#ifdef __cplusplus
|
||||
} /* End of the 'extern "C"' block */
|
||||
#endif
|
||||
#endif
|
||||
#endif /* _SQLITE3_H_ */
|
||||
|
||||
/*
|
||||
** 2010 August 30
|
||||
|
|
|
@ -5999,7 +5999,7 @@ nsGlobalWindow::ResizeTo(int32_t aWidth, int32_t aHeight)
|
|||
* If caller is a browser-element then dispatch a resize event to
|
||||
* the embedder.
|
||||
*/
|
||||
if (mDocShell->GetIsBrowserOrApp()) {
|
||||
if (mDocShell && mDocShell->GetIsBrowserOrApp()) {
|
||||
nsIntSize size(aWidth, aHeight);
|
||||
if (!DispatchResizeEvent(size)) {
|
||||
// The embedder chose to prevent the default action for this
|
||||
|
@ -6039,7 +6039,7 @@ nsGlobalWindow::ResizeBy(int32_t aWidthDif, int32_t aHeightDif)
|
|||
* If caller is a browser-element then dispatch a resize event to
|
||||
* parent.
|
||||
*/
|
||||
if (mDocShell->GetIsBrowserOrApp()) {
|
||||
if (mDocShell && mDocShell->GetIsBrowserOrApp()) {
|
||||
CSSIntSize size;
|
||||
nsresult rv = GetInnerSize(size);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
|
|
|
@ -214,6 +214,11 @@ public:
|
|||
return mHandler;
|
||||
}
|
||||
|
||||
void ForgetHandler()
|
||||
{
|
||||
mHandler.ForgetHandler();
|
||||
}
|
||||
|
||||
nsIAtom* EventName() const
|
||||
{
|
||||
return mEventName;
|
||||
|
|
|
@ -1019,13 +1019,21 @@ XrayResolveProperty(JSContext* cx, JS::Handle<JSObject*> wrapper,
|
|||
for ( ; methodIds[i] != JSID_VOID; ++i) {
|
||||
if (id == methodIds[i]) {
|
||||
const JSFunctionSpec& methodSpec = methodsSpecs[i];
|
||||
JSFunction *fun = JS_NewFunctionById(cx, methodSpec.call.op,
|
||||
methodSpec.nargs, 0,
|
||||
wrapper, id);
|
||||
JSFunction *fun;
|
||||
if (methodSpec.selfHostedName) {
|
||||
fun = JS::GetSelfHostedFunction(cx, methodSpec.selfHostedName, id, methodSpec.nargs);
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
MOZ_ASSERT(!methodSpec.call.op, "Bad FunctionSpec declaration: non-null native");
|
||||
MOZ_ASSERT(!methodSpec.call.info, "Bad FunctionSpec declaration: non-null jitinfo");
|
||||
} else {
|
||||
fun = JS_NewFunctionById(cx, methodSpec.call.op, methodSpec.nargs, 0, wrapper, id);
|
||||
if (!fun) {
|
||||
return false;
|
||||
}
|
||||
SET_JITINFO(fun, methodSpec.call.info);
|
||||
}
|
||||
JSObject *funobj = JS_GetFunctionObject(fun);
|
||||
desc.value().setObject(*funobj);
|
||||
desc.setAttributes(methodSpec.flags);
|
||||
|
|
|
@ -1571,17 +1571,25 @@ class MethodDefiner(PropertyDefiner):
|
|||
return m["condition"]
|
||||
|
||||
def specData(m):
|
||||
if "selfHostedName" in m:
|
||||
selfHostedName = '"%s"' % m["selfHostedName"]
|
||||
assert not m.get("methodInfo", True)
|
||||
accessor = "nullptr"
|
||||
jitinfo = "nullptr"
|
||||
else:
|
||||
selfHostedName = "nullptr";
|
||||
accessor = m.get("nativeName", m["name"])
|
||||
if m.get("methodInfo", True):
|
||||
jitinfo = ("&%s_methodinfo" % accessor)
|
||||
accessor = "genericMethod"
|
||||
else:
|
||||
jitinfo = "nullptr"
|
||||
return (m["name"], accessor, jitinfo, m["length"], m["flags"])
|
||||
|
||||
return (m["name"], accessor, jitinfo, m["length"], m["flags"], selfHostedName)
|
||||
|
||||
return self.generatePrefableArray(
|
||||
array, name,
|
||||
' JS_FNINFO("%s", %s, %s, %s, %s)',
|
||||
' JS_FNSPEC("%s", %s, %s, %s, %s, %s)',
|
||||
' JS_FS_END',
|
||||
'JSFunctionSpec',
|
||||
condition, specData, doIdArrays)
|
||||
|
|
|
@ -60,7 +60,7 @@ globalgen_targets := \
|
|||
# would break |make FooBinding.o(bj)|. Ah, well.
|
||||
ifneq (export TestExampleInterface-example TestExampleProxyInterface-example,$(MAKECMDGOALS))
|
||||
CPPSRCS = \
|
||||
$(linked_binding_cpp_files) \
|
||||
$(unified_binding_cpp_files) \
|
||||
$(linked_generated_events_cpp_files) \
|
||||
$(filter %.cpp, $(globalgen_targets)) \
|
||||
BindingUtils.cpp \
|
||||
|
@ -119,7 +119,7 @@ globalgen_headers_FILES := \
|
|||
UnionTypes.h \
|
||||
$(NULL)
|
||||
globalgen_headers_DEST = $(DIST)/include/mozilla/dom
|
||||
globalgen_headers_TARGET := webidl
|
||||
globalgen_headers_TARGET := export
|
||||
INSTALL_TARGETS += globalgen_headers
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
@ -258,6 +258,7 @@ GARBAGE += \
|
|||
parser.out \
|
||||
$(wildcard *-example.h) \
|
||||
$(wildcard *-example.cpp) \
|
||||
$(unified_binding_cpp_files) \
|
||||
.BindingGen \
|
||||
.all-webidl-file-list \
|
||||
.generated-events-webidl-files \
|
||||
|
@ -270,9 +271,7 @@ GARBAGE += \
|
|||
# headers they depend on. This is really only needed for the test files, since
|
||||
# the non-test headers are all exported above anyway. Note that this means that
|
||||
# we do all of our codegen during export.
|
||||
webidl:: $(generated_header_files)
|
||||
|
||||
.PHONY: webidl
|
||||
export:: $(generated_header_files)
|
||||
|
||||
distclean::
|
||||
-$(RM) \
|
||||
|
@ -282,9 +281,3 @@ distclean::
|
|||
$(globalgen_targets) \
|
||||
ParserResults.pkl \
|
||||
$(NULL)
|
||||
|
||||
# This is only needed to support |make| from this leaf directory/Makefile.
|
||||
NONRECURSIVE_TARGETS := export
|
||||
NONRECURSIVE_TARGETS_export := webidl
|
||||
NONRECURSIVE_TARGETS_export_webidl_DIRECTORY := .
|
||||
NONRECURSIVE_TARGETS_export_webidl_TARGETS := webidl
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
|
||||
#include "nsIIDBKeyRange.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
#include "mozilla/dom/ipc/Blob.h"
|
||||
|
@ -563,6 +564,7 @@ IDBIndex::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
|
|||
IDBTransaction* transaction = mObjectStore->Transaction();
|
||||
if (!transaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
|
@ -1367,10 +1369,11 @@ GetHelper::UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
|
|||
nsresult
|
||||
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
||||
{
|
||||
NS_ASSERTION(!NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_LABEL("IndexedDB", "GetAllKeysHelper::DoDatabaseWork");
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::DoDatabaseWork [IDBIndex.cpp]");
|
||||
|
||||
nsCString tableName;
|
||||
if (mIndex->IsUnique()) {
|
||||
|
@ -1410,7 +1413,7 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
|||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mKeys.SetCapacity(50);
|
||||
mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
|
||||
|
||||
bool hasResult;
|
||||
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
|
@ -1433,7 +1436,12 @@ nsresult
|
|||
GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
||||
JS::MutableHandle<JS::Value> aVal)
|
||||
{
|
||||
NS_ASSERTION(mKeys.Length() <= mLimit, "Too many results!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mKeys.Length() <= mLimit);
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::GetSuccessResult "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
nsTArray<Key> keys;
|
||||
mKeys.SwapElements(keys);
|
||||
|
@ -1475,11 +1483,12 @@ GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
|
|||
nsresult
|
||||
GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(!IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess");
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
GetAllKeysParams params;
|
||||
|
||||
|
@ -1501,11 +1510,12 @@ GetAllKeysHelper::PackArgumentsForParentProcess(IndexRequestParams& aParams)
|
|||
AsyncConnectionHelper::ChildProcessSendResult
|
||||
GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
|
||||
{
|
||||
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
|
||||
NS_ASSERTION(IndexedDatabaseManager::IsMainProcess(), "Wrong process!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::SendResponseToChildProcess");
|
||||
"GetAllKeysHelper::SendResponseToChildProcess "
|
||||
"[IDBIndex.cpp]");
|
||||
|
||||
IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
|
||||
NS_ASSERTION(actor, "How did we get this far without an actor?");
|
||||
|
@ -1531,8 +1541,9 @@ nsresult
|
|||
GetAllKeysHelper::UnpackResponseFromParentProcess(
|
||||
const ResponseValue& aResponseValue)
|
||||
{
|
||||
NS_ASSERTION(aResponseValue.type() == ResponseValue::TGetAllKeysResponse,
|
||||
"Bad response type!");
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
|
||||
|
||||
mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
|
||||
return NS_OK;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "mozilla/dom/ipc/nsIRemoteBlob.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include "jsfriendapi.h"
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/dom/ContentParent.h"
|
||||
|
@ -441,6 +442,46 @@ private:
|
|||
nsTArray<StructuredCloneReadInfo> mCloneReadInfos;
|
||||
};
|
||||
|
||||
class GetAllKeysHelper MOZ_FINAL : public ObjectStoreHelper
|
||||
{
|
||||
public:
|
||||
GetAllKeysHelper(IDBTransaction* aTransaction,
|
||||
IDBRequest* aRequest,
|
||||
IDBObjectStore* aObjectStore,
|
||||
IDBKeyRange* aKeyRange,
|
||||
const uint32_t aLimit)
|
||||
: ObjectStoreHelper(aTransaction, aRequest, aObjectStore),
|
||||
mKeyRange(aKeyRange), mLimit(aLimit)
|
||||
{ }
|
||||
|
||||
virtual nsresult
|
||||
DoDatabaseWork(mozIStorageConnection* aConnection) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal) MOZ_OVERRIDE;
|
||||
|
||||
virtual void
|
||||
ReleaseMainThreadObjects() MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
PackArgumentsForParentProcess(ObjectStoreRequestParams& aParams) MOZ_OVERRIDE;
|
||||
|
||||
virtual ChildProcessSendResult
|
||||
SendResponseToChildProcess(nsresult aResultCode) MOZ_OVERRIDE;
|
||||
|
||||
virtual nsresult
|
||||
UnpackResponseFromParentProcess(const ResponseValue& aResponseValue)
|
||||
MOZ_OVERRIDE;
|
||||
|
||||
private:
|
||||
~GetAllKeysHelper()
|
||||
{ }
|
||||
|
||||
nsRefPtr<IDBKeyRange> mKeyRange;
|
||||
const uint32_t mLimit;
|
||||
nsTArray<Key> mKeys;
|
||||
};
|
||||
|
||||
class CountHelper : public ObjectStoreHelper
|
||||
{
|
||||
public:
|
||||
|
@ -2081,6 +2122,47 @@ IDBObjectStore::GetAllInternal(IDBKeyRange* aKeyRange,
|
|||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::GetAllKeysInternal(IDBKeyRange* aKeyRange, uint32_t aLimit,
|
||||
ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mTransaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBRequest> request = GenerateRequest(this);
|
||||
if (!request) {
|
||||
NS_WARNING("Failed to generate request!");
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<GetAllKeysHelper> helper =
|
||||
new GetAllKeysHelper(mTransaction, request, this, aKeyRange, aLimit);
|
||||
|
||||
nsresult rv = helper->DispatchToTransactionPool();
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to dispatch!");
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
IDB_PROFILER_MARK("IndexedDB Request %llu: "
|
||||
"database(%s).transaction(%s).objectStore(%s)."
|
||||
"getAllKeys(%s, %lu)",
|
||||
"IDBRequest[%llu] MT IDBObjectStore.getAllKeys()",
|
||||
request->GetSerialNumber(),
|
||||
IDB_PROFILER_STRING(Transaction()->Database()),
|
||||
IDB_PROFILER_STRING(Transaction()),
|
||||
IDB_PROFILER_STRING(this), IDB_PROFILER_STRING(aKeyRange),
|
||||
aLimit);
|
||||
|
||||
return request.forget();
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::DeleteInternal(IDBKeyRange* aKeyRange,
|
||||
ErrorResult& aRv)
|
||||
|
@ -2767,6 +2849,32 @@ IDBObjectStore::Count(JSContext* aCx,
|
|||
return CountInternal(keyRange, aRv);
|
||||
}
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
IDBObjectStore::GetAllKeys(JSContext* aCx,
|
||||
const Optional<JS::HandleValue>& aKey,
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
if (!mTransaction->IsOpen()) {
|
||||
aRv.Throw(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
if (aKey.WasPassed()) {
|
||||
aRv = IDBKeyRange::FromJSVal(aCx, aKey.Value(), getter_AddRefs(keyRange));
|
||||
ENSURE_SUCCESS(aRv, nullptr);
|
||||
}
|
||||
|
||||
uint32_t limit = UINT32_MAX;
|
||||
if (aLimit.WasPassed() && aLimit.Value() != 0) {
|
||||
limit = aLimit.Value();
|
||||
}
|
||||
|
||||
return GetAllKeysInternal(keyRange, limit, aRv);
|
||||
}
|
||||
|
||||
inline nsresult
|
||||
CopyData(nsIInputStream* aInputStream, nsIOutputStream* aOutputStream)
|
||||
{
|
||||
|
@ -4297,6 +4405,195 @@ GetAllHelper::UnpackResponseFromParentProcess(
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* /* aConnection */)
|
||||
{
|
||||
MOZ_ASSERT(!NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::DoDatabaseWork [IDObjectStore.cpp]");
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(keyValue, "key_value");
|
||||
|
||||
nsAutoCString keyRangeClause;
|
||||
if (mKeyRange) {
|
||||
mKeyRange->GetBindingClause(keyValue, keyRangeClause);
|
||||
}
|
||||
|
||||
nsAutoCString limitClause;
|
||||
if (mLimit != UINT32_MAX) {
|
||||
limitClause = NS_LITERAL_CSTRING(" LIMIT ");
|
||||
limitClause.AppendInt(mLimit);
|
||||
}
|
||||
|
||||
NS_NAMED_LITERAL_CSTRING(osid, "osid");
|
||||
|
||||
nsCString query = NS_LITERAL_CSTRING("SELECT ") + keyValue +
|
||||
NS_LITERAL_CSTRING(" FROM object_data WHERE "
|
||||
"object_store_id = :") +
|
||||
osid + keyRangeClause +
|
||||
NS_LITERAL_CSTRING(" ORDER BY key_value ASC") +
|
||||
limitClause;
|
||||
|
||||
nsCOMPtr<mozIStorageStatement> stmt = mTransaction->GetCachedStatement(query);
|
||||
NS_ENSURE_TRUE(stmt, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
mozStorageStatementScoper scoper(stmt);
|
||||
|
||||
nsresult rv = stmt->BindInt64ByName(osid, mObjectStore->Id());
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
if (mKeyRange) {
|
||||
rv = mKeyRange->BindToStatement(stmt);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
mKeys.SetCapacity(std::min<uint32_t>(50, mLimit));
|
||||
|
||||
bool hasResult;
|
||||
while(NS_SUCCEEDED((rv = stmt->ExecuteStep(&hasResult))) && hasResult) {
|
||||
if (mKeys.Capacity() == mKeys.Length()) {
|
||||
mKeys.SetCapacity(mKeys.Capacity() * 2);
|
||||
}
|
||||
|
||||
Key* key = mKeys.AppendElement();
|
||||
NS_ASSERTION(key, "This shouldn't fail!");
|
||||
|
||||
rv = key->SetFromStatement(stmt, 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::GetSuccessResult(JSContext* aCx, JS::MutableHandleValue aVal)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(mKeys.Length() <= mLimit);
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::GetSuccessResult "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
nsTArray<Key> keys;
|
||||
mKeys.SwapElements(keys);
|
||||
|
||||
JS::RootedObject array(aCx, JS_NewArrayObject(aCx, 0, NULL));
|
||||
if (!array) {
|
||||
NS_WARNING("Failed to make array!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
if (!keys.IsEmpty()) {
|
||||
if (!JS_SetArrayLength(aCx, array, keys.Length())) {
|
||||
NS_WARNING("Failed to set array length!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
|
||||
for (uint32_t index = 0, count = keys.Length(); index < count; index++) {
|
||||
const Key& key = keys[index];
|
||||
MOZ_ASSERT(!key.IsUnset());
|
||||
|
||||
JS::RootedValue value(aCx);
|
||||
nsresult rv = key.ToJSVal(aCx, &value);
|
||||
if (NS_FAILED(rv)) {
|
||||
NS_WARNING("Failed to get jsval for key!");
|
||||
return rv;
|
||||
}
|
||||
|
||||
if (!JS_SetElement(aCx, array, index, &value)) {
|
||||
NS_WARNING("Failed to set array element!");
|
||||
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aVal.setObject(*array);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
GetAllKeysHelper::ReleaseMainThreadObjects()
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
mKeyRange = nullptr;
|
||||
|
||||
ObjectStoreHelper::ReleaseMainThreadObjects();
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::PackArgumentsForParentProcess(
|
||||
ObjectStoreRequestParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::PackArgumentsForParentProcess "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
GetAllKeysParams params;
|
||||
|
||||
if (mKeyRange) {
|
||||
KeyRange keyRange;
|
||||
mKeyRange->ToSerializedKeyRange(keyRange);
|
||||
params.optionalKeyRange() = keyRange;
|
||||
} else {
|
||||
params.optionalKeyRange() = mozilla::void_t();
|
||||
}
|
||||
|
||||
params.limit() = mLimit;
|
||||
|
||||
aParams = params;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
AsyncConnectionHelper::ChildProcessSendResult
|
||||
GetAllKeysHelper::SendResponseToChildProcess(nsresult aResultCode)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(IndexedDatabaseManager::IsMainProcess());
|
||||
|
||||
PROFILER_MAIN_THREAD_LABEL("IndexedDB",
|
||||
"GetAllKeysHelper::SendResponseToChildProcess "
|
||||
"[IDBObjectStore.cpp]");
|
||||
|
||||
IndexedDBRequestParentBase* actor = mRequest->GetActorParent();
|
||||
MOZ_ASSERT(actor);
|
||||
|
||||
ResponseValue response;
|
||||
if (NS_FAILED(aResultCode)) {
|
||||
response = aResultCode;
|
||||
}
|
||||
else {
|
||||
GetAllKeysResponse getAllKeysResponse;
|
||||
getAllKeysResponse.keys().AppendElements(mKeys);
|
||||
response = getAllKeysResponse;
|
||||
}
|
||||
|
||||
if (!actor->SendResponse(response)) {
|
||||
return Error;
|
||||
}
|
||||
|
||||
return Success_Sent;
|
||||
}
|
||||
|
||||
nsresult
|
||||
GetAllKeysHelper::UnpackResponseFromParentProcess(
|
||||
const ResponseValue& aResponseValue)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
MOZ_ASSERT(!IndexedDatabaseManager::IsMainProcess());
|
||||
MOZ_ASSERT(aResponseValue.type() == ResponseValue::TGetAllKeysResponse);
|
||||
|
||||
mKeys.AppendElements(aResponseValue.get_GetAllKeysResponse().keys());
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult
|
||||
CountHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
|
||||
{
|
||||
|
|
|
@ -9,6 +9,7 @@
|
|||
|
||||
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/dom/IDBCursorBinding.h"
|
||||
#include "mozilla/dom/IDBIndexBinding.h"
|
||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
|
@ -220,6 +221,11 @@ public:
|
|||
uint32_t aLimit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
GetAllKeysInternal(IDBKeyRange* aKeyRange,
|
||||
uint32_t aLimit,
|
||||
ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
DeleteInternal(IDBKeyRange* aKeyRange,
|
||||
ErrorResult& aRv);
|
||||
|
@ -233,7 +239,8 @@ public:
|
|||
size_t aDirection,
|
||||
ErrorResult& aRv);
|
||||
|
||||
nsresult OpenCursorFromChildProcess(
|
||||
nsresult
|
||||
OpenCursorFromChildProcess(
|
||||
IDBRequest* aRequest,
|
||||
size_t aDirection,
|
||||
const Key& aKey,
|
||||
|
@ -319,7 +326,7 @@ public:
|
|||
|
||||
already_AddRefed<IDBIndex>
|
||||
CreateIndex(JSContext* aCx, const nsAString& aName,
|
||||
const Sequence<nsString >& aKeyPath,
|
||||
const Sequence<nsString>& aKeyPath,
|
||||
const IDBIndexParameters& aOptionalParameters, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBIndex>
|
||||
|
@ -334,7 +341,11 @@ public:
|
|||
|
||||
already_AddRefed<IDBRequest>
|
||||
GetAll(JSContext* aCx, const Optional<JS::Handle<JS::Value> >& aKey,
|
||||
const Optional<uint32_t >& aLimit, ErrorResult& aRv);
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
||||
|
||||
already_AddRefed<IDBRequest>
|
||||
GetAllKeys(JSContext* aCx, const Optional<JS::HandleValue>& aKey,
|
||||
const Optional<uint32_t>& aLimit, ErrorResult& aRv);
|
||||
|
||||
protected:
|
||||
IDBObjectStore();
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include "nsIObserverService.h"
|
||||
#include "nsIScriptError.h"
|
||||
|
||||
#include "jsapi.h"
|
||||
#include "mozilla/ClearOnShutdown.h"
|
||||
#include "mozilla/CondVar.h"
|
||||
#include "mozilla/ContentEvents.h"
|
||||
|
@ -22,6 +23,7 @@
|
|||
#include "mozilla/dom/TabContext.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/storage.h"
|
||||
#include "mozilla/Util.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsEventDispatcher.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
@ -31,6 +33,17 @@
|
|||
#include "IDBKeyRange.h"
|
||||
#include "IDBRequest.h"
|
||||
|
||||
// Bindings for ResolveConstructors
|
||||
#include "mozilla/dom/IDBCursorBinding.h"
|
||||
#include "mozilla/dom/IDBDatabaseBinding.h"
|
||||
#include "mozilla/dom/IDBFactoryBinding.h"
|
||||
#include "mozilla/dom/IDBIndexBinding.h"
|
||||
#include "mozilla/dom/IDBObjectStoreBinding.h"
|
||||
#include "mozilla/dom/IDBOpenDBRequestBinding.h"
|
||||
#include "mozilla/dom/IDBRequestBinding.h"
|
||||
#include "mozilla/dom/IDBTransactionBinding.h"
|
||||
#include "mozilla/dom/IDBVersionChangeEventBinding.h"
|
||||
|
||||
// The two possible values for the data argument when receiving the disk space
|
||||
// observer notification.
|
||||
#define LOW_DISK_SPACE_DATA_FULL "full"
|
||||
|
@ -94,6 +107,32 @@ mozilla::StaticRefPtr<IndexedDatabaseManager> gInstance;
|
|||
mozilla::Atomic<int32_t> gInitialized(0);
|
||||
mozilla::Atomic<int32_t> gClosed(0);
|
||||
|
||||
// See ResolveConstructors below.
|
||||
struct ConstructorInfo {
|
||||
const char* const name;
|
||||
JS::Handle<JSObject*> (* const resolve)(JSContext*, JS::Handle<JSObject*>,
|
||||
bool);
|
||||
jsid id;
|
||||
};
|
||||
|
||||
ConstructorInfo gConstructorInfo[] = {
|
||||
|
||||
#define BINDING_ENTRY(_name) \
|
||||
{ #_name, _name##Binding::GetConstructorObject, JSID_VOID },
|
||||
|
||||
BINDING_ENTRY(IDBFactory)
|
||||
BINDING_ENTRY(IDBDatabase)
|
||||
BINDING_ENTRY(IDBTransaction)
|
||||
BINDING_ENTRY(IDBObjectStore)
|
||||
BINDING_ENTRY(IDBIndex)
|
||||
BINDING_ENTRY(IDBCursor)
|
||||
BINDING_ENTRY(IDBRequest)
|
||||
BINDING_ENTRY(IDBOpenDBRequest)
|
||||
BINDING_ENTRY(IDBVersionChangeEvent)
|
||||
|
||||
#undef BINDING_ENTRY
|
||||
};
|
||||
|
||||
class AsyncDeleteFileRunnable MOZ_FINAL : public nsIRunnable
|
||||
{
|
||||
public:
|
||||
|
@ -884,3 +923,48 @@ GetFileReferencesHelper::Run()
|
|||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
BEGIN_INDEXEDDB_NAMESPACE
|
||||
|
||||
bool
|
||||
ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId,
|
||||
JS::MutableHandleObject aObjp)
|
||||
{
|
||||
MOZ_ASSERT(NS_IsMainThread());
|
||||
|
||||
// The first time this function is called we need to intern all the strings we
|
||||
// care about.
|
||||
if (JSID_IS_VOID(gConstructorInfo[0].id)) {
|
||||
for (uint32_t i = 0; i < mozilla::ArrayLength(gConstructorInfo); i++) {
|
||||
JS::RootedString str(aCx, JS_InternString(aCx, gConstructorInfo[i].name));
|
||||
if (!str) {
|
||||
NS_WARNING("Failed to intern string!");
|
||||
while (i) {
|
||||
gConstructorInfo[--i].id = JSID_VOID;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
gConstructorInfo[i].id = INTERNED_STRING_TO_JSID(aCx, str);
|
||||
}
|
||||
}
|
||||
|
||||
// Now resolve.
|
||||
for (uint32_t i = 0; i < mozilla::ArrayLength(gConstructorInfo); i++) {
|
||||
if (gConstructorInfo[i].id == aId) {
|
||||
JS::RootedObject constructor(aCx,
|
||||
gConstructorInfo[i].resolve(aCx, aObj, true));
|
||||
if (!constructor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
aObjp.set(aObj);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Not resolved.
|
||||
aObjp.set(nullptr);
|
||||
return true;
|
||||
}
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#include "nsIIndexedDatabaseManager.h"
|
||||
#include "nsIObserver.h"
|
||||
|
||||
#include "js/TypeDecls.h"
|
||||
#include "mozilla/Atomics.h"
|
||||
#include "mozilla/dom/quota/PersistenceType.h"
|
||||
#include "mozilla/Mutex.h"
|
||||
|
@ -166,6 +167,10 @@ private:
|
|||
static mozilla::Atomic<int32_t> sLowDiskSpaceMode;
|
||||
};
|
||||
|
||||
bool
|
||||
ResolveConstructors(JSContext* aCx, JS::HandleObject aObj, JS::HandleId aId,
|
||||
JS::MutableHandleObject aObjp);
|
||||
|
||||
END_INDEXEDDB_NAMESPACE
|
||||
|
||||
#endif /* mozilla_dom_indexeddb_indexeddatabasemanager_h__ */
|
||||
|
|
|
@ -1069,6 +1069,9 @@ IndexedDBObjectStoreRequestChild::Recv__delete__(const ResponseValue& aResponse)
|
|||
case ResponseValue::TGetAllResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllParams);
|
||||
break;
|
||||
case ResponseValue::TGetAllKeysResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
|
||||
break;
|
||||
case ResponseValue::TAddResponse:
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TAddParams);
|
||||
break;
|
||||
|
|
|
@ -40,6 +40,12 @@ struct GetAllParams
|
|||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct GetAllKeysParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct CountParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
|
|
|
@ -1097,6 +1097,9 @@ IndexedDBObjectStoreParent::RecvPIndexedDBRequestConstructor(
|
|||
case ObjectStoreRequestParams::TGetAllParams:
|
||||
return actor->GetAll(aParams.get_GetAllParams());
|
||||
|
||||
case ObjectStoreRequestParams::TGetAllKeysParams:
|
||||
return actor->GetAllKeys(aParams.get_GetAllKeysParams());
|
||||
|
||||
case ObjectStoreRequestParams::TAddParams:
|
||||
return actor->Add(aParams.get_AddParams());
|
||||
|
||||
|
@ -1554,6 +1557,44 @@ IndexedDBObjectStoreRequestParent::GetAll(const GetAllParams& aParams)
|
|||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IndexedDBObjectStoreRequestParent::GetAllKeys(const GetAllKeysParams& aParams)
|
||||
{
|
||||
MOZ_ASSERT(mRequestType == ParamsUnionType::TGetAllKeysParams);
|
||||
MOZ_ASSERT(mObjectStore);
|
||||
|
||||
nsRefPtr<IDBRequest> request;
|
||||
|
||||
const ipc::OptionalKeyRange keyRangeUnion = aParams.optionalKeyRange();
|
||||
|
||||
nsRefPtr<IDBKeyRange> keyRange;
|
||||
|
||||
switch (keyRangeUnion.type()) {
|
||||
case ipc::OptionalKeyRange::TKeyRange:
|
||||
keyRange =
|
||||
IDBKeyRange::FromSerializedKeyRange(keyRangeUnion.get_KeyRange());
|
||||
break;
|
||||
|
||||
case ipc::OptionalKeyRange::Tvoid_t:
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("Unknown param type!");
|
||||
}
|
||||
|
||||
{
|
||||
AutoSetCurrentTransaction asct(mObjectStore->Transaction());
|
||||
|
||||
ErrorResult rv;
|
||||
request = mObjectStore->GetAllKeysInternal(keyRange, aParams.limit(), rv);
|
||||
ENSURE_SUCCESS(rv, false);
|
||||
}
|
||||
|
||||
request->SetActor(this);
|
||||
mRequest.swap(request);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
IndexedDBObjectStoreRequestParent::Add(const AddParams& aParams)
|
||||
{
|
||||
|
|
|
@ -707,6 +707,7 @@ class IndexedDBObjectStoreRequestParent : public IndexedDBRequestParentBase
|
|||
typedef ipc::DeleteParams DeleteParams;
|
||||
typedef ipc::GetParams GetParams;
|
||||
typedef ipc::GetAllParams GetAllParams;
|
||||
typedef ipc::GetAllKeysParams GetAllKeysParams;
|
||||
typedef ipc::CountParams CountParams;
|
||||
typedef ipc::OpenCursorParams OpenCursorParams;
|
||||
|
||||
|
@ -721,6 +722,9 @@ public:
|
|||
bool
|
||||
GetAll(const GetAllParams& aParams);
|
||||
|
||||
bool
|
||||
GetAllKeys(const GetAllKeysParams& aParams);
|
||||
|
||||
bool
|
||||
Add(const AddParams& aParams);
|
||||
|
||||
|
|
|
@ -22,12 +22,6 @@ struct GetKeyParams
|
|||
KeyRange keyRange;
|
||||
};
|
||||
|
||||
struct GetAllKeysParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
uint32_t limit;
|
||||
};
|
||||
|
||||
struct OpenKeyCursorParams
|
||||
{
|
||||
OptionalKeyRange optionalKeyRange;
|
||||
|
|
|
@ -52,6 +52,7 @@ union ObjectStoreRequestParams
|
|||
{
|
||||
GetParams;
|
||||
GetAllParams;
|
||||
GetAllKeysParams;
|
||||
AddParams;
|
||||
PutParams;
|
||||
DeleteParams;
|
||||
|
|
|
@ -36,6 +36,7 @@ tail =
|
|||
[test_names_sorted.js]
|
||||
[test_object_identity.js]
|
||||
[test_objectCursors.js]
|
||||
[test_objectStore_getAllKeys.js]
|
||||
[test_objectStore_inline_autoincrement_key_added_on_put.js]
|
||||
[test_objectStore_remove_values.js]
|
||||
[test_odd_result_order.js]
|
||||
|
|
|
@ -70,6 +70,7 @@ MOCHITEST_FILES = \
|
|||
test_multientry.html \
|
||||
test_names_sorted.html \
|
||||
test_objectCursors.html \
|
||||
test_objectStore_getAllKeys.html \
|
||||
test_objectStore_inline_autoincrement_key_added_on_put.html \
|
||||
test_objectStore_remove_values.html \
|
||||
test_object_identity.html \
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
<!--
|
||||
Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/
|
||||
-->
|
||||
<html>
|
||||
<head>
|
||||
<title>Indexed Database Property Test</title>
|
||||
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
||||
|
||||
<script type="text/javascript;version=1.7" src="unit/test_objectStore_getAllKeys.js"></script>
|
||||
<script type="text/javascript;version=1.7" src="helpers.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body onload="runTest();"></body>
|
||||
|
||||
</html>
|
|
@ -38,6 +38,7 @@ MOCHITEST_FILES = \
|
|||
test_names_sorted.js \
|
||||
test_object_identity.js \
|
||||
test_objectCursors.js \
|
||||
test_objectStore_getAllKeys.js \
|
||||
test_objectStore_inline_autoincrement_key_added_on_put.js \
|
||||
test_objectStore_remove_values.js \
|
||||
test_odd_result_order.js \
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
/**
|
||||
* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/
|
||||
*/
|
||||
|
||||
let testGenerator = testSteps();
|
||||
|
||||
function testSteps() {
|
||||
const dbName = this.window ?
|
||||
window.location.pathname :
|
||||
"test_objectStore_getAllKeys";
|
||||
const dbVersion = 1;
|
||||
const objectStoreName = "foo";
|
||||
const keyCount = 200;
|
||||
|
||||
let request = indexedDB.open(dbName, dbVersion);
|
||||
request.onerror = errorHandler;
|
||||
request.onupgradeneeded = grabEventAndContinueHandler;
|
||||
request.onsuccess = unexpectedSuccessHandler;
|
||||
|
||||
let event = yield undefined;
|
||||
|
||||
info("Creating database");
|
||||
|
||||
let db = event.target.result;
|
||||
let objectStore = db.createObjectStore(objectStoreName);
|
||||
for (let i = 0; i < keyCount; i++) {
|
||||
objectStore.add(true, i);
|
||||
}
|
||||
|
||||
request.onupgradeneeded = unexpectedSuccessHandler;
|
||||
request.onsuccess = grabEventAndContinueHandler;
|
||||
|
||||
event = yield undefined;
|
||||
|
||||
db = event.target.result;
|
||||
objectStore = db.transaction(objectStoreName).objectStore(objectStoreName);
|
||||
|
||||
info("Getting all keys");
|
||||
objectStore.getAllKeys().onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, keyCount, "Got correct array length");
|
||||
|
||||
let match = true;
|
||||
for (let i = 0; i < keyCount; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range");
|
||||
let keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 10, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 20; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
info("Getting all keys with limit");
|
||||
objectStore.getAllKeys(null, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 0; i < 5; i++) {
|
||||
if (event.target.result[i] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10, 20, false, true);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 5, "Got correct array length");
|
||||
|
||||
match = true;
|
||||
for (let i = 10; i < 15; i++) {
|
||||
if (event.target.result[i - 10] != i) {
|
||||
match = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ok(match, "Got correct keys");
|
||||
|
||||
info("Getting all keys with unmatched key range and limit");
|
||||
keyRange = IDBKeyRange.bound(10000, 200000);
|
||||
objectStore.getAllKeys(keyRange, 5).onsuccess = grabEventAndContinueHandler;
|
||||
event = yield undefined;
|
||||
|
||||
ok(Array.isArray(event.target.result), "Got an array result");
|
||||
is(event.target.result.length, 0, "Got correct array length");
|
||||
|
||||
finishTest();
|
||||
yield undefined;
|
||||
}
|
|
@ -39,6 +39,7 @@ tail =
|
|||
[test_names_sorted.js]
|
||||
[test_object_identity.js]
|
||||
[test_objectCursors.js]
|
||||
[test_objectStore_getAllKeys.js]
|
||||
[test_objectStore_inline_autoincrement_key_added_on_put.js]
|
||||
[test_objectStore_remove_values.js]
|
||||
[test_odd_result_order.js]
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -109,7 +109,7 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
|
|||
++writeIndex;
|
||||
}
|
||||
|
||||
function writeUint32(value) {
|
||||
function writeInt32(value) {
|
||||
writeUint8(value & 0xff);
|
||||
writeUint8((value >> 8) & 0xff);
|
||||
writeUint8((value >> 16) & 0xff);
|
||||
|
@ -128,8 +128,8 @@ function newIncomingParcel(fakeParcelSize, response, request, data) {
|
|||
}
|
||||
writeParcelSize(fakeParcelSize);
|
||||
|
||||
writeUint32(response);
|
||||
writeUint32(request);
|
||||
writeInt32(response);
|
||||
writeInt32(request);
|
||||
|
||||
// write parcel data
|
||||
for (let ii = 0; ii < data.length; ++ii) {
|
||||
|
|
|
@ -42,10 +42,10 @@ add_test(function test_change_call_barring_password() {
|
|||
function do_test(facility, pin, newPin) {
|
||||
buf.sendParcel = function fakeSendParcel () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_CHANGE_BARRING_PASSWORD);
|
||||
do_check_eq(this.readInt32(), REQUEST_CHANGE_BARRING_PASSWORD);
|
||||
|
||||
// Token : we don't care.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
let parcel = this.readStringList();
|
||||
do_check_eq(parcel.length, 3);
|
||||
|
|
|
@ -51,7 +51,7 @@ add_test_incoming_parcel(null,
|
|||
function test_normal_parcel_handling(worker) {
|
||||
do_check_throws(function normal_handler() {
|
||||
// reads exactly the same size, should not throw anything.
|
||||
worker.Buf.readUint32();
|
||||
worker.Buf.readInt32();
|
||||
});
|
||||
}
|
||||
);
|
||||
|
|
|
@ -31,7 +31,7 @@ function newWorkerWithParcel(parcelBuf) {
|
|||
return buf[index++];
|
||||
};
|
||||
|
||||
worker.Buf.readUint32 = function () {
|
||||
worker.Buf.readInt32 = function () {
|
||||
return buf[index++];
|
||||
};
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ add_test(function test_queryCallForwardStatus_unconditional() {
|
|||
});
|
||||
};
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ add_test(function test_queryCLIP_provisioned() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
@ -58,7 +58,7 @@ add_test(function test_getCLIP_error_generic_failure_invalid_length() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
|
|
@ -85,7 +85,7 @@ add_test(function test_getCLIR_n0_m1() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
@ -117,7 +117,7 @@ add_test(function test_getCLIR_error_generic_failure_invalid_length() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
|
|
@ -74,7 +74,7 @@ add_test(function test_queryCallWaiting_success_enabled_true() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
@ -104,7 +104,7 @@ add_test(function test_queryCallWaiting_success_enabled_false() {
|
|||
let workerHelper = _getWorker();
|
||||
let worker = workerHelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
|
|
@ -492,13 +492,13 @@ add_test(function test_icc_get_card_lock_state_fdn() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_QUERY_FACILITY_LOCK)
|
||||
do_check_eq(this.readInt32(), REQUEST_QUERY_FACILITY_LOCK)
|
||||
|
||||
// Token : we don't care.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// String Array Length.
|
||||
do_check_eq(this.readUint32(), worker.RILQUIRKS_V5_LEGACY ? 3 : 4);
|
||||
do_check_eq(this.readInt32(), worker.RILQUIRKS_V5_LEGACY ? 3 : 4);
|
||||
|
||||
// Facility.
|
||||
do_check_eq(this.readString(), ICC_CB_FACILITY_FDN);
|
||||
|
@ -513,7 +513,7 @@ add_test(function test_icc_get_card_lock_state_fdn() {
|
|||
|
||||
if (!worker.RILQUIRKS_V5_LEGACY) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
|
@ -759,7 +759,7 @@ add_test(function test_read_pbr() {
|
|||
];
|
||||
|
||||
// Write data size
|
||||
buf.writeUint32(pbr_1.length * 2);
|
||||
buf.writeInt32(pbr_1.length * 2);
|
||||
|
||||
// Write pbr
|
||||
for (let i = 0; i < pbr_1.length; i++) {
|
||||
|
@ -820,7 +820,7 @@ add_test(function test_read_email() {
|
|||
0x6F, 0x6D, 0x02, 0x23];
|
||||
|
||||
// Write data size
|
||||
buf.writeUint32(email_1.length * 2);
|
||||
buf.writeInt32(email_1.length * 2);
|
||||
|
||||
// Write email
|
||||
for (let i = 0; i < email_1.length; i++) {
|
||||
|
@ -888,32 +888,32 @@ add_test(function test_update_email() {
|
|||
count++;
|
||||
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
|
||||
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
do_check_eq(this.readUint32(), fileId);
|
||||
do_check_eq(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
do_check_eq(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
|
||||
|
||||
// p1.
|
||||
do_check_eq(this.readUint32(), recordNumber);
|
||||
do_check_eq(this.readInt32(), recordNumber);
|
||||
|
||||
// p2.
|
||||
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
do_check_eq(this.readUint32(), recordSize);
|
||||
do_check_eq(this.readInt32(), recordSize);
|
||||
|
||||
// data.
|
||||
let strLen = this.readUint32();
|
||||
let strLen = this.readInt32();
|
||||
let email;
|
||||
if (pbr.email.fileType === ICC_USIM_TYPE1_TAG) {
|
||||
email = pduHelper.read8BitUnpackedToString(recordSize);
|
||||
|
@ -930,7 +930,7 @@ add_test(function test_update_email() {
|
|||
|
||||
if (!worker.RILQUIRKS_V5_LEGACY) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
}
|
||||
|
||||
if (count == NUM_TESTS) {
|
||||
|
@ -962,7 +962,7 @@ add_test(function test_read_anr() {
|
|||
0x54, 0xF6, 0xFF, 0xFF];
|
||||
|
||||
// Write data size
|
||||
buf.writeUint32(anr_1.length * 2);
|
||||
buf.writeInt32(anr_1.length * 2);
|
||||
|
||||
// Write anr
|
||||
for (let i = 0; i < anr_1.length; i++) {
|
||||
|
@ -1029,32 +1029,32 @@ add_test(function test_update_anr() {
|
|||
count++;
|
||||
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
|
||||
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
do_check_eq(this.readUint32(), fileId);
|
||||
do_check_eq(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
do_check_eq(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
|
||||
|
||||
// p1.
|
||||
do_check_eq(this.readUint32(), recordNumber);
|
||||
do_check_eq(this.readInt32(), recordNumber);
|
||||
|
||||
// p2.
|
||||
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
do_check_eq(this.readUint32(), recordSize);
|
||||
do_check_eq(this.readInt32(), recordSize);
|
||||
|
||||
// data.
|
||||
let strLen = this.readUint32();
|
||||
let strLen = this.readInt32();
|
||||
// EF_AAS, ignore.
|
||||
pduHelper.readHexOctet();
|
||||
do_check_eq(pduHelper.readNumberWithLength(), expectedANR);
|
||||
|
@ -1073,7 +1073,7 @@ add_test(function test_update_anr() {
|
|||
|
||||
if (!worker.RILQUIRKS_V5_LEGACY) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
}
|
||||
|
||||
if (count == NUM_TESTS) {
|
||||
|
@ -1103,7 +1103,7 @@ add_test(function test_read_iap() {
|
|||
let iap_1 = [0x01, 0x02];
|
||||
|
||||
// Write data size/
|
||||
buf.writeUint32(iap_1.length * 2);
|
||||
buf.writeInt32(iap_1.length * 2);
|
||||
|
||||
// Write iap.
|
||||
for (let i = 0; i < iap_1.length; i++) {
|
||||
|
@ -1172,32 +1172,32 @@ add_test(function test_update_iap() {
|
|||
function do_test(expectedIAP) {
|
||||
buf.sendParcel = function () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
|
||||
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
do_check_eq(this.readUint32(), fileId);
|
||||
do_check_eq(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
do_check_eq(this.readString(),
|
||||
EF_PATH_MF_SIM + EF_PATH_DF_TELECOM + EF_PATH_DF_PHONEBOOK);
|
||||
|
||||
// p1.
|
||||
do_check_eq(this.readUint32(), recordNumber);
|
||||
do_check_eq(this.readInt32(), recordNumber);
|
||||
|
||||
// p2.
|
||||
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
do_check_eq(this.readUint32(), recordSize);
|
||||
do_check_eq(this.readInt32(), recordSize);
|
||||
|
||||
// data.
|
||||
let strLen = this.readUint32();
|
||||
let strLen = this.readInt32();
|
||||
for (let i = 0; i < recordSize; i++) {
|
||||
do_check_eq(expectedIAP[i], pduHelper.readHexOctet());
|
||||
}
|
||||
|
@ -1208,7 +1208,7 @@ add_test(function test_update_iap() {
|
|||
|
||||
if (!worker.RILQUIRKS_V5_LEGACY) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
}
|
||||
|
||||
run_next_test();
|
||||
|
@ -1246,28 +1246,28 @@ add_test(function test_update_adn_like() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_SIM_IO);
|
||||
do_check_eq(this.readInt32(), REQUEST_SIM_IO);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// command.
|
||||
do_check_eq(this.readUint32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
do_check_eq(this.readInt32(), ICC_COMMAND_UPDATE_RECORD);
|
||||
|
||||
// fileId.
|
||||
do_check_eq(this.readUint32(), fileId);
|
||||
do_check_eq(this.readInt32(), fileId);
|
||||
|
||||
// pathId.
|
||||
do_check_eq(this.readString(), EF_PATH_MF_SIM + EF_PATH_DF_TELECOM);
|
||||
|
||||
// p1.
|
||||
do_check_eq(this.readUint32(), 1);
|
||||
do_check_eq(this.readInt32(), 1);
|
||||
|
||||
// p2.
|
||||
do_check_eq(this.readUint32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
do_check_eq(this.readInt32(), READ_RECORD_ABSOLUTE_MODE);
|
||||
|
||||
// p3.
|
||||
do_check_eq(this.readUint32(), 0x20);
|
||||
do_check_eq(this.readInt32(), 0x20);
|
||||
|
||||
// data.
|
||||
let contact = pdu.readAlphaIdDiallingNumber(0x20);
|
||||
|
@ -1283,7 +1283,7 @@ add_test(function test_update_adn_like() {
|
|||
|
||||
if (!worker.RILQUIRKS_V5_LEGACY) {
|
||||
// AID. Ignore because it's from modem.
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
}
|
||||
|
||||
if (fileId == ICC_EF_FDN) {
|
||||
|
@ -1313,7 +1313,7 @@ add_test(function test_find_free_record_id() {
|
|||
|
||||
function writeRecord (record) {
|
||||
// Write data size
|
||||
buf.writeUint32(record.length * 2);
|
||||
buf.writeInt32(record.length * 2);
|
||||
|
||||
for (let i = 0; i < record.length; i++) {
|
||||
pduHelper.writeHexOctet(record[i]);
|
||||
|
@ -1733,10 +1733,10 @@ add_test(function test_set_icc_card_lock_facility_lock() {
|
|||
function do_test(aLock, aPassword, aEnabled) {
|
||||
buf.sendParcel = function fakeSendParcel () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_SET_FACILITY_LOCK);
|
||||
do_check_eq(this.readInt32(), REQUEST_SET_FACILITY_LOCK);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
let parcel = this.readStringList();
|
||||
do_check_eq(parcel.length, 5);
|
||||
|
@ -1783,14 +1783,14 @@ add_test(function test_unlock_card_lock_corporateLocked() {
|
|||
function do_test(aLock, aPassword) {
|
||||
buf.sendParcel = function fakeSendParcel () {
|
||||
// Request Type.
|
||||
do_check_eq(this.readUint32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
|
||||
do_check_eq(this.readInt32(), REQUEST_ENTER_NETWORK_DEPERSONALIZATION_CODE);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
let lockType = GECKO_PERSO_LOCK_TO_CARD_PERSO_LOCK[aLock];
|
||||
// Lock Type
|
||||
do_check_eq(this.readUint32(), lockType);
|
||||
do_check_eq(this.readInt32(), lockType);
|
||||
|
||||
// Pin/Puk.
|
||||
do_check_eq(this.readString(), aPassword);
|
||||
|
@ -1867,7 +1867,7 @@ add_test(function test_reading_ad_and_parsing_mcc_mnc() {
|
|||
}
|
||||
|
||||
// Write data size
|
||||
buf.writeUint32(ad.length * 2);
|
||||
buf.writeInt32(ad.length * 2);
|
||||
|
||||
// Write data
|
||||
for (let i = 0; i < ad.length; i++) {
|
||||
|
|
|
@ -435,7 +435,7 @@ add_test(function test_sendMMI_call_forwarding_interrogation() {
|
|||
let workerhelper = getWorker();
|
||||
let worker = workerhelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
@ -477,7 +477,7 @@ add_test(function test_sendMMI_call_forwarding_interrogation_no_rules() {
|
|||
let workerhelper = getWorker();
|
||||
let worker = workerhelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return 0;
|
||||
};
|
||||
|
||||
|
@ -771,7 +771,7 @@ add_test(function test_sendMMI_call_barring_BAIC_interrogation_voice() {
|
|||
let workerhelper = getWorker();
|
||||
let worker = workerhelper.worker;
|
||||
|
||||
worker.Buf.readUint32List = function fakeReadUint32List() {
|
||||
worker.Buf.readInt32List = function fakeReadUint32List() {
|
||||
return [1];
|
||||
};
|
||||
|
||||
|
@ -954,7 +954,7 @@ add_test(function test_sendMMI_call_waiting_interrogation() {
|
|||
let workerhelper = getWorker();
|
||||
let worker = workerhelper.worker;
|
||||
|
||||
worker.Buf.readUint32 = function fakeReadUint32() {
|
||||
worker.Buf.readInt32 = function fakeReadUint32() {
|
||||
return worker.Buf.int32Array.pop();
|
||||
};
|
||||
|
||||
|
|
|
@ -82,7 +82,7 @@ add_test(function test_read_cdmahome() {
|
|||
let cdmaHome = [0xc1, 0x34, 0xff, 0xff, 0x00];
|
||||
|
||||
// Write data size
|
||||
buf.writeUint32(cdmaHome.length * 2);
|
||||
buf.writeInt32(cdmaHome.length * 2);
|
||||
|
||||
// Write cdma home file.
|
||||
for (let i = 0; i < cdmaHome.length; i++) {
|
||||
|
@ -128,7 +128,7 @@ add_test(function test_read_cdmaspn() {
|
|||
function testReadSpn(file, expectedSpn, expectedDisplayCondition) {
|
||||
io.loadTransparentEF = function fakeLoadTransparentEF(options) {
|
||||
// Write data size
|
||||
buf.writeUint32(file.length * 2);
|
||||
buf.writeInt32(file.length * 2);
|
||||
|
||||
// Write file.
|
||||
for (let i = 0; i < file.length; i++) {
|
||||
|
|
|
@ -92,16 +92,16 @@ add_test(function test_stk_terminal_response() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Type
|
||||
do_check_eq(this.readUint32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_TERMINAL_RESPONSE);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 44 = 2 * (TLV_COMMAND_DETAILS_SIZE(5) +
|
||||
// TLV_DEVICE_ID_SIZE(4) +
|
||||
// TLV_RESULT_SIZE(3) +
|
||||
// TEXT LENGTH(10))
|
||||
do_check_eq(this.readUint32(), 44);
|
||||
do_check_eq(this.readInt32(), 44);
|
||||
|
||||
// Command Details, Type-Length-Value
|
||||
do_check_eq(pduHelper.readHexOctet(), COMPREHENSIONTLV_TAG_COMMAND_DETAILS |
|
||||
|
@ -748,16 +748,16 @@ add_test(function test_stk_event_download_location_status() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Type
|
||||
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 42 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
|
||||
// TLV_EVENT_LIST_SIZE(3) +
|
||||
// TLV_LOCATION_STATUS_SIZE(3) +
|
||||
// TLV_LOCATION_INFO_GSM_SIZE(9))
|
||||
do_check_eq(this.readUint32(), 42);
|
||||
do_check_eq(this.readInt32(), 42);
|
||||
|
||||
// BER tag
|
||||
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
|
||||
|
@ -830,15 +830,15 @@ add_test(function test_stk_event_download_language_selection() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Type
|
||||
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 26 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) +
|
||||
// TLV_EVENT_LIST_SIZE(3) +
|
||||
// TLV_LANGUAGE(4))
|
||||
do_check_eq(this.readUint32(), 26);
|
||||
do_check_eq(this.readInt32(), 26);
|
||||
|
||||
// BER tag
|
||||
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
|
||||
|
@ -888,13 +888,13 @@ add_test(function test_stk_event_download_user_activity() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Type
|
||||
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
|
||||
do_check_eq(this.readUint32(), 18);
|
||||
do_check_eq(this.readInt32(), 18);
|
||||
|
||||
// BER tag
|
||||
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
|
||||
|
@ -936,13 +936,13 @@ add_test(function test_stk_event_download_idle_screen_available() {
|
|||
|
||||
buf.sendParcel = function () {
|
||||
// Type
|
||||
do_check_eq(this.readUint32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
do_check_eq(this.readInt32(), REQUEST_STK_SEND_ENVELOPE_COMMAND);
|
||||
|
||||
// Token : we don't care
|
||||
this.readUint32();
|
||||
this.readInt32();
|
||||
|
||||
// Data Size, 18 = 2 * (2 + TLV_DEVICE_ID_SIZE(4) + TLV_EVENT_LIST_SIZE(3))
|
||||
do_check_eq(this.readUint32(), 18);
|
||||
do_check_eq(this.readInt32(), 18);
|
||||
|
||||
// BER tag
|
||||
do_check_eq(pduHelper.readHexOctet(), BER_EVENT_DOWNLOAD_TAG);
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче