Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(413)

Unified Diff: lib/src/firebase/firebase-debug.js

Issue 1418513006: update elements and fix some bugs (Closed) Base URL: git@github.com:dart-lang/polymer_elements.git@master
Patch Set: code review updates Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « lib/src/firebase/firebase.js ('k') | lib/src/ga-api-utils/build/ga-api-utils.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/src/firebase/firebase-debug.js
diff --git a/lib/src/firebase/firebase-debug.js b/lib/src/firebase/firebase-debug.js
index 91dd2138ad2394f7fd842ab4e4b4da8bbcbe9f23..3b4589a15f9c745912b3717fd19e80fcadd3d705 100644
--- a/lib/src/firebase/firebase-debug.js
+++ b/lib/src/firebase/firebase-debug.js
@@ -1,4 +1,4 @@
-/*! @license Firebase v2.2.9
+/*! @license Firebase v2.3.1
License: https://www.firebase.com/terms/terms-of-service.html */
(function(ns) {
ns.wrapper = function(goog, fb) {
@@ -6,7 +6,7 @@
var CLOSURE_NO_DEPS = true;
// Sets CLIENT_VERSION manually, since we can't use a closure --define with WHITESPACE_ONLY compilation.
- var CLIENT_VERSION = '2.2.9';
+ var CLIENT_VERSION = '2.3.1';
var COMPILED = false;
var goog = goog || {};
goog.global = this;
@@ -4132,161 +4132,6 @@ fb.core.util.ServerValues.resolveDeferredValueSnapshot = function(node, serverVa
return newNode;
}
};
-goog.provide("fb.core.util.Path");
-goog.provide("fb.core.util.ValidationPath");
-fb.core.util.Path = goog.defineClass(null, {constructor:function(pathOrString, opt_pieceNum) {
- if (arguments.length == 1) {
- this.pieces_ = pathOrString.split("/");
- var copyTo = 0;
- for (var i = 0;i < this.pieces_.length;i++) {
- if (this.pieces_[i].length > 0) {
- this.pieces_[copyTo] = this.pieces_[i];
- copyTo++;
- }
- }
- this.pieces_.length = copyTo;
- this.pieceNum_ = 0;
- } else {
- this.pieces_ = pathOrString;
- this.pieceNum_ = opt_pieceNum;
- }
-}, getFront:function() {
- if (this.pieceNum_ >= this.pieces_.length) {
- return null;
- }
- return this.pieces_[this.pieceNum_];
-}, getLength:function() {
- return this.pieces_.length - this.pieceNum_;
-}, popFront:function() {
- var pieceNum = this.pieceNum_;
- if (pieceNum < this.pieces_.length) {
- pieceNum++;
- }
- return new fb.core.util.Path(this.pieces_, pieceNum);
-}, getBack:function() {
- if (this.pieceNum_ < this.pieces_.length) {
- return this.pieces_[this.pieces_.length - 1];
- }
- return null;
-}, toString:function() {
- var pathString = "";
- for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
- if (this.pieces_[i] !== "") {
- pathString += "/" + this.pieces_[i];
- }
- }
- return pathString || "/";
-}, toUrlEncodedString:function() {
- var pathString = "";
- for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
- if (this.pieces_[i] !== "") {
- pathString += "/" + goog.string.urlEncode(this.pieces_[i]);
- }
- }
- return pathString || "/";
-}, slice:function(opt_begin) {
- var begin = opt_begin || 0;
- return this.pieces_.slice(this.pieceNum_ + begin);
-}, parent:function() {
- if (this.pieceNum_ >= this.pieces_.length) {
- return null;
- }
- var pieces = [];
- for (var i = this.pieceNum_;i < this.pieces_.length - 1;i++) {
- pieces.push(this.pieces_[i]);
- }
- return new fb.core.util.Path(pieces, 0);
-}, child:function(childPathObj) {
- var pieces = [];
- for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
- pieces.push(this.pieces_[i]);
- }
- if (childPathObj instanceof fb.core.util.Path) {
- for (i = childPathObj.pieceNum_;i < childPathObj.pieces_.length;i++) {
- pieces.push(childPathObj.pieces_[i]);
- }
- } else {
- var childPieces = childPathObj.split("/");
- for (i = 0;i < childPieces.length;i++) {
- if (childPieces[i].length > 0) {
- pieces.push(childPieces[i]);
- }
- }
- }
- return new fb.core.util.Path(pieces, 0);
-}, isEmpty:function() {
- return this.pieceNum_ >= this.pieces_.length;
-}, statics:{relativePath:function(outerPath, innerPath) {
- var outer = outerPath.getFront(), inner = innerPath.getFront();
- if (outer === null) {
- return innerPath;
- } else {
- if (outer === inner) {
- return fb.core.util.Path.relativePath(outerPath.popFront(), innerPath.popFront());
- } else {
- throw new Error("INTERNAL ERROR: innerPath (" + innerPath + ") is not within " + "outerPath (" + outerPath + ")");
- }
- }
-}}, equals:function(other) {
- if (this.getLength() !== other.getLength()) {
- return false;
- }
- for (var i = this.pieceNum_, j = other.pieceNum_;i <= this.pieces_.length;i++, j++) {
- if (this.pieces_[i] !== other.pieces_[j]) {
- return false;
- }
- }
- return true;
-}, contains:function(other) {
- var i = this.pieceNum_;
- var j = other.pieceNum_;
- if (this.getLength() > other.getLength()) {
- return false;
- }
- while (i < this.pieces_.length) {
- if (this.pieces_[i] !== other.pieces_[j]) {
- return false;
- }
- ++i;
- ++j;
- }
- return true;
-}});
-fb.core.util.Path.Empty = new fb.core.util.Path("");
-fb.core.util.ValidationPath = goog.defineClass(null, {constructor:function(path, errorPrefix) {
- this.parts_ = path.slice();
- this.byteLength_ = Math.max(1, this.parts_.length);
- this.errorPrefix_ = errorPrefix;
- for (var i = 0;i < this.parts_.length;i++) {
- this.byteLength_ += fb.util.utf8.stringLength(this.parts_[i]);
- }
- this.checkValid_();
-}, statics:{MAX_PATH_DEPTH:32, MAX_PATH_LENGTH_BYTES:768}, push:function(child) {
- if (this.parts_.length > 0) {
- this.byteLength_ += 1;
- }
- this.parts_.push(child);
- this.byteLength_ += fb.util.utf8.stringLength(child);
- this.checkValid_();
-}, pop:function() {
- var last = this.parts_.pop();
- this.byteLength_ -= fb.util.utf8.stringLength(last);
- if (this.parts_.length > 0) {
- this.byteLength_ -= 1;
- }
-}, checkValid_:function() {
- if (this.byteLength_ > fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES) {
- throw new Error(this.errorPrefix_ + "has a key path longer than " + fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES + " bytes (" + this.byteLength_ + ").");
- }
- if (this.parts_.length > fb.core.util.ValidationPath.MAX_PATH_DEPTH) {
- throw new Error(this.errorPrefix_ + "path specified exceeds the maximum depth that can be written (" + fb.core.util.ValidationPath.MAX_PATH_DEPTH + ") or object contains a cycle " + this.toErrorString());
- }
-}, toErrorString:function() {
- if (this.parts_.length == 0) {
- return "";
- }
- return "in property '" + this.parts_.join(".") + "'";
-}});
goog.provide("fb.core.storage.MemoryStorage");
goog.require("fb.util.obj");
goog.scope(function() {
@@ -4395,6 +4240,28 @@ fb.core.RepoInfo.prototype.updateHost = function(newHost) {
}
}
};
+fb.core.RepoInfo.prototype.connectionURL = function(type, params) {
+ fb.core.util.assert(typeof type === "string", "typeof type must == string");
+ fb.core.util.assert(typeof params === "object", "typeof params must == object");
+ var connURL;
+ if (type === fb.realtime.Constants.WEBSOCKET) {
+ connURL = (this.secure ? "wss://" : "ws://") + this.internalHost + "/.ws?";
+ } else {
+ if (type === fb.realtime.Constants.LONG_POLLING) {
+ connURL = (this.secure ? "https://" : "http://") + this.internalHost + "/.lp?";
+ } else {
+ throw new Error("Unknown connection type: " + type);
+ }
+ }
+ if (this.needsQueryParam()) {
+ params["ns"] = this.namespace;
+ }
+ var pairs = [];
+ goog.object.forEach(params, function(element, index, obj) {
+ pairs.push(index + "=" + element);
+ });
+ return connURL + pairs.join("&");
+};
fb.core.RepoInfo.prototype.toString = function() {
var str = (this.secure ? "https://" : "http://") + this.host;
if (this.persistenceKey) {
@@ -5482,15 +5349,15 @@ fb.core.view.ViewProcessor.prototype.assertIndexed = function(viewCache) {
};
fb.core.view.ViewProcessor.prototype.applyOperation = function(oldViewCache, operation, writesCache, optCompleteCache) {
var accumulator = new fb.core.view.ChildChangeAccumulator;
- var newViewCache, constrainNode;
+ var newViewCache, filterServerNode;
if (operation.type === fb.core.OperationType.OVERWRITE) {
var overwrite = (operation);
if (overwrite.source.fromUser) {
newViewCache = this.applyUserOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, optCompleteCache, accumulator);
} else {
fb.core.util.assert(overwrite.source.fromServer, "Unknown source.");
- constrainNode = overwrite.source.tagged;
- newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, optCompleteCache, constrainNode, accumulator);
+ filterServerNode = overwrite.source.tagged || oldViewCache.getServerCache().isFiltered() && !overwrite.path.isEmpty();
+ newViewCache = this.applyServerOverwrite_(oldViewCache, overwrite.path, overwrite.snap, writesCache, optCompleteCache, filterServerNode, accumulator);
}
} else {
if (operation.type === fb.core.OperationType.MERGE) {
@@ -5499,8 +5366,8 @@ fb.core.view.ViewProcessor.prototype.applyOperation = function(oldViewCache, ope
newViewCache = this.applyUserMerge_(oldViewCache, merge.path, merge.children, writesCache, optCompleteCache, accumulator);
} else {
fb.core.util.assert(merge.source.fromServer, "Unknown source.");
- constrainNode = merge.source.tagged;
- newViewCache = this.applyServerMerge_(oldViewCache, merge.path, merge.children, writesCache, optCompleteCache, constrainNode, accumulator);
+ filterServerNode = merge.source.tagged || oldViewCache.getServerCache().isFiltered();
+ newViewCache = this.applyServerMerge_(oldViewCache, merge.path, merge.children, writesCache, optCompleteCache, filterServerNode, accumulator);
}
} else {
if (operation.type === fb.core.OperationType.ACK_USER_WRITE) {
@@ -5586,10 +5453,10 @@ fb.core.view.ViewProcessor.prototype.generateEventCacheAfterServerEvent_ = funct
return viewCache.updateEventSnap(newEventCache, oldEventSnap.isFullyInitialized() || changePath.isEmpty(), this.filter_.filtersNodes());
}
};
-fb.core.view.ViewProcessor.prototype.applyServerOverwrite_ = function(oldViewCache, changePath, changedSnap, writesCache, optCompleteCache, constrainServerNode, accumulator) {
+fb.core.view.ViewProcessor.prototype.applyServerOverwrite_ = function(oldViewCache, changePath, changedSnap, writesCache, optCompleteCache, filterServerNode, accumulator) {
var oldServerSnap = oldViewCache.getServerCache();
var newServerCache;
- var serverFilter = constrainServerNode ? this.filter_ : this.filter_.getIndexedFilter();
+ var serverFilter = filterServerNode ? this.filter_ : this.filter_.getIndexedFilter();
if (changePath.isEmpty()) {
newServerCache = serverFilter.updateFullNode(oldServerSnap.getNode(), changedSnap, null);
} else {
@@ -5681,7 +5548,7 @@ fb.core.view.ViewProcessor.prototype.applyMerge_ = function(node, merge) {
});
return node;
};
-fb.core.view.ViewProcessor.prototype.applyServerMerge_ = function(viewCache, path, changedChildren, writesCache, serverCache, constrainServerNode, accumulator) {
+fb.core.view.ViewProcessor.prototype.applyServerMerge_ = function(viewCache, path, changedChildren, writesCache, serverCache, filterServerNode, accumulator) {
if (viewCache.getServerCache().getNode().isEmpty() && !viewCache.getServerCache().isFullyInitialized()) {
return viewCache;
}
@@ -5698,7 +5565,7 @@ fb.core.view.ViewProcessor.prototype.applyServerMerge_ = function(viewCache, pat
if (serverNode.hasChild(childKey)) {
var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);
var newChild = self.applyMerge_(serverChild, childTree);
- curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, constrainServerNode, accumulator);
+ curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);
}
});
viewMergeTree.children.inorderTraversal(function(childKey, childMergeTree) {
@@ -5706,7 +5573,7 @@ fb.core.view.ViewProcessor.prototype.applyServerMerge_ = function(viewCache, pat
if (!serverNode.hasChild(childKey) && !isUnknownDeepMerge) {
var serverChild = viewCache.getServerCache().getNode().getImmediateChild(childKey);
var newChild = self.applyMerge_(serverChild, childMergeTree);
- curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, constrainServerNode, accumulator);
+ curViewCache = self.applyServerOverwrite_(curViewCache, new fb.core.util.Path(childKey), newChild, writesCache, serverCache, filterServerNode, accumulator);
}
});
return curViewCache;
@@ -5715,17 +5582,18 @@ fb.core.view.ViewProcessor.prototype.ackUserWrite_ = function(viewCache, ackPath
if (writesCache.shadowingWrite(ackPath) != null) {
return viewCache;
}
+ var filterServerNode = viewCache.getServerCache().isFiltered();
var serverCache = viewCache.getServerCache();
if (affectedTree.value != null) {
if (ackPath.isEmpty() && serverCache.isFullyInitialized() || serverCache.isCompleteForPath(ackPath)) {
- return this.applyServerOverwrite_(viewCache, ackPath, serverCache.getNode().getChild(ackPath), writesCache, optCompleteCache, false, accumulator);
+ return this.applyServerOverwrite_(viewCache, ackPath, serverCache.getNode().getChild(ackPath), writesCache, optCompleteCache, filterServerNode, accumulator);
} else {
if (ackPath.isEmpty()) {
var changedChildren = (fb.core.util.ImmutableTree.Empty);
serverCache.getNode().forEachChild(fb.core.snap.KeyIndex, function(name, node) {
changedChildren = changedChildren.set(new fb.core.util.Path(name), node);
});
- return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, optCompleteCache, false, accumulator);
+ return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, optCompleteCache, filterServerNode, accumulator);
} else {
return viewCache;
}
@@ -5738,7 +5606,7 @@ fb.core.view.ViewProcessor.prototype.ackUserWrite_ = function(viewCache, ackPath
changedChildren = changedChildren.set(mergePath, serverCache.getNode().getChild(serverCachePath));
}
});
- return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, optCompleteCache, false, accumulator);
+ return this.applyServerMerge_(viewCache, ackPath, changedChildren, writesCache, optCompleteCache, filterServerNode, accumulator);
}
};
fb.core.view.ViewProcessor.prototype.revertUserWrite_ = function(viewCache, path, writesCache, optCompleteServerCache, accumulator) {
@@ -5792,9 +5660,10 @@ fb.core.view.ViewProcessor.prototype.listenComplete_ = function(viewCache, path,
return this.generateEventCacheAfterServerEvent_(newViewCache, path, writesCache, fb.core.view.NO_COMPLETE_CHILD_SOURCE, accumulator);
};
goog.provide("fb.core.snap.Index");
+goog.provide("fb.core.snap.KeyIndex");
+goog.provide("fb.core.snap.PathIndex");
goog.provide("fb.core.snap.PriorityIndex");
-goog.provide("fb.core.snap.SubKeyIndex");
-goog.require("fb.core.snap.comparators");
+goog.provide("fb.core.snap.ValueIndex");
goog.require("fb.core.util");
fb.core.snap.Index = function() {
};
@@ -5816,18 +5685,19 @@ fb.core.snap.Index.prototype.minPost = function() {
fb.core.snap.Index.prototype.maxPost = goog.abstractMethod;
fb.core.snap.Index.prototype.makePost = goog.abstractMethod;
fb.core.snap.Index.prototype.toString = goog.abstractMethod;
-fb.core.snap.SubKeyIndex = function(indexKey) {
+fb.core.snap.PathIndex = function(indexPath) {
fb.core.snap.Index.call(this);
- this.indexKey_ = indexKey;
+ fb.core.util.assert(!indexPath.isEmpty() && indexPath.getFront() !== ".priority", "Can't create PathIndex with empty path or .priority key");
+ this.indexPath_ = indexPath;
};
-goog.inherits(fb.core.snap.SubKeyIndex, fb.core.snap.Index);
-fb.core.snap.SubKeyIndex.prototype.extractChild = function(snap) {
- return snap.getImmediateChild(this.indexKey_);
+goog.inherits(fb.core.snap.PathIndex, fb.core.snap.Index);
+fb.core.snap.PathIndex.prototype.extractChild = function(snap) {
+ return snap.getChild(this.indexPath_);
};
-fb.core.snap.SubKeyIndex.prototype.isDefinedOn = function(node) {
- return!node.getImmediateChild(this.indexKey_).isEmpty();
+fb.core.snap.PathIndex.prototype.isDefinedOn = function(node) {
+ return!node.getChild(this.indexPath_).isEmpty();
};
-fb.core.snap.SubKeyIndex.prototype.compare = function(a, b) {
+fb.core.snap.PathIndex.prototype.compare = function(a, b) {
var aChild = this.extractChild(a.node);
var bChild = this.extractChild(b.node);
var indexCmp = aChild.compareTo(bChild);
@@ -5837,17 +5707,17 @@ fb.core.snap.SubKeyIndex.prototype.compare = function(a, b) {
return indexCmp;
}
};
-fb.core.snap.SubKeyIndex.prototype.makePost = function(indexValue, name) {
+fb.core.snap.PathIndex.prototype.makePost = function(indexValue, name) {
var valueNode = fb.core.snap.NodeFromJSON(indexValue);
- var node = fb.core.snap.EMPTY_NODE.updateImmediateChild(this.indexKey_, valueNode);
+ var node = fb.core.snap.EMPTY_NODE.updateChild(this.indexPath_, valueNode);
return new fb.core.snap.NamedNode(name, node);
};
-fb.core.snap.SubKeyIndex.prototype.maxPost = function() {
- var node = fb.core.snap.EMPTY_NODE.updateImmediateChild(this.indexKey_, fb.core.snap.MAX_NODE);
+fb.core.snap.PathIndex.prototype.maxPost = function() {
+ var node = fb.core.snap.EMPTY_NODE.updateChild(this.indexPath_, fb.core.snap.MAX_NODE);
return new fb.core.snap.NamedNode(fb.core.util.MAX_NAME, node);
};
-fb.core.snap.SubKeyIndex.prototype.toString = function() {
- return this.indexKey_;
+fb.core.snap.PathIndex.prototype.toString = function() {
+ return this.indexPath_.slice().join("/");
};
fb.core.snap.PriorityIndex_ = function() {
fb.core.snap.Index.call(this);
@@ -6155,7 +6025,7 @@ fb.core.view.QueryParams.prototype.toRestQueryStringParameters = function() {
if (this.index_ === fb.core.snap.KeyIndex) {
orderBy = REST_CONSTANTS.KEY_INDEX;
} else {
- fb.core.util.assert(this.index_ instanceof fb.core.snap.SubKeyIndex, "Unrecognized index type!");
+ fb.core.util.assert(this.index_ instanceof fb.core.snap.PathIndex, "Unrecognized index type!");
orderBy = this.index_.toString();
}
}
@@ -7159,19 +7029,328 @@ fb.core.ReadonlyRestClient = goog.defineClass(null, {constructor:function(repoIn
}
callback(xhr.status);
}
- callback = null;
+ callback = null;
+ }
+ };
+ xhr.open("GET", url, true);
+ xhr.send();
+}, statics:{getListenId_:function(query, opt_tag) {
+ if (goog.isDef(opt_tag)) {
+ return "tag$" + opt_tag;
+ } else {
+ fb.core.util.assert(query.getQueryParams().isDefault(), "should have a tag if it's not a default query.");
+ return query.path.toString();
+ }
+}}});
+goog.provide("fb.core.util.EventEmitter");
+goog.require("fb.core.util");
+goog.require("goog.array");
+fb.core.util.EventEmitter = goog.defineClass(null, {constructor:function(allowedEvents) {
+ fb.core.util.assert(goog.isArray(allowedEvents) && allowedEvents.length > 0, "Requires a non-empty array");
+ this.allowedEvents_ = allowedEvents;
+ this.listeners_ = {};
+}, getInitialEvent:goog.abstractMethod, trigger:function(eventType, var_args) {
+ var listeners = goog.array.clone(this.listeners_[eventType] || []);
+ for (var i = 0;i < listeners.length;i++) {
+ listeners[i].callback.apply(listeners[i].context, Array.prototype.slice.call(arguments, 1));
+ }
+}, on:function(eventType, callback, context) {
+ this.validateEventType_(eventType);
+ this.listeners_[eventType] = this.listeners_[eventType] || [];
+ this.listeners_[eventType].push({callback:callback, context:context});
+ var eventData = this.getInitialEvent(eventType);
+ if (eventData) {
+ callback.apply(context, eventData);
+ }
+}, off:function(eventType, callback, context) {
+ this.validateEventType_(eventType);
+ var listeners = this.listeners_[eventType] || [];
+ for (var i = 0;i < listeners.length;i++) {
+ if (listeners[i].callback === callback && (!context || context === listeners[i].context)) {
+ listeners.splice(i, 1);
+ return;
+ }
+ }
+}, validateEventType_:function(eventType) {
+ fb.core.util.assert(goog.array.find(this.allowedEvents_, function(et) {
+ return et === eventType;
+ }), "Unknown event: " + eventType);
+}});
+goog.provide("fb.core.util.nextPushId");
+goog.require("fb.core.util");
+fb.core.util.nextPushId = function() {
+ var PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
+ var lastPushTime = 0;
+ var lastRandChars = [];
+ return function(now) {
+ var duplicateTime = now === lastPushTime;
+ lastPushTime = now;
+ var timeStampChars = new Array(8);
+ for (var i = 7;i >= 0;i--) {
+ timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
+ now = Math.floor(now / 64);
+ }
+ fb.core.util.assert(now === 0, "Cannot push at time == 0");
+ var id = timeStampChars.join("");
+ if (!duplicateTime) {
+ for (i = 0;i < 12;i++) {
+ lastRandChars[i] = Math.floor(Math.random() * 64);
+ }
+ } else {
+ for (i = 11;i >= 0 && lastRandChars[i] === 63;i--) {
+ lastRandChars[i] = 0;
+ }
+ lastRandChars[i]++;
+ }
+ for (i = 0;i < 12;i++) {
+ id += PUSH_CHARS.charAt(lastRandChars[i]);
+ }
+ fb.core.util.assert(id.length === 20, "nextPushId: Length should be 20.");
+ return id;
+ };
+}();
+goog.provide("fb.core.util.OnlineMonitor");
+goog.require("fb.core.util");
+goog.require("fb.core.util.EventEmitter");
+fb.core.util.OnlineMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
+ fb.core.util.EventEmitter.call(this, ["online"]);
+ this.online_ = true;
+ if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
+ var self = this;
+ window.addEventListener("online", function() {
+ if (!self.online_) {
+ self.online_ = true;
+ self.trigger("online", true);
+ }
+ }, false);
+ window.addEventListener("offline", function() {
+ if (self.online_) {
+ self.online_ = false;
+ self.trigger("online", false);
+ }
+ }, false);
+ }
+}, getInitialEvent:function(eventType) {
+ fb.core.util.assert(eventType === "online", "Unknown event type: " + eventType);
+ return[this.online_];
+}, currentlyOnline:function() {
+ return this.online_;
+}});
+goog.addSingletonGetter(fb.core.util.OnlineMonitor);
+goog.provide("fb.core.util.VisibilityMonitor");
+goog.require("fb.core.util");
+goog.require("fb.core.util.EventEmitter");
+fb.core.util.VisibilityMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
+ fb.core.util.EventEmitter.call(this, ["visible"]);
+ var hidden, visibilityChange;
+ if (typeof document !== "undefined" && typeof document.addEventListener !== "undefined") {
+ if (typeof document["hidden"] !== "undefined") {
+ visibilityChange = "visibilitychange";
+ hidden = "hidden";
+ } else {
+ if (typeof document["mozHidden"] !== "undefined") {
+ visibilityChange = "mozvisibilitychange";
+ hidden = "mozHidden";
+ } else {
+ if (typeof document["msHidden"] !== "undefined") {
+ visibilityChange = "msvisibilitychange";
+ hidden = "msHidden";
+ } else {
+ if (typeof document["webkitHidden"] !== "undefined") {
+ visibilityChange = "webkitvisibilitychange";
+ hidden = "webkitHidden";
+ }
+ }
+ }
+ }
+ }
+ this.visible_ = true;
+ if (visibilityChange) {
+ var self = this;
+ document.addEventListener(visibilityChange, function() {
+ var visible = !document[hidden];
+ if (visible !== self.visible_) {
+ self.visible_ = visible;
+ self.trigger("visible", visible);
+ }
+ }, false);
+ }
+}, getInitialEvent:function(eventType) {
+ fb.core.util.assert(eventType === "visible", "Unknown event type: " + eventType);
+ return[this.visible_];
+}});
+goog.addSingletonGetter(fb.core.util.VisibilityMonitor);
+goog.provide("fb.core.util.Path");
+goog.provide("fb.core.util.ValidationPath");
+goog.require("fb.core.util");
+goog.require("fb.util.utf8");
+goog.require("goog.string");
+fb.core.util.Path = goog.defineClass(null, {constructor:function(pathOrString, opt_pieceNum) {
+ if (arguments.length == 1) {
+ this.pieces_ = pathOrString.split("/");
+ var copyTo = 0;
+ for (var i = 0;i < this.pieces_.length;i++) {
+ if (this.pieces_[i].length > 0) {
+ this.pieces_[copyTo] = this.pieces_[i];
+ copyTo++;
+ }
+ }
+ this.pieces_.length = copyTo;
+ this.pieceNum_ = 0;
+ } else {
+ this.pieces_ = pathOrString;
+ this.pieceNum_ = opt_pieceNum;
+ }
+}, getFront:function() {
+ if (this.pieceNum_ >= this.pieces_.length) {
+ return null;
+ }
+ return this.pieces_[this.pieceNum_];
+}, getLength:function() {
+ return this.pieces_.length - this.pieceNum_;
+}, popFront:function() {
+ var pieceNum = this.pieceNum_;
+ if (pieceNum < this.pieces_.length) {
+ pieceNum++;
+ }
+ return new fb.core.util.Path(this.pieces_, pieceNum);
+}, getBack:function() {
+ if (this.pieceNum_ < this.pieces_.length) {
+ return this.pieces_[this.pieces_.length - 1];
+ }
+ return null;
+}, toString:function() {
+ var pathString = "";
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ if (this.pieces_[i] !== "") {
+ pathString += "/" + this.pieces_[i];
+ }
+ }
+ return pathString || "/";
+}, toUrlEncodedString:function() {
+ var pathString = "";
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ if (this.pieces_[i] !== "") {
+ pathString += "/" + goog.string.urlEncode(this.pieces_[i]);
+ }
+ }
+ return pathString || "/";
+}, slice:function(opt_begin) {
+ var begin = opt_begin || 0;
+ return this.pieces_.slice(this.pieceNum_ + begin);
+}, parent:function() {
+ if (this.pieceNum_ >= this.pieces_.length) {
+ return null;
+ }
+ var pieces = [];
+ for (var i = this.pieceNum_;i < this.pieces_.length - 1;i++) {
+ pieces.push(this.pieces_[i]);
+ }
+ return new fb.core.util.Path(pieces, 0);
+}, child:function(childPathObj) {
+ var pieces = [];
+ for (var i = this.pieceNum_;i < this.pieces_.length;i++) {
+ pieces.push(this.pieces_[i]);
+ }
+ if (childPathObj instanceof fb.core.util.Path) {
+ for (i = childPathObj.pieceNum_;i < childPathObj.pieces_.length;i++) {
+ pieces.push(childPathObj.pieces_[i]);
+ }
+ } else {
+ var childPieces = childPathObj.split("/");
+ for (i = 0;i < childPieces.length;i++) {
+ if (childPieces[i].length > 0) {
+ pieces.push(childPieces[i]);
+ }
}
- };
- xhr.open("GET", url, true);
- xhr.send();
-}, statics:{getListenId_:function(query, opt_tag) {
- if (goog.isDef(opt_tag)) {
- return "tag$" + opt_tag;
+ }
+ return new fb.core.util.Path(pieces, 0);
+}, isEmpty:function() {
+ return this.pieceNum_ >= this.pieces_.length;
+}, statics:{relativePath:function(outerPath, innerPath) {
+ var outer = outerPath.getFront(), inner = innerPath.getFront();
+ if (outer === null) {
+ return innerPath;
} else {
- fb.core.util.assert(query.getQueryParams().isDefault(), "should have a tag if it's not a default query.");
- return query.path.toString();
+ if (outer === inner) {
+ return fb.core.util.Path.relativePath(outerPath.popFront(), innerPath.popFront());
+ } else {
+ throw new Error("INTERNAL ERROR: innerPath (" + innerPath + ") is not within " + "outerPath (" + outerPath + ")");
+ }
}
-}}});
+}, comparePaths:function(left, right) {
+ var leftKeys = left.slice();
+ var rightKeys = right.slice();
+ for (var i = 0;i < leftKeys.length && i < rightKeys.length;i++) {
+ var cmp = fb.core.util.nameCompare(leftKeys[i], rightKeys[i]);
+ if (cmp !== 0) {
+ return cmp;
+ }
+ }
+ if (leftKeys.length === rightKeys.length) {
+ return 0;
+ }
+ return leftKeys.length < rightKeys.length ? -1 : 1;
+}}, equals:function(other) {
+ if (this.getLength() !== other.getLength()) {
+ return false;
+ }
+ for (var i = this.pieceNum_, j = other.pieceNum_;i <= this.pieces_.length;i++, j++) {
+ if (this.pieces_[i] !== other.pieces_[j]) {
+ return false;
+ }
+ }
+ return true;
+}, contains:function(other) {
+ var i = this.pieceNum_;
+ var j = other.pieceNum_;
+ if (this.getLength() > other.getLength()) {
+ return false;
+ }
+ while (i < this.pieces_.length) {
+ if (this.pieces_[i] !== other.pieces_[j]) {
+ return false;
+ }
+ ++i;
+ ++j;
+ }
+ return true;
+}});
+fb.core.util.Path.Empty = new fb.core.util.Path("");
+fb.core.util.ValidationPath = goog.defineClass(null, {constructor:function(path, errorPrefix) {
+ this.parts_ = path.slice();
+ this.byteLength_ = Math.max(1, this.parts_.length);
+ this.errorPrefix_ = errorPrefix;
+ for (var i = 0;i < this.parts_.length;i++) {
+ this.byteLength_ += fb.util.utf8.stringLength(this.parts_[i]);
+ }
+ this.checkValid_();
+}, statics:{MAX_PATH_DEPTH:32, MAX_PATH_LENGTH_BYTES:768}, push:function(child) {
+ if (this.parts_.length > 0) {
+ this.byteLength_ += 1;
+ }
+ this.parts_.push(child);
+ this.byteLength_ += fb.util.utf8.stringLength(child);
+ this.checkValid_();
+}, pop:function() {
+ var last = this.parts_.pop();
+ this.byteLength_ -= fb.util.utf8.stringLength(last);
+ if (this.parts_.length > 0) {
+ this.byteLength_ -= 1;
+ }
+}, checkValid_:function() {
+ if (this.byteLength_ > fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES) {
+ throw new Error(this.errorPrefix_ + "has a key path longer than " + fb.core.util.ValidationPath.MAX_PATH_LENGTH_BYTES + " bytes (" + this.byteLength_ + ").");
+ }
+ if (this.parts_.length > fb.core.util.ValidationPath.MAX_PATH_DEPTH) {
+ throw new Error(this.errorPrefix_ + "path specified exceeds the maximum depth that can be written (" + fb.core.util.ValidationPath.MAX_PATH_DEPTH + ") or object contains a cycle " + this.toErrorString());
+ }
+}, toErrorString:function() {
+ if (this.parts_.length == 0) {
+ return "";
+ }
+ return "in property '" + this.parts_.join(".") + "'";
+}});
goog.provide("fb.core.util.ImmutableTree");
goog.require("fb.core.util");
goog.require("fb.core.util.Path");
@@ -8133,7 +8312,7 @@ fb.core.SyncTree.prototype.removeEventRegistration = function(query, eventRegist
for (var i = 0;i < newViews.length;++i) {
var view = newViews[i], newQuery = view.getQuery();
var listener = this.createListenerForView_(view);
- this.listenProvider_.startListening(newQuery, this.tagForQuery_(newQuery), listener.hashFn, listener.onComplete);
+ this.listenProvider_.startListening(this.queryForListening_(newQuery), this.tagForQuery_(newQuery), listener.hashFn, listener.onComplete);
}
} else {
}
@@ -8141,13 +8320,13 @@ fb.core.SyncTree.prototype.removeEventRegistration = function(query, eventRegist
if (!covered && removed.length > 0 && !cancelError) {
if (removingDefault) {
var defaultTag = null;
- this.listenProvider_.stopListening(query, defaultTag);
+ this.listenProvider_.stopListening(this.queryForListening_(query), defaultTag);
} else {
var self = this;
goog.array.forEach(removed, function(queryToRemove) {
var queryIdToRemove = queryToRemove.queryIdentifier();
var tagToRemove = self.queryToTagMap_[self.makeQueryKey_(queryToRemove)];
- self.listenProvider_.stopListening(queryToRemove, tagToRemove);
+ self.listenProvider_.stopListening(self.queryForListening_(queryToRemove), tagToRemove);
});
}
}
@@ -8196,11 +8375,18 @@ fb.core.SyncTree.prototype.removeTags_ = function(queries) {
}
}
};
+fb.core.SyncTree.prototype.queryForListening_ = function(query) {
+ if (query.getQueryParams().loadsAllData() && !query.getQueryParams().isDefault()) {
+ return(query.ref());
+ } else {
+ return query;
+ }
+};
fb.core.SyncTree.prototype.setupListener_ = function(query, view) {
var path = query.path;
var tag = this.tagForQuery_(query);
var listener = this.createListenerForView_(view);
- var events = this.listenProvider_.startListening(query, tag, listener.hashFn, listener.onComplete);
+ var events = this.listenProvider_.startListening(this.queryForListening_(query), tag, listener.hashFn, listener.onComplete);
var subtree = this.syncPointTree_.subtree(path);
if (tag) {
fb.core.util.assert(!subtree.value.hasCompleteView(), "If we're adding a query, it shouldn't be shadowed");
@@ -8223,7 +8409,7 @@ fb.core.SyncTree.prototype.setupListener_ = function(query, view) {
});
for (var i = 0;i < queriesToStop.length;++i) {
var queryToStop = queriesToStop[i];
- this.listenProvider_.stopListening(queryToStop, this.tagForQuery_(queryToStop));
+ this.listenProvider_.stopListening(this.queryForListening_(queryToStop), this.tagForQuery_(queryToStop));
}
}
return events;
@@ -8414,144 +8600,6 @@ fb.core.util.Tree = goog.defineClass(null, {constructor:function(opt_name, opt_p
}
}
}});
-goog.provide("fb.core.util.EventEmitter");
-goog.require("fb.core.util");
-goog.require("goog.array");
-fb.core.util.EventEmitter = goog.defineClass(null, {constructor:function(allowedEvents) {
- fb.core.util.assert(goog.isArray(allowedEvents) && allowedEvents.length > 0, "Requires a non-empty array");
- this.allowedEvents_ = allowedEvents;
- this.listeners_ = {};
-}, getInitialEvent:goog.abstractMethod, trigger:function(eventType, var_args) {
- var listeners = this.listeners_[eventType] || [];
- for (var i = 0;i < listeners.length;i++) {
- listeners[i].callback.apply(listeners[i].context, Array.prototype.slice.call(arguments, 1));
- }
-}, on:function(eventType, callback, context) {
- this.validateEventType_(eventType);
- this.listeners_[eventType] = this.listeners_[eventType] || [];
- this.listeners_[eventType].push({callback:callback, context:context});
- var eventData = this.getInitialEvent(eventType);
- if (eventData) {
- callback.apply(context, eventData);
- }
-}, off:function(eventType, callback, context) {
- this.validateEventType_(eventType);
- var listeners = this.listeners_[eventType] || [];
- for (var i = 0;i < listeners.length;i++) {
- if (listeners[i].callback === callback && (!context || context === listeners[i].context)) {
- listeners.splice(i, 1);
- return;
- }
- }
-}, validateEventType_:function(eventType) {
- fb.core.util.assert(goog.array.find(this.allowedEvents_, function(et) {
- return et === eventType;
- }), "Unknown event: " + eventType);
-}});
-goog.provide("fb.core.util.nextPushId");
-goog.require("fb.core.util");
-fb.core.util.nextPushId = function() {
- var PUSH_CHARS = "-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
- var lastPushTime = 0;
- var lastRandChars = [];
- return function(now) {
- var duplicateTime = now === lastPushTime;
- lastPushTime = now;
- var timeStampChars = new Array(8);
- for (var i = 7;i >= 0;i--) {
- timeStampChars[i] = PUSH_CHARS.charAt(now % 64);
- now = Math.floor(now / 64);
- }
- fb.core.util.assert(now === 0, "Cannot push at time == 0");
- var id = timeStampChars.join("");
- if (!duplicateTime) {
- for (i = 0;i < 12;i++) {
- lastRandChars[i] = Math.floor(Math.random() * 64);
- }
- } else {
- for (i = 11;i >= 0 && lastRandChars[i] === 63;i--) {
- lastRandChars[i] = 0;
- }
- lastRandChars[i]++;
- }
- for (i = 0;i < 12;i++) {
- id += PUSH_CHARS.charAt(lastRandChars[i]);
- }
- fb.core.util.assert(id.length === 20, "nextPushId: Length should be 20.");
- return id;
- };
-}();
-goog.provide("fb.core.util.OnlineMonitor");
-goog.require("fb.core.util");
-goog.require("fb.core.util.EventEmitter");
-fb.core.util.OnlineMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
- fb.core.util.EventEmitter.call(this, ["online"]);
- this.online_ = true;
- if (typeof window !== "undefined" && typeof window.addEventListener !== "undefined") {
- var self = this;
- window.addEventListener("online", function() {
- if (!self.online_) {
- self.online_ = true;
- self.trigger("online", true);
- }
- }, false);
- window.addEventListener("offline", function() {
- if (self.online_) {
- self.online_ = false;
- self.trigger("online", false);
- }
- }, false);
- }
-}, getInitialEvent:function(eventType) {
- fb.core.util.assert(eventType === "online", "Unknown event type: " + eventType);
- return[this.online_];
-}, currentlyOnline:function() {
- return this.online_;
-}});
-goog.addSingletonGetter(fb.core.util.OnlineMonitor);
-goog.provide("fb.core.util.VisibilityMonitor");
-goog.require("fb.core.util");
-goog.require("fb.core.util.EventEmitter");
-fb.core.util.VisibilityMonitor = goog.defineClass(fb.core.util.EventEmitter, {constructor:function() {
- fb.core.util.EventEmitter.call(this, ["visible"]);
- var hidden, visibilityChange;
- if (typeof document !== "undefined" && typeof document.addEventListener !== "undefined") {
- if (typeof document["hidden"] !== "undefined") {
- visibilityChange = "visibilitychange";
- hidden = "hidden";
- } else {
- if (typeof document["mozHidden"] !== "undefined") {
- visibilityChange = "mozvisibilitychange";
- hidden = "mozHidden";
- } else {
- if (typeof document["msHidden"] !== "undefined") {
- visibilityChange = "msvisibilitychange";
- hidden = "msHidden";
- } else {
- if (typeof document["webkitHidden"] !== "undefined") {
- visibilityChange = "webkitvisibilitychange";
- hidden = "webkitHidden";
- }
- }
- }
- }
- }
- this.visible_ = true;
- if (visibilityChange) {
- var self = this;
- document.addEventListener(visibilityChange, function() {
- var visible = !document[hidden];
- if (visible !== self.visible_) {
- self.visible_ = visible;
- self.trigger("visible", visible);
- }
- }, false);
- }
-}, getInitialEvent:function(eventType) {
- fb.core.util.assert(eventType === "visible", "Unknown event type: " + eventType);
- return[this.visible_];
-}});
-goog.addSingletonGetter(fb.core.util.VisibilityMonitor);
goog.provide("fb.core.util.validation");
goog.require("fb.core.util");
goog.require("fb.core.util.Path");
@@ -8612,17 +8660,49 @@ fb.core.util.validation = {INVALID_KEY_REGEX_:/[\[\].#$\/\u0000-\u001F\u007F]/,
throw new Error(errorPrefix + ' contains ".value" child ' + path.toErrorString() + " in addition to actual children.");
}
}
+}, validateFirebaseMergePaths:function(errorPrefix, mergePaths) {
+ var i, curPath;
+ for (i = 0;i < mergePaths.length;i++) {
+ curPath = mergePaths[i];
+ var keys = curPath.slice();
+ for (var j = 0;j < keys.length;j++) {
+ if (keys[j] === ".priority" && j === keys.length - 1) {
+ } else {
+ if (!fb.core.util.validation.isValidKey(keys[j])) {
+ throw new Error(errorPrefix + "contains an invalid key (" + keys[j] + ") in path " + curPath.toString() + ". Keys must be non-empty strings " + 'and can\'t contain ".", "#", "$", "/", "[", or "]"');
+ }
+ }
+ }
+ }
+ mergePaths.sort(fb.core.util.Path.comparePaths);
+ var prevPath = null;
+ for (i = 0;i < mergePaths.length;i++) {
+ curPath = mergePaths[i];
+ if (prevPath !== null && prevPath.contains(curPath)) {
+ throw new Error(errorPrefix + "contains a path " + prevPath.toString() + " that is ancestor of another path " + curPath.toString());
+ }
+ prevPath = curPath;
+ }
}, validateFirebaseMergeDataArg:function(fnName, argumentNumber, data, path, optional) {
if (optional && !goog.isDef(data)) {
return;
}
+ var errorPrefix = fb.util.validation.errorPrefix(fnName, argumentNumber, optional);
if (!goog.isObject(data) || goog.isArray(data)) {
- throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + " must be an Object containing " + "the children to replace.");
+ throw new Error(errorPrefix + " must be an object containing the children to replace.");
}
- if (fb.util.obj.contains(data, ".value")) {
- throw new Error(fb.util.validation.errorPrefix(fnName, argumentNumber, optional) + ' must not contain ".value". ' + "To overwrite with a leaf value, just use .set() instead.");
- }
- fb.core.util.validation.validateFirebaseDataArg(fnName, argumentNumber, data, path, optional);
+ var mergePaths = [];
+ fb.util.obj.foreach(data, function(key, value) {
+ var curPath = new fb.core.util.Path(key);
+ fb.core.util.validation.validateFirebaseData(errorPrefix, value, path.child(curPath));
+ if (curPath.getBack() === ".priority") {
+ if (!fb.core.util.validation.isValidPriority(value)) {
+ throw new Error(errorPrefix + "contains an invalid value for '" + curPath.toString() + "', which must be a valid " + "Firebase priority (a string, finite number, server value, or null).");
+ }
+ }
+ mergePaths.push(curPath);
+ });
+ fb.core.util.validation.validateFirebaseMergePaths(errorPrefix, mergePaths);
}, validatePriority:function(fnName, argumentNumber, priority, optional) {
if (optional && !goog.isDef(priority)) {
return;
@@ -9947,7 +10027,7 @@ fb.realtime.Transport.prototype.send = function(data) {
fb.realtime.Transport.prototype.bytesReceived;
fb.realtime.Transport.prototype.bytesSent;
goog.provide("fb.realtime.Constants");
-fb.realtime.Constants = {PROTOCOL_VERSION:"5", VERSION_PARAM:"v", SESSION_PARAM:"s", REFERER_PARAM:"r", FORGE_REF:"f", FORGE_DOMAIN:"firebaseio.com"};
+fb.realtime.Constants = {PROTOCOL_VERSION:"5", VERSION_PARAM:"v", TRANSPORT_SESSION_PARAM:"s", REFERER_PARAM:"r", FORGE_REF:"f", FORGE_DOMAIN:"firebaseio.com", LAST_SESSION_PARAM:"ls", WEBSOCKET:"websocket", LONG_POLLING:"long_polling"};
goog.provide("fb.realtime.polling.PacketReceiver");
fb.realtime.polling.PacketReceiver = function(onMessage) {
this.onMessage_ = onMessage;
@@ -10015,26 +10095,18 @@ var SEG_HEADER_SIZE = 30;
var MAX_PAYLOAD_SIZE = MAX_URL_DATA_SIZE - SEG_HEADER_SIZE;
var KEEPALIVE_REQUEST_INTERVAL = 25E3;
var LP_CONNECT_TIMEOUT = 3E4;
-fb.realtime.BrowserPollConnection = function(connId, repoInfo, sessionId) {
+fb.realtime.BrowserPollConnection = function(connId, repoInfo, opt_transportSessionId, opt_lastSessionId) {
this.connId = connId;
this.log_ = fb.core.util.logWrapper(connId);
this.repoInfo = repoInfo;
this.bytesSent = 0;
this.bytesReceived = 0;
this.stats_ = fb.core.stats.StatsManager.getCollection(repoInfo);
- this.sessionId = sessionId;
+ this.transportSessionId = opt_transportSessionId;
this.everConnected_ = false;
+ this.lastSessionId = opt_lastSessionId;
this.urlFn = function(params) {
- if (repoInfo.needsQueryParam()) {
- params["ns"] = repoInfo.namespace;
- }
- var pairs = [];
- for (var k in params) {
- if (params.hasOwnProperty(k)) {
- pairs.push(k + "=" + params[k]);
- }
- }
- return(repoInfo.secure ? "https://" : "http://") + repoInfo.internalHost + "/.lp?" + pairs.join("&");
+ return repoInfo.connectionURL(fb.realtime.Constants.LONG_POLLING, params);
};
};
fb.realtime.BrowserPollConnection.prototype.open = function(onMessage, onDisconnect) {
@@ -10092,8 +10164,11 @@ fb.realtime.BrowserPollConnection.prototype.open = function(onMessage, onDisconn
urlParams[FIREBASE_LONGPOLL_CALLBACK_ID_PARAM] = self.scriptTagHolder.uniqueCallbackIdentifier;
}
urlParams[fb.realtime.Constants.VERSION_PARAM] = fb.realtime.Constants.PROTOCOL_VERSION;
- if (self.sessionId) {
- urlParams[fb.realtime.Constants.SESSION_PARAM] = self.sessionId;
+ if (self.transportSessionId) {
+ urlParams[fb.realtime.Constants.TRANSPORT_SESSION_PARAM] = self.transportSessionId;
+ }
+ if (self.lastSessionId) {
+ urlParams[fb.realtime.Constants.LAST_SESSION_PARAM] = self.lastSessionId;
}
if (!NODE_CLIENT && typeof location !== "undefined" && location.href && location.href.indexOf(fb.realtime.Constants.FORGE_DOMAIN) !== -1) {
urlParams[fb.realtime.Constants.REFERER_PARAM] = fb.realtime.Constants.FORGE_REF;
@@ -10408,7 +10483,7 @@ if (NODE_CLIENT) {
}
}
}
-fb.realtime.WebSocketConnection = function(connId, repoInfo, sessionId) {
+fb.realtime.WebSocketConnection = function(connId, repoInfo, opt_transportSessionId, opt_lastSessionId) {
this.connId = connId;
this.log_ = fb.core.util.logWrapper(this.connId);
this.keepaliveTimer = null;
@@ -10417,16 +10492,21 @@ fb.realtime.WebSocketConnection = function(connId, repoInfo, sessionId) {
this.bytesSent = 0;
this.bytesReceived = 0;
this.stats_ = fb.core.stats.StatsManager.getCollection(repoInfo);
- this.connURL = (repoInfo.secure ? "wss://" : "ws://") + repoInfo.internalHost + "/.ws?" + fb.realtime.Constants.VERSION_PARAM + "=" + fb.realtime.Constants.PROTOCOL_VERSION;
+ this.connURL = this.connectionURL_(repoInfo, opt_transportSessionId, opt_lastSessionId);
+};
+fb.realtime.WebSocketConnection.prototype.connectionURL_ = function(repoInfo, opt_transportSessionId, opt_lastSessionId) {
+ var urlParams = {};
+ urlParams[fb.realtime.Constants.VERSION_PARAM] = fb.realtime.Constants.PROTOCOL_VERSION;
if (!NODE_CLIENT && typeof location !== "undefined" && location.href && location.href.indexOf(fb.realtime.Constants.FORGE_DOMAIN) !== -1) {
- this.connURL = this.connURL + "&" + fb.realtime.Constants.REFERER_PARAM + "=" + fb.realtime.Constants.FORGE_REF;
+ urlParams[fb.realtime.Constants.REFERER_PARAM] = fb.realtime.Constants.FORGE_REF;
}
- if (repoInfo.needsQueryParam()) {
- this.connURL = this.connURL + "&ns=" + repoInfo.namespace;
+ if (opt_transportSessionId) {
+ urlParams[fb.realtime.Constants.TRANSPORT_SESSION_PARAM] = opt_transportSessionId;
}
- if (sessionId) {
- this.connURL = this.connURL + "&" + fb.realtime.Constants.SESSION_PARAM + "=" + sessionId;
+ if (opt_lastSessionId) {
+ urlParams[fb.realtime.Constants.LAST_SESSION_PARAM] = opt_lastSessionId;
}
+ return repoInfo.connectionURL(fb.realtime.Constants.WEBSOCKET, urlParams);
};
fb.realtime.WebSocketConnection.prototype.open = function(onMess, onDisconn) {
this.onDisconnect = onDisconn;
@@ -10655,7 +10735,7 @@ var SWITCH_ACK = "a";
var END_TRANSMISSION = "n";
var PING = "p";
var SERVER_HELLO = "h";
-fb.realtime.Connection = function(connId, repoInfo, onMessage, onReady, onDisconnect, onKill) {
+fb.realtime.Connection = function(connId, repoInfo, onMessage, onReady, onDisconnect, onKill, lastSessionId) {
this.id = connId;
this.log_ = fb.core.util.logWrapper("c:" + this.id + ":");
this.onMessage_ = onMessage;
@@ -10667,12 +10747,13 @@ fb.realtime.Connection = function(connId, repoInfo, onMessage, onReady, onDiscon
this.connectionCount = 0;
this.transportManager_ = new fb.realtime.TransportManager(repoInfo);
this.state_ = REALTIME_STATE_CONNECTING;
+ this.lastSessionId = lastSessionId;
this.log_("Connection created");
this.start_();
};
fb.realtime.Connection.prototype.start_ = function() {
var conn = this.transportManager_.initialTransport();
- this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_);
+ this.conn_ = new conn(this.nextTransportId_(), this.repoInfo_, undefined, this.lastSessionId);
this.primaryResponsesRequired_ = conn["responsesRequiredToBeHealthy"] || 0;
var onMessageReceived = this.connReceiver_(this.conn_);
var onConnectionLost = this.disconnReceiver_(this.conn_);
@@ -10919,7 +11000,7 @@ fb.realtime.Connection.prototype.onConnectionEstablished_ = function(conn, times
this.conn_ = conn;
this.state_ = REALTIME_STATE_CONNECTED;
if (this.onReady_) {
- this.onReady_(timestamp);
+ this.onReady_(timestamp, this.sessionId);
this.onReady_ = null;
}
var self = this;
@@ -11033,6 +11114,7 @@ fb.core.PersistentConnection = goog.defineClass(null, {constructor:function(repo
this.onServerInfoUpdate_ = onServerInfoUpdate;
this.repoInfo_ = repoInfo;
this.securityDebugCallback_ = null;
+ this.lastSessionId = null;
this.realtime_ = null;
this.credential_ = null;
this.establishConnectionTimer_ = null;
@@ -11061,6 +11143,7 @@ fb.core.PersistentConnection = goog.defineClass(null, {constructor:function(repo
var pathString = query.path.toString();
this.log_("Listen called for " + pathString + " " + queryId);
this.listens_[pathString] = this.listens_[pathString] || {};
+ fb.core.util.assert(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), "listen() called for non-default but complete query");
fb.core.util.assert(!this.listens_[pathString][queryId], "listen() called twice for same path/queryId.");
var listenSpec = {onComplete:onComplete, hashFn:currentHashFn, query:query, tag:tag};
this.listens_[pathString][queryId] = listenSpec;
@@ -11151,6 +11234,7 @@ fb.core.PersistentConnection = goog.defineClass(null, {constructor:function(repo
var pathString = query.path.toString();
var queryId = query.queryIdentifier();
this.log_("Unlisten called for " + pathString + " " + queryId);
+ fb.core.util.assert(query.getQueryParams().isDefault() || !query.getQueryParams().loadsAllData(), "unlisten() called for non-default but complete query");
var listen = this.removeListen_(pathString, queryId);
if (listen && this.connected_) {
this.sendUnlisten_(pathString, queryId, query.queryObject(), tag);
@@ -11281,11 +11365,12 @@ fb.core.PersistentConnection = goog.defineClass(null, {constructor:function(repo
}
}
}
-}, onReady_:function(timestamp) {
+}, onReady_:function(timestamp, sessionId) {
this.log_("connection ready");
this.connected_ = true;
this.lastConnectionEstablishedTime_ = (new Date).getTime();
this.handleTimestamp_(timestamp);
+ this.lastSessionId = sessionId;
if (this.firstConnection_) {
this.sendConnectStats_();
}
@@ -11362,10 +11447,11 @@ fb.core.PersistentConnection = goog.defineClass(null, {constructor:function(repo
var onDisconnect = goog.bind(this.onRealtimeDisconnect_, this);
var connId = this.id + ":" + fb.core.PersistentConnection.nextConnectionId_++;
var self = this;
+ var lastSessionId = this.lastSessionId;
this.realtime_ = new fb.realtime.Connection(connId, this.repoInfo_, onDataMessage, onReady, onDisconnect, function(reason) {
fb.core.util.warn(reason + " (" + self.repoInfo_.toString() + ")");
self.killed_ = true;
- });
+ }, lastSessionId);
}
}, interrupt:function() {
this.interrupted_ = true;
@@ -12381,7 +12467,7 @@ fb.api.Query = goog.defineClass(null, {constructor:function(repo, path, queryPar
throw new Error("Query: When ordering by priority, the first argument passed to startAt(), " + "endAt(), or equalTo() must be a valid priority value (null, a number, or a string).");
}
} else {
- fb.core.util.assert(params.getIndex() instanceof fb.core.snap.SubKeyIndex || params.getIndex() === fb.core.snap.ValueIndex, "unknown index type.");
+ fb.core.util.assert(params.getIndex() instanceof fb.core.snap.PathIndex || params.getIndex() === fb.core.snap.ValueIndex, "unknown index type.");
if (startNode != null && typeof startNode === "object" || endNode != null && typeof endNode === "object") {
throw new Error("Query: First argument passed to startAt(), endAt(), or equalTo() cannot be " + "an object.");
}
@@ -12488,22 +12574,26 @@ fb.api.Query = goog.defineClass(null, {constructor:function(repo, path, queryPar
throw new Error("Query.limitToLast: Limit was already set (by another call to limit, " + "limitToFirst, or limitToLast).");
}
return new fb.api.Query(this.repo, this.path, this.queryParams_.limitToLast(limit), this.orderByCalled_);
-}, orderByChild:function(key) {
+}, orderByChild:function(path) {
fb.util.validation.validateArgCount("Query.orderByChild", 1, 1, arguments.length);
- if (key === "$key") {
+ if (path === "$key") {
throw new Error('Query.orderByChild: "$key" is invalid. Use Query.orderByKey() instead.');
} else {
- if (key === "$priority") {
+ if (path === "$priority") {
throw new Error('Query.orderByChild: "$priority" is invalid. Use Query.orderByPriority() instead.');
} else {
- if (key === "$value") {
+ if (path === "$value") {
throw new Error('Query.orderByChild: "$value" is invalid. Use Query.orderByValue() instead.');
}
}
}
- fb.core.util.validation.validateKey("Query.orderByChild", 1, key, false);
+ fb.core.util.validation.validatePathString("Query.orderByChild", 1, path, false);
this.validateNoPreviousOrderByCall_("Query.orderByChild");
- var index = new fb.core.snap.SubKeyIndex(key);
+ var parsedPath = new fb.core.util.Path(path);
+ if (parsedPath.isEmpty()) {
+ throw new Error("Query.orderByChild: cannot pass in empty path. Use Query.orderByValue() instead.");
+ }
+ var index = new fb.core.snap.PathIndex(parsedPath);
var newParams = this.queryParams_.orderBy(index);
this.validateQueryEndpoints_(newParams);
return new fb.api.Query(this.repo, this.path, newParams, true);
« no previous file with comments | « lib/src/firebase/firebase.js ('k') | lib/src/ga-api-utils/build/ga-api-utils.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698