5 |
5 |
6 """ |
6 """ |
7 Module implementing a class to apply AdBlock rules to a web page. |
7 Module implementing a class to apply AdBlock rules to a web page. |
8 """ |
8 """ |
9 |
9 |
10 from PyQt4.QtCore import QObject |
10 from PyQt4.QtCore import QObject, QUrl |
11 |
11 |
12 import Helpviewer.HelpWindow |
12 import Helpviewer.HelpWindow |
13 |
13 |
14 |
14 |
15 class AdBlockPage(QObject): |
15 class AdBlockPage(QObject): |
16 """ |
16 """ |
17 Class to apply AdBlock rules to a web page. |
17 Class to apply AdBlock rules to a web page. |
18 """ |
18 """ |
19 def __checkRule(self, rule, page, host): |
19 def hideBlockedPageEntries(self, page): |
20 """ |
20 """ |
21 Private method to check, if a rule applies to the given web page and host. |
21 Public method to apply AdBlock rules to a web page. |
22 |
22 |
23 @param rule reference to the rule to check (AdBlockRule) |
23 @param page reference to the web page (HelpWebPage) |
24 @param page reference to the web page (QWebPage) |
|
25 @param host host name (string) |
|
26 """ |
|
27 if not rule.isEnabled(): |
|
28 return |
|
29 |
|
30 filter = rule.filter() |
|
31 offset = filter.find("##") |
|
32 if offset == -1: |
|
33 return |
|
34 |
|
35 selectorQuery = "" |
|
36 if offset > 0: |
|
37 domainRules = filter[:offset] |
|
38 selectorQuery = filter[offset + 2:] |
|
39 domains = domainRules.split(",") |
|
40 |
|
41 match = False |
|
42 for domain in domains: |
|
43 reverse = domain[0] == '~' |
|
44 if reverse: |
|
45 xdomain = domain[1:] |
|
46 if host.endswith(xdomain): |
|
47 return |
|
48 match = True |
|
49 if host.endswith(domain): |
|
50 match = True |
|
51 if not match: |
|
52 return |
|
53 |
|
54 if offset == 0: |
|
55 selectorQuery = filter[2:] |
|
56 |
|
57 document = page.mainFrame().documentElement() |
|
58 elements = document.findAll(selectorQuery) |
|
59 for element in elements.toList(): |
|
60 element.setStyleProperty("visibility", "hidden") |
|
61 element.removeFromDocument() |
|
62 |
|
63 def applyRulesToPage(self, page): |
|
64 """ |
|
65 Public method to applay AdBlock rules to a web page. |
|
66 |
|
67 @param page reference to the web page (QWebPage) |
|
68 """ |
24 """ |
69 if page is None or page.mainFrame() is None: |
25 if page is None or page.mainFrame() is None: |
70 return |
26 return |
71 |
27 |
72 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager() |
28 manager = Helpviewer.HelpWindow.HelpWindow.adblockManager() |
73 if not manager.isEnabled(): |
29 if not manager.isEnabled(): |
74 return |
30 return |
75 |
31 |
76 host = page.mainFrame().url().host() |
32 docElement = page.mainFrame().documentElement() |
77 subscriptions = manager.subscriptions() |
33 |
78 for subscription in subscriptions: |
34 for entry in page.getAdBlockedPageEntries(): |
79 rules = subscription.pageRules() |
35 urlString = entry.urlString() |
80 for rule in rules: |
36 if urlString.endswith((".js", ".css")): |
81 self.__checkRule(rule, page, host) |
37 continue |
|
38 |
|
39 urlEnd = "" |
|
40 pos = urlString.rfind("/") |
|
41 if pos >= 0: |
|
42 urlEnd = urlString[pos + 1:] |
|
43 if urlString.endswith("/"): |
|
44 urlEnd = urlString[:-1] |
|
45 |
|
46 selector = 'img[src$="{0}"], iframe[src$="{0}"], embed[src$="{0}"]'\ |
|
47 .format(urlEnd) |
|
48 elements = docElement.findAll(selector) |
|
49 |
|
50 for element in elements: |
|
51 src = element.attribute("src") |
|
52 src = src.replace("../", "") |
|
53 if src in urlString: |
|
54 element.setStyleProperty("display", "none") |
|
55 |
|
56 # apply domain specific element hiding rules |
|
57 elementHiding = manager.elementHidingRulesForDomain(page.url()) |
|
58 if not elementHiding: |
|
59 return |
|
60 |
|
61 elementHiding += "{display: none !important;}\n</style>" |
|
62 |
|
63 bodyElement = docElement.findFirst("body") |
|
64 bodyElement.appendInside('<style type="text/css">\n/* AdBlock for eric */\n' + |
|
65 elementHiding) |
|
66 |
|
67 |
|
68 class AdBlockedPageEntry(object): |
|
69 """ |
|
70 Class implementing a data structure for web page rules. |
|
71 """ |
|
72 def __init__(self, rule, url): |
|
73 """ |
|
74 Constructor |
|
75 |
|
76 @param rule AdBlock rule to add (AdBlockRule) |
|
77 @param url URL that matched the rule (QUrl) |
|
78 """ |
|
79 self.rule = rule |
|
80 self.url = QUrl(url) |
|
81 |
|
82 def __eq__(self, other): |
|
83 """ |
|
84 Special method to test equality. |
|
85 |
|
86 @param other reference to the other entry (AdBlockedPageEntry) |
|
87 @return flag indicating equality (boolean) |
|
88 """ |
|
89 return self.rule == other.rule and self.url == other.url |
|
90 |
|
91 def urlString(self): |
|
92 """ |
|
93 Public method to get the URL as a string. |
|
94 |
|
95 @return URL as a string (string) |
|
96 """ |
|
97 return self.url.toString() |