Bug 677565 - Update mobile SHistory after changes from
bug 646641 (rev dc162f9bce24, f9247cadf32b). r=mfinkle
--- a/mobile/chrome/content/bindings/browser.js
+++ b/mobile/chrome/content/bindings/browser.js
@@ -251,43 +251,40 @@ let WebNavigation = {
aIdMap.used[id] = true;
}
shEntry.ID = id;
}
if (aEntry.docshellID)
shEntry.docshellID = aEntry.docshellID;
- if (aEntry.stateData)
- shEntry.stateData = aEntry.stateData;
+ if (aEntry.structuredCloneState && aEntry.structuredCloneVersion) {
+ shEntry.stateData =
+ Cc["@mozilla.org/docshell/structured-clone-container;1"].
+ createInstance(Ci.nsIStructuredCloneContainer);
+
+ shEntry.stateData.initFromBase64(aEntry.structuredCloneState, aEntry.structuredCloneVersion);
+ }
if (aEntry.scroll) {
let scrollPos = aEntry.scroll.split(",");
scrollPos = [parseInt(scrollPos[0]) || 0, parseInt(scrollPos[1]) || 0];
shEntry.setScrollPosition(scrollPos[0], scrollPos[1]);
}
if (aEntry.docIdentifier) {
- // Get a new document identifier for this entry to ensure that history
- // entries after a session restore are considered to have different
- // documents from the history entries before the session restore.
- // Document identifiers are 64-bit ints, so JS will loose precision and
- // start assigning all entries the same doc identifier if these ever get
- // large enough.
- //
- // It's a potential security issue if document identifiers aren't
- // globally unique, but shEntry.setUniqueDocIdentifier() below guarantees
- // that we won't re-use a doc identifier within a given instance of the
- // application.
- let ident = aDocIdentMap[aEntry.docIdentifier];
- if (!ident) {
- shEntry.setUniqueDocIdentifier();
- aDocIdentMap[aEntry.docIdentifier] = shEntry.docIdentifier;
+ // If we have a serialized document identifier, try to find an SHEntry
+ // which matches that doc identifier and adopt that SHEntry's
+ // BFCacheEntry. If we don't find a match, insert shEntry as the match
+ // for the document identifier.
+ let matchingEntry = aDocIdentMap[aEntry.docIdentifier];
+ if (!matchingEntry) {
+ aDocIdentMap[aEntry.docIdentifier] = shEntry;
} else {
- shEntry.docIdentifier = ident;
+ shEntry.adoptBFCacheEntry(matchingEntry);
}
}
if (aEntry.owner_b64) {
let ownerInput = Cc["@mozilla.org/io/string-input-stream;1"].createInstance(Ci.nsIStringInputStream);
let binaryData = atob(aEntry.owner_b64);
ownerInput.setData(binaryData, binaryData.length);
let binaryStream = Cc["@mozilla.org/binaryinputstream;1"].createInstance(Ci.nsIObjectInputStream);
@@ -362,21 +359,22 @@ let WebNavigation = {
let ownerBytes = scriptableStream.readByteArray(scriptableStream.available());
// We can stop doing base64 encoding once our serialization into JSON
// is guaranteed to handle all chars in strings, including embedded
// nulls.
entry.owner_b64 = btoa(String.fromCharCode.apply(null, ownerBytes));
} catch (e) { dump(e); }
}
- if (aEntry.docIdentifier)
- entry.docIdentifier = aEntry.docIdentifier;
+ entry.docIdentifier = aEntry.BFCacheEntry.ID;
- if (aEntry.stateData)
- entry.stateData = aEntry.stateData;
+ if (aEntry.stateData != null) {
+ entry.structuredCloneState = aEntry.stateData.getDataAsBase64();
+ entry.structuredCloneVersion = aEntry.stateData.formatVersion;
+ }
if (!(aEntry instanceof Ci.nsISHContainer))
return entry;
if (aEntry.childCount > 0) {
entry.children = [];
for (let i = 0; i < aEntry.childCount; i++) {
let child = aEntry.GetChildAt(i);