forked from mirrors/gecko-dev
		
	
		
			
				
	
	
		
			185 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			185 lines
		
	
	
	
		
			6.8 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
function swapTabsAndCloseOther(a, b) {
 | 
						|
  gBrowser.swapBrowsersAndCloseOther(gBrowser.tabs[b], gBrowser.tabs[a]);
 | 
						|
}
 | 
						|
 | 
						|
var getClicks = function(tab) {
 | 
						|
  return ContentTask.spawn(tab.linkedBrowser, {}, function() {
 | 
						|
    return content.wrappedJSObject.clicks;
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
var clickTest = async function(tab) {
 | 
						|
  let clicks = await getClicks(tab);
 | 
						|
 | 
						|
  await ContentTask.spawn(tab.linkedBrowser, {}, function() {
 | 
						|
    let target = content.document.body;
 | 
						|
    let rect = target.getBoundingClientRect();
 | 
						|
    let left = (rect.left + rect.right) / 2;
 | 
						|
    let top = (rect.top + rect.bottom) / 2;
 | 
						|
 | 
						|
    let utils = content.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
 | 
						|
                       .getInterface(Components.interfaces.nsIDOMWindowUtils);
 | 
						|
    utils.sendMouseEvent("mousedown", left, top, 0, 1, 0, false, 0, 0);
 | 
						|
    utils.sendMouseEvent("mouseup", left, top, 0, 1, 0, false, 0, 0);
 | 
						|
  });
 | 
						|
 | 
						|
  let newClicks = await getClicks(tab);
 | 
						|
  is(newClicks, clicks + 1, "adding 1 more click on BODY");
 | 
						|
};
 | 
						|
 | 
						|
function loadURI(tab, url) {
 | 
						|
  tab.linkedBrowser.loadURI(url);
 | 
						|
  return BrowserTestUtils.browserLoaded(tab.linkedBrowser);
 | 
						|
}
 | 
						|
 | 
						|
// Creates a framescript which caches the current object value from the plugin
 | 
						|
// in the page. checkObjectValue below verifies that the framescript is still
 | 
						|
// active for the browser and that the cached value matches that from the plugin
 | 
						|
// in the page which tells us the plugin hasn't been reinitialized.
 | 
						|
async function cacheObjectValue(browser) {
 | 
						|
  await ContentTask.spawn(browser, null, async function() {
 | 
						|
    let plugin = content.document.getElementById("p").wrappedJSObject;
 | 
						|
    info(`plugin is ${plugin}`);
 | 
						|
    let win = content.document.defaultView;
 | 
						|
    info(`win is ${win}`);
 | 
						|
    win.objectValue = plugin.getObjectValue();
 | 
						|
    info(`got objectValue: ${win.objectValue}`);
 | 
						|
    win.checkObjectValueListener = () => {
 | 
						|
      let result;
 | 
						|
      let exception;
 | 
						|
      try {
 | 
						|
        result = plugin.checkObjectValue(win.objectValue);
 | 
						|
      } catch (e) {
 | 
						|
        exception = e.toString();
 | 
						|
      }
 | 
						|
      info(`sending plugin.checkObjectValue(objectValue): ${result}`);
 | 
						|
      sendAsyncMessage("Test:CheckObjectValueResult", {
 | 
						|
        result,
 | 
						|
        exception
 | 
						|
      });
 | 
						|
    };
 | 
						|
 | 
						|
    addMessageListener("Test:CheckObjectValue", win.checkObjectValueListener);
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
// Note, can't run this via registerCleanupFunction because it needs the
 | 
						|
// browser to still be alive and have a messageManager.
 | 
						|
async function cleanupObjectValue(browser) {
 | 
						|
  info("entered cleanupObjectValue")
 | 
						|
  await ContentTask.spawn(browser, null, async function() {
 | 
						|
    info("in cleanup function");
 | 
						|
    let win = content.document.defaultView;
 | 
						|
    info(`about to delete objectValue: ${win.objectValue}`);
 | 
						|
    delete win.objectValue;
 | 
						|
    removeMessageListener("Test:CheckObjectValue", win.checkObjectValueListener);
 | 
						|
    info(`about to delete checkObjectValueListener: ${win.checkObjectValueListener}`);
 | 
						|
    delete win.checkObjectValueListener;
 | 
						|
    info(`deleted objectValue (${win.objectValue}) and checkObjectValueListener (${win.checkObjectValueListener})`);
 | 
						|
  });
 | 
						|
  info("exiting cleanupObjectValue")
 | 
						|
}
 | 
						|
 | 
						|
// See the notes for cacheObjectValue above.
 | 
						|
function checkObjectValue(browser) {
 | 
						|
  let mm = browser.messageManager;
 | 
						|
 | 
						|
  return new Promise((resolve, reject) => {
 | 
						|
    let listener  = ({ data }) => {
 | 
						|
      mm.removeMessageListener("Test:CheckObjectValueResult", listener);
 | 
						|
      if (data.result === null) {
 | 
						|
        ok(false, "checkObjectValue threw an exception: " + data.exception);
 | 
						|
        reject(data.exception);
 | 
						|
      } else {
 | 
						|
        resolve(data.result);
 | 
						|
      }
 | 
						|
    };
 | 
						|
 | 
						|
    mm.addMessageListener("Test:CheckObjectValueResult", listener);
 | 
						|
    mm.sendAsyncMessage("Test:CheckObjectValue");
 | 
						|
  });
 | 
						|
}
 | 
						|
 | 
						|
add_task(async function() {
 | 
						|
  setTestPluginEnabledState(Ci.nsIPluginTag.STATE_ENABLED);
 | 
						|
 | 
						|
  // create a few tabs
 | 
						|
  let tabs = [
 | 
						|
    gBrowser.tabs[0],
 | 
						|
    BrowserTestUtils.addTab(gBrowser, "about:blank", {skipAnimation: true}),
 | 
						|
    BrowserTestUtils.addTab(gBrowser, "about:blank", {skipAnimation: true}),
 | 
						|
    BrowserTestUtils.addTab(gBrowser, "about:blank", {skipAnimation: true}),
 | 
						|
    BrowserTestUtils.addTab(gBrowser, "about:blank", {skipAnimation: true})
 | 
						|
  ];
 | 
						|
 | 
						|
  // Initially 0 1 2 3 4
 | 
						|
  await loadURI(tabs[1], "data:text/html;charset=utf-8,<title>tab1</title><body>tab1<iframe>");
 | 
						|
  await loadURI(tabs[2], "data:text/plain;charset=utf-8,tab2");
 | 
						|
  await loadURI(tabs[3], "data:text/html;charset=utf-8,<title>tab3</title><body>tab3<iframe>");
 | 
						|
  await loadURI(tabs[4], "http://example.com/browser/browser/base/content/test/general/browser_tab_dragdrop_embed.html");
 | 
						|
  await BrowserTestUtils.switchTab(gBrowser, tabs[3]);
 | 
						|
 | 
						|
  swapTabsAndCloseOther(2, 3); // now: 0 1 2 4
 | 
						|
  is(gBrowser.tabs[1], tabs[1], "tab1");
 | 
						|
  is(gBrowser.tabs[2], tabs[3], "tab3");
 | 
						|
  is(gBrowser.tabs[3], tabs[4], "tab4");
 | 
						|
  delete tabs[2];
 | 
						|
 | 
						|
  info("about to cacheObjectValue")
 | 
						|
  await cacheObjectValue(tabs[4].linkedBrowser);
 | 
						|
  info("just finished cacheObjectValue")
 | 
						|
 | 
						|
  swapTabsAndCloseOther(3, 2); // now: 0 1 4
 | 
						|
  is(Array.prototype.indexOf.call(gBrowser.tabs, gBrowser.selectedTab), 2,
 | 
						|
     "The third tab should be selected");
 | 
						|
  delete tabs[4];
 | 
						|
 | 
						|
 | 
						|
  ok((await checkObjectValue(gBrowser.tabs[2].linkedBrowser)), "same plugin instance");
 | 
						|
 | 
						|
  is(gBrowser.tabs[1], tabs[1], "tab1");
 | 
						|
  is(gBrowser.tabs[2], tabs[3], "tab4");
 | 
						|
 | 
						|
  let clicks = await getClicks(gBrowser.tabs[2]);
 | 
						|
  is(clicks, 0, "no click on BODY so far");
 | 
						|
  await clickTest(gBrowser.tabs[2]);
 | 
						|
 | 
						|
  swapTabsAndCloseOther(2, 1); // now: 0 4
 | 
						|
  is(gBrowser.tabs[1], tabs[1], "tab1");
 | 
						|
  delete tabs[3];
 | 
						|
 | 
						|
  ok((await checkObjectValue(gBrowser.tabs[1].linkedBrowser)), "same plugin instance");
 | 
						|
  await cleanupObjectValue(gBrowser.tabs[1].linkedBrowser);
 | 
						|
 | 
						|
  await clickTest(gBrowser.tabs[1]);
 | 
						|
 | 
						|
  // Load a new document (about:blank) in tab4, then detach that tab into a new window.
 | 
						|
  // In the new window, navigate back to the original document and click on its <body>,
 | 
						|
  // verify that its onclick was called.
 | 
						|
  is(Array.prototype.indexOf.call(gBrowser.tabs, gBrowser.selectedTab), 1,
 | 
						|
     "The second tab should be selected");
 | 
						|
  is(gBrowser.tabs[1], tabs[1],
 | 
						|
     "The second tab in gBrowser.tabs should be equal to the second tab in our array");
 | 
						|
  is(gBrowser.selectedTab, tabs[1],
 | 
						|
     "The second tab in our array is the selected tab");
 | 
						|
  await loadURI(tabs[1], "about:blank");
 | 
						|
  let key = tabs[1].linkedBrowser.permanentKey;
 | 
						|
 | 
						|
  let win = gBrowser.replaceTabWithWindow(tabs[1]);
 | 
						|
  await new Promise(resolve => whenDelayedStartupFinished(win, resolve));
 | 
						|
  delete tabs[1];
 | 
						|
 | 
						|
  // Verify that the original window now only has the initial tab left in it.
 | 
						|
  is(gBrowser.tabs[0], tabs[0], "tab0");
 | 
						|
  is(gBrowser.tabs[0].linkedBrowser.currentURI.spec, "about:blank", "tab0 uri");
 | 
						|
 | 
						|
  let tab = win.gBrowser.tabs[0];
 | 
						|
  is(tab.linkedBrowser.permanentKey, key, "Should have kept the key");
 | 
						|
 | 
						|
  let awaitPageShow = BrowserTestUtils.waitForContentEvent(tab.linkedBrowser, "pageshow");
 | 
						|
  win.gBrowser.goBack();
 | 
						|
  await awaitPageShow;
 | 
						|
 | 
						|
  await clickTest(tab);
 | 
						|
  promiseWindowClosed(win);
 | 
						|
});
 |