accessibility-developer-tools
Version:
This is a library of accessibility-related testing and utility code.
214 lines (183 loc) • 6.34 kB
JavaScript
// Copyright 2011 The Closure Library Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS-IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/**
* @fileoverview Wrapper for an IndexedDB transaction.
*
*/
goog.provide('goog.db.Transaction');
goog.provide('goog.db.Transaction.TransactionMode');
goog.require('goog.async.Deferred');
goog.require('goog.db.Error');
goog.require('goog.db.ObjectStore');
goog.require('goog.events');
goog.require('goog.events.EventHandler');
goog.require('goog.events.EventTarget');
/**
* Creates a new transaction. Transactions contain methods for accessing object
* stores and are created from the database object. Should not be created
* directly, open a database and call createTransaction on it.
* @see goog.db.IndexedDb#createTransaction
*
* @param {!IDBTransaction} tx IndexedDB transaction to back this wrapper.
* @param {!goog.db.IndexedDb} db The database that this transaction modifies.
* @constructor
* @extends {goog.events.EventTarget}
* @final
*/
goog.db.Transaction = function(tx, db) {
goog.db.Transaction.base(this, 'constructor');
/**
* Underlying IndexedDB transaction object.
*
* @type {!IDBTransaction}
* @private
*/
this.tx_ = tx;
/**
* The database that this transaction modifies.
*
* @type {!goog.db.IndexedDb}
* @private
*/
this.db_ = db;
/**
* Event handler for this transaction.
*
* @type {!goog.events.EventHandler<!goog.db.Transaction>}
* @private
*/
this.eventHandler_ = new goog.events.EventHandler(this);
// TODO(user): remove these casts once the externs file is updated to
// correctly reflect that IDBTransaction extends EventTarget
this.eventHandler_.listen(
/** @type {!EventTarget} */ (this.tx_), 'complete',
goog.bind(
this.dispatchEvent, this, goog.db.Transaction.EventTypes.COMPLETE));
this.eventHandler_.listen(
/** @type {!EventTarget} */ (this.tx_), 'abort',
goog.bind(
this.dispatchEvent, this, goog.db.Transaction.EventTypes.ABORT));
this.eventHandler_.listen(
/** @type {!EventTarget} */ (this.tx_), 'error', this.dispatchError_);
};
goog.inherits(goog.db.Transaction, goog.events.EventTarget);
/**
* Dispatches an error event based on the given event, wrapping the error
* if necessary.
*
* @param {Event} ev The error event given to the underlying IDBTransaction.
* @private
*/
goog.db.Transaction.prototype.dispatchError_ = function(ev) {
if (ev.target instanceof goog.db.Error) {
this.dispatchEvent(
{type: goog.db.Transaction.EventTypes.ERROR, target: ev.target});
} else {
this.dispatchEvent({
type: goog.db.Transaction.EventTypes.ERROR,
target: goog.db.Error.fromRequest(
/** @type {!IDBRequest} */ (ev.target), 'in transaction')
});
}
};
/**
* Event types the Transaction can dispatch. COMPLETE events are dispatched
* when the transaction is committed. If a transaction is aborted it dispatches
* both an ABORT event and an ERROR event with the ABORT_ERR code. Error events
* are dispatched on any error.
*
* @enum {string}
*/
goog.db.Transaction.EventTypes = {
COMPLETE: 'complete',
ABORT: 'abort',
ERROR: 'error'
};
/**
* @return {goog.db.Transaction.TransactionMode} The transaction's mode.
*/
goog.db.Transaction.prototype.getMode = function() {
return /** @type {goog.db.Transaction.TransactionMode} */ (this.tx_.mode);
};
/**
* @return {!goog.db.IndexedDb} The database that this transaction modifies.
*/
goog.db.Transaction.prototype.getDatabase = function() {
return this.db_;
};
/**
* Opens an object store to do operations on in this transaction. The requested
* object store must be one that is in this transaction's scope.
* @see goog.db.IndexedDb#createTransaction
*
* @param {string} name The name of the requested object store.
* @return {!goog.db.ObjectStore} The wrapped object store.
* @throws {goog.db.Error} In case of error getting the object store.
*/
goog.db.Transaction.prototype.objectStore = function(name) {
try {
return new goog.db.ObjectStore(this.tx_.objectStore(name));
} catch (ex) {
throw goog.db.Error.fromException(ex, 'getting object store ' + name);
}
};
/**
* @return {!goog.async.Deferred} A deferred that will fire once the
* transaction is complete. It fires the errback chain if an error occurs
* in the transaction, or if it is aborted.
*/
goog.db.Transaction.prototype.wait = function() {
var d = new goog.async.Deferred();
goog.events.listenOnce(
this, goog.db.Transaction.EventTypes.COMPLETE, goog.bind(d.callback, d));
var errorKey;
var abortKey = goog.events.listenOnce(
this, goog.db.Transaction.EventTypes.ABORT, function() {
goog.events.unlistenByKey(errorKey);
d.errback(
new goog.db.Error(
goog.db.Error.ErrorCode.ABORT_ERR,
'waiting for transaction to complete'));
});
errorKey = goog.events.listenOnce(
this, goog.db.Transaction.EventTypes.ERROR, function(e) {
goog.events.unlistenByKey(abortKey);
d.errback(e.target);
});
var db = this.getDatabase();
return d.addCallback(function() { return db; });
};
/**
* Aborts this transaction. No pending operations will be applied to the
* database. Dispatches an ABORT event.
*/
goog.db.Transaction.prototype.abort = function() {
this.tx_.abort();
};
/** @override */
goog.db.Transaction.prototype.disposeInternal = function() {
goog.db.Transaction.base(this, 'disposeInternal');
this.eventHandler_.dispose();
};
/**
* The three possible transaction modes.
* @see http://www.w3.org/TR/IndexedDB/#idl-def-IDBTransaction
*
* @enum {string}
*/
goog.db.Transaction.TransactionMode = {
READ_ONLY: 'readonly',
READ_WRITE: 'readwrite',
VERSION_CHANGE: 'versionchange'
};