Пример #1
0
function toggleEnabled()
{
  let disabled = document.body.classList.toggle("disabled");
  if (disabled)
  {
    let host = getDecodedHostname(page.url).replace(/^www\./, "");
    let filter = Filter.fromText("@@||" + host + "^$document");
    if (filter.subscriptions.length && filter.disabled)
      filter.disabled = false;
    else
    {
      filter.disabled = false;
      FilterStorage.addFilter(filter);
    }
  }
  else
  {
    // Remove any exception rules applying to this URL
    let filter = checkWhitelisted(page);
    while (filter)
    {
      FilterStorage.removeFilter(filter);
      if (filter.subscriptions.length)
        filter.disabled = true;
      filter = checkWhitelisted(page);
    }
  }
}
Пример #2
0
chrome.webNavigation.onCreatedNavigationTarget.addListener(details =>
{
  if (!hasLoadingPopups())
  {
    chrome.webRequest.onBeforeRequest.addListener(
      onBeforeRequest,
      {
        urls:  ["<all_urls>"],
        types: ["main_frame"]
      }
    );

    chrome.webNavigation.onCompleted.addListener(onCompleted);
    chrome.tabs.onRemoved.addListener(forgetPopup);
  }

  let tabId = details.tabId;
  let popup = loadingPopups[tabId] = {
    url: details.url,
    sourcePage: new ext.Page({id: details.sourceTabId}),
    sourceFrame: null
  };
  let frame = ext.getFrame(details.sourceTabId, details.sourceFrameId);

  if (checkWhitelisted(popup.sourcePage, frame))
  {
    forgetPopup(tabId);
  }
  else
  {
    popup.sourceFrame = frame;
    checkPotentialPopup(tabId, popup);
  }
});
Пример #3
0
function checkPotentialPopup(tabId, popup)
{
  let urlObj = new URL(popup.url || "about:blank");
  let urlString = stringifyURL(urlObj);
  let documentHost = extractHostFromFrame(popup.sourceFrame);
  let thirdParty = isThirdParty(urlObj, documentHost);

  let specificOnly = !!checkWhitelisted(
    popup.sourcePage, popup.sourceFrame,
    RegExpFilter.typeMap.GENERICBLOCK
  );

  let filter = defaultMatcher.matchesAny(
    urlString, RegExpFilter.typeMap.POPUP,
    documentHost, thirdParty, null, specificOnly
  );

  if (filter instanceof BlockingFilter)
    chrome.tabs.remove(tabId);

  logRequest(
    popup.sourcePage, urlString, "POPUP",
    documentHost, thirdParty, null,
    specificOnly, filter
  );
}
Пример #4
0
  port.on("filters.get", (message, sender) =>
  {
    if (message.what == "elemhideemulation")
    {
      let filters = [];
      const {checkWhitelisted} = require("whitelisting");

      let isWhitelisted = checkWhitelisted(sender.page, sender.frame,
        RegExpFilter.typeMap.DOCUMENT | RegExpFilter.typeMap.ELEMHIDE);
      if (Prefs.enabled && !isWhitelisted)
      {
        let {hostname} = sender.frame.url;
        filters = ElemHideEmulation.getRulesForDomain(hostname);
        filters = filters.map((filter) =>
        {
          return {
            selector: filter.selector,
            text: filter.text
          };
        });
      }
      return filters;
    }

    let subscription = Subscription.fromURL(message.subscriptionUrl);
    if (!subscription)
      return [];

    return subscription.filters.map(convertFilter);
  });
Пример #5
0
function updateContextMenu(page, filter)
{
  page.contextMenus.remove(contextMenuItem);

  if (typeof filter == "undefined")
    filter = checkWhitelisted(page);
  if (!filter && Prefs.shouldShowBlockElementMenu && readyPages.has(page))
    page.contextMenus.create(contextMenuItem);
}
var updateContextMenuItems = function (page)
{
  // Remove the AdBlock context menu
  page.contextMenus.remove(AdBlockContextMenuItemOne);
  page.contextMenus.remove(AdBlockContextMenuItemTwo);

  // Check if the context menu items should be added
  if (Prefs.shouldShowBlockElementMenu &&
      !checkWhitelisted(page))
  {
    page.contextMenus.create(AdBlockContextMenuItemOne);
    page.contextMenus.create(AdBlockContextMenuItemTwo);
  }
};
function onSourceFrameRetrieved(tabId, frame)
{
  let popup = loadingPopups[tabId];
  if (popup)
  {
    if (checkWhitelisted(popup.sourcePage, frame))
    {
      forgetPopup(tabId);
    }
    else
    {
      popup.sourceFrame = frame;
      checkPotentialPopup(tabId, popup);
    }
  }
}
Пример #8
0
  ext.pages.query({active: true, lastFocusedWindow: true}, pages =>
  {
    page = pages[0];

    // Mark page as 'local' or 'nohtml' to hide non-relevant elements
    if (!page || (page.url.protocol != "http:" &&
                  page.url.protocol != "https:"))
      document.body.classList.add("local");
    else if (!require("filterComposer").isPageReady(page))
    {
      document.body.classList.add("nohtml");
      require("messaging").getPort(window).on(
        "composer.ready", (message, sender) =>
        {
          if (sender.page.id == page.id)
            document.body.classList.remove("nohtml");
        }
      );
    }

    // Ask content script whether clickhide is active. If so, show
    // cancel button.  If that isn't the case, ask background.html
    // whether it has cached filters. If so, ask the user whether she
    // wants those filters. Otherwise, we are in default state.
    if (page)
    {
      if (checkWhitelisted(page))
        document.body.classList.add("disabled");

      page.sendMessage({type: "composer.content.getState"}, response =>
      {
        if (response && response.active)
          document.body.classList.add("clickhide-active");
      });
    }
  });
Пример #9
0
  global.ext.onMessage.addListener(function(message, sender, callback)
  {
    var listenerFilters = null;
    switch (message.type)
    {
      case "app.listen":
      case "filters.listen":
      case "subscriptions.listen":
        if (!changeListeners)
        {
          changeListeners = new global.ext.PageMap();
          FilterNotifier.addListener(onFilterChange);
        }

        listenerFilters = changeListeners.get(sender.page);
        if (!listenerFilters)
        {
          listenerFilters = Object.create(null);
          changeListeners.set(sender.page, listenerFilters);
        }
        break;
    }

    switch (message.type)
    {
      case "add-subscription":
        ext.showOptions(function()
        {
          var subscription = Subscription.fromURL(message.url);
          subscription.title = message.title;
          onFilterChange("addSubscription", subscription);
        });
        break;
      case "app.get":
        if (message.what == "issues")
        {
          var info = require("info");
          callback({
            seenDataCorruption: "seenDataCorruption" in global ? global.seenDataCorruption : false,
            filterlistsReinitialized: "filterlistsReinitialized" in global ? global.filterlistsReinitialized : false,
            legacySafariVersion: (info.platform == "safari" && (
                Services.vc.compare(info.platformVersion, "6.0") < 0 ||   // beforeload breaks websites in Safari 5
                Services.vc.compare(info.platformVersion, "6.1") == 0 ||  // extensions are broken in 6.1 and 7.0
                Services.vc.compare(info.platformVersion, "7.0") == 0))
          });
        }
        else if (message.what == "doclink")
          callback(Utils.getDocLink(message.link));
        else if (message.what == "localeInfo")
        {
          var bidiDir;
          if ("chromeRegistry" in Utils)
            bidiDir = Utils.chromeRegistry.isLocaleRTL("adblockplus") ? "rtl" : "ltr";
          else
            bidiDir = ext.i18n.getMessage("@@bidi_dir");

          callback({locale: Utils.appLocale, bidiDir: bidiDir});
        }
        else if (message.what == "addonVersion")
        {
          callback(require("info").addonVersion);
        }
        else
          callback(null);
        break;
      case "app.listen":
        if (message.filter)
          listenerFilters.app = message.filter;
        else
          delete listenerFilters.app;
        break;
      case "app.open":
        if (message.what == "options")
          ext.showOptions();
        break;
      case "filters.add":
        var filter = Filter.fromText(message.text);
        var result = require("filterValidation").parseFilter(message.text);
        if (result.error)
          sendMessage("app", "error", [result.error.toString()], sender.page);
        else if (result.filter)
          FilterStorage.addFilter(result.filter);
        break;
      case "filters.blocked":
        var filter = defaultMatcher.matchesAny(message.url, message.requestType,
          message.docDomain, message.thirdParty);
        callback(filter instanceof BlockingFilter);
        break;
      case "filters.get":
        if (message.what == "cssproperties")
        {
          var filters = [];
          var checkWhitelisted = require("whitelisting").checkWhitelisted;

          if (!checkWhitelisted(sender.page, sender.frame,
                                RegExpFilter.typeMap.DOCUMENT |
                                RegExpFilter.typeMap.ELEMHIDE))
          {
            filters = CSSRules.getRulesForDomain(sender.frame.url.hostname);
            filters = filters.map(function(filter)
            {
              return {
                prefix: filter.selectorPrefix,
                suffix: filter.selectorSuffix,
                regexp: filter.regexpString
              };
            });
          }
          callback(filters);
          break;
        }

        var subscription = Subscription.fromURL(message.subscriptionUrl);
        if (!subscription)
        {
          callback([]);
          break;
        }

        callback(subscription.filters.map(convertFilter));
        break;
      case "filters.importRaw":
        var result = require("filterValidation").parseFilters(message.text);
        var errors = [];
        for (var i = 0; i < result.errors.length; i++)
        {
          var error = result.errors[i];
          if (error.type != "unexpected-filter-list-header")
            errors.push(error.toString());
        }

        if (errors.length > 0)
        {
          sendMessage("app", "error", errors, sender.page);
          return;
        }

        var seenFilter = Object.create(null);
        for (var i = 0; i < result.filters.length; i++)
        {
          var filter = result.filters[i];
          FilterStorage.addFilter(filter);
          seenFilter[filter.text] = null;
        }

        for (var i = 0; i < FilterStorage.subscriptions.length; i++)
        {
          var subscription = FilterStorage.subscriptions[i];
          if (!(subscription instanceof SpecialSubscription))
            continue;

          for (var j = subscription.filters.length - 1; j >= 0; j--)
          {
            var filter = subscription.filters[j];
            if (/^@@\|\|([^\/:]+)\^\$document$/.test(filter.text))
              continue;

            if (!(filter.text in seenFilter))
              FilterStorage.removeFilter(filter);
          }
        }
        break;
      case "filters.listen":
        if (message.filter)
          listenerFilters.filter = message.filter;
        else
          delete listenerFilters.filter;
        break;
      case "filters.remove":
        var filter = Filter.fromText(message.text);
        var subscription = null;
        if (message.subscriptionUrl)
          subscription = Subscription.fromURL(message.subscriptionUrl);

        if (!subscription)
          FilterStorage.removeFilter(filter);
        else
          FilterStorage.removeFilter(filter, subscription, message.index);
        break;
      case "prefs.get":
        callback(Prefs[message.key]);
        break;
      case "subscriptions.add":
        if (message.url in FilterStorage.knownSubscriptions)
          return;

        var subscription = Subscription.fromURL(message.url);
        if (!subscription)
          return;

        subscription.disabled = false;
        if ("title" in message)
          subscription.title = message.title;
        if ("homepage" in message)
          subscription.homepage = message.homepage;
        FilterStorage.addSubscription(subscription);

        if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
          Synchronizer.execute(subscription);
        break;
      case "subscriptions.get":
        var subscriptions = FilterStorage.subscriptions.filter(function(s)
        {
          if (message.ignoreDisabled && s.disabled)
            return false;
          if (s instanceof DownloadableSubscription && message.downloadable)
            return true;
          if (s instanceof SpecialSubscription && message.special)
            return true;
          return false;
        });
        callback(subscriptions.map(convertSubscription));
        break;
      case "subscriptions.listen":
        if (message.filter)
          listenerFilters.subscription = message.filter;
        else
          delete listenerFilters.subscription;
        break;
      case "subscriptions.remove":
        var subscription = Subscription.fromURL(message.url);
        if (subscription.url in FilterStorage.knownSubscriptions)
          FilterStorage.removeSubscription(subscription);
        break;
      case "subscriptions.toggle":
        var subscription = Subscription.fromURL(message.url);
        if (subscription.url in FilterStorage.knownSubscriptions && !subscription.disabled)
          FilterStorage.removeSubscription(subscription);
        else
        {
          subscription.disabled = false;
          subscription.title = message.title;
          subscription.homepage = message.homepage;
          FilterStorage.addSubscription(subscription);
          if (!subscription.lastDownload)
            Synchronizer.execute(subscription);
        }
        break;
    }
  });
Пример #10
0
function composeFilters(details)
{
  let filters = [];
  let selectors = [];

  let page = details.page;
  let frame = details.frame;

  if (!checkWhitelisted(page, frame))
  {
    let typeMask = RegExpFilter.typeMap[details.type];
    let docDomain = extractHostFromFrame(frame);
    let specificOnly = checkWhitelisted(page, frame, RegExpFilter.typeMap.GENERICBLOCK);

    // Add a blocking filter for each URL of the element that can be blocked
    for (let url of details.urls)
    {
      let urlObj = new URL(url, details.baseURL);
      url = stringifyURL(urlObj);

      let filter = defaultMatcher.whitelist.matchesAny(
        url, typeMask, docDomain,
        isThirdParty(urlObj, docDomain),
        getKey(page, frame), specificOnly
      );

      if (!filter)
      {
        let filterText = url.replace(/^[\w\-]+:\/+(?:www\.)?/, "||");

        if (specificOnly)
          filterText += "$domain=" + docDomain;

        if (filters.indexOf(filterText) == -1)
          filters.push(filterText);
      }
    }

    // If we couldn't generate any blocking filters, fallback to element hiding
    let selectors = [];
    if (filters.length == 0 && !checkWhitelisted(page, frame, RegExpFilter.typeMap.ELEMHIDE))
    {
      // Generate CSS selectors based on the element's "id" and "class" attribute
      if (isValidString(details.id))
        selectors.push("#" + escapeCSS(details.id));

      let classes = details.classes.filter(isValidString);
      if (classes.length > 0)
        selectors.push(classes.map(c => "." + escapeCSS(c)).join(""));

      // If there is a "src" attribute, specifiying a URL that we can't block,
      // generate a CSS selector matching the "src" attribute
      if (isValidString(details.src))
        selectors.push(escapeCSS(details.tagName) + "[src=" + quoteCSS(details.src) + "]");

      // As last resort, if there is a "style" attribute, and we couldn't generate
      // any filters so far, generate a CSS selector matching the "style" attribute
      if (isValidString(details.style) && selectors.length == 0 && filters.length == 0)
        selectors.push(escapeCSS(details.tagName) + "[style=" + quoteCSS(details.style) + "]");

      // Add an element hiding filter for each generated CSS selector
      for (let selector of selectors)
        filters.push(docDomain.replace(/^www\./, "") + "##" + selector);
    }
  }

  return {filters: filters, selectors: selectors};
}
  global.ext.onMessage.addListener(function(message, sender, callback)
  {
    switch (message.type)
    {
      case "app.get":
        if (message.what == "issues")
        {
          var subscriptionInit = tryRequire("subscriptionInit");
          callback({
            filterlistsReinitialized: subscriptionInit ? subscriptionInit.reinitialized : false,
            legacySafariVersion: (info.platform == "safari" && (
                Services.vc.compare(info.platformVersion, "6.0") < 0 ||   // beforeload breaks websites in Safari 5
                Services.vc.compare(info.platformVersion, "6.1") == 0 ||  // extensions are broken in 6.1 and 7.0
                Services.vc.compare(info.platformVersion, "7.0") == 0))
          });
        }
        else if (message.what == "doclink")
          callback(Utils.getDocLink(message.link));
        else if (message.what == "localeInfo")
        {
          var bidiDir;
          if ("chromeRegistry" in Utils)
            bidiDir = Utils.chromeRegistry.isLocaleRTL("stopallads") ? "rtl" : "ltr";
          else
            bidiDir = ext.i18n.getMessage("@@bidi_dir");

          callback({locale: Utils.appLocale, bidiDir: bidiDir});
        }
        else if (message.what == "features")
        {
          callback({
            devToolsPanel: info.platform == "chromium",
            safariContentBlocker: "safari" in global
                && "extension" in global.safari
                && "setContentBlocker" in global.safari.extension
          });
        }
        else
          callback(info[message.what]);
        break;
      case "app.listen":
        getListenerFilters(sender.page).app = message.filter;
        break;
      case "app.open":
        if (message.what == "options")
          ext.showOptions();
        break;
      case "filters.add":
        var result = require("filterValidation").parseFilter(message.text);
        var errors = [];
        if (result.error)
          errors.push(result.error.toString());
        else if (result.filter)
          FilterStorage.addFilter(result.filter);
        callback(errors);
        break;
      case "filters.blocked":
        var filter = defaultMatcher.matchesAny(message.url,
          RegExpFilter.typeMap[message.requestType], message.docDomain,
          message.thirdParty);
        callback(filter instanceof BlockingFilter);
        break;
      case "filters.get":
        if (message.what == "cssproperties")
        {
          var filters = [];
          var checkWhitelisted = require("whitelisting").checkWhitelisted;

          if (!checkWhitelisted(sender.page, sender.frame,
                                RegExpFilter.typeMap.DOCUMENT |
                                RegExpFilter.typeMap.ELEMHIDE))
          {
            filters = CSSRules.getRulesForDomain(sender.frame.url.hostname);
            filters = filters.map(function(filter)
            {
              return {
                prefix: filter.selectorPrefix,
                suffix: filter.selectorSuffix,
                regexp: filter.regexpString,
                text: filter.text
              };
            });
          }
          callback(filters);
          break;
        }

        var subscription = Subscription.fromURL(message.subscriptionUrl);
        if (!subscription)
        {
          callback([]);
          break;
        }

        callback(subscription.filters.map(convertFilter));
        break;
      case "filters.importRaw":
        var result = require("filterValidation").parseFilters(message.text);
        var errors = [];
        for (var i = 0; i < result.errors.length; i++)
        {
          var error = result.errors[i];
          if (error.type != "unexpected-filter-list-header")
            errors.push(error.toString());
        }

        callback(errors);
        if (errors.length > 0)
          return;

        var seenFilter = Object.create(null);
        for (var i = 0; i < result.filters.length; i++)
        {
          var filter = result.filters[i];
          FilterStorage.addFilter(filter);
          seenFilter[filter.text] = null;
        }

        if (!message.removeExisting)
          return;

        for (var i = 0; i < FilterStorage.subscriptions.length; i++)
        {
          var subscription = FilterStorage.subscriptions[i];
          if (!(subscription instanceof SpecialSubscription))
            continue;

          for (var j = subscription.filters.length - 1; j >= 0; j--)
          {
            var filter = subscription.filters[j];
            if (/^@@\|\|([^\/:]+)\^\$document$/.test(filter.text))
              continue;

            if (!(filter.text in seenFilter))
              FilterStorage.removeFilter(filter);
          }
        }
        break;
      case "filters.listen":
        getListenerFilters(sender.page).filter = message.filter;
        addFilterListeners("filter", message.filter);
        break;
      case "filters.remove":
        var filter = Filter.fromText(message.text);
        var subscription = null;
        if (message.subscriptionUrl)
          subscription = Subscription.fromURL(message.subscriptionUrl);

        if (!subscription)
          FilterStorage.removeFilter(filter);
        else
          FilterStorage.removeFilter(filter, subscription, message.index);
        break;
      case "prefs.get":
        callback(Prefs[message.key]);
        break;
      case "prefs.listen":
        getListenerFilters(sender.page).pref = message.filter;
        message.filter.forEach(function(preference)
        {
          if (!(preference in listenedPreferences))
          {
            listenedPreferences[preference] = null;
            Prefs.on(preference, function()
            {
              sendMessage("pref", preference, Prefs[preference]);
            });
          }
        });
        break;
      case "prefs.toggle":
        if (message.key == "notifications_ignoredcategories")
          NotificationStorage.toggleIgnoreCategory("*");
        else
          Prefs[message.key] = !Prefs[message.key];
        break;
      case "subscriptions.add":
        var subscription = Subscription.fromURL(message.url);
        if ("title" in message)
          subscription.title = message.title;
        if ("homepage" in message)
          subscription.homepage = message.homepage;

        if (message.confirm)
        {
          ext.showOptions(function()
          {
            sendMessage("app", "addSubscription", subscription);
          });
        }
        else
        {
          subscription.disabled = false;
          FilterStorage.addSubscription(subscription);

          if (subscription instanceof DownloadableSubscription && !subscription.lastDownload)
            Synchronizer.execute(subscription);
        }
        break;
      case "subscriptions.get":
        var subscriptions = FilterStorage.subscriptions.filter(function(s)
        {
          if (message.ignoreDisabled && s.disabled)
            return false;
          if (s instanceof DownloadableSubscription && message.downloadable)
            return true;
          if (s instanceof SpecialSubscription && message.special)
            return true;
          return false;
        });
        callback(subscriptions.map(convertSubscription));
        break;
      case "subscriptions.listen":
        getListenerFilters(sender.page).subscription = message.filter;
        addFilterListeners("subscription", message.filter);
        break;
      case "subscriptions.remove":
        var subscription = Subscription.fromURL(message.url);
        if (subscription.url in FilterStorage.knownSubscriptions)
          FilterStorage.removeSubscription(subscription);
        break;
      case "subscriptions.toggle":
        var subscription = Subscription.fromURL(message.url);
        if (subscription.url in FilterStorage.knownSubscriptions)
        {
          if (subscription.disabled || message.keepInstalled)
            subscription.disabled = !subscription.disabled;
          else
            FilterStorage.removeSubscription(subscription);
        }
        else
        {
          subscription.disabled = false;
          subscription.title = message.title;
          subscription.homepage = message.homepage;
          FilterStorage.addSubscription(subscription);
          if (!subscription.lastDownload)
            Synchronizer.execute(subscription);
        }
        break;
      case "subscriptions.update":
        var subscriptions = message.url ? [Subscription.fromURL(message.url)] :
                            FilterStorage.subscriptions;
        for (var i = 0; i < subscriptions.length; i++)
        {
          var subscription = subscriptions[i];
          if (subscription instanceof DownloadableSubscription)
            Synchronizer.execute(subscription, true);
        }
        break;
    }
  });