Merge tracemonkey and mozilla-central.

This commit is contained in:
Chris Leary 2011-01-07 00:17:35 -08:00
Родитель 53b8d1381b fc410aa79a
Коммит 6806325137
347 изменённых файлов: 7159 добавлений и 3995 удалений

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

@ -142,7 +142,7 @@ ifeq (,$(CYGWIN_WRAPPER))
# this doesn't work with Cygwin Python
MAKE_SYM_STORE_ARGS += --vcs-info
endif
DUMP_SYMS_BIN ?= $(topsrcdir)/toolkit/crashreporter/tools/win32/dump_syms.exe
DUMP_SYMS_BIN ?= $(topsrcdir)/toolkit/crashreporter/tools/win32/dump_syms_vc$(_MSC_VER).exe
# PDB files don't get moved to dist, so we need to scan the whole objdir
MAKE_SYM_STORE_PATH := .
endif

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

@ -2735,10 +2735,10 @@ var PrintPreviewListener = {
onExit: function () {
gBrowser.selectedTab = this._tabBeforePrintPreview;
this._tabBeforePrintPreview = null;
gBrowser.removeTab(this._printPreviewTab);
this._printPreviewTab = null;
gInPrintPreviewMode = false;
this._toggleAffectedChrome();
gBrowser.removeTab(this._printPreviewTab);
this._printPreviewTab = null;
},
_toggleAffectedChrome: function () {
#ifdef MENUBAR_CAN_AUTOHIDE

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

@ -45,8 +45,8 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
const PIN_PART_LENGTH = 4;
const ADD_DEVICE_PAGE = 0;
const DEVICE_CONNECTED_PAGE = 1;
const SYNC_KEY_PAGE = 2;
const SYNC_KEY_PAGE = 1;
const DEVICE_CONNECTED_PAGE = 2;
let gSyncAddDevice = {
@ -68,23 +68,23 @@ let gSyncAddDevice = {
switch (this.wizard.pageIndex) {
case ADD_DEVICE_PAGE:
this.wizard.canAdvance = false;
this.onTextBoxInput();
this.wizard.canRewind = false;
this.wizard.getButton("next").hidden = false;
this.pin1.focus();
break;
case SYNC_KEY_PAGE:
this.wizard.canAdvance = false;
this.wizard.canRewind = true;
this.wizard.getButton("back").hidden = false;
this.wizard.getButton("next").hidden = true;
document.getElementById("weavePassphrase").value =
Weave.Utils.hyphenatePassphrase(Weave.Service.passphrase);
break;
case DEVICE_CONNECTED_PAGE:
this.wizard.canAdvance = true;
this.wizard.canRewind = false;
this.wizard.getButton("next").hidden = true;
this.wizard.getButton("cancel").hidden = true;
this.wizard.getButton("finish").hidden = false;
break;
case SYNC_KEY_PAGE:
this.wizard.canAdvance = true;
this.wizard.canRewind = true;
this.wizard.getButton("back").hidden = false;
document.getElementById("weavePassphrase").value =
Weave.Utils.hyphenatePassphrase(Weave.Service.passphrase);
break;
}
},
@ -152,7 +152,7 @@ let gSyncAddDevice = {
},
onTextBoxInput: function onTextBoxInput(textbox) {
if (textbox.value.length == PIN_PART_LENGTH)
if (textbox && textbox.value.length == PIN_PART_LENGTH)
this.nextFocusEl[textbox.id].focus();
this.wizard.canAdvance = (this.pin1.value.length == PIN_PART_LENGTH

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

@ -114,18 +114,6 @@
onclick="gSyncAddDevice.goToSyncKeyPage();"/>
</wizardpage>
<wizardpage id="deviceConnectedPage"
label="&addDevice.dialog.connected.label;"
onpageshow="gSyncAddDevice.onPageShow();">
<vbox align="center">
<image id="successPageIcon"/>
</vbox>
<separator/>
<description class="normal">
&addDevice.dialog.successful.label;
</description>
</wizardpage>
<!-- Need a non-empty label here, otherwise we get a default label on Mac -->
<wizardpage id="syncKeyPage"
label=" "
@ -140,7 +128,7 @@
accesskey="&syncKeyEntry.accesskey;"
control="weavePassphrase"/>
<textbox id="weavePassphrase"
disabled="true"/>
readonly="true"/>
</groupbox>
<groupbox align="center">
@ -158,4 +146,16 @@
</groupbox>
</wizardpage>
<wizardpage id="deviceConnectedPage"
label="&addDevice.dialog.connected.label;"
onpageshow="gSyncAddDevice.onPageShow();">
<vbox align="center">
<image id="successPageIcon"/>
</vbox>
<separator/>
<description class="normal">
&addDevice.dialog.successful.label;
</description>
</wizardpage>
</wizard>

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

@ -98,7 +98,7 @@
<label id="passphraseLabel" control="passphraseBox"/>
<textbox id="passphraseBox"
onfocus="this.select()"
onkeyup="Change.validate(event)"/>
oninput="Change.validate()"/>
<label id="generatePassphraseButton"
value="&syncKeyGenerate.label;"
class="text-link inline-link"

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

@ -197,10 +197,6 @@ var gSyncSetup = {
}
},
onPassphraseKeyUp: function (event) {
this.checkFields();
},
// fun with validation!
checkFields: function () {
this.wizard.canAdvance = this.readyToAdvance();
@ -333,6 +329,7 @@ var gSyncSetup = {
this.wizard.getButton("next").hidden = false;
this.wizard.getButton("back").hidden = false;
this.wizard.getButton("extra1").hidden = false;
this.wizard.canAdvance = false;
this.wizard.canRewind = true;
this.startEasySetup();
break;
@ -777,8 +774,6 @@ var gSyncSetup = {
"strftime('%s','now','localtime','utc') - " +
"( " +
"SELECT visit_date FROM moz_historyvisits " +
"UNION ALL " +
"SELECT visit_date FROM moz_historyvisits_temp " +
"ORDER BY visit_date ASC LIMIT 1 " +
")/1000000 " +
")/86400) AS daysOfHistory ");

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

@ -172,7 +172,7 @@
<hbox align="center">
<checkbox id="tos"
accesskey="&setup.tosAgree1.accesskey;"
oncommand="gSyncSetup.checkFields();"/>
oncommand="this.focus(); gSyncSetup.checkFields();"/>
<description id="tosDesc"
onclick="document.getElementById('tos').focus();
document.getElementById('tos').click()">
@ -349,8 +349,7 @@
accesskey="&signIn.syncKey.accesskey;"
control="existingPassphrase"/>
<textbox id="existingPassphrase"
onkeyup="gSyncSetup.onPassphraseKeyUp(event)"
onchange="gSyncSetup.checkFields()"/>
oninput="gSyncSetup.checkFields()"/>
<hbox id="login-throbber" hidden="true">
<image/>
<label value="&verifying.label;"/>

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

@ -555,7 +555,7 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// Function: close
// Closes the groupItem, removing (but not closing) all of its children.
close: function GroupItem_close() {
this.removeAll();
this.removeAll({dontClose: true});
GroupItems.unregister(this);
if (this.hidden) {
@ -811,9 +811,13 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
//
// a - The item to add. Can be an <Item>, a DOM element or an iQ object.
// The latter two must refer to the container of an <Item>.
// dropPos - An object with left and top properties referring to the location dropped at. Optional.
// options - An object with optional settings for this call. Currently this includes dontArrange
// and immediately
// dropPos - An object with left and top properties referring to the
// location dropped at. Optional.
// options - An optional object with settings for this call. See below.
//
// Possible options:
// dontArrange - Don't rearrange the children for the new item
// immediately - Don't animate
add: function GroupItem_add(a, dropPos, options) {
try {
var item;
@ -931,8 +935,12 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
//
// a - The item to remove. Can be an <Item>, a DOM element or an iQ object.
// The latter two must refer to the container of an <Item>.
// options - An object with optional settings for this call. Currently this includes
// dontArrange and immediately
// options - An optional object with settings for this call. See below.
//
// Possible options:
// dontArrange - don't rearrange the remaining items
// dontClose - don't close the group even if it normally would
// immediately - don't animate
remove: function GroupItem_remove(a, options) {
try {
var $el;
@ -988,11 +996,16 @@ GroupItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// ----------
// Function: removeAll
// Removes all of the groupItem's children.
removeAll: function GroupItem_removeAll() {
var self = this;
var toRemove = this._children.concat();
// The optional "options" param is passed to each remove call.
removeAll: function GroupItem_removeAll(options) {
let self = this;
let newOptions = {dontArrange: true};
if (options)
Utils.extend(newOptions, options);
let toRemove = this._children.concat();
toRemove.forEach(function(child) {
self.remove(child, {dontArrange: true});
self.remove(child, newOptions);
});
},
@ -1546,6 +1559,7 @@ let GroupItems = {
_arrangePaused: false,
_arrangesPending: [],
_removingHiddenGroups: false,
_updatingTabBarPaused: false,
// ----------
// Function: init
@ -1727,24 +1741,41 @@ let GroupItems = {
if (groupItemsData) {
if (groupItemsData.nextID)
this.nextID = groupItemsData.nextID;
this.nextID = Math.max(this.nextID, groupItemsData.nextID);
if (groupItemsData.activeGroupId)
activeGroupId = groupItemsData.activeGroupId;
}
if (groupItemData) {
var toClose = this.groupItems.concat();
for (var id in groupItemData) {
var groupItem = groupItemData[id];
if (this.groupItemStorageSanity(groupItem)) {
var options = {
dontPush: true,
immediately: true
};
new GroupItem([], Utils.extend({}, groupItem, options));
let data = groupItemData[id];
if (this.groupItemStorageSanity(data)) {
let groupItem = this.groupItem(data.id);
if (groupItem) {
groupItem.userSize = data.userSize;
groupItem.setTitle(data.title);
groupItem.setBounds(data.bounds, true);
let index = toClose.indexOf(groupItem);
if (index != -1)
toClose.splice(index, 1);
} else {
var options = {
dontPush: true,
immediately: true
};
new GroupItem([], Utils.extend({}, data, options));
}
}
}
toClose.forEach(function(groupItem) {
groupItem.close();
});
}
// set active group item
if (activeGroupId) {
let activeGroupItem = this.groupItem(activeGroupId);
@ -1759,6 +1790,19 @@ let GroupItems = {
}
},
// ----------
// Function: load
// Loads the storage data for groups.
// Returns true if there was global group data.
load: function GroupItems_load() {
let groupItemsData = Storage.readGroupItemsData(gWindow);
let groupItemData = Storage.readGroupItemData(gWindow);
this.reconstitute(groupItemsData, groupItemData);
this.killNewTabGroup(); // temporary?
return (groupItemsData && !Utils.isEmptyObject(groupItemsData));
},
// ----------
// Function: groupItemStorageSanity
// Given persistent storage data for a groupItem, returns true if it appears to not be damaged.
@ -1960,6 +2004,25 @@ let GroupItems = {
this._activeOrphanTab = tabItem;
},
// ----------
// Function: pauseUpdatingTabBar
// Don't update the tab bar until resume is called.
pauseUpdatingTabBar: function GroupItems_pauseUdatingTabBar() {
Utils.assertThrow(!this._updatingTabBarPaused, "shouldn't already be paused");
this._updatingTabBarPaused = true;
},
// ----------
// Function: resumeUpdatingTabBar
// Allows updating the tab bar, and does an update.
resumeUpdatingTabBar: function GroupItems_resumeUpdatingTabBar() {
Utils.assertThrow(this._updatingTabBarPaused, "should already be paused");
this._updatingTabBarPaused = false;
this._updateTabBar();
},
// ----------
// Function: _updateTabBar
// Hides and shows tabs in the tab bar based on the active groupItem or
@ -1967,6 +2030,9 @@ let GroupItems = {
_updateTabBar: function GroupItems__updateTabBar() {
if (!window.UI)
return; // called too soon
if (this._updatingTabBarPaused)
return;
if (!this._activeGroupItem && !this._activeOrphanTab) {
Utils.assert(false, "There must be something to show in the tab bar!");

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

@ -86,6 +86,8 @@ function TabItem(tab, options) {
this._zoomPrep = false;
this.sizeExtra = new Point();
this.keepProportional = true;
this._hasBeenDrawn = false;
this._reconnected = false;
var self = this;
@ -104,10 +106,6 @@ function TabItem(tab, options) {
// ___ superclass setup
this._init($div[0]);
// ___ reconnect to data from Storage
this._hasBeenDrawn = false;
let reconnected = TabItems.reconnect(this);
// ___ drag/drop
// override dropOptions with custom tabitem methods
// This is mostly to support the phantom groupItems.
@ -206,19 +204,15 @@ function TabItem(tab, options) {
.addClass('expander')
.appendTo($div);
this.setResizable(true, options.immediately);
this.droppable(true);
this._updateDebugBounds();
TabItems.register(this);
if (!this.reconnected)
GroupItems.newTab(this, options);
// tabs which were not reconnected at all or were not immediately added
// to a group get the same treatment.
if (!this.reconnected || (reconnected && !reconnected.addedToGroup) ) {
this.setResizable(true, options.immediately);
this.droppable(true);
}
// ___ reconnect to data from Storage
if (!TabItems.reconnectingPaused())
this._reconnect();
};
TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
@ -325,7 +319,7 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
// saveImageData - true to include thumbnail pixels (and page title as well); default false
save: function TabItem_save(saveImageData) {
try{
if (!this.tab || this.tab.parentNode == null || !this.reconnected) // too soon/late to save
if (!this.tab || this.tab.parentNode == null || !this._reconnected) // too soon/late to save
return;
var data = this.getStorageData(saveImageData);
@ -336,6 +330,48 @@ TabItem.prototype = Utils.extend(new Item(), new Subscribable(), {
}
},
// ----------
// Function: _reconnect
// Load the reciever's persistent data from storage. If there is none,
// treats it as a new tab.
_reconnect: function TabItem__reconnect() {
Utils.assertThrow(!this._reconnected, "shouldn't already be reconnected");
Utils.assertThrow(this.tab, "should have a xul:tab");
let tabData = Storage.getTabData(this.tab);
if (tabData && TabItems.storageSanity(tabData)) {
if (this.parent)
this.parent.remove(this, {immediately: true});
this.setBounds(tabData.bounds, true);
if (Utils.isPoint(tabData.userSize))
this.userSize = new Point(tabData.userSize);
if (tabData.groupID) {
var groupItem = GroupItems.groupItem(tabData.groupID);
if (groupItem) {
groupItem.add(this, null, {immediately: true});
// if it matches the selected tab or no active tab and the browser
// tab is hidden, the active group item would be set.
if (this.tab == gBrowser.selectedTab ||
(!GroupItems.getActiveGroupItem() && !this.tab.hidden))
GroupItems.setActiveGroupItem(this.parent);
}
}
if (tabData.imageData)
this.showCachedData(tabData);
} else {
GroupItems.newTab(this, {immediately: true});
}
this._reconnected = true;
this.save();
this._sendToSubscribers("reconnected");
},
// ----------
// Function: setBounds
// Moves this item to the specified location and size.
@ -752,6 +788,7 @@ let TabItems = {
_eventListeners: [],
_pauseUpdateForTest: false,
tempCanvas: null,
_reconnectingPaused: false,
// ----------
// Function: init
@ -902,10 +939,6 @@ let TabItems = {
if (tabUrl != tabItem.url) {
let oldURL = tabItem.url;
tabItem.url = tabUrl;
if (!tabItem.reconnected)
this.reconnect(tabItem);
tabItem.save();
}
@ -1059,6 +1092,35 @@ let TabItems = {
return this.paintingPaused > 0;
},
// ----------
// Function: pauseReconnecting
// Don't reconnect any new tabs until resume is called.
pauseReconnecting: function TabItems_pauseReconnecting() {
Utils.assertThrow(!this._reconnectingPaused, "shouldn't already be paused");
this._reconnectingPaused = true;
},
// ----------
// Function: resumeReconnecting
// Reconnect all of the tabs that were created since we paused.
resumeReconnecting: function TabItems_resumeReconnecting() {
Utils.assertThrow(this._reconnectingPaused, "should already be paused");
this._reconnectingPaused = false;
this.items.forEach(function(item) {
if (!item._reconnected)
item._reconnect();
});
},
// ----------
// Function: reconnectingPaused
// Returns true if reconnecting is paused.
reconnectingPaused: function TabItems_reconnectingPaused() {
return this._reconnectingPaused;
},
// ----------
// Function: register
// Adds the given <TabItem> to the master list.
@ -1110,67 +1172,6 @@ let TabItems = {
}
return sane;
},
// ----------
// Function: reconnect
// Given a <TabItem>, attempts to load its persistent data from storage.
reconnect: function TabItems_reconnect(item) {
var found = false;
try{
Utils.assert(item, 'item');
Utils.assert(item.tab, 'item.tab');
if (item.reconnected)
return true;
if (!item.tab)
return false;
let tabData = Storage.getTabData(item.tab);
if (tabData && this.storageSanity(tabData)) {
if (item.parent)
item.parent.remove(item, {immediately: true});
item.setBounds(tabData.bounds, true);
if (Utils.isPoint(tabData.userSize))
item.userSize = new Point(tabData.userSize);
if (tabData.groupID) {
var groupItem = GroupItems.groupItem(tabData.groupID);
if (groupItem) {
groupItem.add(item, null, {immediately: true});
// if it matches the selected tab or no active tab and the browser
// tab is hidden, the active group item would be set.
if (item.tab == gBrowser.selectedTab ||
(!GroupItems.getActiveGroupItem() && !item.tab.hidden))
GroupItems.setActiveGroupItem(item.parent);
}
}
if (tabData.imageData)
item.showCachedData(tabData);
item.reconnected = true;
found = {addedToGroup: tabData.groupID};
} else {
// We should never have any orphaned tabs. Therefore, item is not
// connected if it has no parent and GroupItems.newTab() would handle
// the group creation.
item.reconnected = (item.parent != null);
}
item.save();
if (item.reconnected)
item._sendToSubscribers("reconnected");
} catch(e) {
Utils.log(e);
}
return found;
}
};

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

@ -100,14 +100,16 @@ let UI = {
// Variable: _privateBrowsing
// Keeps track of info related to private browsing, including:
// transitionStage - what step we're on in entering/exiting PB
// transitionMode - whether we're entering or exiting PB
// wasInTabView - whether TabView was visible before we went into PB
_privateBrowsing: {
transitionStage: 0,
transitionMode: "",
wasInTabView: false
},
// Variable: _storageBusyCount
// Used to keep track of how many calls to storageBusy vs storageReady.
_storageBusyCount: 0,
// ----------
// Function: init
@ -172,24 +174,21 @@ let UI = {
// ___ add tab action handlers
this._addTabActionHandlers();
// ___ Storage
GroupItems.pauseArrange();
// ___ groups
GroupItems.init();
let firstTime = true;
if (gPrefBranch.prefHasUserValue("experienced_first_run"))
firstTime = !gPrefBranch.getBoolPref("experienced_first_run");
let groupItemsData = Storage.readGroupItemsData(gWindow);
let groupItemData = Storage.readGroupItemData(gWindow);
GroupItems.reconstitute(groupItemsData, groupItemData);
GroupItems.killNewTabGroup(); // temporary?
GroupItems.pauseArrange();
let hasGroupItemsData = GroupItems.load();
// ___ tabs
TabItems.init();
TabItems.pausePainting();
// if first time in Panorama or no group data:
if (firstTime || !groupItemsData || Utils.isEmptyObject(groupItemsData))
let firstTime = true;
if (gPrefBranch.prefHasUserValue("experienced_first_run"))
firstTime = !gPrefBranch.getBoolPref("experienced_first_run");
if (firstTime || !hasGroupItemsData)
this.reset(firstTime);
// ___ resizing
@ -514,51 +513,65 @@ let UI = {
},
#endif
// ----------
// Function: storageBusy
// Pauses the storage activity that conflicts with sessionstore updates and
// private browsing mode switches. Calls can be nested.
storageBusy: function UI_storageBusy() {
if (!this._storageBusyCount)
TabItems.pauseReconnecting();
this._storageBusyCount++;
},
// ----------
// Function: storageReady
// Resumes the activity paused by storageBusy, and updates for any new group
// information in sessionstore. Calls can be nested.
storageReady: function UI_storageReady() {
this._storageBusyCount--;
if (!this._storageBusyCount) {
let hasGroupItemsData = GroupItems.load();
if (!hasGroupItemsData)
this.reset(false);
TabItems.resumeReconnecting();
}
},
// ----------
// Function: _addTabActionHandlers
// Adds handlers to handle tab actions.
_addTabActionHandlers: function UI__addTabActionHandlers() {
var self = this;
// session restore
function srObserver(aSubject, aTopic, aData) {
if (aTopic != "sessionstore-browser-state-restored")
return;
// if we're transitioning into/out of private browsing, update appropriately
if (self._privateBrowsing.transitionStage == 1)
self._privateBrowsing.transitionStage = 2;
else if (self._privateBrowsing.transitionStage == 3) {
if (self._privateBrowsing.transitionMode == "exit" &&
self._privateBrowsing.wasInTabView)
self.showTabView(false);
self._privateBrowsing.transitionStage = 0;
self._privateBrowsing.transitionMode = "";
}
// session restore events
function handleSSWindowStateBusy() {
self.storageBusy();
}
Services.obs.addObserver(srObserver, "sessionstore-browser-state-restored", false);
function handleSSWindowStateReady() {
self.storageReady();
}
gWindow.addEventListener("SSWindowStateBusy", handleSSWindowStateBusy, false);
gWindow.addEventListener("SSWindowStateReady", handleSSWindowStateReady, false);
this._cleanupFunctions.push(function() {
Services.obs.removeObserver(srObserver, "sessionstore-browser-state-restored");
gWindow.removeEventListener("SSWindowStateBusy", handleSSWindowStateBusy, false);
gWindow.removeEventListener("SSWindowStateReady", handleSSWindowStateReady, false);
});
// Private Browsing:
// We keep track of the transition to/from PB with the transitionStage
// and transitionMode properties of _privateBrowsing. The stage is 0 if
// not transitioning, 1 if just started ("change-granted"), 2 after the
// first sessionrestore, 3 after the "private-browsing" notification, and
// then back to 0 after the second sessionrestore. The mode is "" if not
// transitioning, otherwise it's "enter" or "exit" as appropriate. When
// transitioning to PB, we exit Panorama if necessary (making note of the
// When transitioning to PB, we exit Panorama if necessary (making note of the
// fact that we were there so we can return after PB) and make sure we
// don't reenter Panorama due to all of the session restore tab
// manipulation (which otherwise we might). When transitioning away from
// PB, we reenter Panorama if we had been there directly before PB.
function pbObserver(aSubject, aTopic, aData) {
if (aTopic == "private-browsing") {
self._privateBrowsing.transitionStage = 3;
// We could probably do this in private-browsing-change-granted, but
// this seems like a nicer spot, right in the middle of the process.
if (aData == "enter") {
// If we are in Tab View, exit.
self._privateBrowsing.wasInTabView = self.isTabViewVisible();
@ -567,18 +580,30 @@ let UI = {
}
} else if (aTopic == "private-browsing-change-granted") {
if (aData == "enter" || aData == "exit") {
self._privateBrowsing.transitionStage = 1;
self._privateBrowsing.transitionMode = aData;
GroupItems.pauseUpdatingTabBar();
self.storageBusy();
}
} else if (aTopic == "private-browsing-transition-complete") {
// We use .transitionMode here, as aData is empty.
if (self._privateBrowsing.transitionMode == "exit" &&
self._privateBrowsing.wasInTabView)
self.showTabView(false);
self._privateBrowsing.transitionMode = "";
self.storageReady();
GroupItems.resumeUpdatingTabBar();
}
}
Services.obs.addObserver(pbObserver, "private-browsing", false);
Services.obs.addObserver(pbObserver, "private-browsing-change-granted", false);
Services.obs.addObserver(pbObserver, "private-browsing-transition-complete", false);
this._cleanupFunctions.push(function() {
Services.obs.removeObserver(pbObserver, "private-browsing");
Services.obs.removeObserver(pbObserver, "private-browsing-change-granted");
Services.obs.removeObserver(pbObserver, "private-browsing-transition-complete");
});
// TabOpen
@ -607,7 +632,7 @@ let UI = {
} else {
// If we're currently in the process of entering private browsing,
// we don't want to go to the Tab View UI.
if (self._privateBrowsing.transitionStage > 0)
if (self._privateBrowsing.transitionMode)
return;
// if not closing the last tab

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

@ -202,7 +202,7 @@ function onTabViewShown() {
tabItems.forEach(function(tabItem) {
// tabitem might not be connected so use subscriber for those which are not
// connected.
if (tabItem.reconnected) {
if (tabItem._reconnected) {
ok(tabItem.isShowingCachedData(),
"Tab item is showing cached data and is already connected. " +
tabItem.tab.linkedBrowser.currentURI.spec);

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

@ -83,17 +83,21 @@ function onTabViewWindowLoaded() {
is(groupItems[0].getChildren().length, 2, "The group has two tab items");
tabTwo = undoCloseTab(0);
ok(TabView.isVisible(), "Tab View is still visible after restoring a tab");
is(groupItems[0].getChildren().length, 3, "The group has three tab items");
tabTwo.tabItem.addSubscriber(tabTwo, "reconnected", function() {
tabTwo.tabItem.removeSubscriber(tabTwo, "reconnected");
// clean up and finish
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
gBrowser.removeTab(tabOne);
gBrowser.removeTab(tabTwo);
finish();
}
window.addEventListener("tabviewhidden", endGame, false);
TabView.toggle();
ok(TabView.isVisible(), "Tab View is still visible after restoring a tab");
is(groupItems[0].getChildren().length, 3, "The group still has three tab items");
// clean up and finish
let endGame = function() {
window.removeEventListener("tabviewhidden", endGame, false);
gBrowser.removeTab(tabOne);
gBrowser.removeTab(tabTwo);
finish();
}
window.addEventListener("tabviewhidden", endGame, false);
TabView.toggle();
});
}

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

@ -92,7 +92,7 @@ function onTabViewWindowLoaded() {
};
let tabItem = groupItem.getChild(0);
// the item may not be connected so subscriber would be used in that case.
if (tabItem.reconnected) {
if (tabItem._reconnected) {
checkAndFinish();
} else {
tabItem.addSubscriber(tabItem, "reconnected", function() {

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

@ -36,8 +36,11 @@
*
* ***** END LICENSE BLOCK ***** */
let contentWindow = null;
let normalURLs = [];
let pbTabURL = "about:privatebrowsing";
let groupTitles = [];
let normalIteration = 0;
let pb = Cc["@mozilla.org/privatebrowsing;1"].
getService(Ci.nsIPrivateBrowsingService);
@ -46,23 +49,9 @@ let pb = Cc["@mozilla.org/privatebrowsing;1"].
function test() {
waitForExplicitFinish();
// Establish initial state
is(gBrowser.tabs.length, 1, "we start with 1 tab");
// Create a second tab
gBrowser.addTab("about:robots");
is(gBrowser.tabs.length, 2, "we now have 2 tabs");
afterAllTabsLoaded(function() {
// Get normal tab urls
for (let a = 0; a < gBrowser.tabs.length; a++) {
normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
}
// Go into Tab View
window.addEventListener("tabviewshown", onTabViewLoadedAndShown, false);
TabView.toggle();
});
// Go into Tab View
window.addEventListener("tabviewshown", onTabViewLoadedAndShown, false);
TabView.toggle();
}
// -----------
@ -70,20 +59,64 @@ function onTabViewLoadedAndShown() {
window.removeEventListener("tabviewshown", onTabViewLoadedAndShown, false);
ok(TabView.isVisible(), "Tab View is visible");
// go into private browsing and make sure Tab View becomes hidden
togglePBAndThen(function() {
ok(!TabView.isVisible(), "Tab View is no longer visible");
verifyPB();
// exit private browsing and make sure Tab View is shown again
// Establish initial state
contentWindow = document.getElementById("tab-view").contentWindow;
verifyCleanState("start");
// register a clean up for private browsing just in case
registerCleanupFunction(function() {
pb.privateBrowsingEnabled = false;
});
// create a group
let box = new contentWindow.Rect(20, 20, 180, 180);
let groupItem = new contentWindow.GroupItem([], {bounds: box, title: "test1"});
let id = groupItem.id;
is(contentWindow.GroupItems.groupItems.length, 2, "we now have two groups");
registerCleanupFunction(function() {
contentWindow.GroupItems.groupItem(id).close();
});
// make it the active group so new tabs will be added to it
contentWindow.GroupItems.setActiveGroupItem(groupItem);
// collect the group titles
let count = contentWindow.GroupItems.groupItems.length;
for (let a = 0; a < count; a++) {
let gi = contentWindow.GroupItems.groupItems[a];
groupTitles[a] = gi.getTitle();
}
// Create a second tab
gBrowser.addTab("about:robots");
is(gBrowser.tabs.length, 2, "we now have 2 tabs");
registerCleanupFunction(function() {
gBrowser.removeTab(gBrowser.tabs[1]);
});
afterAllTabsLoaded(function() {
// Get normal tab urls
for (let a = 0; a < gBrowser.tabs.length; a++)
normalURLs.push(gBrowser.tabs[a].linkedBrowser.currentURI.spec);
// verify that we're all set up for our test
verifyNormal();
// go into private browsing and make sure Tab View becomes hidden
togglePBAndThen(function() {
ok(TabView.isVisible(), "Tab View is visible again");
verifyNormal();
ok(!TabView.isVisible(), "Tab View is no longer visible");
verifyPB();
// exit Tab View
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.toggle();
});
// exit private browsing and make sure Tab View is shown again
togglePBAndThen(function() {
ok(TabView.isVisible(), "Tab View is visible again");
verifyNormal();
// exit Tab View
window.addEventListener("tabviewhidden", onTabViewHidden, false);
TabView.toggle();
});
});
});
}
@ -101,22 +134,31 @@ function onTabViewHidden() {
togglePBAndThen(function() {
verifyNormal();
// clean up
gBrowser.removeTab(gBrowser.tabs[1]);
is(gBrowser.tabs.length, 1, "we finish with one tab");
ok(!pb.privateBrowsingEnabled, "we finish with private browsing off");
// end game
ok(!TabView.isVisible(), "we finish with Tab View not visible");
registerCleanupFunction(verifyCleanState); // verify after all cleanups
finish();
});
});
}
// ----------
function verifyCleanState(mode) {
let prefix = "we " + (mode || "finish") + " with ";
is(gBrowser.tabs.length, 1, prefix + "one tab");
is(contentWindow.GroupItems.groupItems.length, 1, prefix + "1 group");
ok(gBrowser.tabs[0].tabItem.parent == contentWindow.GroupItems.groupItems[0],
"the tab is in the group");
ok(!pb.privateBrowsingEnabled, prefix + "private browsing off");
}
// ----------
function verifyPB() {
ok(pb.privateBrowsingEnabled == true, "private browsing is on");
is(gBrowser.tabs.length, 1, "we have 1 tab in private browsing");
is(contentWindow.GroupItems.groupItems.length, 1, "we have 1 group in private browsing");
ok(gBrowser.tabs[0].tabItem.parent == contentWindow.GroupItems.groupItems[0],
"the tab is in the group");
let browser = gBrowser.tabs[0].linkedBrowser;
is(browser.currentURI.spec, pbTabURL, "correct URL for private browsing");
@ -124,14 +166,26 @@ function verifyPB() {
// ----------
function verifyNormal() {
ok(pb.privateBrowsingEnabled == false, "private browsing is off");
let prefix = "verify normal " + normalIteration + ": ";
normalIteration++;
ok(pb.privateBrowsingEnabled == false, prefix + "private browsing is off");
let tabCount = gBrowser.tabs.length;
let groupCount = contentWindow.GroupItems.groupItems.length;
is(tabCount, 2, prefix + "we have 2 tabs");
is(groupCount, 2, prefix + "we have 2 groups");
ok(tabCount == groupCount, prefix + "same number of tabs as groups");
for (let a = 0; a < tabCount; a++) {
let tab = gBrowser.tabs[a];
is(tab.linkedBrowser.currentURI.spec, normalURLs[a],
prefix + "correct URL");
let count = gBrowser.tabs.length;
is(count, 2, "we have 2 tabs in normal mode");
for (let a = 0; a < count; a++) {
let browser = gBrowser.tabs[a].linkedBrowser;
is(browser.currentURI.spec, normalURLs[a], "correct URL for normal mode");
let groupItem = contentWindow.GroupItems.groupItems[a];
is(groupItem.getTitle(), groupTitles[a], prefix + "correct group title");
ok(tab.tabItem.parent == groupItem,
prefix + "tab " + a + " is in group " + a);
}
}

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

@ -43,6 +43,7 @@ it
ja
ja-JP-mac
ka
kk
km
kn
ko

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

@ -158,6 +158,10 @@
-moz-binding: url("chrome://global/content/bindings/toolbar.xml#toolbar-drag");
}
#appcontent:not(:-moz-lwtheme) {
background-color: -moz-dialog;
}
#browser-bottombox:not(:-moz-lwtheme) {
background-color: -moz-dialog;
background-clip: padding-box;

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

@ -1,96 +1,96 @@
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is cl.py: a python wrapper for cl to automatically generate
# dependency information.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Kyle Huey <me@kylehuey.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import os, os.path
import subprocess
import sys
CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
def InvokeClWithDependencyGeneration(cmdline):
target = ""
# Figure out what the target is
for arg in cmdline:
if arg.startswith("-Fo"):
target = arg[3:]
break
if target == None:
print >>sys.stderr, "No target set" and sys.exit(1)
# The deps target lives here
depstarget = os.path.basename(target) + ".pp"
cmdline += ['-showIncludes']
cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
deps = set()
for line in cl.stdout:
# cl -showIncludes prefixes every header with "Note: including file:"
# and an indentation corresponding to the depth (which we don't need)
if line.startswith(CL_INCLUDES_PREFIX):
dep = line[len(CL_INCLUDES_PREFIX):].strip()
# We can't handle pathes with spaces properly in mddepend.pl, but
# we can assume that anything in a path with spaces is a system
# header and throw it away.
if dep.find(' ') == -1:
deps.add(dep)
else:
sys.stdout.write(line) # Make sure we preserve the relevant output
# from cl
ret = cl.wait()
if ret != 0 or target == "":
sys.exit(ret)
depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
depstarget = os.path.join(depsdir, depstarget)
if not os.path.isdir(depsdir):
try:
os.makedirs(depsdir)
except OSError:
pass # This suppresses the error we get when the dir exists, at the
# cost of masking failure to create the directory. We'll just
# die on the next line though, so it's not that much of a loss.
f = open(depstarget, "w")
for dep in sorted(deps):
print >>f, "%s: %s" % (target, dep)
if __name__ == "__main__":
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is cl.py: a python wrapper for cl to automatically generate
# dependency information.
#
# The Initial Developer of the Original Code is
# Mozilla Foundation.
# Portions created by the Initial Developer are Copyright (C) 2010
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Kyle Huey <me@kylehuey.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
import os, os.path
import subprocess
import sys
CL_INCLUDES_PREFIX = os.environ.get("CL_INCLUDES_PREFIX", "Note: including file:")
def InvokeClWithDependencyGeneration(cmdline):
target = ""
# Figure out what the target is
for arg in cmdline:
if arg.startswith("-Fo"):
target = arg[3:]
break
if target == None:
print >>sys.stderr, "No target set" and sys.exit(1)
# The deps target lives here
depstarget = os.path.basename(target) + ".pp"
cmdline += ['-showIncludes']
cl = subprocess.Popen(cmdline, stdout=subprocess.PIPE)
deps = set()
for line in cl.stdout:
# cl -showIncludes prefixes every header with "Note: including file:"
# and an indentation corresponding to the depth (which we don't need)
if line.startswith(CL_INCLUDES_PREFIX):
dep = line[len(CL_INCLUDES_PREFIX):].strip()
# We can't handle pathes with spaces properly in mddepend.pl, but
# we can assume that anything in a path with spaces is a system
# header and throw it away.
if dep.find(' ') == -1:
deps.add(dep)
else:
sys.stdout.write(line) # Make sure we preserve the relevant output
# from cl
ret = cl.wait()
if ret != 0 or target == "":
sys.exit(ret)
depsdir = os.path.normpath(os.path.join(os.path.dirname(target), ".deps"))
depstarget = os.path.join(depsdir, depstarget)
if not os.path.isdir(depsdir):
try:
os.makedirs(depsdir)
except OSError:
pass # This suppresses the error we get when the dir exists, at the
# cost of masking failure to create the directory. We'll just
# die on the next line though, so it's not that much of a loss.
f = open(depstarget, "w")
for dep in sorted(deps):
print >>f, "%s: %s" % (target, dep)
if __name__ == "__main__":
InvokeClWithDependencyGeneration(sys.argv[1:])

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

@ -1,13 +1,13 @@
"""
Implicit variables; perhaps in the future this will also include some implicit
rules, at least match-anything cancellation rules.
"""
variables = {
'RM': '%pymake.builtins rm -f',
'SLEEP': '%pymake.builtins sleep',
'TOUCH': '%pymake.builtins touch',
'.LIBPATTERNS': 'lib%.so lib%.a',
'.PYMAKE': '1',
}
"""
Implicit variables; perhaps in the future this will also include some implicit
rules, at least match-anything cancellation rules.
"""
variables = {
'RM': '%pymake.builtins rm -f',
'SLEEP': '%pymake.builtins sleep',
'TOUCH': '%pymake.builtins touch',
'.LIBPATTERNS': 'lib%.so lib%.a',
'.PYMAKE': '1',
}

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

@ -1,227 +1,227 @@
#!/usr/bin/python
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ted Mielczarek <ted.mielczarek@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#
# When run directly, this script expects the following environment variables
# to be set:
# UPLOAD_HOST : host to upload files to
# UPLOAD_USER : username on that host
# UPLOAD_PATH : path on that host to put the files in
#
# And will use the following optional environment variables if set:
# UPLOAD_SSH_KEY : path to a ssh private key to use
# UPLOAD_PORT : port to use for ssh
# POST_UPLOAD_CMD: a commandline to run on the remote host after uploading.
# UPLOAD_PATH and the full paths of all files uploaded will
# be appended to the commandline.
#
# All files to be uploaded should be passed as commandline arguments to this
# script. The script takes one other parameter, --base-path, which you can use
# to indicate that files should be uploaded including their paths relative
# to the base path.
import sys, os
from optparse import OptionParser
from subprocess import Popen, PIPE
from util import check_call
def RequireEnvironmentVariable(v):
"""Return the value of the environment variable named v, or print
an error and exit if it's unset (or empty)."""
if not v in os.environ or os.environ[v] == "":
print "Error: required environment variable %s not set" % v
sys.exit(1)
return os.environ[v]
def OptionalEnvironmentVariable(v):
"""Return the value of the environment variable named v, or None
if it's unset (or empty)."""
if v in os.environ and os.environ[v] != "":
return os.environ[v]
return None
def FixupMsysPath(path):
"""MSYS helpfully translates absolute pathnames in environment variables
and commandline arguments into Windows native paths. This sucks if you're
trying to pass an absolute path on a remote server. This function attempts
to un-mangle such paths."""
if 'OSTYPE' in os.environ and os.environ['OSTYPE'] == 'msys':
# sort of awful, find out where our shell is (should be in msys/bin)
# and strip the first part of that path out of the other path
if 'SHELL' in os.environ:
sh = os.environ['SHELL']
msys = sh[:sh.find('/bin')]
if path.startswith(msys):
path = path[len(msys):]
return path
def WindowsPathToMsysPath(path):
"""Translate a Windows pathname to an MSYS pathname.
Necessary because we call out to ssh/scp, which are MSYS binaries
and expect MSYS paths."""
if sys.platform != 'win32':
return path
(drive, path) = os.path.splitdrive(os.path.abspath(path))
return "/" + drive[0] + path.replace('\\','/')
def AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key):
"""Given optional port and ssh key values, append valid OpenSSH
commandline arguments to the list cmdline if the values are not None."""
if port is not None:
cmdline.append("-P%d" % port)
if ssh_key is not None:
# Don't interpret ~ paths - ssh can handle that on its own
if not ssh_key.startswith('~'):
ssh_key = WindowsPathToMsysPath(ssh_key)
cmdline.extend(["-o", "IdentityFile=%s" % ssh_key])
def DoSSHCommand(command, user, host, port=None, ssh_key=None):
"""Execute command on user@host using ssh. Optionally use
port and ssh_key, if provided."""
cmdline = ["ssh"]
AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
cmdline.extend(["%s@%s" % (user, host), command])
cmd = Popen(cmdline, stdout=PIPE)
retcode = cmd.wait()
if retcode != 0:
raise Exception("Command %s returned non-zero exit code: %i" % \
(cmdline, retcode))
return cmd.stdout.read().strip()
def DoSCPFile(file, remote_path, user, host, port=None, ssh_key=None):
"""Upload file to user@host:remote_path using scp. Optionally use
port and ssh_key, if provided."""
cmdline = ["scp"]
AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
cmdline.extend([WindowsPathToMsysPath(file),
"%s@%s:%s" % (user, host, remote_path)])
check_call(cmdline)
def GetRemotePath(path, local_file, base_path):
"""Given a remote path to upload to, a full path to a local file, and an
optional full path that is a base path of the local file, construct the
full remote path to place the file in. If base_path is not None, include
the relative path from base_path to file."""
if base_path is None or not local_file.startswith(base_path):
return path
dir = os.path.dirname(local_file)
# strip base_path + extra slash and make it unixy
dir = dir[len(base_path)+1:].replace('\\','/')
return path + dir
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None):
"""Upload each file in the list files to user@host:path. Optionally pass
port and ssh_key to the ssh commands. If base_path is not None, upload
files including their path relative to base_path. If upload_to_temp_dir is
True files will be uploaded to a temporary directory on the remote server.
Generally, you should have a post upload command specified in these cases
that can move them around to their correct location(s).
If post_upload_command is not None, execute that command on the remote host
after uploading all files, passing it the upload path, and the full paths to
all files uploaded.
If verbose is True, print status updates while working."""
if upload_to_temp_dir:
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
if not path.endswith("/"):
path += "/"
if base_path is not None:
base_path = os.path.abspath(base_path)
remote_files = []
try:
for file in files:
file = os.path.abspath(file)
if not os.path.isfile(file):
raise IOError("File not found: %s" % file)
# first ensure that path exists remotely
remote_path = GetRemotePath(path, file, base_path)
DoSSHCommand("mkdir -p " + remote_path, user, host, port=port, ssh_key=ssh_key)
if verbose:
print "Uploading " + file
DoSCPFile(file, remote_path, user, host, port=port, ssh_key=ssh_key)
remote_files.append(remote_path + '/' + os.path.basename(file))
if post_upload_command is not None:
if verbose:
print "Running post-upload command: " + post_upload_command
file_list = '"' + '" "'.join(remote_files) + '"'
DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
finally:
if upload_to_temp_dir:
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
ssh_key=ssh_key)
if verbose:
print "Upload complete"
if __name__ == '__main__':
host = RequireEnvironmentVariable('UPLOAD_HOST')
user = RequireEnvironmentVariable('UPLOAD_USER')
path = OptionalEnvironmentVariable('UPLOAD_PATH')
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
port = OptionalEnvironmentVariable('UPLOAD_PORT')
if port is not None:
port = int(port)
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
"defined."
sys.exit(1)
if sys.platform == 'win32':
if path is not None:
path = FixupMsysPath(path)
if post_upload_command is not None:
post_upload_command = FixupMsysPath(post_upload_command)
parser = OptionParser(usage="usage: %prog [options] <files>")
parser.add_option("-b", "--base-path",
action="store", dest="base_path",
help="Preserve file paths relative to this path when uploading. If unset, all files will be uploaded directly to UPLOAD_PATH.")
(options, args) = parser.parse_args()
if len(args) < 1:
print "You must specify at least one file to upload"
sys.exit(1)
try:
UploadFiles(user, host, path, args, base_path=options.base_path,
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
post_upload_command=post_upload_command,
verbose=True)
except IOError, (strerror):
print strerror
sys.exit(1)
except Exception, (err):
print err
sys.exit(2)
#!/usr/bin/python
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ted Mielczarek <ted.mielczarek@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
#
# When run directly, this script expects the following environment variables
# to be set:
# UPLOAD_HOST : host to upload files to
# UPLOAD_USER : username on that host
# UPLOAD_PATH : path on that host to put the files in
#
# And will use the following optional environment variables if set:
# UPLOAD_SSH_KEY : path to a ssh private key to use
# UPLOAD_PORT : port to use for ssh
# POST_UPLOAD_CMD: a commandline to run on the remote host after uploading.
# UPLOAD_PATH and the full paths of all files uploaded will
# be appended to the commandline.
#
# All files to be uploaded should be passed as commandline arguments to this
# script. The script takes one other parameter, --base-path, which you can use
# to indicate that files should be uploaded including their paths relative
# to the base path.
import sys, os
from optparse import OptionParser
from subprocess import Popen, PIPE
from util import check_call
def RequireEnvironmentVariable(v):
"""Return the value of the environment variable named v, or print
an error and exit if it's unset (or empty)."""
if not v in os.environ or os.environ[v] == "":
print "Error: required environment variable %s not set" % v
sys.exit(1)
return os.environ[v]
def OptionalEnvironmentVariable(v):
"""Return the value of the environment variable named v, or None
if it's unset (or empty)."""
if v in os.environ and os.environ[v] != "":
return os.environ[v]
return None
def FixupMsysPath(path):
"""MSYS helpfully translates absolute pathnames in environment variables
and commandline arguments into Windows native paths. This sucks if you're
trying to pass an absolute path on a remote server. This function attempts
to un-mangle such paths."""
if 'OSTYPE' in os.environ and os.environ['OSTYPE'] == 'msys':
# sort of awful, find out where our shell is (should be in msys/bin)
# and strip the first part of that path out of the other path
if 'SHELL' in os.environ:
sh = os.environ['SHELL']
msys = sh[:sh.find('/bin')]
if path.startswith(msys):
path = path[len(msys):]
return path
def WindowsPathToMsysPath(path):
"""Translate a Windows pathname to an MSYS pathname.
Necessary because we call out to ssh/scp, which are MSYS binaries
and expect MSYS paths."""
if sys.platform != 'win32':
return path
(drive, path) = os.path.splitdrive(os.path.abspath(path))
return "/" + drive[0] + path.replace('\\','/')
def AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key):
"""Given optional port and ssh key values, append valid OpenSSH
commandline arguments to the list cmdline if the values are not None."""
if port is not None:
cmdline.append("-P%d" % port)
if ssh_key is not None:
# Don't interpret ~ paths - ssh can handle that on its own
if not ssh_key.startswith('~'):
ssh_key = WindowsPathToMsysPath(ssh_key)
cmdline.extend(["-o", "IdentityFile=%s" % ssh_key])
def DoSSHCommand(command, user, host, port=None, ssh_key=None):
"""Execute command on user@host using ssh. Optionally use
port and ssh_key, if provided."""
cmdline = ["ssh"]
AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
cmdline.extend(["%s@%s" % (user, host), command])
cmd = Popen(cmdline, stdout=PIPE)
retcode = cmd.wait()
if retcode != 0:
raise Exception("Command %s returned non-zero exit code: %i" % \
(cmdline, retcode))
return cmd.stdout.read().strip()
def DoSCPFile(file, remote_path, user, host, port=None, ssh_key=None):
"""Upload file to user@host:remote_path using scp. Optionally use
port and ssh_key, if provided."""
cmdline = ["scp"]
AppendOptionalArgsToSSHCommandline(cmdline, port, ssh_key)
cmdline.extend([WindowsPathToMsysPath(file),
"%s@%s:%s" % (user, host, remote_path)])
check_call(cmdline)
def GetRemotePath(path, local_file, base_path):
"""Given a remote path to upload to, a full path to a local file, and an
optional full path that is a base path of the local file, construct the
full remote path to place the file in. If base_path is not None, include
the relative path from base_path to file."""
if base_path is None or not local_file.startswith(base_path):
return path
dir = os.path.dirname(local_file)
# strip base_path + extra slash and make it unixy
dir = dir[len(base_path)+1:].replace('\\','/')
return path + dir
def UploadFiles(user, host, path, files, verbose=False, port=None, ssh_key=None, base_path=None, upload_to_temp_dir=False, post_upload_command=None):
"""Upload each file in the list files to user@host:path. Optionally pass
port and ssh_key to the ssh commands. If base_path is not None, upload
files including their path relative to base_path. If upload_to_temp_dir is
True files will be uploaded to a temporary directory on the remote server.
Generally, you should have a post upload command specified in these cases
that can move them around to their correct location(s).
If post_upload_command is not None, execute that command on the remote host
after uploading all files, passing it the upload path, and the full paths to
all files uploaded.
If verbose is True, print status updates while working."""
if upload_to_temp_dir:
path = DoSSHCommand("mktemp -d", user, host, port=port, ssh_key=ssh_key)
if not path.endswith("/"):
path += "/"
if base_path is not None:
base_path = os.path.abspath(base_path)
remote_files = []
try:
for file in files:
file = os.path.abspath(file)
if not os.path.isfile(file):
raise IOError("File not found: %s" % file)
# first ensure that path exists remotely
remote_path = GetRemotePath(path, file, base_path)
DoSSHCommand("mkdir -p " + remote_path, user, host, port=port, ssh_key=ssh_key)
if verbose:
print "Uploading " + file
DoSCPFile(file, remote_path, user, host, port=port, ssh_key=ssh_key)
remote_files.append(remote_path + '/' + os.path.basename(file))
if post_upload_command is not None:
if verbose:
print "Running post-upload command: " + post_upload_command
file_list = '"' + '" "'.join(remote_files) + '"'
DoSSHCommand('%s "%s" %s' % (post_upload_command, path, file_list), user, host, port=port, ssh_key=ssh_key)
finally:
if upload_to_temp_dir:
DoSSHCommand("rm -rf %s" % path, user, host, port=port,
ssh_key=ssh_key)
if verbose:
print "Upload complete"
if __name__ == '__main__':
host = RequireEnvironmentVariable('UPLOAD_HOST')
user = RequireEnvironmentVariable('UPLOAD_USER')
path = OptionalEnvironmentVariable('UPLOAD_PATH')
upload_to_temp_dir = OptionalEnvironmentVariable('UPLOAD_TO_TEMP')
port = OptionalEnvironmentVariable('UPLOAD_PORT')
if port is not None:
port = int(port)
key = OptionalEnvironmentVariable('UPLOAD_SSH_KEY')
post_upload_command = OptionalEnvironmentVariable('POST_UPLOAD_CMD')
if (not path and not upload_to_temp_dir) or (path and upload_to_temp_dir):
print "One (and only one of UPLOAD_PATH or UPLOAD_TO_TEMP must be " + \
"defined."
sys.exit(1)
if sys.platform == 'win32':
if path is not None:
path = FixupMsysPath(path)
if post_upload_command is not None:
post_upload_command = FixupMsysPath(post_upload_command)
parser = OptionParser(usage="usage: %prog [options] <files>")
parser.add_option("-b", "--base-path",
action="store", dest="base_path",
help="Preserve file paths relative to this path when uploading. If unset, all files will be uploaded directly to UPLOAD_PATH.")
(options, args) = parser.parse_args()
if len(args) < 1:
print "You must specify at least one file to upload"
sys.exit(1)
try:
UploadFiles(user, host, path, args, base_path=options.base_path,
port=port, ssh_key=key, upload_to_temp_dir=upload_to_temp_dir,
post_upload_command=post_upload_command,
verbose=True)
except IOError, (strerror):
print strerror
sys.exit(1)
except Exception, (err):
print err
sys.exit(2)

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

@ -1,50 +1,50 @@
#!/usr/bin/python
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ted Mielczarek <ted.mielczarek@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
try:
from subprocess import check_call
except ImportError:
import subprocess
def check_call(*popenargs, **kwargs):
retcode = subprocess.call(*popenargs, **kwargs)
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise Exception("Command '%s' returned non-zero exit status %i" % (cmd, retcode))
#!/usr/bin/python
#
# ***** BEGIN LICENSE BLOCK *****
# Version: MPL 1.1/GPL 2.0/LGPL 2.1
#
# The contents of this file are subject to the Mozilla Public License Version
# 1.1 (the "License"); you may not use this file except in compliance with
# the License. You may obtain a copy of the License at
# http://www.mozilla.org/MPL/
#
# Software distributed under the License is distributed on an "AS IS" basis,
# WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
# for the specific language governing rights and limitations under the
# License.
#
# The Original Code is mozilla.org code.
#
# The Initial Developer of the Original Code is
# The Mozilla Foundation
# Portions created by the Initial Developer are Copyright (C) 2008
# the Initial Developer. All Rights Reserved.
#
# Contributor(s):
# Ted Mielczarek <ted.mielczarek@gmail.com>
#
# Alternatively, the contents of this file may be used under the terms of
# either the GNU General Public License Version 2 or later (the "GPL"), or
# the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
# in which case the provisions of the GPL or the LGPL are applicable instead
# of those above. If you wish to allow use of your version of this file only
# under the terms of either the GPL or the LGPL, and not to allow others to
# use your version of this file under the terms of the MPL, indicate your
# decision by deleting the provisions above and replace them with the notice
# and other provisions required by the GPL or the LGPL. If you do not delete
# the provisions above, a recipient may use your version of this file under
# the terms of any one of the MPL, the GPL or the LGPL.
#
# ***** END LICENSE BLOCK *****
try:
from subprocess import check_call
except ImportError:
import subprocess
def check_call(*popenargs, **kwargs):
retcode = subprocess.call(*popenargs, **kwargs)
if retcode:
cmd = kwargs.get("args")
if cmd is None:
cmd = popenargs[0]
raise Exception("Command '%s' returned non-zero exit status %i" % (cmd, retcode))

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

@ -76,7 +76,7 @@ ifdef SYSTEM_LIBXUL
endif
# ELOG prints out failed command when building silently (gmake -s).
ifneq (,$(findstring -s,$(MAKEFLAGS)))
ifneq (,$(findstring s, $(filter-out --%, $(MAKEFLAGS))))
ELOG := $(EXEC) sh $(BUILD_TOOLS)/print-failed-commands.sh
else
ELOG :=

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

@ -1551,6 +1551,10 @@ x86_64 | ia64)
arm*)
CPU_ARCH=arm
;;
mips|mipsel)
CPU_ARCH="mips"
;;
esac
if test -z "$OS_TARGET"; then
@ -5638,7 +5642,7 @@ dnl ========================================================
dnl = libproxy support
dnl ========================================================
if test "$MOZ_ENABLE_GTK2"
if test "$MOZ_ENABLE_GTK2" -o "$MOZ_ENABLE_QT"
then
MOZ_ENABLE_LIBPROXY=
@ -6343,10 +6347,10 @@ if test -n "$MOZ_ANGLE"; then
if test -z "$MOZ_ANGLE"; then
# Try again, but try to get the SDK path from the registry. We're going to hardcode
# the February 2010 SDK, since that's the one that's installed on the tinderboxen.
MOZ_DIRECTX_SDK_PATH=`reg query 'HKLM\Software\Microsoft\DirectX\Microsoft DirectX SDK (February 2010)' //v InstallPath | grep REG_SZ | sed 's, *, ,g' | cut -d' ' -f4`
MOZ_DIRECTX_SDK_PATH=`reg query 'HKLM\Software\Microsoft\DirectX\Microsoft DirectX SDK (February 2010)' //v InstallPath | grep REG_SZ | sed 's, *, ,g' | cut -d' ' -f4-`
if test -n "$MOZ_DIRECTX_SDK_PATH" ; then
if test -f "$MOZ_DIRECTX_SDK_PATH"/include/d3dx9.h && test -f "$MOZ_DIRECTX_SDK_PATH"/lib/x86/dxguid.lib ; then
AC_MSG_WARN([Found DirectX SDK in registry, using $MOZ_DIRECTX_SDK])
AC_MSG_WARN([Found DirectX SDK in registry, using $MOZ_DIRECTX_SDK_PATH])
MOZ_ANGLE=1
fi
fi

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

@ -1067,10 +1067,7 @@ nsFrameLoader::DestroyChild()
#ifdef MOZ_IPC
if (mRemoteBrowser) {
mRemoteBrowser->SetOwnerElement(nsnull);
// If this fails, it's most likely due to a content-process crash,
// and auto-cleanup will kick in. Otherwise, the child side will
// destroy itself and send back __delete__().
unused << mRemoteBrowser->SendDestroy();
mRemoteBrowser->Destroy();
mRemoteBrowser = nsnull;
}
#endif

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

@ -70,51 +70,51 @@ ok(size > 65536, "test data sufficiently large");
// Test that basic properties work
function testBasics(file, size, type) {
is(file.type, type, "mozGetAsFile type");
is(file.size, size, "file is correct size");
ok(file instanceof File, "file is a File");
ok(file instanceof Blob, "file is also a Blob");
is(file.type, type, "[B0] mozGetAsFile type");
is(file.size, size, "[B0] file is correct size");
ok(file instanceof File, "[B0] file is a File");
ok(file instanceof Blob, "[B0] file is also a Blob");
var slice = file.slice(0, size);
is(slice.type, "", "full-size type");
is(slice.size, size, "full-size size");
ok(slice instanceof Blob, "slice is a Blob");
ok(!(slice instanceof File), "slice is not a File");
is(slice.type, "", "[B1] full-size type");
is(slice.size, size, "[B1] full-size size");
ok(slice instanceof Blob, "[B1] slice is a Blob");
ok(!(slice instanceof File), "[B1] slice is not a File");
slice = file.slice(0, 1234);
is(slice.type, "", "sized type");
is(slice.size, 1234, "sized size");
ok(slice instanceof Blob, "slice is a Blob");
ok(!(slice instanceof File), "slice is not a File");
is(slice.type, "", "[B2] sized type");
is(slice.size, 1234, "[B2] sized size");
ok(slice instanceof Blob, "[B2] slice is a Blob");
ok(!(slice instanceof File), "[B2] slice is not a File");
slice = file.slice(size-500, 1000);
is(slice.type, "", "end-sized type");
is(slice.size, 500, "end-sized size");
is(slice.type, "", "[B3] end-sized type");
is(slice.size, 500, "[B3] end-sized size");
slice = file.slice(size+500, 1000);
is(slice.type, "", "sized type");
is(slice.size, 0, "sized size");
is(slice.type, "", "[B4] sized type");
is(slice.size, 0, "[B4] sized size");
slice = file.slice(0, 0);
is(slice.type, "", "sized type");
is(slice.size, 0, "sized size");
is(slice.type, "", "[B5] sized type");
is(slice.size, 0, "[B5] sized size");
slice = file.slice(1000, 0);
is(slice.type, "", "sized type");
is(slice.size, 0, "sized size");
is(slice.type, "", "[B6] sized type");
is(slice.size, 0, "[B6] sized size");
slice = file.slice(0, size, "foo/bar");
is(slice.type, "foo/bar", "full-size foo/bar type");
is(slice.size, size, "full-size foo/bar size");
is(slice.type, "foo/bar", "[B7] full-size foo/bar type");
is(slice.size, size, "[B7] full-size foo/bar size");
slice = file.slice(0, 5432, "foo/bar");
is(slice.type, "foo/bar", "sized foo/bar type");
is(slice.size, 5432, "sized foo/bar size");
is(slice.type, "foo/bar", "[B8] sized foo/bar type");
is(slice.size, 5432, "[B8] sized foo/bar size");
is(slice.slice(0, 10).type, "", "slice-slice type");
is(slice.slice(0, 10).size, 10, "slice-slice size");
is(slice.slice(0, 10, "hello/world").type, "hello/world", "slice-slice hello/world type");
is(slice.slice(0, 10, "hello/world").size, 10, "slice-slice hello/world type");
is(slice.slice(0, 10).type, "", "[B9] slice-slice type");
is(slice.slice(0, 10).size, 10, "[B9] slice-slice size");
is(slice.slice(0, 10, "hello/world").type, "hello/world", "[B9] slice-slice hello/world type");
is(slice.slice(0, 10, "hello/world").size, 10, "[B9] slice-slice hello/world type");
}
testBasics(memFile, size, "image/png");
@ -149,10 +149,10 @@ testFile(memSlice, fileData.substr(5400, 300), "mem file slice slice slice");
testFile(fileSlice, fileData.substr(5400, 300), "file file slice slice slice");
// empty slice
testFile(memFile.slice(4711, 0), "", "mem file empty slice");
testFile(fileFile.slice(4711, 0), "", "file file empty slice");
testFile(memFile.slice(0, 0), "", "mem file empty slice");
testFile(fileFile.slice(0, 0), "", "file file empty slice");
testFile(memFile.slice(4711, 0), "", "mem file empty slice (1)");
testFile(fileFile.slice(4711, 0), "", "file file empty slice (1)");
testFile(memFile.slice(0, 0), "", "mem file empty slice (2)");
testFile(fileFile.slice(0, 0), "", "file file empty slice (2)");
// slice at end
testFile(memFile.slice(size-1000, 1000), fileData.substr(size-1000, 1000), "mem file slice at end");
@ -163,10 +163,10 @@ testFile(memFile.slice(size-500, 1000), fileData.substr(size-500, 500), "mem fil
testFile(fileFile.slice(size-500, 1000), fileData.substr(size-500, 500), "file file slice across end");
// slice past end
testFile(memFile.slice(size, 1000), "", "mem file slice past end");
testFile(fileFile.slice(size, 1000), "", "file file slice past end");
testFile(memFile.slice(size + 1000, 1000), "", "mem file slice past end");
testFile(fileFile.slice(size + 1000, 1000), "", "file file slice past end");
testFile(memFile.slice(size, 1000), "", "mem file slice past end (1)");
testFile(fileFile.slice(size, 1000), "", "file file slice past end (1)");
testFile(memFile.slice(size + 1000, 1000), "", "mem file slice past end (2)");
testFile(fileFile.slice(size + 1000, 1000), "", "file file slice past end (2)");
// Try loading directly from slice into an image
@ -187,15 +187,20 @@ function imageLoadHandler(event) {
testcanvas.width = origcanvas.width;
testcanvas.height = origcanvas.height;
testcanvas.getContext("2d").drawImage(image, 0, 0);
is(testcanvas.toDataURL("image/png"), origcanvas.toDataURL("image/png"),
"correct image data");
// Do not use |is(testcanvas.toDataURL("image/png"), origcanvas.toDataURL("image/png"), "...");| that results in a _very_ long line.
var origDataURL = origcanvas.toDataURL("image/png");
var testDataURL = testcanvas.toDataURL("image/png");
is(testDataURL.length, origDataURL.length,
"Length of correct image data");
ok(testDataURL == origDataURL,
"Content of correct image data");
testHasRun();
}
// image in the middle
var imgfile = createFileWithData(testBinaryData + fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length * 2, "correct file size");
is(imgfile.size, size + testBinaryData.length * 2, "correct file size (middle)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
img.onload = imageLoadHandler;
@ -203,7 +208,7 @@ expectedTestCount++;
// image at start
var imgfile = createFileWithData(fileData + testBinaryData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
is(imgfile.size, size + testBinaryData.length, "correct file size (start)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(0, size));
img.onload = imageLoadHandler;
@ -211,7 +216,7 @@ expectedTestCount++;
// image at end
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
is(imgfile.size, size + testBinaryData.length, "correct file size (end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size));
img.onload = imageLoadHandler;
@ -219,7 +224,7 @@ expectedTestCount++;
// image past end
var imgfile = createFileWithData(testBinaryData + fileData);
is(imgfile.size, size + testBinaryData.length, "correct file size");
is(imgfile.size, size + testBinaryData.length, "correct file size (past end)");
var img = new Image;
img.src = URL.createObjectURL(imgfile.slice(testBinaryData.length, size + 1000));
img.onload = imageLoadHandler;
@ -284,17 +289,20 @@ function testFile(file, contents, test) {
function getFileReaderLoadHandler(expectedResult, expectedLength, testName) {
return function (event) {
is(event.target.readyState, FileReader.DONE,
"readyState in test " + testName);
"[FileReader] readyState in test " + testName);
is(event.target.error, null,
"no error in test " + testName);
is(event.target.result, expectedResult,
"result in test " + testName);
"[FileReader] no error in test " + testName);
// Do not use |is(event.target.result, expectedResult, "...");| that may output raw binary data.
is(event.target.result.length, expectedResult.length,
"[FileReader] Length of result in test " + testName);
ok(event.target.result == expectedResult,
"[FileReader] Content of result in test " + testName);
is(event.lengthComputable, true,
"lengthComputable in test " + testName);
"[FileReader] lengthComputable in test " + testName);
is(event.loaded, expectedLength,
"lengthComputable in test " + testName);
"[FileReader] Loaded length in test " + testName);
is(event.total, expectedLength,
"lengthComputable in test " + testName);
"[FileReader] Total length in test " + testName);
testHasRun();
}
}
@ -302,23 +310,27 @@ function getFileReaderLoadHandler(expectedResult, expectedLength, testName) {
function getXHRLoadHandler(expectedResult, expectedLength, statusWorking, testName) {
return function (event) {
is(event.target.readyState, 4,
"readyState in test " + testName);
"[XHR] readyState in test " + testName);
if (statusWorking) {
is(event.target.status, 200,
"no error in test " + testName);
"[XHR] no error in test " + testName);
}
else {
todo(event.target.status, 200,
"no error in test " + testName);
"[XHR] no error in test " + testName);
}
is(convertXHRBinary(event.target.responseText), expectedResult,
"result in test " + testName);
// Do not use |is(convertXHRBinary(event.target.responseText), expectedResult, "...");| that may output raw binary data.
var convertedData = convertXHRBinary(event.target.responseText);
is(convertedData.length, expectedResult.length,
"[XHR] Length of result in test " + testName);
ok(convertedData == expectedResult,
"[XHR] Content of result in test " + testName);
is(event.lengthComputable, true,
"lengthComputable in test " + testName);
"[XHR] lengthComputable in test " + testName);
is(event.loaded, expectedLength,
"lengthComputable in test " + testName);
"[XHR] Loaded length in test " + testName);
is(event.total, expectedLength,
"lengthComputable in test " + testName);
"[XHR] Total length in test " + testName);
testHasRun();
}
@ -379,24 +391,26 @@ function checkMPSubmission(sub, expected) {
if (!("fileName" in expected[i])) {
is(sub[i].headers["Content-Disposition"],
"form-data; name=\"" + expected[i].name + "\"",
"Correct name");
"Correct name (A)");
is (getPropCount(sub[i].headers), 1,
"Wrong number of headers");
"Wrong number of headers (A)");
}
else {
is(sub[i].headers["Content-Disposition"],
"form-data; name=\"" + expected[i].name + "\"; filename=\"" +
expected[i].fileName + "\"",
"Correct name");
"Correct name (B)");
is(sub[i].headers["Content-Type"],
expected[i].contentType,
"Correct content type");
"Correct content type (B)");
is (getPropCount(sub[i].headers), 2,
"Wrong number of headers");
"Wrong number of headers (B)");
}
is(sub[i].body,
expected[i].value,
"Correct value");
// Do not use |is(sub[i].body, expected[i].value, "...");| that may output raw binary data.
is(sub[i].body.length, expected[i].value.length,
"Length of correct value");
ok(sub[i].body == expected[i].value,
"Content of correct value");
}
}

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

@ -467,6 +467,18 @@ protected:
gfxImageSurface **imageOut,
int *format);
nsresult CopyTexSubImage2D_base(WebGLenum target,
WebGLint level,
WebGLenum internalformat,
WebGLint xoffset,
WebGLint yoffset,
WebGLint x,
WebGLint y,
WebGLsizei width,
WebGLsizei height,
bool sub
);
// Conversion from public nsI* interfaces to concrete objects
template<class ConcreteObjectType, class BaseInterfaceType>
PRBool GetConcreteObject(const char *info,
@ -510,7 +522,10 @@ protected:
WebGLObjectRefPtr<WebGLBuffer> mBoundArrayBuffer;
WebGLObjectRefPtr<WebGLBuffer> mBoundElementArrayBuffer;
WebGLObjectRefPtr<WebGLProgram> mCurrentProgram;
// note nsRefPtr -- this stays alive even after being deleted,
// and is only explicitly removed from the current state via
// a call to UseProgram.
nsRefPtr<WebGLProgram> mCurrentProgram;
PRUint32 mMaxFramebufferColorAttachments;
@ -1145,7 +1160,7 @@ public:
WebGLShader(WebGLContext *context, WebGLuint name, WebGLenum stype) :
WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE), mType(stype),
mNeedsTranslation(true)
mNeedsTranslation(true), mAttachCount(0)
{ }
void Delete() {
@ -1155,10 +1170,14 @@ public:
mDeleted = PR_TRUE;
}
PRBool Deleted() { return mDeleted; }
PRBool Deleted() { return mDeleted && mAttachCount == 0; }
WebGLuint GLName() { return mName; }
WebGLenum ShaderType() { return mType; }
PRUint32 AttachCount() { return mAttachCount; }
void IncrementAttachCount() { mAttachCount++; }
void DecrementAttachCount() { mAttachCount--; }
void SetSource(const nsCString& src) {
// XXX do some quick gzip here maybe -- getting this will be very rare
mSource.Assign(src);
@ -1189,6 +1208,7 @@ protected:
nsCString mSource;
nsCString mTranslationLog;
bool mNeedsTranslation;
PRUint32 mAttachCount;
};
NS_DEFINE_STATIC_IID_ACCESSOR(WebGLShader, WEBGLSHADER_PRIVATE_IID)
@ -1205,7 +1225,8 @@ public:
WebGLProgram(WebGLContext *context, WebGLuint name) :
WebGLContextBoundObject(context),
mName(name), mDeleted(PR_FALSE), mLinkStatus(PR_FALSE), mGeneration(0),
mName(name), mDeleted(PR_FALSE), mDeletePending(PR_FALSE),
mLinkStatus(PR_FALSE), mGeneration(0),
mUniformMaxNameLength(0), mAttribMaxNameLength(0),
mUniformCount(0), mAttribCount(0)
{
@ -1219,7 +1240,18 @@ public:
mDeleted = PR_TRUE;
}
PRBool Deleted() { return mDeleted; }
void DetachShaders() {
for (PRUint32 i = 0; i < mAttachedShaders.Length(); ++i) {
mAttachedShaders[i]->DecrementAttachCount();
}
mAttachedShaders.Clear();
}
PRBool Deleted() { return mDeleted && !mDeletePending; }
void SetDeletePending() { mDeletePending = PR_TRUE; }
void ClearDeletePending() { mDeletePending = PR_FALSE; }
PRBool HasDeletePending() { return mDeletePending; }
WebGLuint GLName() { return mName; }
const nsTArray<WebGLShader*>& AttachedShaders() const { return mAttachedShaders; }
PRBool LinkStatus() { return mLinkStatus; }
@ -1235,12 +1267,17 @@ public:
if (ContainsShader(shader))
return PR_FALSE;
mAttachedShaders.AppendElement(shader);
shader->IncrementAttachCount();
return PR_TRUE;
}
// return true if the shader was found and removed
PRBool DetachShader(WebGLShader *shader) {
return mAttachedShaders.RemoveElement(shader);
if (mAttachedShaders.RemoveElement(shader)) {
shader->DecrementAttachCount();
return PR_TRUE;
}
return PR_FALSE;
}
PRBool HasAttachedShaderOfType(GLenum shaderType) {
@ -1285,10 +1322,14 @@ public:
protected:
WebGLuint mName;
PRPackedBool mDeleted;
PRPackedBool mDeletePending;
PRPackedBool mLinkStatus;
// attached shaders of the program object
nsTArray<WebGLShader*> mAttachedShaders;
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
CheckedUint32 mGeneration;
// post-link data
nsRefPtrHashtable<nsUint32HashKey, WebGLUniformLocation> mMapUniformLocations;
GLint mUniformMaxNameLength;
GLint mAttribMaxNameLength;
GLint mUniformCount;
@ -1348,9 +1389,12 @@ NS_DEFINE_STATIC_IID_ACCESSOR(WebGLRenderbuffer, WEBGLRENDERBUFFER_PRIVATE_IID)
class WebGLFramebufferAttachment
{
nsRefPtr<WebGLTexture> mTexturePtr;
nsRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
// deleting a texture or renderbuffer immediately detaches it
WebGLObjectRefPtr<WebGLTexture> mTexturePtr;
WebGLObjectRefPtr<WebGLRenderbuffer> mRenderbufferPtr;
WebGLenum mAttachmentPoint;
WebGLint mTextureLevel;
WebGLenum mTextureCubeMapFace;
public:
WebGLFramebufferAttachment(WebGLenum aAttachmentPoint)
@ -1374,9 +1418,11 @@ public:
format == LOCAL_GL_RGB5_A1;
}
void SetTexture(WebGLTexture *tex) {
void SetTexture(WebGLTexture *tex, WebGLint level, WebGLenum face) {
mTexturePtr = tex;
mRenderbufferPtr = nsnull;
mTextureLevel = level;
mTextureCubeMapFace = face;
}
void SetRenderbuffer(WebGLRenderbuffer *rb) {
mTexturePtr = nsnull;
@ -1388,6 +1434,12 @@ public:
WebGLRenderbuffer *Renderbuffer() const {
return mRenderbufferPtr.get();
}
WebGLint TextureLevel() const {
return mTextureLevel;
}
WebGLenum TextureCubeMapFace() const {
return mTextureCubeMapFace;
}
PRBool IsIncompatibleWithAttachmentPoint() const
{
@ -1493,7 +1545,12 @@ public:
}
mContext->MakeContextCurrent();
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_DEPTH_ATTACHMENT, rbtarget, renderbuffername);
mContext->gl->fFramebufferRenderbuffer(target, LOCAL_GL_STENCIL_ATTACHMENT, rbtarget, renderbuffername);
} else {
mContext->gl->fFramebufferRenderbuffer(target, attachment, rbtarget, renderbuffername);
}
return NS_OK;
}
@ -1525,15 +1582,16 @@ public:
if (!isNull && level > 0)
return mContext->ErrorInvalidValue("framebufferTexture2D: level must be 0");
WebGLint face = (textarget == LOCAL_GL_TEXTURE_2D) ? 0 : textarget;
switch (attachment) {
case LOCAL_GL_DEPTH_ATTACHMENT:
mDepthAttachment.SetTexture(wtex);
mDepthAttachment.SetTexture(wtex, level, face);
break;
case LOCAL_GL_STENCIL_ATTACHMENT:
mStencilAttachment.SetTexture(wtex);
mStencilAttachment.SetTexture(wtex, level, face);
break;
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
mDepthStencilAttachment.SetTexture(wtex);
mDepthStencilAttachment.SetTexture(wtex, level, face);
break;
default:
if (attachment != LOCAL_GL_COLOR_ATTACHMENT0)
@ -1542,12 +1600,17 @@ public:
// keep data for readPixels, function only uses COLOR_ATTACHMENT0
setDimensions(wtex);
mColorAttachment.SetTexture(wtex);
mColorAttachment.SetTexture(wtex, level, face);
break;
}
mContext->MakeContextCurrent();
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_DEPTH_ATTACHMENT, textarget, texturename, level);
mContext->gl->fFramebufferTexture2D(target, LOCAL_GL_STENCIL_ATTACHMENT, textarget, texturename, level);
} else {
mContext->gl->fFramebufferTexture2D(target, attachment, textarget, texturename, level);
}
return NS_OK;
}
@ -1589,7 +1652,31 @@ public:
else return PR_FALSE;
}
const WebGLFramebufferAttachment ColorAttachment() const {
const WebGLFramebufferAttachment& ColorAttachment() const {
return mColorAttachment;
}
const WebGLFramebufferAttachment& DepthAttachment() const {
return mDepthAttachment;
}
const WebGLFramebufferAttachment& StencilAttachment() const {
return mStencilAttachment;
}
const WebGLFramebufferAttachment& DepthStencilAttachment() const {
return mDepthStencilAttachment;
}
const WebGLFramebufferAttachment& GetAttachment(WebGLenum attachment) const {
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT)
return mDepthStencilAttachment;
if (attachment == LOCAL_GL_DEPTH_ATTACHMENT)
return mDepthAttachment;
if (attachment == LOCAL_GL_STENCIL_ATTACHMENT)
return mStencilAttachment;
NS_ASSERTION(attachment == LOCAL_GL_COLOR_ATTACHMENT0, "bad attachment!");
return mColorAttachment;
}

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

@ -580,6 +580,103 @@ GL_SAME_METHOD_1(ClearStencil, ClearStencil, WebGLint)
GL_SAME_METHOD_4(ColorMask, ColorMask, WebGLboolean, WebGLboolean, WebGLboolean, WebGLboolean)
nsresult
WebGLContext::CopyTexSubImage2D_base(WebGLenum target,
WebGLint level,
WebGLenum internalformat,
WebGLint xoffset,
WebGLint yoffset,
WebGLint x,
WebGLint y,
WebGLsizei width,
WebGLsizei height,
bool sub)
{
WebGLsizei framebufferWidth = mBoundFramebuffer ? mBoundFramebuffer->width() : mWidth;
WebGLsizei framebufferHeight = mBoundFramebuffer ? mBoundFramebuffer->height() : mHeight;
const char *info = sub ? "copyTexSubImage2D" : "copyTexImage2D";
MakeContextCurrent();
if (CanvasUtils::CheckSaneSubrectSize(x, y, width, height, framebufferWidth, framebufferHeight)) {
if (sub)
gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
else
gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, 0);
} else {
// the rect doesn't fit in the framebuffer
/*** first, we initialize the texture as black ***/
// first, compute the size of the buffer we should allocate to initialize the texture as black
PRUint32 texelSize = 0;
if (!ValidateTexFormatAndType(internalformat, LOCAL_GL_UNSIGNED_BYTE, &texelSize, info))
return NS_OK;
CheckedUint32 checked_plainRowSize = CheckedUint32(width) * texelSize;
PRUint32 unpackAlignment = mPixelStoreUnpackAlignment;
// alignedRowSize = row size rounded up to next multiple of packAlignment
CheckedUint32 checked_alignedRowSize
= ((checked_plainRowSize + unpackAlignment-1) / unpackAlignment) * unpackAlignment;
CheckedUint32 checked_neededByteLength
= (height-1) * checked_alignedRowSize + checked_plainRowSize;
if (!checked_neededByteLength.valid())
return ErrorInvalidOperation("%s: integer overflow computing the needed buffer size", info);
PRUint32 bytesNeeded = checked_neededByteLength.value();
// now that the size is known, create the buffer
// We need some zero pages, because GL doesn't guarantee the
// contents of a texture allocated with NULL data.
// Hopefully calloc will just mmap zero pages here.
void *tempZeroData = calloc(1, bytesNeeded);
if (!tempZeroData)
return SynthesizeGLError(LOCAL_GL_OUT_OF_MEMORY, "%s: could not allocate %d bytes (for zero fill)", info, bytesNeeded);
// now initialize the texture as black
if (sub)
gl->fTexSubImage2D(target, level, 0, 0, width, height, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
else
gl->fTexImage2D(target, level, internalformat, width, height, 0, internalformat, LOCAL_GL_UNSIGNED_BYTE, tempZeroData);
free(tempZeroData);
// if we are completely outside of the framebuffer, we can exit now with our black texture
if ( x >= framebufferWidth
|| x+width <= 0
|| y >= framebufferHeight
|| y+height <= 0)
{
// we are completely outside of range, can exit now with buffer filled with zeros
return NS_OK;
}
GLint actual_x = PR_MIN(framebufferWidth, PR_MAX(0, x));
GLint actual_x_plus_width = PR_MIN(framebufferWidth, PR_MAX(0, x + width));
GLsizei actual_width = actual_x_plus_width - actual_x;
GLint actual_xoffset = xoffset + actual_x - x;
GLint actual_y = PR_MIN(framebufferHeight, PR_MAX(0, y));
GLint actual_y_plus_height = PR_MIN(framebufferHeight, PR_MAX(0, y + height));
GLsizei actual_height = actual_y_plus_height - actual_y;
GLint actual_yoffset = yoffset + actual_y - y;
gl->fCopyTexSubImage2D(target, level, actual_xoffset, actual_yoffset, actual_x, actual_y, actual_width, actual_height);
}
return NS_OK;
}
NS_IMETHODIMP
WebGLContext::CopyTexImage2D(WebGLenum target,
WebGLint level,
@ -618,6 +715,9 @@ WebGLContext::CopyTexImage2D(WebGLenum target,
if (border != 0)
return ErrorInvalidValue("copyTexImage2D: border must be 0");
if (width < 0 || height < 0)
return ErrorInvalidValue("copyTexImage2D: width and height may not be negative");
if (level < 0)
return ErrorInvalidValue("copyTexImage2D: level may not be negative");
@ -636,10 +736,6 @@ WebGLContext::CopyTexImage2D(WebGLenum target,
return ErrorInvalidOperation("copyTexImage2D: texture format requires an alpha channel "
"but the framebuffer doesn't have one");
if (!CanvasUtils::CheckSaneSubrectSize(x,y,width, height, mWidth, mHeight))
return ErrorInvalidOperation("CopyTexImage2D: copied rectangle out of bounds");
if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
return NS_OK;
@ -649,11 +745,7 @@ WebGLContext::CopyTexImage2D(WebGLenum target,
tex->SetImageInfo(target, level, width, height);
MakeContextCurrent();
gl->fCopyTexImage2D(target, level, internalformat, x, y, width, height, border);
return NS_OK;
return CopyTexSubImage2D_base(target, level, internalformat, 0, 0, x, y, width, height, false);
}
NS_IMETHODIMP
@ -679,11 +771,29 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target,
return ErrorInvalidEnumInfo("CopyTexSubImage2D: target", target);
}
if (level < 0)
return ErrorInvalidValue("copyTexSubImage2D: level may not be negative");
if (width < 0 || height < 0)
return ErrorInvalidValue("copyTexSubImage2D: width and height may not be negative");
if (xoffset < 0 || yoffset < 0)
return ErrorInvalidValue("copyTexSubImage2D: xoffset and yoffset may not be negative");
WebGLTexture *tex = activeBoundTextureForTarget(target);
if (!tex)
return ErrorInvalidOperation("copyTexSubImage2D: no texture bound to this target");
WebGLenum format = tex->ImageInfoAt(0,0).mFormat;
WebGLsizei texWidth = tex->ImageInfoAt(level,0).mWidth;
WebGLsizei texHeight = tex->ImageInfoAt(level,0).mHeight;
if (xoffset + width > texWidth || xoffset + width < 0)
return ErrorInvalidValue("copyTexSubImage2D: xoffset+width is too large");
if (yoffset + height > texHeight || yoffset + height < 0)
return ErrorInvalidValue("copyTexSubImage2D: yoffset+height is too large");
WebGLenum format = tex->ImageInfoAt(level,0).mFormat;
PRBool texFormatRequiresAlpha = format == LOCAL_GL_RGBA ||
format == LOCAL_GL_ALPHA ||
format == LOCAL_GL_LUMINANCE_ALPHA;
@ -694,17 +804,10 @@ WebGLContext::CopyTexSubImage2D(WebGLenum target,
return ErrorInvalidOperation("copyTexSubImage2D: texture format requires an alpha channel "
"but the framebuffer doesn't have one");
if (!CanvasUtils::CheckSaneSubrectSize(x,y,width, height, mWidth, mHeight))
return ErrorInvalidOperation("CopyTexSubImage2D: copied rectangle out of bounds");
if (mBoundFramebuffer && !mBoundFramebuffer->CheckAndInitializeRenderbuffers())
return NS_OK;
MakeContextCurrent();
gl->fCopyTexSubImage2D(target, level, xoffset, yoffset, x, y, width, height);
return NS_OK;
return CopyTexSubImage2D_base(target, level, format, xoffset, yoffset, x, y, width, height, true);
}
@ -869,6 +972,13 @@ WebGLContext::DeleteProgram(nsIWebGLProgram *pobj)
MakeContextCurrent();
gl->fDeleteProgram(progname);
if (prog == mCurrentProgram) {
prog->SetDeletePending();
} else {
prog->DetachShaders();
}
prog->Delete();
mMapPrograms.Remove(progname);
@ -902,10 +1012,13 @@ WebGLContext::DetachShader(nsIWebGLProgram *pobj, nsIWebGLShader *shobj)
WebGLuint progname, shadername;
WebGLProgram *program;
WebGLShader *shader;
PRBool shaderDeleted;
if (!GetConcreteObjectAndGLName("detachShader: program", pobj, &program, &progname) ||
!GetConcreteObjectAndGLName("detachShader: shader", shobj, &shader, &shadername))
!GetConcreteObjectAndGLName("detachShader: shader", shobj, &shader, &shadername, nsnull, &shaderDeleted))
return NS_OK;
// shaderDeleted is ignored -- it's valid to attempt to detach a
// deleted shader, since it's still a shader
if (!program->DetachShader(shader))
return ErrorInvalidOperation("DetachShader: shader is not attached");
@ -1157,7 +1270,7 @@ WebGLContext::DrawElements(WebGLenum mode, WebGLsizei count, WebGLenum type, Web
if (type == LOCAL_GL_UNSIGNED_SHORT) {
checked_byteCount = 2 * CheckedUint32(count);
if (byteOffset % 2 != 0)
return ErrorInvalidValue("DrawElements: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)");
return ErrorInvalidOperation("DrawElements: invalid byteOffset for UNSIGNED_SHORT (must be a multiple of 2)");
} else if (type == LOCAL_GL_UNSIGNED_BYTE) {
checked_byteCount = count;
} else {
@ -1259,10 +1372,10 @@ WebGLContext::EnableVertexAttribArray(WebGLuint index)
NS_IMETHODIMP
WebGLContext::FramebufferRenderbuffer(WebGLenum target, WebGLenum attachment, WebGLenum rbtarget, nsIWebGLRenderbuffer *rbobj)
{
if (mBoundFramebuffer)
return mBoundFramebuffer->FramebufferRenderbuffer(target, attachment, rbtarget, rbobj);
else
if (!mBoundFramebuffer)
return ErrorInvalidOperation("framebufferRenderbuffer: cannot modify framebuffer 0");
return mBoundFramebuffer->FramebufferRenderbuffer(target, attachment, rbtarget, rbobj);
}
NS_IMETHODIMP
@ -1426,7 +1539,7 @@ WebGLContext::GetAttachedShaders(nsIWebGLProgram *pobj, nsIVariant **retval)
MakeContextCurrent();
if (isNull) {
wrval->SetAsVoid();
wrval->SetAsEmpty();
// note no return, we still want to return the variant
ErrorInvalidValue("getAttachedShaders: invalid program");
} else if (prog->AttachedShaders().Length() == 0) {
@ -1568,7 +1681,7 @@ WebGLContext::GetParameter(PRUint32 pname, nsIVariant **retval)
wrval->SetAsInt32(0);
break;
case LOCAL_GL_COMPRESSED_TEXTURE_FORMATS:
wrval->SetAsVoid(); // the spec says we must return null
wrval->SetAsEmpty(); // the spec says we must return null
break;
// unsigned int. here we may have to return very large values like 2^32-1 that can't be represented as
@ -1768,6 +1881,7 @@ WebGLContext::GetFramebufferAttachmentParameter(WebGLenum target, WebGLenum atta
case LOCAL_GL_COLOR_ATTACHMENT0:
case LOCAL_GL_DEPTH_ATTACHMENT:
case LOCAL_GL_STENCIL_ATTACHMENT:
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
break;
default:
return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: attachment", attachment);
@ -1778,57 +1892,46 @@ WebGLContext::GetFramebufferAttachmentParameter(WebGLenum target, WebGLenum atta
MakeContextCurrent();
GLint atype = 0;
gl->fGetFramebufferAttachmentParameteriv(target, attachment, LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &atype);
const WebGLFramebufferAttachment& fba = mBoundFramebuffer->GetAttachment(attachment);
if (atype == LOCAL_GL_RENDERBUFFER) {
if (fba.Renderbuffer()) {
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
wrval->SetAsInt32(atype);
wrval->SetAsInt32(LOCAL_GL_RENDERBUFFER);
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: {
GLint i = 0;
gl->fGetFramebufferAttachmentParameteriv(target, attachment, pname, &i);
WebGLRenderbuffer *rb = mMapRenderbuffers.GetWeak(PRUint32(i));
NS_ASSERTION(rb, "Expected to find renderbuffer in table, but it's not there?");
wrval->SetAsISupports(rb);
}
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
wrval->SetAsISupports(fba.Renderbuffer());
break;
default:
return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: pname", pname);
}
} else if (atype == LOCAL_GL_TEXTURE) {
} else if (fba.Texture()) {
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
wrval->SetAsInt32(atype);
wrval->SetAsInt32(LOCAL_GL_TEXTURE);
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME: {
GLint i = 0;
gl->fGetFramebufferAttachmentParameteriv(target, attachment, pname, &i);
WebGLTexture *tex = mMapTextures.GetWeak(PRUint32(i));
NS_ASSERTION(tex, "Expected to find texture in table, but it's not there?");
wrval->SetAsISupports(tex);
}
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
wrval->SetAsISupports(fba.Texture());
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE: {
GLint i = 0;
gl->fGetFramebufferAttachmentParameteriv(target, attachment, pname, &i);
wrval->SetAsInt32(i);
}
wrval->SetAsInt32(fba.TextureLevel());
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
wrval->SetAsInt32(fba.TextureCubeMapFace());
break;
default:
return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: pname", pname);
}
} else if (atype == LOCAL_GL_NONE) {
} else {
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
wrval->SetAsInt32(atype);
wrval->SetAsInt32(LOCAL_GL_NONE);
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
@ -1838,8 +1941,6 @@ WebGLContext::GetFramebufferAttachmentParameter(WebGLenum target, WebGLenum atta
default:
return ErrorInvalidEnumInfo("GetFramebufferAttachmentParameter: pname", pname);
}
} else { // GL bug? should never happen
return NS_ERROR_FAILURE;
}
*retval = wrval.forget().get();
@ -1956,7 +2057,8 @@ WebGLContext::GetProgramParameter(nsIWebGLProgram *pobj, PRUint32 pname, nsIVari
*retval = nsnull;
WebGLuint progname;
if (!GetGLName<WebGLProgram>("getProgramParameter: program", pobj, &progname))
PRBool isDeleted;
if (!GetGLName<WebGLProgram>("getProgramParameter: program", pobj, &progname, nsnull, &isDeleted))
return NS_OK;
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
@ -2187,7 +2289,7 @@ WebGLContext::GetUniform(nsIWebGLProgram *pobj, nsIWebGLUniformLocation *ploc, n
return ErrorInvalidValue("GetUniform: this uniform location corresponds to another program");
if (location->ProgramGeneration() != prog->Generation())
return ErrorInvalidValue("GetUniform: this uniform location is obsolete since the program has been relinked");
return ErrorInvalidOperation("GetUniform: this uniform location is obsolete since the program has been relinked");
nsCOMPtr<nsIWritableVariant> wrval = do_CreateInstance("@mozilla.org/variant;1");
NS_ENSURE_TRUE(wrval, NS_ERROR_FAILURE);
@ -2271,12 +2373,12 @@ WebGLContext::GetUniform(nsIWebGLProgram *pobj, nsIWebGLUniformLocation *ploc, n
GLint iv[16] = { 0 };
gl->fGetUniformiv(progname, location->Location(), iv);
if (unitSize == 1) {
wrval->SetAsBool(PRBool(iv[0]));
wrval->SetAsBool(iv[0] ? PR_TRUE : PR_FALSE);
} else {
PRUint8 uv[16] = { 0 };
PRBool uv[16] = { 0 };
for (int k = 0; k < unitSize; k++)
uv[k] = PRUint8(iv[k]);
wrval->SetAsArray(nsIDataType::VTYPE_UINT8, nsnull,
uv[k] = iv[k] ? PR_TRUE : PR_FALSE;
wrval->SetAsArray(nsIDataType::VTYPE_BOOL, nsnull,
unitSize, static_cast<void*>(uv));
}
} else {
@ -2430,7 +2532,18 @@ NS_IMETHODIMP
WebGLContext::IsProgram(nsIWebGLProgram *pobj, WebGLboolean *retval)
{
PRBool isDeleted;
*retval = CanGetConcreteObject<WebGLProgram>("isProgram", pobj, 0, &isDeleted) && !isDeleted;
WebGLProgram *prog = nsnull;
PRBool ok = GetConcreteObject("isProgram", pobj, &prog, 0, &isDeleted, PR_FALSE);
if (!ok) {
*retval = PR_FALSE;
return NS_OK;
}
if (isDeleted) {
*retval = PR_FALSE;
} else {
*retval = PR_TRUE;
}
return NS_OK;
}
@ -2454,7 +2567,18 @@ NS_IMETHODIMP
WebGLContext::IsShader(nsIWebGLShader *sobj, WebGLboolean *retval)
{
PRBool isDeleted;
*retval = CanGetConcreteObject<WebGLShader>("isShader", sobj, 0, &isDeleted) && !isDeleted;
WebGLShader *shader = nsnull;
PRBool ok = GetConcreteObject("isShader", sobj, &shader, 0, &isDeleted, PR_FALSE);
if (!ok) {
*retval = PR_FALSE;
return NS_OK;
}
if (isDeleted) {
*retval = PR_FALSE;
} else {
*retval = PR_TRUE;
}
return NS_OK;
}
@ -3332,16 +3456,18 @@ WebGLContext::UseProgram(nsIWebGLProgram *pobj)
MakeContextCurrent();
if (isNull) {
gl->fUseProgram(0);
mCurrentProgram = nsnull;
} else {
if (!prog->LinkStatus())
return ErrorInvalidOperation("UseProgram: program was not linked successfully");
gl->fUseProgram(progname);
mCurrentProgram = prog;
if (prog && !prog->LinkStatus())
return ErrorInvalidOperation("UseProgram: program was not linked successfully");
gl->fUseProgram(progname);
if (mCurrentProgram && mCurrentProgram->HasDeletePending()) {
mCurrentProgram->DetachShaders();
mCurrentProgram->ClearDeletePending();
}
mCurrentProgram = prog;
return NS_OK;
}
@ -3405,7 +3531,7 @@ NS_IMETHODIMP
WebGLContext::Viewport(WebGLint x, WebGLint y, WebGLsizei width, WebGLsizei height)
{
if (width < 0 || height < 0)
return ErrorInvalidOperation("Viewport: negative size");
return ErrorInvalidValue("Viewport: negative size");
MakeContextCurrent();
gl->fViewport(x, y, width, height);
@ -3419,6 +3545,7 @@ WebGLContext::CompileShader(nsIWebGLShader *sobj)
WebGLuint shadername;
if (!GetConcreteObjectAndGLName("compileShader", sobj, &shader, &shadername))
return NS_OK;
MakeContextCurrent();
#if defined(USE_ANGLE)
@ -3602,6 +3729,9 @@ WebGLContext::ShaderSource(nsIWebGLShader *sobj, const nsAString& source)
if (!GetConcreteObjectAndGLName("shaderSource: shader", sobj, &shader, &shadername))
return NS_OK;
if (!NS_IsAscii(nsPromiseFlatString(source).get()))
return ErrorInvalidValue("shaderSource: non-ascii characters found in source");
shader->SetSource(NS_LossyConvertUTF16toASCII(source));
shader->SetNeedsTranslation();
@ -3645,19 +3775,19 @@ WebGLContext::VertexAttribPointer(WebGLuint index, WebGLint size, WebGLenum type
return ErrorInvalidValue("VertexAttribPointer: invalid element size");
if (stride < 0 || stride > 255) // see WebGL spec section 6.6 "Vertex Attribute Data Stride"
return ErrorInvalidValue("VertexAttribPointer: negative stride");
return ErrorInvalidValue("VertexAttribPointer: negative or too large stride");
if (byteOffset < 0)
return ErrorInvalidValue("VertexAttribPointer: negative offset");
if (stride & requiredAlignmentMask) {
return ErrorInvalidValue("VertexAttribPointer: stride doesn't satisfy the alignment "
"requirement of given type");
return ErrorInvalidOperation("VertexAttribPointer: stride doesn't satisfy the alignment "
"requirement of given type");
}
if (byteOffset & requiredAlignmentMask) {
return ErrorInvalidValue("VertexAttribPointer: byteOffset doesn't satisfy the alignment "
"requirement of given type");
return ErrorInvalidOperation("VertexAttribPointer: byteOffset doesn't satisfy the alignment "
"requirement of given type");
}
@ -4172,3 +4302,10 @@ int mozilla::GetWebGLTexelFormat(GLenum format, GLenum type)
}
}
}
NS_IMETHODIMP
WebGLContext::GetExtension(const nsAString& aName, nsISupports **retval)
{
*retval = nsnull;
return NS_OK;
}

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

@ -2726,6 +2726,22 @@ nsGenericHTMLFormElement::CanBeDisabled() const
type != NS_FORM_OUTPUT;
}
PRBool
nsGenericHTMLFormElement::IsHTMLFocusable(PRBool aWithMouse,
PRBool* aIsFocusable,
PRInt32* aTabIndex)
{
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
return PR_TRUE;
}
#ifdef XP_MACOSX
*aIsFocusable =
(!aWithMouse || nsFocusManager::sMouseFocusesFormControl) && *aIsFocusable;
#endif
return PR_FALSE;
}
PRBool
nsGenericHTMLFormElement::IsSubmitControl() const
{
@ -3317,10 +3333,6 @@ nsGenericHTMLElement::IsHTMLFocusable(PRBool aWithMouse,
// If a tabindex is specified at all, or the default tabindex is 0, we're focusable
*aIsFocusable =
#ifdef XP_MACOSX
// can only focus with the mouse on Mac if editable
(!aWithMouse || override) &&
#endif
(tabIndex >= 0 || (!disabled && HasAttr(kNameSpaceID_None, nsGkAtoms::tabindex)));
return override;

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

@ -924,6 +924,9 @@ public:
*/
PRBool CanBeDisabled() const;
virtual PRBool IsHTMLFocusable(PRBool aWithMouse, PRBool* aIsFocusable,
PRInt32* aTabIndex);
protected:
virtual nsresult BeforeSetAttr(PRInt32 aNameSpaceID, nsIAtom* aName,
const nsAString* aValue, PRBool aNotify);

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

@ -281,7 +281,7 @@ nsHTMLButtonElement::Click()
PRBool
nsHTMLButtonElement::IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
return PR_TRUE;
}

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

@ -3531,7 +3531,7 @@ nsHTMLInputElement::WillRemoveFromRadioGroup()
PRBool
nsHTMLInputElement::IsHTMLFocusable(PRBool aWithMouse, PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
return PR_TRUE;
}

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

@ -1289,7 +1289,7 @@ PRBool
nsHTMLSelectElement::IsHTMLFocusable(PRBool aWithMouse,
PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
return PR_TRUE;
}

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

@ -480,7 +480,7 @@ PRBool
nsHTMLTextAreaElement::IsHTMLFocusable(PRBool aWithMouse,
PRBool *aIsFocusable, PRInt32 *aTabIndex)
{
if (nsGenericHTMLElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
if (nsGenericHTMLFormElement::IsHTMLFocusable(aWithMouse, aIsFocusable, aTabIndex)) {
return PR_TRUE;
}

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

@ -13,8 +13,8 @@
var a = document.getElementById("a");
isnot(a, document.elementFromPoint(5, 5), "a shouldn't be found");
isnot(a, document.elementFromPoint(5.25, 5.25), "a shouldn't be found");
is(a, document.elementFromPoint(5.5, 5.5), "a should be found");
is(a, document.elementFromPoint(5.75, 5.75), "a should be found");
isnot(a, document.elementFromPoint(5.5, 5.5), "a shouldn't be found");
isnot(a, document.elementFromPoint(5.75, 5.75), "a shouldn't be found");
is(a, document.elementFromPoint(6, 6), "a should be found");
is(a, document.elementFromPoint(105, 105), "a should be found");
is(a, document.elementFromPoint(105.25, 105.25), "a should be found");

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

@ -2776,7 +2776,19 @@ nsXULDocument::LoadOverlayInternal(nsIURI* aURI, PRBool aIsDynamic,
NS_RELEASE(parserObserver);
nsCOMPtr<nsILoadGroup> group = do_QueryReferent(mDocumentLoadGroup);
rv = NS_OpenURI(listener, nsnull, aURI, nsnull, group);
nsCOMPtr<nsIChannel> channel;
rv = NS_NewChannel(getter_AddRefs(channel), aURI, nsnull, group);
if (NS_SUCCEEDED(rv)) {
// Set the owner of the channel to be our principal so
// that the overlay's JSObjects etc end up being created
// with the right principal and in the correct
// compartment.
channel->SetOwner(NodePrincipal());
rv = channel->AsyncOpen(listener, nsnull);
}
if (NS_FAILED(rv)) {
// Abandon this prototype
mCurrentPrototype = nsnull;
@ -4531,7 +4543,7 @@ nsXULDocument::ParserObserver::OnStartRequest(nsIRequest *request,
secMan->GetChannelPrincipal(channel, getter_AddRefs(principal));
// Failure there is ok -- it'll just set a (safe) null principal
mPrototype->SetDocumentPrincipal(principal);
mPrototype->SetDocumentPrincipal(principal);
}
// Make sure to avoid cycles

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

@ -1,5 +1,5 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* vim: ft=cpp tw=78 sw=4 et ts=8 sts=4 cin */
/* vim: set ts=4 sw=4 tw=80 et: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*

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

@ -91,7 +91,7 @@ DOM_MSG_DEF(NS_ERROR_DOM_DATA_CLONE_ERR, "The object could not be cloned.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR, "The operation failed for reasons unrelated to the database itself and not covered by any other error code.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR, "This error occurred because an operation was not allowed on an object. A retry of the same operation would fail unless the cause of the error is corrected.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR, "The operation failed because the requested database object could not be found. For example, an object store did not exist but was being opened.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR, "A mutation operation in the transaction failed due to a because a constraint was not satisfied. For example, an object such as an object store or index already exists and a new one was being attempted to be created.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR, "A mutation operation in the transaction failed because a constraint was not satisfied. For example, an object such as an object store or index already exists and a new one was being attempted to be created.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_DATA_ERR, "Data provided to an operation does not meet requirements.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR, "A mutation operation was attempted on a database that did not allow mutations.")
DOM_MSG_DEF(NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR, "A request was placed against a transaction which is currently not active, or which is finished.")

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

@ -1458,12 +1458,6 @@ static nsDOMClassInfoData sClassInfoData[] = {
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBDatabase, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBErrorEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBSuccessEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBTransactionEvent, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBObjectStore, nsDOMGenericSH,
DOM_DEFAULT_SCRIPTABLE_FLAGS)
NS_DEFINE_CLASSINFO_DATA(IDBTransaction, nsDOMGenericSH,
@ -4098,25 +4092,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEventTarget)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(IDBErrorEvent, nsIIDBErrorEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBErrorEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(IDBSuccessEvent, nsIIDBSuccessEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBSuccessEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(IDBTransactionEvent, nsIIDBTransactionEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBTransactionEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBSuccessEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
DOM_CLASSINFO_MAP_BEGIN(IDBObjectStore, nsIIDBObjectStore)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBObjectStore)
DOM_CLASSINFO_MAP_END
@ -4141,7 +4116,6 @@ nsDOMClassInfo::Init()
DOM_CLASSINFO_MAP_BEGIN(IDBVersionChangeEvent, nsIIDBVersionChangeEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBVersionChangeEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIIDBEvent)
DOM_CLASSINFO_MAP_ENTRY(nsIDOMEvent)
DOM_CLASSINFO_MAP_END
@ -6115,8 +6089,19 @@ GetXPCProto(nsIXPConnect *aXPConnect, JSContext *cx, nsGlobalWindow *aWin,
}
NS_ENSURE_TRUE(ci, NS_ERROR_UNEXPECTED);
return aXPConnect->GetWrappedNativePrototype(cx, aWin->GetGlobalJSObject(),
ci, aProto);
nsresult rv =
aXPConnect->GetWrappedNativePrototype(cx, aWin->GetGlobalJSObject(), ci,
aProto);
NS_ENSURE_SUCCESS(rv, rv);
JSObject *proto_obj;
(*aProto)->GetJSObject(&proto_obj);
if (!JS_WrapObject(cx, &proto_obj)) {
return NS_ERROR_FAILURE;
}
NS_IF_RELEASE(*aProto);
return aXPConnect->HoldObject(cx, proto_obj, aProto);
}
// Either ci_data must be non-null or name_struct must be non-null and of type

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

@ -496,9 +496,6 @@ DOMCI_CLASS(CloseEvent)
DOMCI_CLASS(IDBFactory)
DOMCI_CLASS(IDBRequest)
DOMCI_CLASS(IDBDatabase)
DOMCI_CLASS(IDBErrorEvent)
DOMCI_CLASS(IDBSuccessEvent)
DOMCI_CLASS(IDBTransactionEvent)
DOMCI_CLASS(IDBObjectStore)
DOMCI_CLASS(IDBTransaction)
DOMCI_CLASS(IDBCursor)

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

@ -92,20 +92,20 @@
/* IndexedDB error codes http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html */
#define NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,0)
#define NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,1)
#define NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,2)
#define NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,3)
#define NS_ERROR_DOM_INDEXEDDB_DATA_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,4)
#define NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,5)
#define NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,1)
#define NS_ERROR_DOM_INDEXEDDB_NON_TRANSIENT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,2)
#define NS_ERROR_DOM_INDEXEDDB_NOT_FOUND_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,3)
#define NS_ERROR_DOM_INDEXEDDB_CONSTRAINT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,4)
#define NS_ERROR_DOM_INDEXEDDB_DATA_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,5)
#define NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,6)
#define NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR \
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,6)
#define NS_ERROR_DOM_INDEXEDDB_ABORT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,7)
#define NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,11)
#define NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,21)
#define NS_ERROR_DOM_INDEXEDDB_TRANSIENT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,31)
#define NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,32)
#define NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,33)
NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,7)
#define NS_ERROR_DOM_INDEXEDDB_ABORT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,8)
#define NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,9)
#define NS_ERROR_DOM_INDEXEDDB_RECOVERABLE_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,10)
#define NS_ERROR_DOM_INDEXEDDB_TRANSIENT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,11)
#define NS_ERROR_DOM_INDEXEDDB_TIMEOUT_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,12)
#define NS_ERROR_DOM_INDEXEDDB_DEADLOCK_ERR NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_DOM_INDEXEDDB,13)
/* DOM error codes defined by us */

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

@ -1108,11 +1108,8 @@ nsGlobalWindow::CleanUp(PRBool aIgnoreModalDialog)
inner->CleanUp(aIgnoreModalDialog);
}
if (mHasAcceleration) {
nsCOMPtr<nsIAccelerometer> ac = do_GetService(NS_ACCELEROMETER_CONTRACTID);
if (ac)
ac->RemoveWindowListener(this);
}
DisableAccelerationUpdates();
mHasAcceleration = PR_FALSE;
if (mIsChrome && static_cast<nsGlobalChromeWindow*>(this)->mMessageManager) {
static_cast<nsFrameMessageManager*>(
@ -2557,7 +2554,7 @@ nsGlobalWindow::AreDialogsBlocked()
{
nsGlobalWindow *topWindow = GetTop();
if (!topWindow) {
NS_ERROR("AreDialogsBlocked() called without a top window?");
NS_ASSERTION(!mDocShell, "AreDialogsBlocked() called without a top window?");
return true;
}
@ -7350,6 +7347,31 @@ void nsGlobalWindow::UpdateTouchState()
}
}
void
nsGlobalWindow::EnableAccelerationUpdates()
{
if (mHasAcceleration) {
nsCOMPtr<nsIAccelerometer> ac =
do_GetService(NS_ACCELEROMETER_CONTRACTID);
if (ac) {
ac->AddWindowListener(this);
}
}
}
void
nsGlobalWindow::DisableAccelerationUpdates()
{
if (mHasAcceleration) {
nsCOMPtr<nsIAccelerometer> ac =
do_GetService(NS_ACCELEROMETER_CONTRACTID);
if (ac) {
ac->RemoveWindowListener(this);
}
}
}
void
nsGlobalWindow::SetChromeEventHandler(nsPIDOMEventTarget* aChromeEventHandler)
{
@ -9656,6 +9678,8 @@ nsGlobalWindow::SuspendTimeouts(PRUint32 aIncrease,
mTimeoutsSuspendDepth += aIncrease;
if (!suspended) {
DisableAccelerationUpdates();
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->SuspendWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
@ -9730,6 +9754,8 @@ nsGlobalWindow::ResumeTimeouts(PRBool aThawChildren)
nsresult rv;
if (shouldResume) {
EnableAccelerationUpdates();
nsDOMThreadService* dts = nsDOMThreadService::get();
if (dts) {
dts->ResumeWorkersForGlobal(static_cast<nsIScriptGlobalObject*>(this));
@ -9847,13 +9873,8 @@ nsGlobalWindow::SetScriptTypeID(PRUint32 aScriptType)
void
nsGlobalWindow::SetHasOrientationEventListener()
{
nsCOMPtr<nsIAccelerometer> ac =
do_GetService(NS_ACCELEROMETER_CONTRACTID);
if (ac) {
mHasAcceleration = PR_TRUE;
ac->AddWindowListener(this);
}
mHasAcceleration = PR_TRUE;
EnableAccelerationUpdates();
}
NS_IMETHODIMP
@ -10323,8 +10344,8 @@ nsNavigator::SetDocShell(nsIDocShell *aDocShell)
// nsNavigator::nsIDOMNavigator
//*****************************************************************************
NS_IMETHODIMP
nsNavigator::GetUserAgent(nsAString& aUserAgent)
nsresult
NS_GetNavigatorUserAgent(nsAString& aUserAgent)
{
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
@ -10338,92 +10359,8 @@ nsNavigator::GetUserAgent(nsAString& aUserAgent)
return rv;
}
NS_IMETHODIMP
nsNavigator::GetAppCodeName(nsAString& aAppCodeName)
{
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString appName;
rv = service->GetAppName(appName);
CopyASCIItoUTF16(appName, aAppCodeName);
}
return rv;
}
NS_IMETHODIMP
nsNavigator::GetAppVersion(nsAString& aAppVersion)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
const nsAdoptingCString& override =
nsContentUtils::GetCharPref("general.appversion.override");
if (override) {
CopyUTF8toUTF16(override, aAppVersion);
return NS_OK;
}
}
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString str;
rv = service->GetAppVersion(str);
CopyASCIItoUTF16(str, aAppVersion);
if (NS_FAILED(rv))
return rv;
aAppVersion.AppendLiteral(" (");
rv = service->GetPlatform(str);
if (NS_FAILED(rv))
return rv;
AppendASCIItoUTF16(str, aAppVersion);
aAppVersion.Append(PRUnichar(')'));
}
return rv;
}
NS_IMETHODIMP
nsNavigator::GetAppName(nsAString& aAppName)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
const nsAdoptingCString& override =
nsContentUtils::GetCharPref("general.appname.override");
if (override) {
CopyUTF8toUTF16(override, aAppName);
return NS_OK;
}
}
aAppName.AssignLiteral("Netscape");
return NS_OK;
}
NS_IMETHODIMP
nsNavigator::GetLanguage(nsAString& aLanguage)
{
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString lang;
rv = service->GetLanguage(lang);
CopyASCIItoUTF16(lang, aLanguage);
}
return rv;
}
NS_IMETHODIMP
nsNavigator::GetPlatform(nsAString& aPlatform)
nsresult
NS_GetNavigatorPlatform(nsAString& aPlatform)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
const nsAdoptingCString& override =
@ -10466,6 +10403,113 @@ nsNavigator::GetPlatform(nsAString& aPlatform)
return rv;
}
nsresult
NS_GetNavigatorAppVersion(nsAString& aAppVersion)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
const nsAdoptingCString& override =
nsContentUtils::GetCharPref("general.appversion.override");
if (override) {
CopyUTF8toUTF16(override, aAppVersion);
return NS_OK;
}
}
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString str;
rv = service->GetAppVersion(str);
CopyASCIItoUTF16(str, aAppVersion);
if (NS_FAILED(rv))
return rv;
aAppVersion.AppendLiteral(" (");
rv = service->GetPlatform(str);
if (NS_FAILED(rv))
return rv;
AppendASCIItoUTF16(str, aAppVersion);
aAppVersion.Append(PRUnichar(')'));
}
return rv;
}
nsresult
NS_GetNavigatorAppName(nsAString& aAppName)
{
if (!nsContentUtils::IsCallerTrustedForRead()) {
const nsAdoptingCString& override =
nsContentUtils::GetCharPref("general.appname.override");
if (override) {
CopyUTF8toUTF16(override, aAppName);
return NS_OK;
}
}
aAppName.AssignLiteral("Netscape");
return NS_OK;
}
NS_IMETHODIMP
nsNavigator::GetUserAgent(nsAString& aUserAgent)
{
return NS_GetNavigatorUserAgent(aUserAgent);
}
NS_IMETHODIMP
nsNavigator::GetAppCodeName(nsAString& aAppCodeName)
{
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString appName;
rv = service->GetAppName(appName);
CopyASCIItoUTF16(appName, aAppCodeName);
}
return rv;
}
NS_IMETHODIMP
nsNavigator::GetAppVersion(nsAString& aAppVersion)
{
return NS_GetNavigatorAppVersion(aAppVersion);
}
NS_IMETHODIMP
nsNavigator::GetAppName(nsAString& aAppName)
{
return NS_GetNavigatorAppName(aAppName);
}
NS_IMETHODIMP
nsNavigator::GetLanguage(nsAString& aLanguage)
{
nsresult rv;
nsCOMPtr<nsIHttpProtocolHandler>
service(do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv));
if (NS_SUCCEEDED(rv)) {
nsCAutoString lang;
rv = service->GetLanguage(lang);
CopyASCIItoUTF16(lang, aLanguage);
}
return rv;
}
NS_IMETHODIMP
nsNavigator::GetPlatform(nsAString& aPlatform)
{
return NS_GetNavigatorPlatform(aPlatform);
}
NS_IMETHODIMP
nsNavigator::GetOscpu(nsAString& aOSCPU)

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

@ -574,6 +574,13 @@ public:
return sOuterWindowsById ? sOuterWindowsById->Get(aWindowID) : nsnull;
}
private:
// Enable updates for the accelerometer.
void EnableAccelerationUpdates();
// Disables updates for the accelerometer.
void DisableAccelerationUpdates();
protected:
// Object Management
virtual ~nsGlobalWindow();
@ -869,7 +876,7 @@ protected:
PRPackedBool mFocusByKeyOccurred : 1;
// Indicates whether this window is getting acceleration change events
PRPackedBool mHasAcceleration : 1;
PRPackedBool mHasAcceleration : 1;
// whether we've sent the destroy notification for our window id
PRPackedBool mNotifiedIDDestroyed : 1;
@ -1066,6 +1073,11 @@ protected:
nsIDocShell* mDocShell; // weak reference
};
nsresult NS_GetNavigatorUserAgent(nsAString& aUserAgent);
nsresult NS_GetNavigatorPlatform(nsAString& aPlatform);
nsresult NS_GetNavigatorAppVersion(nsAString& aAppVersion);
nsresult NS_GetNavigatorAppName(nsAString& aAppName);
class nsIURI;
//*****************************************************************************

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

@ -4004,26 +4004,24 @@ ReportAllJSExceptionsPrefChangedCallback(const char* aPrefName, void* aClosure)
static int
SetMemoryHighWaterMarkPrefChangedCallback(const char* aPrefName, void* aClosure)
{
PRInt32 highwatermark = nsContentUtils::GetIntPref(aPrefName, 32);
PRInt32 highwatermark = nsContentUtils::GetIntPref(aPrefName, 128);
if (highwatermark >= 32) {
/*
* There are two ways to allocate memory in SpiderMonkey. One is
* to use jsmalloc() and the other is to use GC-owned memory
* (e.g. js_NewGCThing()).
*
* In the browser, we don't cap the amount of GC-owned memory.
*/
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
128L * 1024L * 1024L);
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
0xffffffff);
} else {
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
highwatermark * 1024L * 1024L);
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
highwatermark * 1024L * 1024L);
}
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_MALLOC_BYTES,
highwatermark * 1024L * 1024L);
return 0;
}
static int
SetMemoryMaxPrefChangedCallback(const char* aPrefName, void* aClosure)
{
PRUint32 max = nsContentUtils::GetIntPref(aPrefName, -1);
if (max == -1UL)
max = 0xffffffff;
else
max = max * 1024L * 1024L;
JS_SetGCParameter(nsJSRuntime::sRuntime, JSGC_MAX_BYTES,
max);
return 0;
}
@ -4066,7 +4064,8 @@ static JSObject*
DOMReadStructuredClone(JSContext* cx,
JSStructuredCloneReader* reader,
uint32 tag,
uint32 data)
uint32 data,
void* closure)
{
// We don't currently support any extensions to structured cloning.
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
@ -4076,7 +4075,8 @@ DOMReadStructuredClone(JSContext* cx,
static JSBool
DOMWriteStructuredClone(JSContext* cx,
JSStructuredCloneWriter* writer,
JSObject* obj)
JSObject* obj,
void *closure)
{
// We don't currently support any extensions to structured cloning.
nsDOMClassInfo::ThrowJSException(cx, NS_ERROR_DOM_DATA_CLONE_ERR);
@ -4161,6 +4161,12 @@ nsJSRuntime::Init()
SetMemoryHighWaterMarkPrefChangedCallback("javascript.options.mem.high_water_mark",
nsnull);
nsContentUtils::RegisterPrefCallback("javascript.options.mem.max",
SetMemoryMaxPrefChangedCallback,
nsnull);
SetMemoryMaxPrefChangedCallback("javascript.options.mem.max",
nsnull);
nsContentUtils::RegisterPrefCallback("javascript.options.mem.gc_frequency",
SetMemoryGCFrequencyPrefChangedCallback,
nsnull);

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

@ -41,6 +41,7 @@
#include "mozilla/storage.h"
#include "nsComponentManagerUtils.h"
#include "nsContentUtils.h"
#include "nsProxyRelease.h"
#include "nsThreadUtils.h"
@ -76,6 +77,48 @@ private:
IDBTransaction* mTransaction;
};
// This inline is just so that we always clear aBuffers appropriately even if
// something fails.
inline
nsresult
ConvertCloneBuffersToArrayInternal(
JSContext* aCx,
nsTArray<JSAutoStructuredCloneBuffer>& aBuffers,
jsval* aResult)
{
JSObject* array = JS_NewArrayObject(aCx, 0, nsnull);
if (!array) {
NS_WARNING("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
if (!aBuffers.IsEmpty()) {
if (!JS_SetArrayLength(aCx, array, jsuint(aBuffers.Length()))) {
NS_WARNING("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
jsint count = jsint(aBuffers.Length());
for (jsint index = 0; index < count; index++) {
JSAutoStructuredCloneBuffer& buffer = aBuffers[index];
jsval val;
if (!buffer.read(&val, aCx)) {
NS_WARNING("Failed to decode!");
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
if (!JS_SetElement(aCx, array, index, &val)) {
NS_WARNING("Failed to set array element!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
}
*aResult = OBJECT_TO_JSVAL(array);
return NS_OK;
}
} // anonymous namespace
AsyncConnectionHelper::AsyncConnectionHelper(IDBDatabase* aDatabase,
@ -141,10 +184,6 @@ NS_IMETHODIMP
AsyncConnectionHelper::Run()
{
if (NS_IsMainThread()) {
if (mRequest) {
mRequest->SetDone();
}
if (mTransaction &&
mTransaction->IsAborted() &&
NS_SUCCEEDED(mResultCode)) {
@ -156,11 +195,15 @@ AsyncConnectionHelper::Run()
IDBTransaction* oldTransaction = gCurrentTransaction;
gCurrentTransaction = mTransaction;
if (mRequest) {
mRequest->SetDone(this);
}
// Call OnError if the database had an error or if the OnSuccess handler
// has an error.
if (NS_FAILED(mResultCode) ||
NS_FAILED((mResultCode = OnSuccess(mRequest)))) {
OnError(mRequest, mResultCode);
NS_FAILED((mResultCode = OnSuccess()))) {
OnError();
}
NS_ASSERTION(gCurrentTransaction == mTransaction, "Should be unchanged!");
@ -330,57 +373,28 @@ AsyncConnectionHelper::GetCurrentTransaction()
nsresult
AsyncConnectionHelper::Init()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return NS_OK;
}
nsresult
AsyncConnectionHelper::OnSuccess(nsIDOMEventTarget* aTarget)
AsyncConnectionHelper::OnSuccess()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIWritableVariant> variant =
do_CreateInstance(NS_VARIANT_CONTRACTID);
if (!variant) {
NS_ERROR("Couldn't create variant!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsresult rv = GetSuccessResult(variant);
if (NS_FAILED(rv)) {
return rv;
}
// Check to make sure we have a listener here before actually firing.
nsCOMPtr<nsPIDOMEventTarget> target(do_QueryInterface(aTarget));
if (target) {
nsIEventListenerManager* manager = target->GetListenerManager(PR_FALSE);
if (!manager ||
!manager->HasListenersFor(NS_LITERAL_STRING(SUCCESS_EVT_STR))) {
// No listeners here, skip creating and dispatching the event.
return NS_OK;
}
}
if (NS_FAILED(variant->SetWritable(PR_FALSE))) {
NS_ERROR("Failed to make variant readonly!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsCOMPtr<nsIDOMEvent> event =
IDBSuccessEvent::Create(mRequest, variant, mTransaction);
nsRefPtr<nsDOMEvent> event =
CreateGenericEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR));
if (!event) {
NS_ERROR("Failed to create event!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
PRBool dummy;
rv = aTarget->DispatchEvent(event, &dummy);
nsresult rv = mRequest->DispatchEvent(event, &dummy);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<nsIPrivateDOMEvent> privateEvent = do_QueryInterface(event);
NS_ASSERTION(privateEvent, "This should always QI properly!");
nsEvent* internalEvent = privateEvent->GetInternalNSEvent();
nsEvent* internalEvent = event->GetInternalNSEvent();
NS_ASSERTION(internalEvent, "This should never be null!");
NS_ASSERTION(!mTransaction ||
@ -399,20 +413,20 @@ AsyncConnectionHelper::OnSuccess(nsIDOMEventTarget* aTarget)
}
void
AsyncConnectionHelper::OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode)
AsyncConnectionHelper::OnError()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
// Make an error event and fire it at the target.
nsCOMPtr<nsIDOMEvent> event(IDBErrorEvent::Create(mRequest, aErrorCode));
nsRefPtr<nsDOMEvent> event =
CreateGenericEvent(NS_LITERAL_STRING(ERROR_EVT_STR), PR_TRUE);
if (!event) {
NS_ERROR("Failed to create event!");
return;
}
PRBool doDefault;
nsresult rv = aTarget->DispatchEvent(event, &doDefault);
nsresult rv = mRequest->DispatchEvent(event, &doDefault);
if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(!mTransaction ||
mTransaction->IsOpen() ||
@ -432,13 +446,12 @@ AsyncConnectionHelper::OnError(nsIDOMEventTarget* aTarget,
}
nsresult
AsyncConnectionHelper::GetSuccessResult(nsIWritableVariant* aResult)
AsyncConnectionHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = aResult->SetAsVoid();
NS_ENSURE_SUCCESS(rv, rv);
*aVal = JSVAL_VOID;
return NS_OK;
}
@ -452,6 +465,69 @@ AsyncConnectionHelper::ReleaseMainThreadObjects()
mRequest = nsnull;
}
// static
nsresult
AsyncConnectionHelper::WrapNative(JSContext* aCx,
nsISupports* aNative,
jsval* aResult)
{
JSObject* global = JS_GetGlobalForObject(aCx, JS_GetScopeChain(aCx));
NS_ENSURE_TRUE(global, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsresult rv =
nsContentUtils::WrapNative(aCx, global,
static_cast<nsPIDOMEventTarget*>(aNative),
aResult);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return NS_OK;
}
// static
nsresult
AsyncConnectionHelper::ConvertCloneBufferToJSVal(
JSContext* aCx,
JSAutoStructuredCloneBuffer& aBuffer,
jsval* aResult)
{
JSAutoRequest ar(aCx);
if (aBuffer.data()) {
JSBool ok = aBuffer.read(aResult, aCx);
aBuffer.clear(aCx);
if (!ok) {
NS_ERROR("Failed to decode!");
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
}
else {
*aResult = JSVAL_VOID;
}
return NS_OK;
}
// static
nsresult
AsyncConnectionHelper::ConvertCloneBuffersToArray(
JSContext* aCx,
nsTArray<JSAutoStructuredCloneBuffer>& aBuffers,
jsval* aResult)
{
JSAutoRequest ar(aCx);
nsresult rv = ConvertCloneBuffersToArrayInternal(aCx, aBuffers, aResult);
for (PRUint32 index = 0; index < aBuffers.Length(); index++) {
aBuffers[index].clear(aCx);
}
aBuffers.Clear();
return rv;
}
NS_IMETHODIMP_(nsrefcnt)
TransactionPoolEventTarget::AddRef()
{

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

@ -48,7 +48,6 @@
#include "mozIStorageProgressHandler.h"
#include "nsIRunnable.h"
#include "nsIThread.h"
#include "nsIVariant.h"
#include "mozilla/TimeStamp.h"
@ -70,6 +69,8 @@ class IDBTransaction;
class AsyncConnectionHelper : public nsIRunnable,
public mozIStorageProgressHandler
{
friend class IDBRequest;
public:
NS_DECL_ISUPPORTS
NS_DECL_NSIRUNNABLE
@ -93,6 +94,11 @@ public:
return mRequest ? mRequest->Source() : nsnull;
}
nsresult GetResultCode()
{
return mResultCode;
}
protected:
AsyncConnectionHelper(IDBDatabase* aDatabase,
IDBRequest* aRequest);
@ -113,42 +119,36 @@ protected:
/**
* This is called on the main thread after Dispatch is called but before the
* runnable is actually dispatched to the database thread. Allows the subclass
* to initialize itself. The default implementation does nothing and returns
* NS_OK.
* to initialize itself.
*/
virtual nsresult Init();
/**
* This callback is run on the database thread. It should return a valid error
* code from nsIIDBDatabaseError or one of the two special values above.
* This callback is run on the database thread.
*/
virtual nsresult DoDatabaseWork(mozIStorageConnection* aConnection) = 0;
/**
* This callback is run on the main thread if the DoDatabaseWork returned OK.
* The default implementation constructs an IDBSuccessEvent with its result
* property set to the value returned by GetSuccessResult. The event is then
* fired at the target. Returning anything other than OK from the OnSuccess
* This callback is run on the main thread if DoDatabaseWork returned NS_OK.
* The default implementation fires a "success" DOM event with its target set
* to the request. Returning anything other than NS_OK from the OnSuccess
* callback will trigger the OnError callback.
*/
virtual nsresult OnSuccess(nsIDOMEventTarget* aTarget);
virtual nsresult OnSuccess();
/**
* This callback is run on the main thread if DoDatabaseWork returned an error
* code. The default implementation constructs an IDBErrorEvent for the error
* code and fires it at the target.
* This callback is run on the main thread if DoDatabaseWork or OnSuccess
* returned an error code. The default implementation fires an "error" DOM
* event with its target set to the request.
*/
virtual void OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode);
virtual void OnError();
/**
* This function is called from the default implementation of OnSuccess. A
* valid nsIWritableVariant is passed into the function which can be modified
* by the subclass. The default implementation returns an nsIVariant that is
* set to nsIDataType::VTYPE_EMPTY. Returning anything other than OK from the
* GetSuccessResult function will trigger the OnError callback.
* This function is called by the request on the main thread when script
* accesses the result property of the request.
*/
virtual nsresult GetSuccessResult(nsIWritableVariant* aVariant);
virtual nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
/**
* Gives the subclass a chance to release any objects that must be released
@ -157,6 +157,30 @@ protected:
*/
virtual void ReleaseMainThreadObjects();
/**
* Helper to wrap a native into a jsval. Uses the global object of the given
* context.
*/
static nsresult WrapNative(JSContext* aCx,
nsISupports* aNative,
jsval* aResult);
/**
* Helper to decode a clone buffer to a jsval.
*/
static nsresult ConvertCloneBufferToJSVal(
JSContext* aCx,
JSAutoStructuredCloneBuffer& aBuffer,
jsval* aResult);
/**
* Helper to make a JS array object out of an array of clone buffers.
*/
static nsresult ConvertCloneBuffersToArray(
JSContext* aCx,
nsTArray<JSAutoStructuredCloneBuffer>& aBuffers,
jsval* aResult);
protected:
nsRefPtr<IDBDatabase> mDatabase;
nsRefPtr<IDBTransaction> mTransaction;

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

@ -85,7 +85,9 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult OnSuccess();
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -273,7 +275,8 @@ IDBCursor::IDBCursor()
mCachedValue(JSVAL_VOID),
mHaveCachedValue(false),
mValueRooted(false),
mContinueCalled(false)
mContinueCalled(false),
mHaveValue(true)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
@ -308,6 +311,7 @@ NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(IDBCursor)
tmp->mCachedValue = JSVAL_VOID;
tmp->mHaveCachedValue = false;
tmp->mValueRooted = false;
tmp->mHaveValue = false;
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
@ -366,19 +370,21 @@ IDBCursor::GetKey(nsIVariant** aKey)
do_CreateInstance(NS_VARIANT_CONTRACTID, &rv);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
NS_ASSERTION(!mKey.IsUnset(), "Bad key!");
NS_ASSERTION(!mKey.IsUnset() || !mHaveValue, "Bad key!");
if (mKey.IsString()) {
if (!mHaveValue) {
rv = variant->SetAsVoid();
}
else if (mKey.IsString()) {
rv = variant->SetAsAString(mKey.StringValue());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else if (mKey.IsInt()) {
rv = variant->SetAsInt64(mKey.IntValue());
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
}
else {
NS_NOTREACHED("Huh?!");
}
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
rv = variant->SetWritable(PR_FALSE);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -400,6 +406,11 @@ IDBCursor::GetValue(JSContext* aCx,
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mHaveValue) {
*aValue = JSVAL_VOID;
return NS_OK;
}
nsresult rv;
if (mType == INDEXKEY) {
@ -442,7 +453,7 @@ IDBCursor::Continue(const jsval &aKey,
return NS_ERROR_DOM_INDEXEDDB_TRANSACTION_INACTIVE_ERR;
}
if (mContinueCalled) {
if (!mHaveValue || mContinueCalled) {
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
@ -525,7 +536,7 @@ IDBCursor::Update(const jsval& aValue,
return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
}
if (mType == INDEXKEY) {
if (!mHaveValue || mType == INDEXKEY) {
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
@ -588,7 +599,7 @@ IDBCursor::Delete(JSContext* aCx,
return NS_ERROR_DOM_INDEXEDDB_READ_ONLY_ERR;
}
if (mType == INDEXKEY) {
if (!mHaveValue || mType == INDEXKEY) {
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
@ -644,14 +655,38 @@ ContinueHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
ContinueHelper::GetSuccessResult(nsIWritableVariant* aResult)
ContinueHelper::OnSuccess()
{
nsresult rv;
// Remove cached stuff from last time.
mCursor->mCachedKey = nsnull;
mCursor->mCachedObjectKey = nsnull;
mCursor->mCachedValue = JSVAL_VOID;
mCursor->mHaveCachedValue = false;
mCursor->mContinueCalled = false;
if (mKey.IsUnset()) {
rv = aResult->SetAsEmpty();
NS_ENSURE_SUCCESS(rv, rv);
mCursor->mHaveValue = false;
}
else {
// Set new values.
mCursor->mKey = mKey;
mCursor->mObjectKey = mObjectKey;
mCursor->mCloneBuffer.clear();
mCursor->mCloneBuffer.swap(mCloneBuffer);
mCursor->mContinueToKey = Key::UNSETKEY;
}
// We want an event, with a result, etc. Call the base class method.
return AsyncConnectionHelper::OnSuccess();
}
nsresult
ContinueHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (mKey.IsUnset()) {
NS_ASSERTION(!mCursor->mHaveValue, "Should have unset this!");
*aVal = JSVAL_VOID;
return NS_OK;
}
@ -661,24 +696,8 @@ ContinueHelper::GetSuccessResult(nsIWritableVariant* aResult)
}
#endif
// Remove cached stuff from last time.
mCursor->mCachedKey = nsnull;
mCursor->mCachedObjectKey = nsnull;
mCursor->mCachedValue = JSVAL_VOID;
mCursor->mHaveCachedValue = false;
mCursor->mContinueCalled = false;
// And set new values.
mCursor->mKey = mKey;
mCursor->mObjectKey = mObjectKey;
mCursor->mCloneBuffer.clear();
mCursor->mCloneBuffer.swap(mCloneBuffer);
mCursor->mContinueToKey = Key::UNSETKEY;
rv = aResult->SetAsISupports(mCursor);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
NS_ASSERTION(mCursor->mHaveValue, "This should still be set to true!");
return WrapNative(aCx, mCursor, aVal);
}
nsresult

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

@ -149,6 +149,7 @@ protected:
nsCOMPtr<nsIScriptContext> mScriptContext;
nsCOMPtr<nsPIDOMWindow> mOwner;
// Not cycle-collected, these are guaranteed to be primitives!
nsCOMPtr<nsIVariant> mCachedKey;
nsCOMPtr<nsIVariant> mCachedObjectKey;
@ -157,6 +158,7 @@ protected:
nsCString mContinueQuery;
nsCString mContinueToQuery;
// This one is cycle-collected!
jsval mCachedValue;
Key mRangeKey;
@ -169,6 +171,7 @@ protected:
bool mHaveCachedValue;
bool mValueRooted;
bool mContinueCalled;
bool mHaveValue;
};
END_INDEXEDDB_NAMESPACE

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

@ -82,7 +82,9 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult OnSuccess();
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
private:
// In-params
@ -98,8 +100,16 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
void OnError(nsIDOMEventTarget* aTarget, nsresult aErrorCode);
nsresult OnSuccess()
{
return NS_OK;
}
void OnError()
{
NS_ASSERTION(mTransaction->IsAborted(), "How else can this fail?!");
}
void ReleaseMainThreadObjects()
{
@ -120,8 +130,16 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
void OnError(nsIDOMEventTarget* aTarget, nsresult aErrorCode);
nsresult OnSuccess()
{
return NS_OK;
}
void OnError()
{
NS_ASSERTION(mTransaction->IsAborted(), "How else can this fail?!");
}
private:
// In-params.
@ -901,15 +919,20 @@ IDBDatabase::PostHandleEvent(nsEventChainPostVisitor& aVisitor)
NS_ENSURE_TRUE(aVisitor.mDOMEvent, NS_ERROR_UNEXPECTED);
if (aVisitor.mEventStatus != nsEventStatus_eConsumeNoDefault) {
nsCOMPtr<nsIDOMEvent> duplicateEvent =
IDBErrorEvent::MaybeDuplicate(aVisitor.mDOMEvent);
nsString type;
nsresult rv = aVisitor.mDOMEvent->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
if (type.EqualsLiteral(ERROR_EVT_STR)) {
nsRefPtr<nsDOMEvent> duplicateEvent = CreateGenericEvent(type);
NS_ENSURE_STATE(duplicateEvent);
if (duplicateEvent) {
nsCOMPtr<nsIDOMEventTarget> target(do_QueryInterface(mOwner));
NS_ASSERTION(target, "How can this happen?!");
PRBool dummy;
target->DispatchEvent(duplicateEvent, &dummy);
rv = target->DispatchEvent(duplicateEvent, &dummy);
NS_ENSURE_SUCCESS(rv, rv);
}
}
@ -939,7 +962,7 @@ SetVersionHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
SetVersionHelper::GetSuccessResult(nsIWritableVariant* aResult)
SetVersionHelper::OnSuccess()
{
DatabaseInfo* info;
if (!DatabaseInfo::Get(mDatabase->Id(), &info)) {
@ -948,8 +971,15 @@ SetVersionHelper::GetSuccessResult(nsIWritableVariant* aResult)
}
info->version = mVersion;
aResult->SetAsISupports(static_cast<nsPIDOMEventTarget*>(mTransaction));
return NS_OK;
// We want an event, with a result, etc. Call the base class method.
return AsyncConnectionHelper::OnSuccess();
}
nsresult
SetVersionHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
return WrapNative(aCx, static_cast<nsPIDOMEventTarget*>(mTransaction), aVal);
}
nsresult
@ -985,20 +1015,6 @@ CreateObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
return NS_OK;
}
nsresult
CreateObjectStoreHelper::OnSuccess(nsIDOMEventTarget* aTarget)
{
NS_ASSERTION(!aTarget, "Huh?!");
return NS_OK;
}
void
CreateObjectStoreHelper::OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode)
{
NS_ASSERTION(!aTarget, "Huh?!");
}
nsresult
DeleteObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{
@ -1019,18 +1035,3 @@ DeleteObjectStoreHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
return NS_OK;
}
nsresult
DeleteObjectStoreHelper::OnSuccess(nsIDOMEventTarget* aTarget)
{
NS_ASSERTION(!aTarget, "Huh?!");
return NS_OK;
}
void
DeleteObjectStoreHelper::OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode)
{
NS_NOTREACHED("Removing an object store should never fail here!");
}

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

@ -56,16 +56,6 @@ USING_INDEXEDDB_NAMESPACE
namespace {
template <class T>
inline
already_AddRefed<nsIDOMEvent>
ForgetEvent(nsRefPtr<T>& aRefPtr)
{
T* result;
aRefPtr.forget(&result);
return static_cast<nsIDOMEvent*>(static_cast<nsDOMEvent*>(result));
}
class EventFiringRunnable : public nsRunnable
{
public:
@ -86,17 +76,47 @@ private:
} // anonymous namespace
// static
already_AddRefed<nsIDOMEvent>
IDBEvent::CreateGenericEvent(const nsAString& aType)
already_AddRefed<nsDOMEvent>
mozilla::dom::indexedDB::CreateGenericEvent(const nsAString& aType,
PRBool aBubblesAndCancelable)
{
nsRefPtr<nsDOMEvent> event(new nsDOMEvent(nsnull, nsnull));
nsresult rv = event->InitEvent(aType, aBubblesAndCancelable,
aBubblesAndCancelable);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
return event.forget();
}
already_AddRefed<nsIRunnable>
mozilla::dom::indexedDB::CreateGenericEventRunnable(const nsAString& aType,
nsIDOMEventTarget* aTarget)
{
nsCOMPtr<nsIDOMEvent> event(CreateGenericEvent(aType));
NS_ENSURE_TRUE(event, nsnull);
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
return runnable.forget();
}
// static
already_AddRefed<nsIDOMEvent>
IDBVersionChangeEvent::CreateInternal(const nsAString& aType,
const nsAString& aVersion)
{
nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent());
nsresult rv = event->InitEvent(aType, PR_FALSE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
event->mVersion = aVersion;
nsDOMEvent* result;
event.forget(&result);
return result;
@ -104,520 +124,24 @@ IDBEvent::CreateGenericEvent(const nsAString& aType)
// static
already_AddRefed<nsIRunnable>
IDBEvent::CreateGenericEventRunnable(const nsAString& aType,
nsIDOMEventTarget* aTarget)
{
nsCOMPtr<nsIDOMEvent> event(IDBEvent::CreateGenericEvent(aType));
NS_ENSURE_TRUE(event, nsnull);
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
return runnable.forget();
}
NS_IMPL_ADDREF_INHERITED(IDBEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(IDBEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBEvent, nsDOMEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBEvent)
NS_INTERFACE_MAP_ENTRY(nsIIDBEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
NS_IMETHODIMP
IDBEvent::GetSource(nsISupports** aSource)
{
nsCOMPtr<nsISupports> source(mSource);
source.forget(aSource);
return NS_OK;
}
// static
already_AddRefed<nsIDOMEvent>
IDBErrorEvent::Create(IDBRequest* aRequest,
nsresult aResult)
{
NS_ASSERTION(NS_FAILED(aResult), "Not a failure code!");
NS_ASSERTION(NS_ERROR_GET_MODULE(aResult) == NS_ERROR_MODULE_DOM_INDEXEDDB,
"Not an IndexedDB error code!");
const char* name = nsnull;
const char* message = nsnull;
if (NS_FAILED(NS_GetNameAndMessageForDOMNSResult(aResult, &name, &message))) {
NS_ERROR("Need a name and message for this code!");
}
nsRefPtr<IDBErrorEvent> event(new IDBErrorEvent());
event->mSource = aRequest->Source();
event->mCode = NS_ERROR_GET_CODE(aResult);
event->mMessage.AssignASCII(message);
nsresult rv = event->InitEvent(NS_LITERAL_STRING(ERROR_EVT_STR), PR_TRUE,
PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
return ForgetEvent(event);
}
// static
already_AddRefed<nsIRunnable>
IDBErrorEvent::CreateRunnable(IDBRequest* aRequest,
nsresult aResult)
{
nsCOMPtr<nsIDOMEvent> event(Create(aRequest, aResult));
NS_ENSURE_TRUE(event, nsnull);
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aRequest, event));
return runnable.forget();
}
// static
already_AddRefed<nsIDOMEvent>
IDBErrorEvent::MaybeDuplicate(nsIDOMEvent* aOther)
{
NS_ASSERTION(aOther, "Null pointer!");
nsCOMPtr<nsIDOMNSEvent> domNSEvent(do_QueryInterface(aOther));
nsCOMPtr<nsIIDBErrorEvent> errorEvent(do_QueryInterface(aOther));
if (!domNSEvent || !errorEvent) {
return nsnull;
}
PRBool isTrusted;
nsresult rv = domNSEvent->GetIsTrusted(&isTrusted);
NS_ENSURE_SUCCESS(rv, nsnull);
if (!isTrusted) {
return nsnull;
}
nsString type;
rv = errorEvent->GetType(type);
NS_ENSURE_SUCCESS(rv, nsnull);
PRBool canBubble;
rv = errorEvent->GetBubbles(&canBubble);
NS_ENSURE_SUCCESS(rv, nsnull);
nsCOMPtr<nsISupports> source;
rv = errorEvent->GetSource(getter_AddRefs(source));
NS_ENSURE_SUCCESS(rv, nsnull);
PRUint16 code;
rv = errorEvent->GetCode(&code);
NS_ENSURE_SUCCESS(rv, nsnull);
nsString message;
rv = errorEvent->GetMessage(message);
NS_ENSURE_SUCCESS(rv, nsnull);
nsRefPtr<IDBErrorEvent> event(new IDBErrorEvent());
event->mSource = source;
event->mCode = code;
event->mMessage = message;
rv = event->InitEvent(type, canBubble, PR_FALSE);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
return ForgetEvent(event);
}
NS_IMPL_ADDREF_INHERITED(IDBErrorEvent, IDBEvent)
NS_IMPL_RELEASE_INHERITED(IDBErrorEvent, IDBEvent)
NS_INTERFACE_MAP_BEGIN(IDBErrorEvent)
NS_INTERFACE_MAP_ENTRY(nsIIDBErrorEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBErrorEvent)
NS_INTERFACE_MAP_END_INHERITING(IDBEvent)
DOMCI_DATA(IDBErrorEvent, IDBErrorEvent)
NS_IMETHODIMP
IDBErrorEvent::GetCode(PRUint16* aCode)
{
*aCode = mCode;
return NS_OK;
}
NS_IMETHODIMP
IDBErrorEvent::GetMessage(nsAString& aMessage)
{
aMessage.Assign(mMessage);
return NS_OK;
}
// static
already_AddRefed<nsIDOMEvent>
IDBSuccessEvent::Create(IDBRequest* aRequest,
nsIVariant* aResult,
nsIIDBTransaction* aTransaction)
{
nsRefPtr<IDBSuccessEvent> event(new IDBSuccessEvent());
event->mSource = aRequest->Source();
event->mResult = aResult;
event->mTransaction = aTransaction;
nsresult rv = event->InitEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR), PR_FALSE,
PR_FALSE);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
return ForgetEvent(event);
}
// static
already_AddRefed<nsIRunnable>
IDBSuccessEvent::CreateRunnable(IDBRequest* aRequest,
nsIVariant* aResult,
nsIIDBTransaction* aTransaction)
{
nsCOMPtr<nsIDOMEvent> event(Create(aRequest, aResult, aTransaction));
NS_ENSURE_TRUE(event, nsnull);
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aRequest, event));
return runnable.forget();
}
NS_IMPL_ADDREF_INHERITED(IDBSuccessEvent, IDBEvent)
NS_IMPL_RELEASE_INHERITED(IDBSuccessEvent, IDBEvent)
NS_IMPL_CYCLE_COLLECTION_CLASS(IDBSuccessEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBSuccessEvent, IDBEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mResult)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mTransaction)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBSuccessEvent, IDBEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBSuccessEvent)
NS_INTERFACE_MAP_ENTRY_CONDITIONAL(nsIIDBTransactionEvent, mTransaction)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO_CONDITIONAL(IDBTransactionEvent,
mTransaction)
NS_INTERFACE_MAP_ENTRY(nsIIDBSuccessEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBSuccessEvent)
NS_INTERFACE_MAP_END_INHERITING(IDBEvent)
DOMCI_DATA(IDBSuccessEvent, IDBSuccessEvent)
DOMCI_DATA(IDBTransactionEvent, IDBSuccessEvent)
NS_IMETHODIMP
IDBSuccessEvent::GetResult(JSContext* aCx,
jsval* aResult)
{
if (!mResult) {
*aResult = JSVAL_VOID;
return NS_OK;
}
nsIXPConnect* xpc = nsContentUtils::XPConnect();
NS_ENSURE_TRUE(xpc, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
JSAutoRequest ar(aCx);
JSObject* scope = JS_GetGlobalObject(aCx);
NS_ENSURE_TRUE(scope, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsresult rv = xpc->VariantToJS(aCx, scope, mResult, aResult);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
return NS_OK;
}
NS_IMETHODIMP
IDBSuccessEvent::GetTransaction(nsIIDBTransaction** aTransaction)
{
nsCOMPtr<nsIIDBTransaction> transaction(mTransaction);
transaction.forget(aTransaction);
return NS_OK;
}
GetSuccessEvent::~GetSuccessEvent()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (mValueRooted) {
NS_DROP_JS_OBJECTS(this, GetSuccessEvent);
}
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffer);
}
nsresult
GetSuccessEvent::Init(IDBRequest* aRequest,
IDBTransaction* aTransaction)
{
mSource = aRequest->Source();
mTransaction = aTransaction;
nsresult rv = InitEvent(NS_LITERAL_STRING(SUCCESS_EVT_STR), PR_FALSE,
PR_FALSE);
NS_ENSURE_SUCCESS(rv, rv);
rv = SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
NS_IMETHODIMP
GetSuccessEvent::GetResult(JSContext* aCx,
jsval* aResult)
{
if (!mValueRooted) {
RootCachedValue();
if (mCloneBuffer.data()) {
JSAutoRequest ar(aCx);
if (!mCloneBuffer.read(&mCachedValue, aCx)) {
mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to decode!");
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
mCloneBuffer.clear();
}
else {
NS_ASSERTION(JSVAL_IS_VOID(mCachedValue), "Should be undefined!");
}
}
*aResult = mCachedValue;
return NS_OK;
}
void
GetSuccessEvent::RootCachedValue()
{
mValueRooted = PR_TRUE;
NS_HOLD_JS_OBJECTS(this, GetSuccessEvent);
}
NS_IMPL_ADDREF_INHERITED(GetSuccessEvent, IDBSuccessEvent)
NS_IMPL_RELEASE_INHERITED(GetSuccessEvent, IDBSuccessEvent)
NS_IMPL_CYCLE_COLLECTION_CLASS(GetSuccessEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(GetSuccessEvent,
IDBSuccessEvent)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(GetSuccessEvent)
if (tmp->mValueRooted) {
NS_DROP_JS_OBJECTS(tmp, GetSuccessEvent);
tmp->mCachedValue = JSVAL_VOID;
tmp->mValueRooted = PR_FALSE;
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(GetSuccessEvent,
IDBSuccessEvent)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mResult)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mTransaction)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(GetSuccessEvent)
if (JSVAL_IS_GCTHING(tmp->mCachedValue)) {
void *gcThing = JSVAL_TO_GCTHING(tmp->mCachedValue);
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing)
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(GetSuccessEvent)
NS_INTERFACE_MAP_END_INHERITING(IDBSuccessEvent)
GetAllSuccessEvent::~GetAllSuccessEvent()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
for (PRUint32 index = 0; index < mCloneBuffers.Length(); index++) {
IDBObjectStore::ClearStructuredCloneBuffer(mCloneBuffers[index]);
}
}
NS_IMETHODIMP
GetAllSuccessEvent::GetResult(JSContext* aCx,
jsval* aResult)
{
if (!mValueRooted) {
// Swap into a stack array so that we don't hang on to the buffers if
// something fails.
nsTArray<JSAutoStructuredCloneBuffer> cloneBuffers;
if (!mCloneBuffers.SwapElements(cloneBuffers)) {
NS_ERROR("Failed to swap elements!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
JSAutoRequest ar(aCx);
JSObject* array = JS_NewArrayObject(aCx, 0, NULL);
if (!array) {
NS_ERROR("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
RootCachedValue();
mCachedValue = OBJECT_TO_JSVAL(array);
if (!cloneBuffers.IsEmpty()) {
if (!JS_SetArrayLength(aCx, array, jsuint(cloneBuffers.Length()))) {
mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
jsint count = jsint(cloneBuffers.Length());
for (jsint index = 0; index < count; index++) {
JSAutoStructuredCloneBuffer& buffer = cloneBuffers[index];
jsval val;
if (!buffer.read(&val, aCx)) {
mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to decode!");
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
buffer.clear(aCx);
if (!JS_SetElement(aCx, array, index, &val)) {
mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to set array element!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
}
}
*aResult = mCachedValue;
return NS_OK;
}
NS_IMETHODIMP
GetAllKeySuccessEvent::GetResult(JSContext* aCx,
jsval* aResult)
{
if (!mValueRooted) {
// Swap into a stack array so that we don't hang on to the strings if
// something fails.
nsTArray<Key> keys;
if (!mKeys.SwapElements(keys)) {
NS_ERROR("Failed to swap elements!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
JSAutoRequest ar(aCx);
JSObject* array = JS_NewArrayObject(aCx, 0, NULL);
if (!array) {
NS_ERROR("Failed to make array!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
RootCachedValue();
mCachedValue = OBJECT_TO_JSVAL(array);
if (!keys.IsEmpty()) {
if (!JS_SetArrayLength(aCx, array, jsuint(keys.Length()))) {
mCachedValue = JSVAL_VOID;
NS_ERROR("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
js::AutoValueRooter value(aCx);
jsint count = jsint(keys.Length());
for (jsint index = 0; index < count; index++) {
const Key& key = keys[index];
NS_ASSERTION(!key.IsUnset(), "Bad key!");
nsresult rv = IDBObjectStore::GetJSValFromKey(key, aCx,
value.jsval_addr());
if (NS_FAILED(rv)) {
mCachedValue = JSVAL_VOID;
NS_WARNING("Failed to get jsval for key!");
return rv;
}
if (!JS_SetElement(aCx, array, index, value.jsval_addr())) {
mCachedValue = JSVAL_VOID;
NS_WARNING("Failed to set array element!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
}
}
}
*aResult = mCachedValue;
return NS_OK;
}
// static
already_AddRefed<nsIDOMEvent>
IDBVersionChangeEvent::CreateInternal(nsISupports* aSource,
const nsAString& aType,
const nsAString& aVersion)
{
nsRefPtr<IDBVersionChangeEvent> event(new IDBVersionChangeEvent());
event->mSource = aSource;
event->mVersion = aVersion;
nsresult rv = event->InitEvent(aType, PR_FALSE, PR_FALSE);
NS_ENSURE_SUCCESS(rv, nsnull);
rv = event->SetTrusted(PR_TRUE);
NS_ENSURE_SUCCESS(rv, nsnull);
return ForgetEvent(event);
}
// static
already_AddRefed<nsIRunnable>
IDBVersionChangeEvent::CreateRunnableInternal(nsISupports* aSource,
const nsAString& aType,
IDBVersionChangeEvent::CreateRunnableInternal(const nsAString& aType,
const nsAString& aVersion,
nsIDOMEventTarget* aTarget)
{
nsCOMPtr<nsIDOMEvent> event = CreateInternal(aSource, aType, aVersion);
nsCOMPtr<nsIDOMEvent> event = CreateInternal(aType, aVersion);
NS_ENSURE_TRUE(event, nsnull);
nsCOMPtr<nsIRunnable> runnable(new EventFiringRunnable(aTarget, event));
return runnable.forget();
}
NS_IMPL_ADDREF_INHERITED(IDBVersionChangeEvent, IDBEvent)
NS_IMPL_RELEASE_INHERITED(IDBVersionChangeEvent, IDBEvent)
NS_IMPL_ADDREF_INHERITED(IDBVersionChangeEvent, nsDOMEvent)
NS_IMPL_RELEASE_INHERITED(IDBVersionChangeEvent, nsDOMEvent)
NS_INTERFACE_MAP_BEGIN(IDBVersionChangeEvent)
NS_INTERFACE_MAP_ENTRY(nsIIDBVersionChangeEvent)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBVersionChangeEvent)
NS_INTERFACE_MAP_END_INHERITING(IDBEvent)
NS_INTERFACE_MAP_END_INHERITING(nsDOMEvent)
DOMCI_DATA(IDBVersionChangeEvent, IDBVersionChangeEvent)

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

@ -42,14 +42,8 @@
#include "mozilla/dom/indexedDB/IndexedDatabase.h"
#include "nsIIDBEvent.h"
#include "nsIIDBErrorEvent.h"
#include "nsIIDBSuccessEvent.h"
#include "nsIIDBTransactionEvent.h"
#include "nsIIDBTransaction.h"
#include "nsIIDBVersionChangeEvent.h"
#include "nsIRunnable.h"
#include "nsIVariant.h"
#include "nsDOMEvent.h"
@ -65,215 +59,60 @@
BEGIN_INDEXEDDB_NAMESPACE
class IDBRequest;
class IDBTransaction;
already_AddRefed<nsDOMEvent>
CreateGenericEvent(const nsAString& aType,
PRBool aBubblesAndCancelable = PR_FALSE);
class IDBEvent : public nsDOMEvent,
public nsIIDBEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIIDBEVENT
NS_FORWARD_TO_NSDOMEVENT
already_AddRefed<nsIRunnable>
CreateGenericEventRunnable(const nsAString& aType,
nsIDOMEventTarget* aTarget);
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBEvent, nsDOMEvent)
static already_AddRefed<nsIDOMEvent>
CreateGenericEvent(const nsAString& aType);
static already_AddRefed<nsIRunnable>
CreateGenericEventRunnable(const nsAString& aType,
nsIDOMEventTarget* aTarget);
protected:
IDBEvent() : nsDOMEvent(nsnull, nsnull) { }
virtual ~IDBEvent() { }
nsCOMPtr<nsISupports> mSource;
};
class IDBErrorEvent : public IDBEvent,
public nsIIDBErrorEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIIDBERROREVENT
NS_FORWARD_NSIDOMEVENT(IDBEvent::)
NS_FORWARD_NSIIDBEVENT(IDBEvent::)
static already_AddRefed<nsIDOMEvent>
Create(IDBRequest* aRequest,
nsresult aResult);
static already_AddRefed<nsIRunnable>
CreateRunnable(IDBRequest* aRequest,
nsresult aResult);
static already_AddRefed<nsIDOMEvent>
MaybeDuplicate(nsIDOMEvent* aOther);
protected:
IDBErrorEvent() { }
PRUint16 mCode;
nsString mMessage;
};
class IDBSuccessEvent : public IDBEvent,
public nsIIDBTransactionEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIIDBSUCCESSEVENT
NS_DECL_NSIIDBTRANSACTIONEVENT
NS_FORWARD_NSIDOMEVENT(IDBEvent::)
NS_FORWARD_NSIIDBEVENT(IDBEvent::)
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBSuccessEvent, IDBEvent)
static already_AddRefed<nsIDOMEvent>
Create(IDBRequest* aRequest,
nsIVariant* aResult,
nsIIDBTransaction* aTransaction);
static already_AddRefed<nsIRunnable>
CreateRunnable(IDBRequest* aRequest,
nsIVariant* aResult,
nsIIDBTransaction* aTransaction);
protected:
IDBSuccessEvent() { }
nsCOMPtr<nsIVariant> mResult;
nsCOMPtr<nsIIDBTransaction> mTransaction;
};
class GetSuccessEvent : public IDBSuccessEvent
{
public:
GetSuccessEvent(JSAutoStructuredCloneBuffer& aCloneBuffer)
: mCachedValue(JSVAL_VOID),
mValueRooted(PR_FALSE)
{
mCloneBuffer.swap(aCloneBuffer);
}
GetSuccessEvent()
: mCachedValue(JSVAL_VOID),
mValueRooted(PR_FALSE)
{ }
~GetSuccessEvent();
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(GetSuccessEvent,
IDBSuccessEvent)
NS_IMETHOD GetResult(JSContext* aCx,
jsval* aResult);
nsresult Init(IDBRequest* aRequest,
IDBTransaction* aTransaction);
private:
JSAutoStructuredCloneBuffer mCloneBuffer;
protected:
void RootCachedValue();
jsval mCachedValue;
JSRuntime* mJSRuntime;
PRBool mValueRooted;
};
class GetAllSuccessEvent : public GetSuccessEvent
{
public:
GetAllSuccessEvent(nsTArray<JSAutoStructuredCloneBuffer>& aCloneBuffers)
{
if (!mCloneBuffers.SwapElements(aCloneBuffers)) {
NS_ERROR("Failed to swap elements!");
}
}
~GetAllSuccessEvent();
NS_IMETHOD GetResult(JSContext* aCx,
jsval* aResult);
private:
nsTArray<JSAutoStructuredCloneBuffer> mCloneBuffers;
};
class GetAllKeySuccessEvent : public GetSuccessEvent
{
public:
GetAllKeySuccessEvent(nsTArray<Key>& aKeys)
{
if (!mKeys.SwapElements(aKeys)) {
NS_ERROR("Failed to swap elements!");
}
}
NS_IMETHOD GetResult(JSContext* aCx,
jsval* aResult);
private:
nsTArray<Key> mKeys;
};
class IDBVersionChangeEvent : public IDBEvent,
class IDBVersionChangeEvent : public nsDOMEvent,
public nsIIDBVersionChangeEvent
{
public:
NS_DECL_ISUPPORTS_INHERITED
NS_FORWARD_TO_NSDOMEVENT
NS_DECL_NSIIDBVERSIONCHANGEEVENT
NS_FORWARD_NSIDOMEVENT(IDBEvent::)
NS_FORWARD_NSIIDBEVENT(IDBEvent::)
inline static already_AddRefed<nsIDOMEvent>
Create(const nsAString& aVersion)
{
NS_NAMED_LITERAL_STRING(type, VERSIONCHANGE_EVT_STR);
return CreateInternal(nsnull, type, aVersion);
return CreateInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR), aVersion);
}
inline static already_AddRefed<nsIDOMEvent>
CreateBlocked(nsISupports* aSource,
const nsAString& aVersion)
CreateBlocked(const nsAString& aVersion)
{
NS_NAMED_LITERAL_STRING(type, BLOCKED_EVT_STR);
return CreateInternal(aSource, type, aVersion);
return CreateInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR), aVersion);
}
inline static already_AddRefed<nsIRunnable>
CreateRunnable(const nsAString& aVersion,
nsIDOMEventTarget* aTarget)
{
NS_NAMED_LITERAL_STRING(type, VERSIONCHANGE_EVT_STR);
return CreateRunnableInternal(nsnull, type, aVersion, aTarget);
return CreateRunnableInternal(NS_LITERAL_STRING(VERSIONCHANGE_EVT_STR),
aVersion, aTarget);
}
static already_AddRefed<nsIRunnable>
CreateBlockedRunnable(nsISupports* aSource,
const nsAString& aVersion,
CreateBlockedRunnable(const nsAString& aVersion,
nsIDOMEventTarget* aTarget)
{
NS_NAMED_LITERAL_STRING(type, BLOCKED_EVT_STR);
return CreateRunnableInternal(aSource, type, aVersion, aTarget);
return CreateRunnableInternal(NS_LITERAL_STRING(BLOCKED_EVT_STR), aVersion,
aTarget);
}
protected:
IDBVersionChangeEvent() { }
IDBVersionChangeEvent() : nsDOMEvent(nsnull, nsnull) { }
virtual ~IDBVersionChangeEvent() { }
static already_AddRefed<nsIDOMEvent>
CreateInternal(nsISupports* aSource,
const nsAString& aType,
CreateInternal(const nsAString& aType,
const nsAString& aVersion);
static already_AddRefed<nsIRunnable>
CreateRunnableInternal(nsISupports* aSource,
const nsAString& aType,
CreateRunnableInternal(const nsAString& aType,
const nsAString& aVersion,
nsIDOMEventTarget* aTarget);

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

@ -41,6 +41,7 @@
#include "nsILocalFile.h"
#include "nsIScriptContext.h"
#include "mozIThirdPartyUtil.h"
#include "mozilla/storage.h"
#include "nsAppDirectoryServiceDefs.h"
@ -120,7 +121,6 @@ struct ObjectStoreInfoMap
ObjectStoreInfo* info;
};
class OpenDatabaseHelper : public AsyncConnectionHelper
{
public:
@ -133,7 +133,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
private:
// In-params.
@ -846,6 +847,20 @@ IDBFactory::Open(const nsAString& aName,
}
NS_ENSURE_TRUE(innerWindow, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil =
do_GetService(THIRDPARTYUTIL_CONTRACTID);
NS_ENSURE_TRUE(thirdPartyUtil, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
PRBool isThirdPartyWindow;
rv = thirdPartyUtil->IsThirdPartyWindow(window, nsnull, &isThirdPartyWindow);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
if (isThirdPartyWindow) {
NS_WARNING("IndexedDB is not permitted in a third-party window.");
*_retval = nsnull;
return NS_OK;
}
nsRefPtr<IDBRequest> request = IDBRequest::Create(this, context, innerWindow,
nsnull);
NS_ENSURE_TRUE(request, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
@ -940,7 +955,8 @@ OpenDatabaseHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
OpenDatabaseHelper::GetSuccessResult(nsIWritableVariant* aResult)
OpenDatabaseHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
DatabaseInfo* dbInfo;
if (DatabaseInfo::Get(mDatabaseId, &dbInfo)) {
@ -1027,6 +1043,5 @@ OpenDatabaseHelper::GetSuccessResult(nsIWritableVariant* aResult)
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
aResult->SetAsISupports(static_cast<nsPIDOMEventTarget*>(db));
return NS_OK;
return WrapNative(aCx, static_cast<nsPIDOMEventTarget*>(db), aVal);
}

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

@ -71,7 +71,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -96,7 +97,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -120,7 +122,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
protected:
const PRUint32 mLimit;
@ -139,7 +142,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -171,7 +175,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -213,7 +218,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -712,21 +718,11 @@ GetKeyHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetKeyHelper::GetSuccessResult(nsIWritableVariant* aResult)
GetKeyHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (mKey.IsUnset()) {
aResult->SetAsEmpty();
}
else if (mKey.IsString()) {
aResult->SetAsAString(mKey.StringValue());
}
else if (mKey.IsInt()) {
aResult->SetAsInt64(mKey.IntValue());
}
else {
NS_NOTREACHED("Unknown key type!");
}
return NS_OK;
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
}
nsresult
@ -774,15 +770,10 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetHelper::OnSuccess(nsIDOMEventTarget* aTarget)
GetHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
nsRefPtr<GetSuccessEvent> event(new GetSuccessEvent(mCloneBuffer));
nsresult rv = event->Init(mRequest, mTransaction);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
PRBool dummy;
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
return NS_OK;
return ConvertCloneBufferToJSVal(aCx, mCloneBuffer, aVal);
}
nsresult
@ -896,17 +887,51 @@ GetAllKeysHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetAllKeysHelper::OnSuccess(nsIDOMEventTarget* aTarget)
GetAllKeysHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
nsRefPtr<GetAllKeySuccessEvent> event(new GetAllKeySuccessEvent(mKeys));
NS_ASSERTION(mKeys.Length() <= mLimit, "Too many results!");
NS_ASSERTION(mKeys.IsEmpty(), "Should have swapped!");
nsTArray<Key> keys;
if (!mKeys.SwapElements(keys)) {
NS_ERROR("Failed to swap elements!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
nsresult rv = event->Init(mRequest, mTransaction);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
JSAutoRequest ar(aCx);
PRBool dummy;
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
JSObject* array = 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, jsuint(keys.Length()))) {
NS_WARNING("Failed to set array length!");
return NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR;
}
jsint count = jsint(keys.Length());
for (jsint index = 0; index < count; index++) {
const Key& key = keys[index];
NS_ASSERTION(!key.IsUnset(), "Bad key!");
jsval value;
nsresult rv = IDBObjectStore::GetJSValFromKey(key, 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 = OBJECT_TO_JSVAL(array);
return NS_OK;
}
@ -1011,19 +1036,11 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetAllHelper::OnSuccess(nsIDOMEventTarget* aTarget)
GetAllHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(mCloneBuffers.Length() <= mLimit, "Too many results!");
nsRefPtr<GetAllSuccessEvent> event = new GetAllSuccessEvent(mCloneBuffers);
NS_ASSERTION(mCloneBuffers.IsEmpty(), "Should have swapped!");
nsresult rv = event->Init(mRequest, mTransaction);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
PRBool dummy;
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
return NS_OK;
return ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal);
}
nsresult
@ -1248,10 +1265,11 @@ OpenKeyCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
OpenKeyCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
OpenKeyCursorHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (mKey.IsUnset()) {
aResult->SetAsEmpty();
*aVal = JSVAL_VOID;
return NS_OK;
}
@ -1260,8 +1278,7 @@ OpenKeyCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
mContinueQuery, mContinueToQuery, mKey, mObjectKey);
NS_ENSURE_TRUE(cursor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
aResult->SetAsISupports(cursor);
return NS_OK;
return WrapNative(aCx, cursor, aVal);
}
nsresult
@ -1431,15 +1448,6 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
mCloneBuffer);
NS_ENSURE_SUCCESS(rv, rv);
/*
SELECT index_data.value, object_data.key_value, object_data.data
FROM object_data INNER JOIN index_data
ON index_data.object_data_id = object_data.id
WHERE index_data.index_id = 2 AND index_data.value < 73
AND ( ( index_data.value = 65 AND object_data.key_value > "237-23-7736" )
OR ( index_data.value > 65 ) )
ORDER BY index_data.value ASC, object_data.key_value ASC
*/
// Now we need to make the query to get the next match.
nsCAutoString queryStart = NS_LITERAL_CSTRING("SELECT ") + value +
NS_LITERAL_CSTRING(", ") + keyValue +
@ -1529,10 +1537,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
OpenCursorHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (mKey.IsUnset()) {
aResult->SetAsEmpty();
*aVal = JSVAL_VOID;
return NS_OK;
}
@ -1542,6 +1551,5 @@ OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
mCloneBuffer);
NS_ENSURE_TRUE(cursor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
aResult->SetAsISupports(cursor);
return NS_OK;
return WrapNative(aCx, cursor, aVal);
}

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

@ -81,7 +81,8 @@ public:
}
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -117,7 +118,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -147,8 +149,9 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult OnSuccess();
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
};
class ClearHelper : public AsyncConnectionHelper
@ -190,7 +193,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult GetSuccessResult(nsIWritableVariant* aResult);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -225,8 +229,16 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
void OnError(nsIDOMEventTarget* aTarget, nsresult aErrorCode);
nsresult OnSuccess()
{
return NS_OK;
}
void OnError()
{
NS_ASSERTION(mTransaction->IsAborted(), "How else can this fail?!");
}
void ReleaseMainThreadObjects()
{
@ -255,8 +267,16 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
void OnError(nsIDOMEventTarget* aTarget, nsresult aErrorCode);
nsresult OnSuccess()
{
return NS_OK;
}
void OnError()
{
NS_ASSERTION(mTransaction->IsAborted(), "How else can this fail?!");
}
void ReleaseMainThreadObjects()
{
@ -287,7 +307,8 @@ public:
{ }
nsresult DoDatabaseWork(mozIStorageConnection* aConnection);
nsresult OnSuccess(nsIDOMEventTarget* aTarget);
nsresult GetSuccessResult(JSContext* aCx,
jsval* aVal);
void ReleaseMainThreadObjects()
{
@ -533,7 +554,7 @@ IDBObjectStore::GetKeyPathValueFromStructuredData(const PRUint8* aData,
jsval clone;
if (!JS_ReadStructuredClone(cx, reinterpret_cast<const uint64*>(aData),
aDataLength, JS_STRUCTURED_CLONE_VERSION,
&clone)) {
&clone, NULL, NULL)) {
return NS_ERROR_DOM_DATA_CLONE_ERR;
}
@ -1688,20 +1709,11 @@ AddHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
AddHelper::GetSuccessResult(nsIWritableVariant* aResult)
AddHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
if (mKey.IsString()) {
aResult->SetAsAString(mKey.StringValue());
}
else if (mKey.IsInt()) {
aResult->SetAsInt64(mKey.IntValue());
}
else {
NS_NOTREACHED("Unknown key type!");
}
return NS_OK;
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
}
nsresult
@ -1801,20 +1813,10 @@ GetHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetHelper::OnSuccess(nsIDOMEventTarget* aTarget)
GetHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (!mCloneBuffer.data()) {
// Default is to have an undefined result.
return AsyncConnectionHelper::OnSuccess(aTarget);
}
nsRefPtr<GetSuccessEvent> event(new GetSuccessEvent(mCloneBuffer));
nsresult rv = event->Init(mRequest, mTransaction);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
PRBool dummy;
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
return NS_OK;
return ConvertCloneBufferToJSVal(aCx, mCloneBuffer, aVal);
}
nsresult
@ -1855,26 +1857,17 @@ DeleteHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
DeleteHelper::OnSuccess(nsIDOMEventTarget* aTarget)
DeleteHelper::OnSuccess()
{
return AsyncConnectionHelper::OnSuccess(aTarget);
return AsyncConnectionHelper::OnSuccess();
}
nsresult
DeleteHelper::GetSuccessResult(nsIWritableVariant* aResult)
DeleteHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(!mKey.IsUnset(), "Badness!");
if (mKey.IsString()) {
aResult->SetAsAString(mKey.StringValue());
}
else if (mKey.IsInt()) {
aResult->SetAsInt64(mKey.IntValue());
}
else {
NS_NOTREACHED("Unknown key type!");
}
return NS_OK;
return IDBObjectStore::GetJSValFromKey(mKey, aCx, aVal);
}
nsresult
@ -2078,10 +2071,11 @@ OpenCursorHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
OpenCursorHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
if (mKey.IsUnset()) {
aResult->SetAsEmpty();
*aVal = JSVAL_VOID;
return NS_OK;
}
@ -2091,8 +2085,7 @@ OpenCursorHelper::GetSuccessResult(nsIWritableVariant* aResult)
mCloneBuffer);
NS_ENSURE_TRUE(cursor, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
aResult->SetAsISupports(cursor);
return NS_OK;
return WrapNative(aCx, cursor, aVal);
}
nsresult
@ -2240,20 +2233,6 @@ CreateIndexHelper::InsertDataFromObjectStore(mozIStorageConnection* aConnection)
return NS_OK;
}
nsresult
CreateIndexHelper::OnSuccess(nsIDOMEventTarget* aTarget)
{
NS_ASSERTION(!aTarget, "Huh?!");
return NS_OK;
}
void
CreateIndexHelper::OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode)
{
NS_ASSERTION(!aTarget, "Huh?!");
}
nsresult
DeleteIndexHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{
@ -2278,21 +2257,6 @@ DeleteIndexHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
return NS_OK;
}
nsresult
DeleteIndexHelper::OnSuccess(nsIDOMEventTarget* aTarget)
{
NS_ASSERTION(!aTarget, "Huh?!");
return NS_OK;
}
void
DeleteIndexHelper::OnError(nsIDOMEventTarget* aTarget,
nsresult aErrorCode)
{
NS_NOTREACHED("Removing an index should never fail here!");
}
nsresult
GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
{
@ -2406,17 +2370,9 @@ GetAllHelper::DoDatabaseWork(mozIStorageConnection* aConnection)
}
nsresult
GetAllHelper::OnSuccess(nsIDOMEventTarget* aTarget)
GetAllHelper::GetSuccessResult(JSContext* aCx,
jsval* aVal)
{
NS_ASSERTION(mCloneBuffers.Length() <= mLimit, "Too many results!");
nsRefPtr<GetAllSuccessEvent> event = new GetAllSuccessEvent(mCloneBuffers);
NS_ASSERTION(mCloneBuffers.IsEmpty(), "Should have swapped!");
nsresult rv = event->Init(mRequest, mTransaction);
NS_ENSURE_SUCCESS(rv, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);
PRBool dummy;
aTarget->DispatchEvent(static_cast<nsDOMEvent*>(event), &dummy);
return NS_OK;
return ConvertCloneBuffersToArray(aCx, mCloneBuffers, aVal);
}

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

@ -51,18 +51,32 @@
#include "nsStringGlue.h"
#include "nsThreadUtils.h"
#include "AsyncConnectionHelper.h"
#include "IDBEvents.h"
#include "IDBTransaction.h"
USING_INDEXEDDB_NAMESPACE
IDBRequest::IDBRequest()
: mReadyState(nsIIDBRequest::LOADING)
: mResultVal(JSVAL_VOID),
mErrorCode(0),
mResultValRooted(false),
mHaveResultOrErrorCode(false)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
}
IDBRequest::~IDBRequest()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (mResultValRooted) {
// Calling a virtual from the destructor is bad... But we know that we won't
// call a subclass' implementation because mResultValRooted will be set to
// false.
UnrootResultVal();
}
if (mListenerManager) {
mListenerManager->Disconnect();
}
@ -75,6 +89,8 @@ IDBRequest::Create(nsISupports* aSource,
nsPIDOMWindow* aOwner,
IDBTransaction* aTransaction)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!aScriptContext || !aOwner) {
NS_ERROR("Null context and owner!");
return nsnull;
@ -90,10 +106,61 @@ IDBRequest::Create(nsISupports* aSource,
return request.forget();
}
void
IDBRequest::Reset()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
mHelper = nsnull;
mResultVal = JSVAL_VOID;
mHaveResultOrErrorCode = false;
mErrorCode = 0;
if (mResultValRooted) {
UnrootResultVal();
}
}
void
IDBRequest::SetDone(AsyncConnectionHelper* aHelper)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ASSERTION(!mHelper, "Already called!");
mErrorCode = NS_ERROR_GET_CODE(aHelper->GetResultCode());
if (mErrorCode) {
mHaveResultOrErrorCode = true;
}
else {
mHelper = aHelper;
}
}
void
IDBRequest::RootResultVal()
{
NS_ASSERTION(!mResultValRooted, "This should be false!");
NS_HOLD_JS_OBJECTS(this, IDBRequest);
mResultValRooted = true;
}
void
IDBRequest::UnrootResultVal()
{
NS_ASSERTION(mResultValRooted, "This should be true!");
NS_DROP_JS_OBJECTS(this, IDBRequest);
mResultValRooted = false;
}
NS_IMETHODIMP
IDBRequest::GetReadyState(PRUint16* aReadyState)
{
*aReadyState = mReadyState;
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (mHaveResultOrErrorCode || mHelper) {
*aReadyState = nsIIDBRequest::DONE;
}
else {
*aReadyState = nsIIDBRequest::LOADING;
}
return NS_OK;
}
@ -107,9 +174,77 @@ IDBRequest::GetSource(nsISupports** aSource)
return NS_OK;
}
NS_IMETHODIMP
IDBRequest::GetTransaction(nsIIDBTransaction** aTransaction)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsCOMPtr<nsIIDBTransaction> transaction(mTransaction);
transaction.forget(aTransaction);
return NS_OK;
}
NS_IMETHODIMP
IDBRequest::GetResult(JSContext* aCx,
jsval* aResult)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
nsresult rv = NS_OK;
if (!mHaveResultOrErrorCode) {
if (!mHelper) {
// XXX Need a real error code here.
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
NS_ASSERTION(!mResultValRooted, "Huh?!");
NS_ASSERTION(JSVAL_IS_VOID(mResultVal), "Should be undefined!");
if (NS_SUCCEEDED(mHelper->GetResultCode())) {
// It's common practice for result values to be rooted before being set.
// Root now, even though we may unroot below, to make mResultVal safe from
// GC.
RootResultVal();
rv = mHelper->GetSuccessResult(aCx, &mResultVal);
if (NS_FAILED(rv)) {
mResultVal = JSVAL_VOID;
}
// There's no point in rooting non-GCThings. Unroot if possible.
if (!JSVAL_IS_GCTHING(mResultVal)) {
UnrootResultVal();
}
}
mHaveResultOrErrorCode = true;
mHelper = nsnull;
}
*aResult = mResultVal;
return rv;
}
NS_IMETHODIMP
IDBRequest::GetErrorCode(PRUint16* aErrorCode)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!mHaveResultOrErrorCode && !mHelper) {
// XXX Need a real error code here.
return NS_ERROR_DOM_INDEXEDDB_NOT_ALLOWED_ERR;
}
*aErrorCode = mErrorCode;
return NS_OK;
}
NS_IMETHODIMP
IDBRequest::SetOnsuccess(nsIDOMEventListener* aSuccessListener)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return RemoveAddEventListener(NS_LITERAL_STRING(SUCCESS_EVT_STR),
mOnSuccessListener, aSuccessListener);
}
@ -117,12 +252,16 @@ IDBRequest::SetOnsuccess(nsIDOMEventListener* aSuccessListener)
NS_IMETHODIMP
IDBRequest::GetOnsuccess(nsIDOMEventListener** aSuccessListener)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return GetInnerEventListener(mOnSuccessListener, aSuccessListener);
}
NS_IMETHODIMP
IDBRequest::SetOnerror(nsIDOMEventListener* aErrorListener)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return RemoveAddEventListener(NS_LITERAL_STRING(ERROR_EVT_STR),
mOnErrorListener, aErrorListener);
}
@ -130,6 +269,8 @@ IDBRequest::SetOnerror(nsIDOMEventListener* aErrorListener)
NS_IMETHODIMP
IDBRequest::GetOnerror(nsIDOMEventListener** aErrorListener)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
return GetInnerEventListener(mOnErrorListener, aErrorListener);
}
@ -137,9 +278,21 @@ NS_IMPL_CYCLE_COLLECTION_CLASS(IDBRequest)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(IDBRequest,
nsDOMEventTargetHelper)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_SCRIPT_OBJECTS
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnSuccessListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mOnErrorListener)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR(mSource)
// mHelper is a threadsafe runnable and can't use a cycle-collecting refcnt.
// We traverse manually here.
if (tmp->mHelper) {
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mHelper->mDatabase,
nsPIDOMEventTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mHelper->mTransaction,
nsPIDOMEventTarget)
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_NSCOMPTR_AMBIGUOUS(mHelper->mRequest,
nsPIDOMEventTarget)
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest,
@ -147,8 +300,25 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(IDBRequest,
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnSuccessListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mOnErrorListener)
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mSource)
// Unlinking mHelper will unlink all the objects that we really care about.
NS_IMPL_CYCLE_COLLECTION_UNLINK_NSCOMPTR(mHelper)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRACE_BEGIN(IDBRequest)
if (JSVAL_IS_GCTHING(tmp->mResultVal)) {
void *gcThing = JSVAL_TO_GCTHING(tmp->mResultVal);
NS_IMPL_CYCLE_COLLECTION_TRACE_JS_CALLBACK(gcThing)
}
NS_IMPL_CYCLE_COLLECTION_TRACE_END
NS_IMPL_CYCLE_COLLECTION_ROOT_BEGIN(IDBRequest)
if (tmp->mResultValRooted) {
tmp->mResultVal = JSVAL_VOID;
tmp->UnrootResultVal();
}
NS_IMPL_CYCLE_COLLECTION_ROOT_END
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION_INHERITED(IDBRequest)
NS_INTERFACE_MAP_ENTRY(nsIIDBRequest)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(IDBRequest)
@ -162,11 +332,22 @@ DOMCI_DATA(IDBRequest, IDBRequest)
nsresult
IDBRequest::PreHandleEvent(nsEventChainPreVisitor& aVisitor)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
aVisitor.mCanHandle = PR_TRUE;
aVisitor.mParentTarget = mTransaction;
return NS_OK;
}
IDBVersionChangeRequest::~IDBVersionChangeRequest()
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (mResultValRooted) {
UnrootResultVal();
}
}
// static
already_AddRefed<IDBVersionChangeRequest>
IDBVersionChangeRequest::Create(nsISupports* aSource,
@ -174,6 +355,8 @@ IDBVersionChangeRequest::Create(nsISupports* aSource,
nsPIDOMWindow* aOwner,
IDBTransaction* aTransaction)
{
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
if (!aScriptContext || !aOwner) {
NS_ERROR("Null context and owner!");
return nsnull;
@ -189,6 +372,22 @@ IDBVersionChangeRequest::Create(nsISupports* aSource,
return request.forget();
}
void
IDBVersionChangeRequest::RootResultVal()
{
NS_ASSERTION(!mResultValRooted, "This should be false!");
NS_HOLD_JS_OBJECTS(this, IDBVersionChangeRequest);
mResultValRooted = true;
}
void
IDBVersionChangeRequest::UnrootResultVal()
{
NS_ASSERTION(mResultValRooted, "This should be true!");
NS_DROP_JS_OBJECTS(this, IDBVersionChangeRequest);
mResultValRooted = false;
}
NS_IMETHODIMP
IDBVersionChangeRequest::SetOnblocked(nsIDOMEventListener* aBlockedListener)
{

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

@ -54,6 +54,7 @@ class nsPIDOMWindow;
BEGIN_INDEXEDDB_NAMESPACE
class AsyncConnectionHelper;
class IDBTransaction;
class IDBRequest : public nsDOMEventTargetHelper,
@ -62,8 +63,8 @@ class IDBRequest : public nsDOMEventTargetHelper,
public:
NS_DECL_ISUPPORTS_INHERITED
NS_DECL_NSIIDBREQUEST
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBRequest,
nsDOMEventTargetHelper)
NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(IDBRequest,
nsDOMEventTargetHelper)
static
already_AddRefed<IDBRequest> Create(nsISupports* aSource,
@ -79,16 +80,9 @@ public:
return mSource;
}
void Reset()
{
mReadyState = nsIIDBRequest::LOADING;
}
void Reset();
void SetDone()
{
NS_ASSERTION(mReadyState != nsIIDBRequest::DONE, "Already set!");
mReadyState = nsIIDBRequest::DONE;
}
void SetDone(AsyncConnectionHelper* aHelper);
nsIScriptContext* ScriptContext()
{
@ -102,17 +96,25 @@ public:
return mOwner;
}
virtual void RootResultVal();
virtual void UnrootResultVal();
protected:
IDBRequest();
~IDBRequest();
nsCOMPtr<nsISupports> mSource;
nsRefPtr<IDBTransaction> mTransaction;
nsRefPtr<AsyncConnectionHelper> mHelper;
nsRefPtr<nsDOMEventListenerWrapper> mOnSuccessListener;
nsRefPtr<nsDOMEventListenerWrapper> mOnErrorListener;
PRUint16 mReadyState;
jsval mResultVal;
PRUint16 mErrorCode;
bool mResultValRooted;
bool mHaveResultOrErrorCode;
};
class IDBVersionChangeRequest : public IDBRequest,
@ -125,6 +127,8 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(IDBVersionChangeRequest,
IDBRequest)
~IDBVersionChangeRequest();
static
already_AddRefed<IDBVersionChangeRequest>
Create(nsISupports* aSource,
@ -132,6 +136,9 @@ public:
nsPIDOMWindow* aOwner,
IDBTransaction* aTransaction);
virtual void RootResultVal();
virtual void UnrootResultVal();
protected:
nsRefPtr<nsDOMEventListenerWrapper> mOnBlockedListener;
};

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

@ -937,10 +937,10 @@ CommitHelper::Run()
}
}
event = IDBEvent::CreateGenericEvent(NS_LITERAL_STRING(ABORT_EVT_STR));
event = CreateGenericEvent(NS_LITERAL_STRING(ABORT_EVT_STR));
}
else {
event = IDBEvent::CreateGenericEvent(NS_LITERAL_STRING(COMPLETE_EVT_STR));
event = CreateGenericEvent(NS_LITERAL_STRING(COMPLETE_EVT_STR));
}
NS_ENSURE_TRUE(event, NS_ERROR_DOM_INDEXEDDB_UNKNOWN_ERR);

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

@ -196,11 +196,8 @@ public:
// then fire the blocked event.
for (PRUint32 index = 0; index < mWaitingDatabases.Length(); index++) {
if (!mWaitingDatabases[index]->IsClosed()) {
nsISupports* source =
static_cast<nsPIDOMEventTarget*>(mRequestingDatabase);
nsCOMPtr<nsIDOMEvent> event =
IDBVersionChangeEvent::CreateBlocked(source, mVersion);
IDBVersionChangeEvent::CreateBlocked(mVersion);
NS_ENSURE_TRUE(event, NS_ERROR_FAILURE);
PRBool dummy;

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

@ -102,16 +102,12 @@ XPIDLSRCS = \
nsIIDBCursor.idl \
nsIIDBDatabase.idl \
nsIIDBDatabaseException.idl \
nsIIDBErrorEvent.idl \
nsIIDBEvent.idl \
nsIIDBFactory.idl \
nsIIDBIndex.idl \
nsIIDBKeyRange.idl \
nsIIDBObjectStore.idl \
nsIIDBRequest.idl \
nsIIDBSuccessEvent.idl \
nsIIDBTransaction.idl \
nsIIDBTransactionEvent.idl \
nsIIDBVersionChangeEvent.idl \
nsIIDBVersionChangeRequest.idl \
nsIIndexedDatabaseManager.idl \

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

@ -42,19 +42,20 @@
[scriptable, uuid(2f182bf1-1542-47fe-b2f7-4b1741b5283c)]
interface nsIIDBDatabaseException : nsISupports
{
const unsigned short UNKNOWN_ERR = 0;
const unsigned short NON_TRANSIENT_ERR = 1;
const unsigned short NOT_FOUND_ERR = 2;
const unsigned short CONSTRAINT_ERR = 3;
const unsigned short DATA_ERR = 4;
const unsigned short NOT_ALLOWED_ERR = 5;
const unsigned short TRANSACTION_INACTIVE_ERR = 6;
const unsigned short ABORT_ERR = 7;
const unsigned short READ_ONLY_ERR = 11;
const unsigned short RECOVERABLE_ERR = 21;
const unsigned short TRANSIENT_ERR = 31;
const unsigned short TIMEOUT_ERR = 32;
const unsigned short DEADLOCK_ERR = 33;
// const unsigned short NO_ERR = 0;
const unsigned short UNKNOWN_ERR = 1;
const unsigned short NON_TRANSIENT_ERR = 2;
const unsigned short NOT_FOUND_ERR = 3;
const unsigned short CONSTRAINT_ERR = 4;
const unsigned short DATA_ERR = 5;
const unsigned short NOT_ALLOWED_ERR = 6;
const unsigned short TRANSACTION_INACTIVE_ERR = 7;
const unsigned short ABORT_ERR = 8;
const unsigned short READ_ONLY_ERR = 9;
const unsigned short RECOVERABLE_ERR = 10;
const unsigned short TRANSIENT_ERR = 11;
const unsigned short TIMEOUT_ERR = 12;
const unsigned short DEADLOCK_ERR = 13;
readonly attribute unsigned short code;
};

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

@ -41,13 +41,14 @@
#include "nsISupports.idl"
interface nsIDOMEventListener;
interface nsIIDBTransaction;
/**
* IDBReqeust interface. See
* http://dev.w3.org/2006/webapi/WebSimpleDB/#idl-def-IDBRequest for more
* information.
*/
[scriptable, uuid(5d55f15e-9521-4c98-ba0f-e8c07783d8d3)]
[scriptable, uuid(a1e4a0ff-e0b2-431c-89cf-43b078189e27)]
interface nsIIDBRequest : nsISupports
{
const unsigned short LOADING = 1;
@ -56,7 +57,13 @@ interface nsIIDBRequest : nsISupports
readonly attribute nsISupports source;
attribute nsIDOMEventListener onsuccess;
readonly attribute nsIIDBTransaction transaction;
[implicit_jscontext]
readonly attribute jsval result;
readonly attribute unsigned short errorCode;
attribute nsIDOMEventListener onsuccess;
attribute nsIDOMEventListener onerror;
};

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

@ -37,10 +37,10 @@
*
* ***** END LICENSE BLOCK ***** */
#include "nsIIDBEvent.idl"
#include "nsIDOMEvent.idl"
[scriptable, uuid(07519073-e626-4d86-994c-801c170d263a)]
interface nsIIDBVersionChangeEvent : nsIIDBEvent
[scriptable, uuid(6a232c30-1bc4-4d5b-9ce0-6e7c08934755)]
interface nsIIDBVersionChangeEvent : nsIDOMEvent
{
readonly attribute AString version;
};

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

@ -86,6 +86,7 @@ TEST_FILES = \
test_remove_objectStore.html \
test_request_readyState.html \
test_success_events_after_abort.html \
test_third_party.html \
test_transaction_abort.html \
test_transaction_lifetimes.html \
test_transaction_lifetimes_nested.html \
@ -93,6 +94,8 @@ TEST_FILES = \
test_setVersion_abort.html \
test_setVersion_events.html \
test_writer_starvation.html \
third_party_iframe1.html \
third_party_iframe2.html \
$(NULL)
ifeq (browser,$(MOZ_BUILD_APP))

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

@ -3,13 +3,13 @@
<head>
<script>
mozIndexedDB.open(parent.location).onsuccess = function(e) {
var db = e.result;
var db = e.target.result;
// This should never be called
db.onversionchange = function(e) {
db.transaction(["mystore"]).objectStore("mystore").put({ hello: "fail" }, 42);
}
db.setVersion("1.0").onsuccess = function(e) {
trans = e.transaction;
trans = e.target.transaction;
if (db.objectStoreNames.contains("mystore")) {
db.deleteObjectStore("mystore");
}

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

@ -4,7 +4,7 @@
<script>
var res = {};
mozIndexedDB.open(parent.location).onsuccess = function(e) {
var db = e.result;
var db = e.target.result;
res.version = db.version;
res.storeCount = db.objectStoreNames.length;
@ -13,9 +13,9 @@ mozIndexedDB.open(parent.location).onsuccess = function(e) {
res.blockedFired = true;
}
req.onsuccess = function(e) {
var trans = e.transaction;
var trans = req.transaction;
trans.objectStore("mystore").get(42).onsuccess = function(e) {
res.value = JSON.stringify(e.result);
res.value = JSON.stringify(e.target.result);
}
trans.oncomplete = function() {
parent.postMessage(JSON.stringify(res), "http://mochi.test:8888");

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

@ -39,7 +39,7 @@ function grabEventAndContinueHandler(event)
function errorHandler(event)
{
throw new Error(event.code + ": " + event.message);
throw new Error("indexedDB error, code " + event.target.errorCode);
}
function continueToNextStep()

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

@ -17,11 +17,11 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
if (event instanceof Components.interfaces.nsIIDBSuccessEvent) {
testResult = event.result;
if (event.type == "success") {
testResult = event.target.result;
}
else {
testException = event.code + ": " + event.message;
testException = event.target.errorCode;
}
finishTest()

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

@ -6,8 +6,6 @@
const testPageURL = "http://mochi.test:8888/browser/" +
"dom/indexedDB/test/browser_permissionsPrompt.html";
const notificationID = "indexedDB-permissions-prompt";
const exceptionText = "5: A mutation operation was attempted on a database " +
"that did not allow mutations.";
function test()
{
@ -26,7 +24,8 @@ function test1()
setFinishedCallback(function(result, exception) {
ok(!result, "No database created");
is(exception, exceptionText, "Correct exception");
is(exception, IDBDatabaseException.NOT_ALLOWED_ERR.toString(),
"Correct exception");
is(getPermission(testPageURL, "indexedDB"),
Components.interfaces.nsIPermissionManager.DENY_ACTION,
"Correct permission set");
@ -61,7 +60,8 @@ function test2()
setFinishedCallback(function(result, exception) {
ok(!result, "No database created");
is(exception, exceptionText, "Correct exception");
is(exception, IDBDatabaseException.NOT_ALLOWED_ERR.toString(),
"Correct exception");
is(getPermission(testPageURL, "indexedDB"),
Components.interfaces.nsIPermissionManager.DENY_ACTION,
"Correct permission set");

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

@ -6,8 +6,6 @@
const testPageURL = "http://mochi.test:8888/browser/" +
"dom/indexedDB/test/browser_permissionsPrompt.html";
const notificationID = "indexedDB-permissions-prompt";
const exceptionText = "5: A mutation operation was attempted on a database " +
"that did not allow mutations.";
function test()
{
@ -52,7 +50,8 @@ function test3()
setFinishedCallback(function(result, exception) {
ok(!result, "No database");
is(exception, exceptionText, "Correct exception");
is(exception, IDBDatabaseException.NOT_ALLOWED_ERR.toString(),
"Correct exception");
gBrowser.removeCurrentTab();
executeSoon(test4);

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

@ -60,7 +60,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
db = event.result;
db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;

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

@ -25,7 +25,7 @@
}
function errorHandler(event) {
ok(false, "indexedDB error (" + event.code + "): " + event.message);
ok(false, "indexedDB error, code " + event.target.errorCcode);
finishTest();
}
@ -61,7 +61,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.version, "", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
@ -71,8 +71,8 @@
request.onerror = errorHandler;
event = yield;
event.transaction.oncomplete = unexpectedSuccessHandler;
event.transaction.onabort = grabEventAndContinueHandler;
event.target.transaction.oncomplete = unexpectedSuccessHandler;
event.target.transaction.onabort = grabEventAndContinueHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
@ -95,7 +95,6 @@
event = yield;
is(event.type, "abort", "Got a transaction abort event");
is(db.version, "", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");
@ -104,8 +103,8 @@
request.onerror = errorHandler;
event = yield;
event.transaction.oncomplete = grabEventAndContinueHandler;
event.transaction.onabort = unexpectedSuccessHandler;
event.target.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.onabort = unexpectedSuccessHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");

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

@ -21,7 +21,7 @@
}
function errorHandler(event) {
ok(false, "indexedDB error (" + event.code + "): " + event.message);
ok(false, "indexedDB error, code " + event.target.errorCode);
finishTest();
}
@ -53,7 +53,7 @@
};
function errorEventCounter(event) {
ok(event instanceof IDBErrorEvent, "Got an error event");
ok(event.type == "error", "Got an error event");
ok(event.target instanceof window[eventChain[0]],
"Correct event.target");
@ -100,7 +100,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
db.onerror = errorEventCounter;
db.addEventListener("error", errorEventCounter, true);
@ -109,7 +109,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
event.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.oncomplete = grabEventAndContinueHandler;
db.createObjectStore("foo", { autoIncrement: true });
yield;

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

@ -28,7 +28,7 @@
}
function errorHandler(event) {
ok(false, "indexedDB error (" + event.code + "): " + event.message);
ok(false, "indexedDB error, code " + event.target.errorCode);
finishTest();
}
@ -65,7 +65,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
db.onerror = function(event) {
event.preventDefault();
};
@ -76,8 +76,8 @@
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
event = yield;
event.transaction.oncomplete = unexpectedSuccessHandler;
event.transaction.onabort = grabEventAndContinueHandler;
event.target.transaction.oncomplete = unexpectedSuccessHandler;
event.target.transaction.onabort = grabEventAndContinueHandler;
is(db.version, "1", "Correct version");
is(db.objectStoreNames.length, 0, "Correct objectStoreNames length");

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

@ -47,7 +47,7 @@ function continueToNextStep()
function errorHandler(event)
{
ok(false, "indexedDB error (" + event.code + "): " + event.message);
ok(false, "indexedDB error, code " + event.target.errorCode);
finishTest();
}
@ -70,7 +70,8 @@ function ExpectError(code)
ExpectError.prototype = {
handleEvent: function(event)
{
is(this._code, event.code, "Expected error was thrown.");
is(event.type, "error", "Got an error event");
is(this._code, event.target.errorCode, "Expected error was thrown.");
event.preventDefault();
grabEventAndContinueHandler(event);
}

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

@ -21,13 +21,15 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = request.result;
request = db.setVersion("1");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
ok(event.target === request, "Good event target");
let objectStore = db.createObjectStore("foo", { keyPath: "" });
let key = 10;
@ -36,7 +38,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key, "Correct key");
is(request.result, key, "Correct key");
request = objectStore.add({}, key);
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);

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

@ -21,7 +21,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = request.result;
request = db.setVersion("1");
request.onerror = errorHandler;

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

@ -24,14 +24,14 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = request.result;
request = db.setVersion("1");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
event.transaction.oncomplete = continueToNextStep;
event.target.transaction.oncomplete = continueToNextStep;
let objectStore = db.createObjectStore("foo", { autoIncrement: true });
@ -41,7 +41,7 @@
request.onerror = errorHandler;
if (!i) {
request.onsuccess = function(event) {
firstKey = event.result;
firstKey = event.target.result;
};
}
}
@ -54,7 +54,7 @@
request = db.transaction("foo").objectStore("foo").openCursor();
request.onerror = errorHandler;
request.onsuccess = function(event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
seenEntryCount++;
cursor.continue();
@ -80,12 +80,14 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.result === undefined, "Correct event.result");
ok(event.target.result === undefined, "Correct event.target.result");
ok(request.result === undefined, "Correct request.result");
ok(request === event.target, "Correct event.target");
request = db.transaction("foo").objectStore("foo").openCursor();
request.onerror = errorHandler;
request.onsuccess = function(event) {
let cursor = event.result;
let cursor = request.result;
if (cursor) {
ok(false, "Shouldn't have any entries");
}
@ -98,7 +100,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
isnot(event.result, firstKey, "Got a different key");
isnot(event.target.result, firstKey, "Got a different key");
finishTest();
yield;

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

@ -32,7 +32,7 @@
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -111,15 +111,16 @@
}
ok(found, "Name is on objectStore.indexNames");
ok(event.transaction, "event has a transaction");
ok(event.transaction.db === db, "transaction has the right db");
is(event.transaction.readyState, nsIIDBTransaction.LOADING,
ok(event.target.transaction, "event has a transaction");
ok(event.target.transaction.db === db,
"transaction has the right db");
is(event.target.transaction.readyState, nsIIDBTransaction.LOADING,
"transaction has the correct readyState");
is(event.transaction.mode, nsIIDBTransaction.VERSION_CHANGE,
is(event.target.transaction.mode, nsIIDBTransaction.VERSION_CHANGE,
"transaction has the correct mode");
is(event.transaction.objectStoreNames.length, i + 1,
is(event.target.transaction.objectStoreNames.length, i + 1,
"transaction only has one object store");
is(event.transaction.objectStoreNames.item(0), objectStoreName,
is(event.target.transaction.objectStoreNames.item(0), objectStoreName,
"transaction has the correct object store");
}
}

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

@ -37,8 +37,9 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
ok(event.source === mozIndexedDB, "event.source is correct");
let db = event.result;
ok(event.target.source === mozIndexedDB,
"event.target.source is correct");
let db = event.target.result;
let count = db.objectStoreNames.length;
is(count, 0, "correct objectStoreNames length");
@ -48,7 +49,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.source === db, "event.source is correct");
ok(event.target.source === db, "event.target.source is correct");
try {
db.createObjectStore(null);
@ -108,17 +109,18 @@
"Bad keyPath");
if(objectStore.indexNames.length, 0, "Bad indexNames");
ok(event.transaction, "event has a transaction");
ok(event.transaction.db === db, "transaction has the right db");
is(event.transaction.readyState, nsIIDBTransaction.LOADING,
ok(event.target.transaction, "event has a transaction");
ok(event.target.transaction.db === db, "transaction has the right db");
is(event.target.transaction.readyState, nsIIDBTransaction.LOADING,
"transaction has the correct readyState");
is(event.transaction.mode, nsIIDBTransaction.VERSION_CHANGE,
is(event.target.transaction.mode, nsIIDBTransaction.VERSION_CHANGE,
"transaction has the correct mode");
is(event.transaction.objectStoreNames.length, index + 1,
is(event.target.transaction.objectStoreNames.length, index + 1,
"transaction has correct objectStoreNames list");
found = false;
for (let j = 0; j < event.transaction.objectStoreNames.length; j++) {
if (event.transaction.objectStoreNames.item(j) == info.name) {
for (let j = 0; j < event.target.transaction.objectStoreNames.length;
j++) {
if (event.target.transaction.objectStoreNames.item(j) == info.name) {
found = true;
break;
}

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

@ -35,12 +35,12 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
event = yield;
event.transaction.oncomplete = continueToNextStep;
event.target.transaction.oncomplete = continueToNextStep;
let objectStore = db.createObjectStore("foo", { keyPath: "ss" });
objectStore.createIndex("name", "name", { unique: true });
@ -57,8 +57,8 @@
db.transaction("foo").objectStore("foo").openCursor().onsuccess =
function(event) {
event.transaction.oncomplete = continueToNextStep;
let cursor = event.result;
event.target.transaction.oncomplete = continueToNextStep;
let cursor = event.target.result;
if (cursor) {
if (cursor.value.name == objectStoreData[0].name) {
sawRemoved = true;
@ -83,8 +83,8 @@
db.transaction("foo", IDBTransaction.READ_WRITE).objectStore("foo")
.index("name").openCursor().onsuccess = function(event) {
event.transaction.oncomplete = continueToNextStep;
let cursor = event.result;
event.target.transaction.oncomplete = continueToNextStep;
let cursor = event.target.result;
if (cursor) {
if (cursor.value.name == objectStoreData[0].name) {
sawRemoved = true;
@ -99,7 +99,7 @@
"Correct name");
if (count == 1) {
let objectStore = event.transaction.objectStore("foo");
let objectStore = event.target.transaction.objectStore("foo");
objectStore.delete(objectStoreData[0].ss)
.onsuccess = function(event) {
objectStore.add(objectStoreData[objectStoreData.length - 1])

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

@ -36,7 +36,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
for (let i = 0; i < objectStoreInfo.length; i++) {
// Create our object stores.
@ -58,7 +58,6 @@
{ unique: false });
let uniqueIndex = objectStore.createIndex("unique_data_index", "data",
{ unique: true });
// Populate the object store with one entry of data.
request = info.hasOwnProperty("key") ?
objectStore.add(info.entry, info.key) :
@ -75,7 +74,7 @@
event = yield;
ok(true, "4");
let cursor = event.result;
let cursor = request.result;
let obj = cursor.value;
obj.data = END_DATA;
request = cursor.update(obj);
@ -90,7 +89,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(true, "6");
SimpleTest.ok(obj.data, event.result.data,
SimpleTest.ok(obj.data, event.target.result.data,
"Non-unique index was properly updated.");
request = uniqueIndex.get(END_DATA);
@ -99,7 +98,7 @@
event = yield;
ok(true, "7");
SimpleTest.ok(obj.data, event.result.data,
SimpleTest.ok(obj.data, event.target.result.data,
"Unique index was properly updated.");
}

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

@ -25,7 +25,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -38,7 +38,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
ok(!event.result, "No results");
ok(!event.target.result, "No results");
testGenerator.next();
}
yield;
@ -50,7 +50,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
ok(!event.result, "No results");
ok(!event.target.result, "No results");
testGenerator.next();
}
yield;
@ -60,7 +60,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
ok(!event.result, "No results");
ok(!event.target.result, "No results");
testGenerator.next();
}
yield;
@ -70,7 +70,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
ok(!event.result, "No results");
ok(!event.target.result, "No results");
testGenerator.next();
}
yield;
@ -93,7 +93,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -128,7 +128,7 @@
request = objectStore.openCursor(range);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -153,7 +153,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -183,7 +183,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -213,7 +213,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -243,7 +243,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -274,7 +274,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, "bar", "Update succeeded");
is(event.target.result, "bar", "Update succeeded");
request = objectStore.put("foo", sortedKeys[4]);
request.onerror = errorHandler;
@ -289,7 +289,7 @@
request = objectStore.openCursor(null, IDBCursor.NEXT);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");
@ -298,7 +298,7 @@
request = cursor.delete();
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, sortedKeys[4], "Correct key");
is(event.target.result, sortedKeys[4], "Correct key");
is(keyIndex, 5, "Got result of remove before next continue");
gotRemoveEvent = true;
};
@ -321,7 +321,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, undefined, "Entry was deleted");
is(event.target.result, undefined, "Entry was deleted");
request = objectStore.add("foo", sortedKeys[4]);
request.onerror = errorHandler;
@ -333,7 +333,7 @@
request = objectStore.openCursor(null, IDBCursor.PREV);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, sortedKeys[keyIndex], "Correct key");
is(cursor.value, "foo", "Correct value");

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

@ -22,16 +22,16 @@
request.onsuccess = grabEventAndContinueHandler;
var event = yield;
ok(event.source === mozIndexedDB, "correct event.source");
ok(event.target.source === mozIndexedDB, "correct event.target.source");
var db = event.result;
var db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.source === db, "correct event.source");
ok(event.target.source === db, "correct event.target.source");
var objectStore = db.createObjectStore(objectStoreName,
{ autoIncrement: true });
@ -40,7 +40,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.source === objectStore, "correct event.source");
ok(event.target.source === objectStore, "correct event.source");
finishTest();
yield;

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

@ -23,7 +23,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -37,8 +37,8 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 0, "No elements");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 0, "No elements");
let addedCount = 0;
@ -58,11 +58,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, values.length, "Same length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, values.length, "Same length");
for (let i in event.result) {
is(event.result[i], values[i], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[i], "Same value");
}
request = db.transaction("foo").objectStore("foo").getAll(null, 5);
@ -70,11 +70,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 5, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 5, "Correct length");
for (let i in event.result) {
is(event.result[i], values[i], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[i], "Same value");
}
let keyRange = IDBKeyRange.bound(1, 9);
@ -84,11 +84,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, values.length, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, values.length, "Correct length");
for (let i in event.result) {
is(event.result[i], values[i], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[i], "Same value");
}
keyRange = IDBKeyRange.bound(4, 7);
@ -98,11 +98,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 4, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.result) {
is(event.result[i], values[parseInt(i) + 3], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
// Get should take a key range also.
@ -111,11 +111,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 4, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.result) {
is(event.result[i], values[parseInt(i) + 3], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = IDBKeyRange.bound(4, 7);
@ -125,11 +125,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 2, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 2, "Correct length");
for (let i in event.result) {
is(event.result[i], values[parseInt(i) + 3], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = IDBKeyRange.bound(4, 7);
@ -139,11 +139,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 4, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.result) {
is(event.result[i], values[parseInt(i) + 3], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 3], "Same value");
}
keyRange = IDBKeyRange.bound(4, 7);
@ -153,8 +153,8 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 0, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 0, "Correct length");
keyRange = IDBKeyRange.bound(4, 7, true, true);
@ -163,11 +163,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 2, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 2, "Correct length");
for (let i in event.result) {
is(event.result[i], values[parseInt(i) + 4], "Same value");
for (let i in event.target.result) {
is(event.target.result[i], values[parseInt(i) + 4], "Same value");
}
finishTest();

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

@ -23,7 +23,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db1 = event.result;
let db1 = event.target.result;
request = db1.setVersion("1");
request.onerror = errorHandler;
@ -42,7 +42,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let db2 = event.result;
let db2 = event.target.result;
ok(db1 !== db2, "Databases are not the same object");

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

@ -63,7 +63,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -107,11 +107,11 @@
event = yield;
ok(true, "3");
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 2, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 2, "Correct length");
for (let i in event.result) {
is(event.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
for (let i in event.target.result) {
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
"Correct key");
}
@ -121,12 +121,12 @@
event = yield;
ok(true, "4");
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, objectStoreDataHeightSort.length,
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, objectStoreDataHeightSort.length,
"Correct length");
for (let i in event.result) {
is(event.result[i], objectStoreDataHeightSort[i].key, "Correct key");
for (let i in event.target.result) {
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
}
request = objectStore.index("height").getAllKeys(null, 4);
@ -135,11 +135,11 @@
event = yield;
ok(true, "5");
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 4, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.result) {
is(event.result[i], objectStoreDataHeightSort[i].key, "Correct key");
for (let i in event.target.result) {
is(event.target.result[i], objectStoreDataHeightSort[i].key, "Correct key");
}
request = objectStore.index("height").getAllKeys(65, 1);
@ -148,11 +148,11 @@
event = yield;
ok(true, "6");
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 1, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 1, "Correct length");
for (let i in event.result) {
is(event.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
for (let i in event.target.result) {
is(event.target.result[i], objectStoreDataHeightSort[parseInt(i) + 3].key,
"Correct key");
}

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

@ -63,7 +63,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -104,11 +104,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 2, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 2, "Correct length");
for (let i in event.result) {
let result = event.result[i];
for (let i in event.target.result) {
let result = event.target.result[i];
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
is(result.name, testObj.name, "Correct name");
@ -124,12 +124,12 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, objectStoreDataHeightSort.length,
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, objectStoreDataHeightSort.length,
"Correct length");
for (let i in event.result) {
let result = event.result[i];
for (let i in event.target.result) {
let result = event.target.result[i];
let testObj = objectStoreDataHeightSort[i].value;
is(result.name, testObj.name, "Correct name");
@ -145,11 +145,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 4, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 4, "Correct length");
for (let i in event.result) {
let result = event.result[i];
for (let i in event.target.result) {
let result = event.target.result[i];
let testObj = objectStoreDataHeightSort[i].value;
is(result.name, testObj.name, "Correct name");
@ -165,11 +165,11 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result instanceof Array, true, "Got an array object");
is(event.result.length, 1, "Correct length");
is(event.target.result instanceof Array, true, "Got an array object");
is(event.target.result.length, 1, "Correct length");
for (let i in event.result) {
let result = event.result[i];
for (let i in event.target.result) {
let result = event.target.result[i];
let testObj = objectStoreDataHeightSort[parseInt(i) + 3].value;
is(result.name, testObj.name, "Correct name");

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

@ -35,13 +35,13 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
db.onerror = errorHandler;
db.setVersion("1").onsuccess = grabEventAndContinueHandler;
event = yield;
event.result.oncomplete = continueToNextStep;
event.target.result.oncomplete = continueToNextStep;
for (let objectStoreIndex in objectStoreData) {
const objectStoreInfo = objectStoreData[objectStoreIndex];
@ -85,7 +85,7 @@
let keyIndex = 0;
index.openCursor().onsuccess = function(event) {
let cursor = event.result;
let cursor = event.target.result;
if (!cursor) {
continueToNextStep();
return;
@ -123,7 +123,7 @@
db.transaction(objectStoreName).objectStore(objectStoreName)
.openCursor()
.onsuccess = function(event) {
let cursor = event.result;
let cursor = event.target.result;
if (!cursor) {
continueToNextStep();
return;

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

@ -74,7 +74,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -133,16 +133,16 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, "237-23-7732", "Correct key returned!");
is(event.target.result, "237-23-7732", "Correct key returned!");
request = objectStore.index("name").get("Bob");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result.name, "Bob", "Correct name returned!");
is(event.result.height, 60, "Correct height returned!");
is(event.result.weight, 120, "Correct weight returned!");
is(event.target.result.name, "Bob", "Correct name returned!");
is(event.target.result.height, 60, "Correct height returned!");
is(event.target.result.weight, 120, "Correct weight returned!");
ok(true, "Test group 1");
@ -151,7 +151,7 @@
request = objectStore.index("name").openKeyCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -182,7 +182,7 @@
request = objectStore.index("weight").openKeyCursor(null, NEXT);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
"Correct key");
@ -222,7 +222,7 @@
request = objectStore.index("name").openKeyCursor(null, PREV);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -254,7 +254,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -280,7 +280,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -306,7 +306,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -332,7 +332,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -358,7 +358,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -384,7 +384,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -410,7 +410,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -436,7 +436,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -462,7 +462,7 @@
request = objectStore.index("name").openKeyCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -487,7 +487,7 @@
request = objectStore.index("name").openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -534,7 +534,7 @@
request = objectStore.index("name").openCursor(null, PREV);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -582,7 +582,7 @@
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -630,7 +630,7 @@
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -678,7 +678,7 @@
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -726,7 +726,7 @@
request = objectStore.index("name").openCursor(keyRange);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -774,7 +774,7 @@
request = objectStore.index("name").openCursor(keyRange, PREV);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -823,7 +823,7 @@
request = objectStore.index("height").openKeyCursor(keyRange, NEXT);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -850,7 +850,7 @@
NEXT_NO_DUPLICATE);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -876,7 +876,7 @@
PREV_NO_DUPLICATE);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -905,7 +905,7 @@
request = objectStore.index("height").openCursor(keyRange, NEXT);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -940,7 +940,7 @@
NEXT_NO_DUPLICATE);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -974,7 +974,7 @@
PREV_NO_DUPLICATE);
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataHeightSort[keyIndex].value.height,
"Correct key");
@ -1010,7 +1010,7 @@
request = objectStore.index("name").openKeyCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -1048,7 +1048,7 @@
request = objectStore.index("name").openKeyCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -1081,7 +1081,7 @@
request = objectStore.index("name").openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");
@ -1135,7 +1135,7 @@
request = objectStore.index("name").openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataNameSort[keyIndex].value.name,
"Correct key");

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

@ -54,7 +54,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -102,7 +102,7 @@
request = objectStore.index("weight").openKeyCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
is(cursor.key, objectStoreDataWeightSort[keyIndex].value.weight,
"Correct key");
@ -125,7 +125,7 @@
request = objectStore.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
let cursor = event.result;
let cursor = event.target.result;
if (cursor) {
keyIndex++;
cursor.continue();

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

@ -21,7 +21,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
db.addEventListener("error", function(event) {
event.preventDefault();
}, false);
@ -38,14 +38,14 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let key1 = event.result;
let key1 = event.target.result;
request = objectStore.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "put gave the same key back");
is(event.target.result, key1, "put gave the same key back");
let key2 = 10;
@ -54,7 +54,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "put gave the same key back");
is(event.target.result, key2, "put gave the same key back");
key2 = 100;
@ -63,7 +63,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "put gave the same key back");
is(event.target.result, key2, "put gave the same key back");
try {
objectStore.put({});
@ -172,21 +172,21 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "add gave back the same key");
is(event.target.result, key1, "add gave back the same key");
request = objectStore.put({id:10});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "put gave back the same key");
is(event.target.result, key1, "put gave back the same key");
request = objectStore.put({id:10});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "put gave back the same key");
is(event.target.result, key1, "put gave back the same key");
request = objectStore.add({id:10});
request.onerror = new ExpectError(IDBDatabaseException.CONSTRAINT_ERR);
@ -233,14 +233,14 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
key1 = event.result;
key1 = event.target.result;
request = objectStore.put({id:key1});
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key1, "put gave the same key back");
is(event.target.result, key1, "put gave the same key back");
key2 = 10;
@ -249,7 +249,7 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
is(event.result, key2, "put gave the same key back");
is(event.target.result, key2, "put gave the same key back");
try {
objectStore.put({});

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

@ -31,7 +31,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
for (let i in objectStores) {
request = db.setVersion("1");
@ -58,13 +58,13 @@
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.result == 1 || event.result == 2, "Good id");
ok(event.target.result == 1 || event.target.result == 2, "Good id");
}
SimpleTest.executeSoon(function() { testGenerator.next(); });
yield;
let objectStore = event.result;
let objectStore = event.target.result;
for (let i in objectStores) {
for (let j in indexes) {
@ -75,7 +75,7 @@
request = index.openCursor();
request.onerror = errorHandler;
request.onsuccess = function (event) {
is(event.result.value.name, "Ben", "Good object");
is(event.target.result.value.name, "Ben", "Good object");
SimpleTest.executeSoon(function() { testGenerator.next(); });
}
yield;

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

@ -24,7 +24,7 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
var event = yield;
var db = event.result;
var db = event.target.result;
var test = {
name: "inline key; key generator",
@ -47,18 +47,18 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let id = event.result;
let id = event.target.result;
request = objectStore.get(id);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
// Sanity check!
is(event.result.name, test.storedObject.name,
is(event.target.result.name, test.storedObject.name,
"The correct object was stored.");
// Ensure that the id was also stored on the object.
is(event.result.id, id, "The object had the id stored on it.");
is(event.target.result.id, id, "The object had the id stored on it.");
finishTest();
yield;

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

@ -24,7 +24,7 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
var event = yield;
var db = event.result;
var db = event.target.result;
var data = [
{ name: "inline key; key generator",
@ -71,14 +71,14 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let id = event.result;
let id = event.target.result;
request = objectStore.get(id);
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
// Sanity check!
is(test.storedObject.name, event.result.name,
is(test.storedObject.name, event.target.result.name,
"The correct object was stored.");
request = objectStore.delete(id);
@ -92,7 +92,7 @@ function testSteps()
request.onsuccess = grabEventAndContinueHandler;
event = yield;
ok(event.result === undefined, "Object was deleted");
ok(event.target.result === undefined, "Object was deleted");
}
finishTest();

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

@ -18,14 +18,14 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
request.onsuccess = grabEventAndContinueHandler;
event = yield;
let transaction = event.transaction;
let transaction = event.target.transaction;
let objectStore1 = db.createObjectStore("foo");
let objectStore2 = transaction.objectStore("foo");

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

@ -43,11 +43,16 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.name, name, "Bad name");
is(db.version, "", "Bad version");
is(db.objectStoreNames.length, 0, "Bad objectStores list");
is(db.name, request.result.name, "Bad name");
is(db.version, request.result.version, "Bad version");
is(db.objectStoreNames.length, request.result.objectStoreNames.length,
"Bad objectStores list");
finishTest();
yield;
}

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

@ -23,7 +23,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Bad objectStores list");
request = db.setVersion("1");

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

@ -24,13 +24,13 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
request = db.setVersion("1");
request.onerror = errorHandler;
request.onsuccess = function(event) {
event.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.oncomplete = grabEventAndContinueHandler;
for (let i in objectStores) {
db.createObjectStore(objectStores[i], { autoIncrement: true });
}
@ -86,7 +86,7 @@
request.onsuccess = function(event) {
is(stepNumber, 5, "This callback came fifth");
stepNumber++;
event.transaction.oncomplete = grabEventAndContinueHandler;
event.target.transaction.oncomplete = grabEventAndContinueHandler;
}
stepNumber++;

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

@ -25,7 +25,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -38,22 +38,22 @@
request = objectStore.add(testString.value, testString.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testString.key, "Got the right key");
is(event.target.result, testString.key, "Got the right key");
request = objectStore.get(testString.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testString.value, "Got the right value");
is(event.target.result, testString.value, "Got the right value");
};
};
request = objectStore.add(testInt.value, testInt.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testInt.key, "Got the right key");
is(event.target.result, testInt.key, "Got the right key");
request = objectStore.get(testInt.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testInt.value, "Got the right value");
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}

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

@ -25,7 +25,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
request = db.setVersion("1");
request.onerror = errorHandler;
@ -38,22 +38,22 @@
request = objectStore.add(testString.value);
request.onerror = errorHandler;
request.onsuccess = function(event) {
testString.key = event.result;
testString.key = event.target.result;
request = objectStore.get(testString.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testString.value, "Got the right value");
is(event.target.result, testString.value, "Got the right value");
};
};
request = objectStore.add(testInt.value);
request.onerror = errorHandler;
request.onsuccess = function(event) {
testInt.key = event.result;
testInt.key = event.target.result;
request = objectStore.get(testInt.key);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.result, testInt.value, "Got the right value");
is(event.target.result, testInt.value, "Got the right value");
finishTest();
};
}

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

@ -25,7 +25,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
request = db.setVersion("1");
@ -42,8 +42,8 @@
.add({});
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
key1 = event.result;
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
key1 = event.target.result;
testGenerator.next();
}
yield;
@ -51,8 +51,8 @@
request = db.transaction(osName, READ_WRITE).objectStore(osName).add({});
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
key2 = event.result;
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
key2 = event.target.result;
testGenerator.next();
}
yield;
@ -62,7 +62,7 @@
.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;
@ -72,7 +72,7 @@
.put({}, key2);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;
@ -82,7 +82,7 @@
.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;
@ -92,7 +92,7 @@
.put({}, key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;
@ -102,7 +102,7 @@
.delete(key1);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;
@ -112,7 +112,7 @@
.delete(key2);
request.onerror = errorHandler;
request.onsuccess = function(event) {
is(event.transaction.mode, READ_WRITE, "Correct mode");
is(event.target.transaction.mode, READ_WRITE, "Correct mode");
testGenerator.next();
}
yield;

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

@ -24,7 +24,7 @@
request.onsuccess = grabEventAndContinueHandler;
let event = yield;
let db = event.result;
let db = event.target.result;
is(db.objectStoreNames.length, 0, "Correct objectStoreNames list");
request = db.setVersion("1");

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