зеркало из https://github.com/mozilla/gecko-dev.git
Merge tracemonkey and mozilla-central.
This commit is contained in:
Коммит
6806325137
|
@ -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;
|
||||
|
|
190
build/cl.py
190
build/cl.py
|
@ -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',
|
||||
}
|
||||
|
||||
|
|
454
build/upload.py
454
build/upload.py
|
@ -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)
|
||||
|
|
100
build/util.py
100
build/util.py
|
@ -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 :=
|
||||
|
|
10
configure.in
10
configure.in
|
@ -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");
|
||||
|
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче