mirror of
				https://github.com/mozilla/gecko-dev.git
				synced 2025-11-04 10:18:41 +02:00 
			
		
		
		
	The test is updated to take the new behavior into account (empty icon must be set before pageshow), but it doesn't cover the flicker case, as that's complex. Differential Revision: https://phabricator.services.mozilla.com/D199092
		
			
				
	
	
		
			164 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
	
		
			3.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
/* This Source Code Form is subject to the terms of the Mozilla Public
 | 
						|
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 | 
						|
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | 
						|
 | 
						|
const lazy = {};
 | 
						|
 | 
						|
ChromeUtils.defineESModuleGetters(lazy, {
 | 
						|
  PlacesUIUtils: "resource:///modules/PlacesUIUtils.sys.mjs",
 | 
						|
});
 | 
						|
 | 
						|
let gTestListeners = new Set();
 | 
						|
 | 
						|
export class LinkHandlerParent extends JSWindowActorParent {
 | 
						|
  static addListenerForTests(listener) {
 | 
						|
    gTestListeners.add(listener);
 | 
						|
  }
 | 
						|
 | 
						|
  static removeListenerForTests(listener) {
 | 
						|
    gTestListeners.delete(listener);
 | 
						|
  }
 | 
						|
 | 
						|
  receiveMessage(aMsg) {
 | 
						|
    let browser = this.browsingContext.top.embedderElement;
 | 
						|
    if (!browser) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    let win = browser.ownerGlobal;
 | 
						|
 | 
						|
    let gBrowser = win.gBrowser;
 | 
						|
 | 
						|
    switch (aMsg.name) {
 | 
						|
      case "Link:LoadingIcon":
 | 
						|
        if (!gBrowser) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (aMsg.data.canUseForTab) {
 | 
						|
          let tab = gBrowser.getTabForBrowser(browser);
 | 
						|
          if (tab.hasAttribute("busy")) {
 | 
						|
            tab.setAttribute("pendingicon", "true");
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        this.notifyTestListeners("LoadingIcon", aMsg.data);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "Link:SetIcon":
 | 
						|
        // Cache the most recent icon and rich icon locally.
 | 
						|
        if (aMsg.data.canUseForTab) {
 | 
						|
          this.icon = aMsg.data;
 | 
						|
        } else {
 | 
						|
          this.richIcon = aMsg.data;
 | 
						|
        }
 | 
						|
 | 
						|
        if (!gBrowser) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
 | 
						|
        this.setIconFromLink(gBrowser, browser, aMsg.data);
 | 
						|
 | 
						|
        this.notifyTestListeners("SetIcon", aMsg.data);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "Link:SetFailedIcon":
 | 
						|
        if (!gBrowser) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
 | 
						|
        if (aMsg.data.canUseForTab) {
 | 
						|
          this.clearPendingIcon(gBrowser, browser);
 | 
						|
        }
 | 
						|
 | 
						|
        this.notifyTestListeners("SetFailedIcon", aMsg.data);
 | 
						|
        break;
 | 
						|
 | 
						|
      case "Link:AddSearch":
 | 
						|
        if (!gBrowser) {
 | 
						|
          return;
 | 
						|
        }
 | 
						|
 | 
						|
        let tab = gBrowser.getTabForBrowser(browser);
 | 
						|
        if (!tab) {
 | 
						|
          break;
 | 
						|
        }
 | 
						|
 | 
						|
        if (win.BrowserSearch) {
 | 
						|
          win.BrowserSearch.addEngine(browser, aMsg.data.engine);
 | 
						|
        }
 | 
						|
        break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  notifyTestListeners(name, data) {
 | 
						|
    for (let listener of gTestListeners) {
 | 
						|
      listener(name, data);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  clearPendingIcon(gBrowser, aBrowser) {
 | 
						|
    let tab = gBrowser.getTabForBrowser(aBrowser);
 | 
						|
    tab.removeAttribute("pendingicon");
 | 
						|
  }
 | 
						|
 | 
						|
  setIconFromLink(
 | 
						|
    gBrowser,
 | 
						|
    browser,
 | 
						|
    {
 | 
						|
      pageURL,
 | 
						|
      originalURL,
 | 
						|
      canUseForTab,
 | 
						|
      expiration,
 | 
						|
      iconURL,
 | 
						|
      canStoreIcon,
 | 
						|
      beforePageShow,
 | 
						|
    }
 | 
						|
  ) {
 | 
						|
    let tab = gBrowser.getTabForBrowser(browser);
 | 
						|
    if (!tab) {
 | 
						|
      return;
 | 
						|
    }
 | 
						|
 | 
						|
    if (canUseForTab) {
 | 
						|
      this.clearPendingIcon(gBrowser, browser);
 | 
						|
    }
 | 
						|
 | 
						|
    let iconURI;
 | 
						|
    try {
 | 
						|
      iconURI = Services.io.newURI(iconURL);
 | 
						|
    } catch (ex) {
 | 
						|
      console.error(ex);
 | 
						|
      return;
 | 
						|
    }
 | 
						|
    if (iconURI.scheme != "data") {
 | 
						|
      try {
 | 
						|
        Services.scriptSecurityManager.checkLoadURIWithPrincipal(
 | 
						|
          browser.contentPrincipal,
 | 
						|
          iconURI,
 | 
						|
          Services.scriptSecurityManager.ALLOW_CHROME
 | 
						|
        );
 | 
						|
      } catch (ex) {
 | 
						|
        return;
 | 
						|
      }
 | 
						|
    }
 | 
						|
    if (canStoreIcon) {
 | 
						|
      try {
 | 
						|
        lazy.PlacesUIUtils.loadFavicon(
 | 
						|
          browser,
 | 
						|
          Services.scriptSecurityManager.getSystemPrincipal(),
 | 
						|
          Services.io.newURI(pageURL),
 | 
						|
          Services.io.newURI(originalURL),
 | 
						|
          expiration,
 | 
						|
          iconURI
 | 
						|
        );
 | 
						|
      } catch (ex) {
 | 
						|
        console.error(ex);
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (canUseForTab) {
 | 
						|
      gBrowser.setIcon(tab, iconURL, originalURL, null, beforePageShow);
 | 
						|
    }
 | 
						|
  }
 | 
						|
}
 |