This commit is contained in:
Nick Alexander 2013-09-27 08:41:13 -07:00
Родитель 302d0d34d4 158f374a25
Коммит 2c8842b2b6
409 изменённых файлов: 25050 добавлений и 13470 удалений

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

@ -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)) {
newAcc = new EnumRoleAccessible(content, document, roles::EQUATION);
} 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])
])

3
build/docs/Vagrantfile поставляемый
Просмотреть файл

@ -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,28 +348,19 @@ 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])
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__
except ImportError:
return
finally:
sys.path = oldsyspath
sys.path = []
for p in path:
site.addsitedir(p)
sys.path.extend(oldsyspath)
try:
__import__(module)
except ImportError:
return
finally:
sys.path = oldsyspath
class PythonJob(Job):
"""

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

@ -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)
proc = subprocess.Popen(args, stdout = subprocess.PIPE, stderr = subprocess.STDOUT)
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

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

@ -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
MIDL_FLAGS="${MIDL_FLAGS} -env win32"
;;
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;
};
NS_IMETHODIMP Run()
// Record thread task.
// Fetch encoded Audio/Video data from MediaEncoder.
class ExtractRunnable : public nsRunnable
{
MOZ_ASSERT(!NS_IsMainThread());
mRecorder->ExtractEncodedData();
NS_DispatchToMainThread(new ReleaseEncoderThreadTask(mRecorder.forget()));
return NS_OK;
public:
ExtractRunnable(Session *aSession)
: mSession(aSession) {}
NS_IMETHODIMP Run()
{
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;
nsRefPtr<MediaEncoder> mEncoder;
// 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;
}
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);
mState = RecordingState::Recording;
MOZ_ASSERT(mSession != nullptr);
if (mSession) {
mSession->Resume();
mState = RecordingState::Recording;
}
}
void
@ -269,8 +437,11 @@ MediaRecorder::RequestData(ErrorResult& aResult)
aResult.Throw(NS_ERROR_DOM_INVALID_STATE_ERR);
return;
}
NS_DispatchToMainThread(NS_NewRunnableMethod(this, &MediaRecorder::CreateAndDispatchBlobEvent),
NS_DISPATCH_NORMAL);
NS_DispatchToMainThread(
NS_NewRunnableMethodWithArg<Session *>(this,
&MediaRecorder::CreateAndDispatchBlobEvent, mSession),
NS_DISPATCH_NORMAL);
}
JSObject*
@ -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);
if (!fun) {
return false;
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);
}
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):
accessor = m.get("nativeName", m["name"])
if m.get("methodInfo", True):
jitinfo = ("&%s_methodinfo" % accessor)
accessor = "genericMethod"
else:
if "selfHostedName" in m:
selfHostedName = '"%s"' % m["selfHostedName"]
assert not m.get("methodInfo", True)
accessor = "nullptr"
jitinfo = "nullptr"
return (m["name"], accessor, jitinfo, m["length"], m["flags"])
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"], 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);

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