OLD | NEW |
1 /* | 1 /* |
2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
3 * Copyright (C) 2006-2015 Eyeo GmbH | 3 * Copyright (C) 2006-2015 Eyeo GmbH |
4 * | 4 * |
5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
8 * | 8 * |
9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 | 452 |
453 Notification.showNext(subject.location.href); | 453 Notification.showNext(subject.location.href); |
454 }.bind(UI) | 454 }.bind(UI) |
455 }; | 455 }; |
456 Services.obs.addObserver(documentCreationObserver, "content-document-global-
created", false); | 456 Services.obs.addObserver(documentCreationObserver, "content-document-global-
created", false); |
457 onShutdown.add(function() | 457 onShutdown.add(function() |
458 { | 458 { |
459 Services.obs.removeObserver(documentCreationObserver, "content-document-gl
obal-created", false); | 459 Services.obs.removeObserver(documentCreationObserver, "content-document-gl
obal-created", false); |
460 }); | 460 }); |
461 | 461 |
| 462 // Frame script URL has to be randomized due to caching |
| 463 // (see https://bugzilla.mozilla.org/show_bug.cgi?id=1051238) |
| 464 let frameScript = "chrome://adblockplus/content/subscribeLinkHandler.js?" +
Math.random(); |
| 465 |
| 466 // Initialize subscribe link handling |
| 467 let callback = this.subscribeLinkClicked.bind(this); |
| 468 let messageManager = Cc["@mozilla.org/globalmessagemanager;1"] |
| 469 .getService(Ci.nsIMessageListenerManager); |
| 470 messageManager.loadFrameScript(frameScript, true); |
| 471 messageManager.addMessageListener("AdblockPlus:SubscribeLink", callback); |
| 472 onShutdown.add(() => { |
| 473 messageManager.broadcastAsyncMessage("AdblockPlus:Shutdown", frameScript); |
| 474 messageManager.removeDelayedFrameScript(frameScript); |
| 475 messageManager.removeMessageListener("AdblockPlus:SubscribeLink", callback
); |
| 476 }); |
| 477 |
462 // Execute first-run actions if a window is open already, otherwise it | 478 // Execute first-run actions if a window is open already, otherwise it |
463 // will happen in applyToWindow() when a window is opened. | 479 // will happen in applyToWindow() when a window is opened. |
464 this.firstRunActions(this.currentWindow); | 480 this.firstRunActions(this.currentWindow); |
465 }, | 481 }, |
466 | 482 |
467 addToolbarButton: function() | 483 addToolbarButton: function() |
468 { | 484 { |
469 let {WindowObserver} = require("windowObserver"); | 485 let {WindowObserver} = require("windowObserver"); |
470 new WindowObserver(this); | 486 new WindowObserver(this); |
471 | 487 |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 * has been performed. | 551 * has been performed. |
536 * @type Boolean | 552 * @type Boolean |
537 */ | 553 */ |
538 firstRunDone: false, | 554 firstRunDone: false, |
539 | 555 |
540 /** | 556 /** |
541 * Initializes Adblock Plus UI in a window. | 557 * Initializes Adblock Plus UI in a window. |
542 */ | 558 */ |
543 applyToWindow: function(/**Window*/ window, /**Boolean*/ noDelay) | 559 applyToWindow: function(/**Window*/ window, /**Boolean*/ noDelay) |
544 { | 560 { |
545 let {delayInitialization, isKnownWindow, getBrowser, addBrowserLocationListe
ner, addBrowserClickListener} = require("appSupport"); | 561 let {delayInitialization, isKnownWindow, getBrowser, addBrowserLocationListe
ner} = require("appSupport"); |
546 if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnow
nWindow(window)) | 562 if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnow
nWindow(window)) |
547 { | 563 { |
548 // Add style processing instruction | 564 // Add style processing instruction |
549 let style = window.document.createProcessingInstruction("xml-stylesheet",
'class="adblockplus-node" href="chrome://adblockplus/skin/overlay.css" type="tex
t/css"'); | 565 let style = window.document.createProcessingInstruction("xml-stylesheet",
'class="adblockplus-node" href="chrome://adblockplus/skin/overlay.css" type="tex
t/css"'); |
550 window.document.insertBefore(style, window.document.firstChild); | 566 window.document.insertBefore(style, window.document.firstChild); |
551 } | 567 } |
552 | 568 |
553 if (!isKnownWindow(window)) | 569 if (!isKnownWindow(window)) |
554 return; | 570 return; |
555 | 571 |
(...skipping 30 matching lines...) Expand all Loading... |
586 element.addEventListener(event, handler.bind(null, window), false); | 602 element.addEventListener(event, handler.bind(null, window), false); |
587 } | 603 } |
588 window.addEventListener("popupshowing", this.onPopupShowing, false); | 604 window.addEventListener("popupshowing", this.onPopupShowing, false); |
589 window.addEventListener("keypress", this.onKeyPress, false); | 605 window.addEventListener("keypress", this.onKeyPress, false); |
590 | 606 |
591 addBrowserLocationListener(window, function() | 607 addBrowserLocationListener(window, function() |
592 { | 608 { |
593 this.updateIconState(window, window.document.getElementById("abp-status"))
; | 609 this.updateIconState(window, window.document.getElementById("abp-status"))
; |
594 this.updateIconState(window, window.document.getElementById("abp-toolbarbu
tton")); | 610 this.updateIconState(window, window.document.getElementById("abp-toolbarbu
tton")); |
595 }.bind(this)); | 611 }.bind(this)); |
596 addBrowserClickListener(window, this.onBrowserClick.bind(this, window)); | |
597 | 612 |
598 let notificationPanel = window.document.getElementById("abp-notification"); | 613 let notificationPanel = window.document.getElementById("abp-notification"); |
599 notificationPanel.addEventListener("command", function(event) | 614 notificationPanel.addEventListener("command", function(event) |
600 { | 615 { |
601 switch (event.target.id) | 616 switch (event.target.id) |
602 { | 617 { |
603 case "abp-notification-close": | 618 case "abp-notification-close": |
604 notificationPanel.classList.add("abp-closing"); | 619 notificationPanel.classList.add("abp-closing"); |
605 break; | 620 break; |
606 case "abp-notification-optout": | 621 case "abp-notification-optout": |
(...skipping 14 matching lines...) Expand all Loading... |
621 .getInterface(Ci.nsIWebNavigation) | 636 .getInterface(Ci.nsIWebNavigation) |
622 .QueryInterface(Ci.nsIDocShell) | 637 .QueryInterface(Ci.nsIDocShell) |
623 .allowSubframes = true; | 638 .allowSubframes = true; |
624 }, | 639 }, |
625 | 640 |
626 /** | 641 /** |
627 * Removes Adblock Plus UI from a window. | 642 * Removes Adblock Plus UI from a window. |
628 */ | 643 */ |
629 removeFromWindow: function(/**Window*/ window) | 644 removeFromWindow: function(/**Window*/ window) |
630 { | 645 { |
631 let {isKnownWindow, removeBrowserLocationListeners, removeBrowserClickListen
ers} = require("appSupport"); | 646 let {isKnownWindow, removeBrowserLocationListeners} = require("appSupport"); |
632 if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnow
nWindow(window)) | 647 if (window.document.documentElement.id == "CustomizeToolbarWindow" || isKnow
nWindow(window)) |
633 { | 648 { |
634 // Remove style processing instruction | 649 // Remove style processing instruction |
635 for (let child = window.document.firstChild; child; child = child.nextSibl
ing) | 650 for (let child = window.document.firstChild; child; child = child.nextSibl
ing) |
636 if (child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.in
dexOf("adblockplus-node") >= 0) | 651 if (child.nodeType == child.PROCESSING_INSTRUCTION_NODE && child.data.in
dexOf("adblockplus-node") >= 0) |
637 child.parentNode.removeChild(child); | 652 child.parentNode.removeChild(child); |
638 } | 653 } |
639 | 654 |
640 if (!isKnownWindow(window)) | 655 if (!isKnownWindow(window)) |
641 return; | 656 return; |
(...skipping 14 matching lines...) Expand all Loading... |
656 { | 671 { |
657 let clone = window.document.getElementById(id); | 672 let clone = window.document.getElementById(id); |
658 if (clone) | 673 if (clone) |
659 clone.parentNode.removeChild(clone); | 674 clone.parentNode.removeChild(clone); |
660 } | 675 } |
661 } | 676 } |
662 | 677 |
663 window.removeEventListener("popupshowing", this.onPopupShowing, false); | 678 window.removeEventListener("popupshowing", this.onPopupShowing, false); |
664 window.removeEventListener("keypress", this.onKeyPress, false); | 679 window.removeEventListener("keypress", this.onKeyPress, false); |
665 removeBrowserLocationListeners(window); | 680 removeBrowserLocationListeners(window); |
666 removeBrowserClickListeners(window); | |
667 }, | 681 }, |
668 | 682 |
669 /** | 683 /** |
670 * The overlay information to be used when adding elements to the UI. | 684 * The overlay information to be used when adding elements to the UI. |
671 * @type Object | 685 * @type Object |
672 */ | 686 */ |
673 overlay: null, | 687 overlay: null, |
674 | 688 |
675 /** | 689 /** |
676 * Iterator for application windows that Adblock Plus should apply to. | 690 * Iterator for application windows that Adblock Plus should apply to. |
(...skipping 239 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
916 notifyUser(); | 930 notifyUser(); |
917 } | 931 } |
918 }, false); | 932 }, false); |
919 request.send(); | 933 request.send(); |
920 } | 934 } |
921 else | 935 else |
922 notifyUser(); | 936 notifyUser(); |
923 }, | 937 }, |
924 | 938 |
925 /** | 939 /** |
926 * Handles clicks inside the browser's content area, will intercept clicks on | 940 * Called whenever subscribeLinkHandler.js intercepts clicks on abp: links |
927 * abp: links as well as links to subscribe.adblockplus.org. | 941 * as well as links to subscribe.adblockplus.org. |
928 */ | 942 */ |
929 onBrowserClick: function (/**Window*/ window, /**Event*/ event) | 943 subscribeLinkClicked: function(message) |
930 { | 944 { |
931 // Ignore right-clicks | 945 let {title, url, mainSubscriptionTitle, mainSubscriptionURL} = message.data; |
932 if (event.button == 2) | |
933 return; | |
934 | |
935 // Search the link associated with the click | |
936 let link = event.target; | |
937 while (!(link instanceof Ci.nsIDOMHTMLAnchorElement)) | |
938 { | |
939 link = link.parentNode; | |
940 | |
941 if (!link) | |
942 return; | |
943 } | |
944 | |
945 let queryString = null; | |
946 if (link.protocol == "http:" || link.protocol == "https:") | |
947 { | |
948 if (link.host == "subscribe.adblockplus.org" && link.pathname == "/") | |
949 queryString = link.search.substr(1); | |
950 } | |
951 else | |
952 { | |
953 // Firefox doesn't populate the "search" property for links with | |
954 // non-standard URL schemes so we need to extract the query string | |
955 // manually | |
956 let match = /^abp:\/*subscribe\/*\?(.*)/i.exec(link.href); | |
957 if (match) | |
958 queryString = match[1]; | |
959 } | |
960 | |
961 if (!queryString) | |
962 return; | |
963 | |
964 // This is our link - make sure the browser doesn't handle it | |
965 event.preventDefault(); | |
966 event.stopPropagation(); | |
967 | |
968 // Decode URL parameters | |
969 let title = null; | |
970 let url = null; | |
971 let mainSubscriptionTitle = null; | |
972 let mainSubscriptionURL = null; | |
973 for (let param of queryString.split("&")) | |
974 { | |
975 let parts = param.split("=", 2); | |
976 if (parts.length != 2 || !/\S/.test(parts[1])) | |
977 continue; | |
978 switch (parts[0]) | |
979 { | |
980 case "title": | |
981 title = decodeURIComponent(parts[1]); | |
982 break; | |
983 case "location": | |
984 url = decodeURIComponent(parts[1]); | |
985 break; | |
986 case "requiresTitle": | |
987 mainSubscriptionTitle = decodeURIComponent(parts[1]); | |
988 break; | |
989 case "requiresLocation": | |
990 mainSubscriptionURL = decodeURIComponent(parts[1]); | |
991 break; | |
992 } | |
993 } | |
994 if (!url) | 946 if (!url) |
995 return; | 947 return; |
996 | 948 |
997 // Default title to the URL | 949 // Default title to the URL |
998 if (!title) | 950 if (!title) |
999 title = url; | 951 title = url; |
1000 | 952 |
1001 // Main subscription needs both title and URL | 953 // Main subscription needs both title and URL |
1002 if (mainSubscriptionTitle && !mainSubscriptionURL) | 954 if (mainSubscriptionTitle && !mainSubscriptionURL) |
1003 mainSubscriptionTitle = null; | 955 mainSubscriptionTitle = null; |
(...skipping 17 matching lines...) Expand all Loading... |
1021 | 973 |
1022 if (mainSubscriptionURL) | 974 if (mainSubscriptionURL) |
1023 { | 975 { |
1024 mainSubscriptionURL = Utils.makeURI(mainSubscriptionURL); | 976 mainSubscriptionURL = Utils.makeURI(mainSubscriptionURL); |
1025 if (!mainSubscriptionURL || (mainSubscriptionURL.scheme != "http" && mainS
ubscriptionURL.scheme != "https" && mainSubscriptionURL.scheme != "ftp")) | 977 if (!mainSubscriptionURL || (mainSubscriptionURL.scheme != "http" && mainS
ubscriptionURL.scheme != "https" && mainSubscriptionURL.scheme != "ftp")) |
1026 mainSubscriptionURL = mainSubscriptionTitle = null; | 978 mainSubscriptionURL = mainSubscriptionTitle = null; |
1027 else | 979 else |
1028 mainSubscriptionURL = mainSubscriptionURL.spec; | 980 mainSubscriptionURL = mainSubscriptionURL.spec; |
1029 } | 981 } |
1030 | 982 |
1031 this.openSubscriptionDialog(window, url, title, mainSubscriptionURL, mainSub
scriptionTitle); | 983 this.openSubscriptionDialog(this.currentWindow, url, title, mainSubscription
URL, mainSubscriptionTitle); |
1032 }, | 984 }, |
1033 | 985 |
1034 /** | 986 /** |
1035 * Opens a dialog letting the user confirm/adjust a filter subscription to | 987 * Opens a dialog letting the user confirm/adjust a filter subscription to |
1036 * be added. | 988 * be added. |
1037 */ | 989 */ |
1038 openSubscriptionDialog: function(/**Window*/ window, /**String*/ url, /**Strin
g*/ title, /**String*/ mainURL, /**String*/ mainTitle) | 990 openSubscriptionDialog: function(/**Window*/ window, /**String*/ url, /**Strin
g*/ title, /**String*/ mainURL, /**String*/ mainTitle) |
1039 { | 991 { |
1040 let subscription = {url: url, title: title, disabled: false, external: false
, | 992 let subscription = {url: url, title: title, disabled: false, external: false
, |
1041 mainSubscriptionTitle: mainTitle, mainSubscriptionURL: m
ainURL}; | 993 mainSubscriptionTitle: mainTitle, mainSubscriptionURL: m
ainURL}; |
(...skipping 947 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1989 ["abp-command-contribute-hide", "command", UI.hideContributeButton.bind(UI)], | 1941 ["abp-command-contribute-hide", "command", UI.hideContributeButton.bind(UI)], |
1990 ["abp-command-toggleshownotifications", "command", Notification.toggleIgnoreCa
tegory.bind(Notification, "*", null)] | 1942 ["abp-command-toggleshownotifications", "command", Notification.toggleIgnoreCa
tegory.bind(Notification, "*", null)] |
1991 ]; | 1943 ]; |
1992 | 1944 |
1993 onShutdown.add(function() | 1945 onShutdown.add(function() |
1994 { | 1946 { |
1995 for (let window of UI.applicationWindows) | 1947 for (let window of UI.applicationWindows) |
1996 if (UI.isBottombarOpen(window)) | 1948 if (UI.isBottombarOpen(window)) |
1997 UI.toggleBottombar(window); | 1949 UI.toggleBottombar(window); |
1998 }); | 1950 }); |
OLD | NEW |