forked from mirrors/gecko-dev
		
	 6a10a16b5a
			
		
	
	
		6a10a16b5a
		
	
	
	
	
		
			
			content points to the window object, which is gone after a load. Differential Revision: https://phabricator.services.mozilla.com/D99134
		
			
				
	
	
		
			144 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			144 lines
		
	
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /* Any copyright is dedicated to the Public Domain.
 | |
|    http://creativecommons.org/publicdomain/zero/1.0/ */
 | |
| 
 | |
| /**
 | |
|  * Test for Bug 670318
 | |
|  *
 | |
|  * When LoadEntry() is called on a browser that has multiple duplicate history
 | |
|  * entries, history.index can end up out of range (>= history.count).
 | |
|  */
 | |
| 
 | |
| const URL =
 | |
|   "http://mochi.test:8888/browser/docshell/test/browser/file_bug670318.html";
 | |
| 
 | |
| add_task(async function test() {
 | |
|   await BrowserTestUtils.withNewTab(
 | |
|     { gBrowser, url: "about:blank" },
 | |
|     async function(browser) {
 | |
|       if (!SpecialPowers.Services.appinfo.sessionHistoryInParent) {
 | |
|         await ContentTask.spawn(browser, URL, async function(URL) {
 | |
|           let history = docShell.QueryInterface(Ci.nsIWebNavigation)
 | |
|             .sessionHistory;
 | |
|           let count = 0;
 | |
| 
 | |
|           let testDone = {};
 | |
|           testDone.promise = new Promise(resolve => {
 | |
|             testDone.resolve = resolve;
 | |
|           });
 | |
| 
 | |
|           // Since listener implements nsISupportsWeakReference, we are
 | |
|           // responsible for keeping it alive so that the GC doesn't clear
 | |
|           // it before the test completes. We do this by anchoring the listener
 | |
|           // to the message manager, and clearing it just before the test
 | |
|           // completes.
 | |
|           this._testListener = {
 | |
|             owner: this,
 | |
|             OnHistoryNewEntry(aNewURI) {
 | |
|               info("OnHistoryNewEntry " + aNewURI.spec + ", " + count);
 | |
|               if (aNewURI.spec == URL && 5 == ++count) {
 | |
|                 addEventListener(
 | |
|                   "load",
 | |
|                   function onLoad() {
 | |
|                     Assert.ok(
 | |
|                       history.index < history.count,
 | |
|                       "history.index is valid"
 | |
|                     );
 | |
|                     testDone.resolve();
 | |
|                   },
 | |
|                   { capture: true, once: true }
 | |
|                 );
 | |
| 
 | |
|                 history.legacySHistory.removeSHistoryListener(
 | |
|                   this.owner._testListener
 | |
|                 );
 | |
|                 delete this.owner._testListener;
 | |
|                 this.owner = null;
 | |
|                 content.setTimeout(() => {
 | |
|                   content.location.reload();
 | |
|                 }, 0);
 | |
|               }
 | |
|             },
 | |
| 
 | |
|             OnHistoryReload: () => true,
 | |
|             OnHistoryGotoIndex: () => {},
 | |
|             OnHistoryPurge: () => {},
 | |
|             OnHistoryReplaceEntry: () => {
 | |
|               // The initial load of about:blank causes a transient entry to be
 | |
|               // created, so our first navigation to a real page is a replace
 | |
|               // instead of a new entry.
 | |
|               ++count;
 | |
|             },
 | |
| 
 | |
|             QueryInterface: ChromeUtils.generateQI([
 | |
|               "nsISHistoryListener",
 | |
|               "nsISupportsWeakReference",
 | |
|             ]),
 | |
|           };
 | |
| 
 | |
|           history.legacySHistory.addSHistoryListener(this._testListener);
 | |
|           content.location = URL;
 | |
| 
 | |
|           await testDone.promise;
 | |
|         });
 | |
| 
 | |
|         return;
 | |
|       }
 | |
| 
 | |
|       let history = browser.browsingContext.sessionHistory;
 | |
|       let count = 0;
 | |
| 
 | |
|       let testDone = {};
 | |
|       testDone.promise = new Promise(resolve => {
 | |
|         testDone.resolve = resolve;
 | |
|       });
 | |
| 
 | |
|       let listener = {
 | |
|         async OnHistoryNewEntry(aNewURI) {
 | |
|           if (aNewURI.spec == URL && 5 == ++count) {
 | |
|             history.removeSHistoryListener(listener);
 | |
|             await ContentTask.spawn(browser, null, () => {
 | |
|               return new Promise(resolve => {
 | |
|                 addEventListener(
 | |
|                   "load",
 | |
|                   evt => {
 | |
|                     let history = docShell.QueryInterface(Ci.nsIWebNavigation)
 | |
|                       .sessionHistory;
 | |
|                     Assert.ok(
 | |
|                       history.index < history.count,
 | |
|                       "history.index is valid"
 | |
|                     );
 | |
|                     resolve();
 | |
|                   },
 | |
|                   { capture: true, once: true }
 | |
|                 );
 | |
| 
 | |
|                 content.location.reload();
 | |
|               });
 | |
|             });
 | |
|             testDone.resolve();
 | |
|           }
 | |
|         },
 | |
| 
 | |
|         OnHistoryReload: () => true,
 | |
|         OnHistoryGotoIndex: () => {},
 | |
|         OnHistoryPurge: () => {},
 | |
|         OnHistoryReplaceEntry: () => {
 | |
|           // The initial load of about:blank causes a transient entry to be
 | |
|           // created, so our first navigation to a real page is a replace
 | |
|           // instead of a new entry.
 | |
|           ++count;
 | |
|         },
 | |
| 
 | |
|         QueryInterface: ChromeUtils.generateQI([
 | |
|           "nsISHistoryListener",
 | |
|           "nsISupportsWeakReference",
 | |
|         ]),
 | |
|       };
 | |
| 
 | |
|       history.addSHistoryListener(listener);
 | |
|       BrowserTestUtils.loadURI(browser, URL);
 | |
| 
 | |
|       await testDone.promise;
 | |
|     }
 | |
|   );
 | |
| });
 |