Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Side by Side Diff: background.js

Issue 16067002: Added Safari Support (Closed)
Patch Set: Created Oct. 21, 2013, 8:11 p.m.
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View unified diff | Download patch
« no previous file with comments | « .hgsubstate ('k') | block.js » ('j') | block.js » ('J')
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /* 1 /*
2 * This file is part of Adblock Plus <http://adblockplus.org/>, 2 * This file is part of Adblock Plus <http://adblockplus.org/>,
3 * Copyright (C) 2006-2013 Eyeo GmbH 3 * Copyright (C) 2006-2013 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 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
106 106
107 var result = defaultMatcher.matchesAny(url, type || "DOCUMENT", extractHostFro mURL(parentUrl || url), false); 107 var result = defaultMatcher.matchesAny(url, type || "DOCUMENT", extractHostFro mURL(parentUrl || url), false);
108 return (result instanceof WhitelistFilter ? result : null); 108 return (result instanceof WhitelistFilter ? result : null);
109 } 109 }
110 110
111 var activeNotification = null; 111 var activeNotification = null;
112 112
113 // Adds or removes page action icon according to options. 113 // Adds or removes page action icon according to options.
114 function refreshIconAndContextMenu(tab) 114 function refreshIconAndContextMenu(tab)
115 { 115 {
116 // The tab could have been closed by the time this function is called 116 if(!/^https?:/.test(tab.url))
Felix Dahlke 2013/10/24 16:30:34 What if tab is null or undefined? Can that still h
Sebastian Noack 2013/10/25 09:55:03 Did you had a look at the calling code? Maybe I mi
117 if(!tab)
118 return; 117 return;
119 118
120 var excluded = isWhitelisted(tab.url); 119 var excluded = isWhitelisted(tab.url);
121 var iconFilename = excluded ? "icons/abp-19-whitelisted.png" : "icons/abp-19.p ng"; 120 var iconFilename;
122 121
123 if (activeNotification) 122 if (window.safari || !excluded)
Felix Dahlke 2013/10/24 16:30:34 Why do we always show the normal icon on Safari? D
Sebastian Noack 2013/10/25 09:55:03 First of all because of in Safari icons are global
124 startIconAnimation(tab, iconFilename); 123 iconFilename = "icons/abp-18.png";
125 else 124 else
126 chrome.pageAction.setIcon({tabId: tab.id, path: iconFilename}); 125 iconFilename = "icons/abp-18-whitelisted.png";
127 126
128 // Only show icon for pages we can influence (http: and https:) 127 tab.pageAction.setIcon(iconFilename);
129 if(/^https?:/.test(tab.url)) 128 tab.pageAction.setTitle("Adblock Plus");
130 {
131 chrome.pageAction.setTitle({tabId: tab.id, title: "Adblock Plus"});
132 if ("shouldShowIcon" in localStorage && localStorage["shouldShowIcon"] == "f alse")
133 chrome.pageAction.hide(tab.id);
134 else
135 chrome.pageAction.show(tab.id);
136 129
137 // Set context menu status according to whether current tab has whitelisted domain 130 iconAnimation.registerTab(tab, iconFilename);
138 if (excluded) 131
132 if (localStorage.shouldShowIcon == "false")
133 tab.pageAction.hide();
134 else
135 tab.pageAction.show();
136
137 // Set context menu status according to whether current tab has whitelisted do main
138 if (excluded)
139 if (window.chrome) // TODO: Implement context menus for Safari
Felix Dahlke 2013/10/24 16:30:34 The surrounding |if (excluded)| needs braces, othe
Sebastian Noack 2013/10/25 09:55:03 Oh, you are right.
139 chrome.contextMenus.removeAll(); 140 chrome.contextMenus.removeAll();
140 else 141 else
141 showContextMenu(); 142 showContextMenu();
142 }
143 } 143 }
144 144
145 /** 145 /**
146 * Old versions stored filter data in the localStorage object, this will import 146 * Old versions stored filter data in the localStorage object, this will import
147 * it into FilterStorage properly. 147 * it into FilterStorage properly.
148 */ 148 */
149 function importOldData() 149 function importOldData()
150 { 150 {
151 function addSubscription(url, title) 151 function addSubscription(url, title)
152 { 152 {
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
360 } 360 }
361 else 361 else
362 addAcceptable = false; 362 addAcceptable = false;
363 } 363 }
364 364
365 if (!addSubscription && !addAcceptable) 365 if (!addSubscription && !addAcceptable)
366 return; 366 return;
367 367
368 function notifyUser() 368 function notifyUser()
369 { 369 {
370 chrome.tabs.create({ 370 ext.windows.getLastFocused(function(win) {
Felix Dahlke 2013/10/24 16:30:34 Opening braces always go on their own line, except
Sebastian Noack 2013/10/25 09:55:03 I thought we go with Mozilla coding style?
Felix Dahlke 2013/10/25 14:43:08 No, we have our own: https://adblockplus.org/en/co
371 url: chrome.extension.getURL("firstRun.html") 371 win.openTab(ext.getURL("firstRun.html"));
372 }); 372 });
373 } 373 }
374 374
375 if (addSubscription) 375 if (addSubscription)
376 { 376 {
377 // Load subscriptions data 377 // Load subscriptions data
378 var request = new XMLHttpRequest(); 378 var request = new XMLHttpRequest();
379 request.open("GET", "subscriptions.xml"); 379 request.open("GET", "subscriptions.xml");
380 request.addEventListener("load", function() 380 request.addEventListener("load", function()
381 { 381 {
(...skipping 13 matching lines...) Expand all
395 }, false); 395 }, false);
396 request.send(null); 396 request.send(null);
397 } 397 }
398 else 398 else
399 notifyUser(); 399 notifyUser();
400 } 400 }
401 401
402 // Set up context menu for user selection of elements to block 402 // Set up context menu for user selection of elements to block
403 function showContextMenu() 403 function showContextMenu()
404 { 404 {
405 if (!window.chrome) // TODO: Implement context menus for Safari
406 return;
407
405 chrome.contextMenus.removeAll(function() 408 chrome.contextMenus.removeAll(function()
406 { 409 {
407 if(typeof localStorage["shouldShowBlockElementMenu"] == "string" && localSto rage["shouldShowBlockElementMenu"] == "true") 410 if(typeof localStorage["shouldShowBlockElementMenu"] == "string" && localSto rage["shouldShowBlockElementMenu"] == "true")
408 { 411 {
409 chrome.contextMenus.create({'title': chrome.i18n.getMessage('block_element '), 'contexts': ['image', 'video', 'audio'], 'onclick': function(info, tab) 412 chrome.contextMenus.create({"title": chrome.i18n.getMessage("block_element "), "contexts": ["image", "video", "audio"], "onclick": function(info, tab)
410 { 413 {
411 if(info.srcUrl) 414 if(info.srcUrl)
412 chrome.tabs.sendRequest(tab.id, {reqtype: "clickhide-new-filter", fi lter: info.srcUrl}); 415 chrome.tabs.sendRequest(tab.id, {reqtype: "clickhide-new-filter", fi lter: info.srcUrl});
413 }}); 416 }});
414 } 417 }
415 }); 418 });
416 } 419 }
417 420
418 /**
419 * Opens Options window or focuses an existing one.
420 * @param {Function} callback function to be called with the window object of
421 * the Options window
422 */
423 function openOptions(callback) 421 function openOptions(callback)
Felix Dahlke 2013/10/24 16:30:34 Why remove the docs?
Sebastian Noack 2013/10/25 09:55:03 The old docs are deprecated now (the callback is c
Felix Dahlke 2013/11/10 01:07:00 Yeah I guess it's fine, most functions here don't
Wladimir Palant 2013/11/13 07:16:27 I would actually prefer keeping and updating the d
424 { 422 {
425 function findOptions(selectTab) 423 ext.windows.getLastFocused(function(win) {
426 { 424 win.getAllTabs(function(tabs) {
427 var views = chrome.extension.getViews({type: "tab"}); 425 var optionsUrl = ext.getURL("options.html");
428 for (var i = 0; i < views.length; i++)
429 if ("startSubscriptionSelection" in views[i])
430 return views[i];
431 426
432 return null; 427 for (var i = 0; i < tabs.length; i++)
433 } 428 if (tabs[i].url == optionsUrl) {
429 tabs[i].activate();
430 if (callback)
431 callback(tabs[i]);
432 return;
433 }
434 434
435 function selectOptionsTab() 435 win.openTab(optionsUrl, callback && function(tab) {
436 { 436 tab.onCompleted.addListener(callback);
437 chrome.windows.getAll({populate: true}, function(windows) 437 });
438 {
439 var url = chrome.extension.getURL("options.html");
440 for (var i = 0; i < windows.length; i++)
441 for (var j = 0; j < windows[i].tabs.length; j++)
442 if (windows[i].tabs[j].url == url)
443 chrome.tabs.update(windows[i].tabs[j].id, {selected: true});
444 });
445 }
446
447 var view = findOptions();
448 if (view)
449 {
450 selectOptionsTab();
451 callback(view);
452 }
453 else
454 {
455 var onLoad = function()
456 {
457 var view = findOptions();
458 if (view)
459 callback(view);
460 };
461
462 chrome.tabs.create({url: chrome.extension.getURL("options.html")}, function( tab)
463 {
464 if (tab.status == "complete")
465 onLoad();
466 else
467 {
468 var id = tab.id;
469 var listener = function(tabId, changeInfo, tab)
470 {
471 if (tabId == id && changeInfo.status == "complete")
472 {
473 chrome.tabs.onUpdated.removeListener(listener);
474 onLoad();
475 }
476 };
477 chrome.tabs.onUpdated.addListener(listener);
478 }
479 });
480 }
481 }
482
483 var iconAnimationTimer = null;
484 var animatedIconTab = null;
485
486 function stopIconAnimation()
487 {
488 if (!iconAnimationTimer)
489 return;
490
491 clearTimeout(iconAnimationTimer);
492 iconAnimationTimer = null;
493 animatedIconTab = null;
494 }
495
496 function loadImages(imageFiles, callback)
497 {
498 var images = {};
499 var imagesLoaded = 0;
500 imageFiles.forEach(function(imageFile)
501 {
502 var image = new Image();
503 image.src = imageFile;
504 image.addEventListener("load", function()
505 {
506 images[imageFile] = image;
507 if (++imagesLoaded === imageFiles.length)
508 callback(images);
509 }); 438 });
510 }); 439 });
511 } 440 }
512 441
513 function startIconAnimation(tab, iconPath) 442 function IconAnimation() {
514 { 443 this._icons = new TabMap();
515 stopIconAnimation(); 444 this._animatedTabs = new TabMap();
516 animatedIconTab = tab; 445 this._step = 0;
446 };
447 IconAnimation.prototype = {
448 update: function(severity) {
449 if (severity == this._severity)
450 return;
517 451
518 var severitySuffix = activeNotification.severity === "critical" 452 if (!this._severity)
519 ? "critical" : "information"; 453 this._start();
520 var notificationIconPath = "icons/notification-" + severitySuffix + ".png";
521 var iconFiles = [iconPath, notificationIconPath];
522 loadImages(iconFiles, function(images)
523 {
524 var icon = images[iconPath];
525 var notificationIcon = images[notificationIconPath];
526 454
527 var canvas = document.createElement("canvas"); 455 this._severity = severity;
528 canvas.width = icon.width; 456 },
529 canvas.height = icon.height; 457 stop: function() {
530 var context = canvas.getContext("2d"); 458 clearInterval(this._interval);
531 459
532 var currentFrame = 0; 460 delete this._interval;
533 var frameOpacities = [0, 0.2, 0.4, 0.6, 0.8, 461 delete this._severity;
534 1, 1, 1, 1, 1,
535 0.8, 0.6, 0.4, 0.2, 0];
536 462
537 function animationStep() 463 this._animatedTabs.clear();
538 { 464 },
539 var opacity = frameOpacities[currentFrame]; 465 registerTab: function(tab, icon) {
540 context.clearRect(0, 0, canvas.width, canvas.height); 466 this._icons.set(tab, icon);
541 context.globalAlpha = 1;
542 context.drawImage(icon, 0, 0);
543 context.globalAlpha = opacity;
544 context.drawImage(notificationIcon, 0, 0);
545 var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
546 chrome.pageAction.setIcon({tabId: tab.id, imageData: imageData});
547 467
548 var interval; 468 if (this._animatedTabs.has(tab))
549 currentFrame++; 469 this._updateIcon(tab);
550 if (currentFrame < frameOpacities.length) 470 },
551 { 471 _start: function() {
552 var duration = 3000; 472 this._interval = setInterval(function() {
553 interval = duration / frameOpacities.length; 473 this._getVisibleTabs(function(tabs) {
474 if (tabs.length == 0)
475 return;
476
477 for (var i = 0; i < tabs.length; i++)
478 this._animatedTabs.set(tabs[i], null);
479
480 var interval = setInterval(function() {
481 this._step++;
482 tabs.forEach(this._updateIcon.bind(this));
Felix Dahlke 2013/10/24 16:30:34 Is the |bind(this)| actually necessary here?
Sebastian Noack 2013/10/25 09:55:03 Yes, it is. _updateIcon() needs this._step and thi
483
484 if (this._step < 10)
485 return;
486
487 clearInterval(interval);
488 setTimeout(function() {
489 interval = setInterval(function() {
490 this._step--;
491 tabs.forEach(this._updateIcon.bind(this));
492
493 if (this._step > 0)
494 return;
495
496 clearInterval(interval);
497 this._animatedTabs.clear();
498 }.bind(this), 100);
499 }.bind(this), 1000);
500 }.bind(this), 100);
501 }.bind(this));
502 }.bind(this), 15000);
503 },
504 _getVisibleTabs: function(callback) {
505 ext.windows.getAll(function(windows) {
506 var tabs = [];
507 var n = windows.length;
Felix Dahlke 2013/10/24 16:30:34 I'd love a more descriptive variable name here. So
508
509 for (var i = 0; i < windows.length; i++) {
510 if (!windows[i].visible) {
511 if (tabs.length == --n)
Felix Dahlke 2013/10/24 16:30:34 tabs.length will always be 0 here, won't it? In th
Sebastian Noack 2013/10/25 09:55:03 Yes it is. When writing the code I felt it would b
512 callback(tabs);
513
514 continue;
515 }
516
517 windows[i].getActiveTab(function(tab) {
518 tabs.push(tab);
519
520 if (tabs.length == n)
521 callback(tabs);
522 });
554 } 523 }
555 else 524 });
556 { 525 },
557 currentFrame = 0; 526 _updateIcon: function(tab) {
558 interval = 10000; 527 var path = this._icons.get(tab);
559 } 528
560 iconAnimationTimer = setTimeout(animationStep, interval); 529 if (!path)
530 return;
531
532 if (this._step > 0) {
533 var suffix = "-notification-" + this._severity;
534
535 if (this._step < 10)
536 suffix += "-" + this._step;
537
538 path = path.replace(/(?=\..+$)/, suffix);
561 } 539 }
562 animationStep(); 540
563 }); 541 tab.pageAction.setIcon(path);
564 } 542 }
543 };
544 var iconAnimation = new IconAnimation();
Felix Dahlke 2013/10/24 16:30:34 If there's only one instance of IconAnimation, I'd
565 545
566 function prepareNotificationIconAndPopup() 546 function prepareNotificationIconAndPopup()
567 { 547 {
568 activeNotification.onClicked = function() 548 activeNotification.onClicked = function() {
569 { 549 iconAnimation.stop();
570 var tab = animatedIconTab;
571 stopIconAnimation();
572 activeNotification = null; 550 activeNotification = null;
573 refreshIconAndContextMenu(tab);
574 }; 551 };
575 552
576 chrome.windows.getLastFocused({populate: true}, function(window) 553 iconAnimation.update(activeNotification.severity);
577 {
578 chrome.tabs.query({active: true, windowId: window.id}, function(tabs)
579 {
580 tabs.forEach(refreshIconAndContextMenu);
581 });
582 });
583 } 554 }
584 555
585 function showNotification(notification) 556 function showNotification(notification)
586 { 557 {
587 activeNotification = notification; 558 activeNotification = notification;
588 559
589 if (activeNotification.severity === "critical" 560 if (activeNotification.severity === "critical"
590 && typeof webkitNotifications !== "undefined") 561 && typeof webkitNotifications !== "undefined")
591 { 562 {
592 var notification = webkitNotifications.createHTMLNotification("notification. html"); 563 var notification = webkitNotifications.createHTMLNotification("notification. html");
593 notification.show(); 564 notification.show();
594 notification.addEventListener("close", prepareNotificationIconAndPopup); 565 notification.addEventListener("close", prepareNotificationIconAndPopup);
595 } 566 }
596 else 567 else
597 prepareNotificationIconAndPopup(); 568 prepareNotificationIconAndPopup();
598 } 569 }
599 570
600 /** 571 /**
601 * This function is a hack - we only know the tabId and document URL for a 572 * This function is a hack - we only know the tabId and document URL for a
602 * message but we need to know the frame ID. Try to find it in webRequest's 573 * message but we need to know the frame ID. Try to find it in webRequest"s
603 * frame data. 574 * frame data.
604 */ 575 */
605 function getFrameId(tabId, url) 576 function getFrameId(tab, url)
606 { 577 {
607 if (tabId in frames) 578 for (var frameId in frames.get(tab))
608 { 579 if (getFrameUrl(tab, frameId) == url)
609 for (var f in frames[tabId]) 580 return frameId;
610 {
611 if (getFrameUrl(tabId, f) == url)
612 return f;
613 }
614 }
615 return -1; 581 return -1;
616 } 582 }
617 583
618 chrome.extension.onRequest.addListener(function(request, sender, sendResponse) 584 ext.onMessage.addListener(function (msg, sender, sendResponse) {
619 { 585 switch (msg.type)
620 switch (request.reqtype)
621 { 586 {
622 case "get-settings": 587 case "get-settings":
623 var hostDomain = null; 588 var hostDomain = null;
624 var selectors = null; 589 var selectors = null;
625 590
626 var tabId = -1; 591 var frameId = sender.tab ? getFrameId(sender.tab, msg.frameUrl) : -1;
627 var frameId = -1; 592 var enabled = false;
628 if (sender.tab)
629 {
630 tabId = sender.tab.id;
631 frameId = getFrameId(tabId, request.frameUrl);
632 }
633 593
634 var enabled = !isFrameWhitelisted(tabId, frameId, "DOCUMENT") && !isFrameW hitelisted(tabId, frameId, "ELEMHIDE"); 594 if (!isFrameWhitelisted(sender.tab, frameId, "DOCUMENT"))
Felix Dahlke 2013/10/24 16:30:34 I prefer the old code (enabled variable) to nested
635 if (enabled && request.selectors) 595 if (!isFrameWhitelisted(sender.tab, frameId, "ELEMHIDE")) {
636 { 596 var enabled = true;
637 var noStyleRules = false; 597
638 var host = extractHostFromURL(request.frameUrl); 598 if (msg.selectors)
639 hostDomain = getBaseDomain(host);
640 for (var i = 0; i < noStyleRulesHosts.length; i++)
641 { 599 {
642 var noStyleHost = noStyleRulesHosts[i]; 600 var noStyleRules = false;
643 if (host == noStyleHost || (host.length > noStyleHost.length && 601 var host = extractHostFromURL(msg.frameUrl);
644 host.substr(host.length - noStyleHost.leng th - 1) == "." + noStyleHost)) 602 hostDomain = getBaseDomain(host);
603 for (var i = 0; i < noStyleRulesHosts.length; i++)
645 { 604 {
646 noStyleRules = true; 605 var noStyleHost = noStyleRulesHosts[i];
606 if (host == noStyleHost || (host.length > noStyleHost.length &&
607 host.substr(host.length - noStyleHost.le ngth - 1) == "." + noStyleHost))
608 {
609 noStyleRules = true;
610 }
647 } 611 }
648 } 612 selectors = ElemHide.getSelectorsForDomain(host, false);
649 selectors = ElemHide.getSelectorsForDomain(host, false); 613 if (noStyleRules)
650 if (noStyleRules)
651 {
652 selectors = selectors.filter(function(s)
653 { 614 {
654 return !/\[style[\^\$]?=/.test(s); 615 selectors = selectors.filter(function(s)
655 }); 616 {
617 return !/\[style[\^\$]?=/.test(s);
618 });
619 }
656 } 620 }
657 } 621 }
658 622
659 sendResponse({enabled: enabled, hostDomain: hostDomain, selectors: selecto rs}); 623 sendResponse({enabled: enabled, hostDomain: hostDomain, selectors: selecto rs});
660 break; 624 break;
661 case "should-collapse": 625 case "should-collapse":
662 var tabId = -1; 626 var frameId = sender.tab ? getFrameId(sender.tab, msg.documentUrl) : -1;
663 var frameId = -1;
664 if (sender.tab)
665 {
666 tabId = sender.tab.id;
667 frameId = getFrameId(tabId, request.documentUrl);
668 }
669 627
670 if (isFrameWhitelisted(tabId, frameId, "DOCUMENT")) 628 if (isFrameWhitelisted(sender.tab, frameId, "DOCUMENT"))
671 { 629 {
672 sendResponse(false); 630 sendResponse(false);
673 break; 631 break;
674 } 632 }
675 633
676 var requestHost = extractHostFromURL(request.url); 634 var requestHost = extractHostFromURL(msg.url);
677 var documentHost = extractHostFromURL(request.documentUrl); 635 var documentHost = extractHostFromURL(msg.documentUrl);
678 var thirdParty = isThirdParty(requestHost, documentHost); 636 var thirdParty = isThirdParty(requestHost, documentHost);
679 var filter = defaultMatcher.matchesAny(request.url, request.type, document Host, thirdParty); 637 var filter = defaultMatcher.matchesAny(msg.url, msg.mediatype, documentHos t, thirdParty);
680 if (filter instanceof BlockingFilter) 638 if (filter instanceof BlockingFilter)
681 { 639 {
682 var collapse = filter.collapse; 640 var collapse = filter.collapse;
683 if (collapse == null) 641 if (collapse == null)
684 collapse = (localStorage.hidePlaceholders != "false"); 642 collapse = (localStorage.hidePlaceholders != "false");
685 sendResponse(collapse); 643 sendResponse(collapse);
686 } 644 }
687 else 645 else
688 sendResponse(false); 646 sendResponse(false);
689 break; 647 break;
690 case "get-domain-enabled-state": 648 case "get-domain-enabled-state":
691 // Returns whether this domain is in the exclusion list. 649 // Returns whether this domain is in the exclusion list.
692 // The page action popup asks us this. 650 // The page action popup asks us this.
693 if(sender.tab) 651 if(sender.tab)
694 { 652 {
695 sendResponse({enabled: !isWhitelisted(sender.tab.url)}); 653 sendResponse({enabled: !isWhitelisted(sender.tab.url)});
696 return; 654 return;
697 } 655 }
698 break; 656 break;
699 case "add-filters": 657 case "add-filters":
700 if (request.filters && request.filters.length) 658 if (msg.filters && msg.filters.length)
701 { 659 {
702 for (var i = 0; i < request.filters.length; i++) 660 for (var i = 0; i < msg.filters.length; i++)
703 FilterStorage.addFilter(Filter.fromText(request.filters[i])); 661 FilterStorage.addFilter(Filter.fromText(msg.filters[i]));
704 } 662 }
705 break; 663 break;
706 case "add-subscription": 664 case "add-subscription":
707 openOptions(function(view) 665 openOptions(function(tab) {
708 { 666 tab.sendMessage(msg);
709 view.startSubscriptionSelection(request.title, request.url);
710 }); 667 });
711 break; 668 break;
712 case "forward": 669 case "forward":
713 chrome.tabs.sendRequest(sender.tab.id, request.request, sendResponse); 670 tab.sendMessage(msg.payload, sendResponse);
714 break; 671 break;
715 default: 672 default:
716 sendResponse({}); 673 sendResponse({});
717 break; 674 break;
718 } 675 }
719 }); 676 });
720 677
721 // Show icon as page action for all tabs that already exist 678 // Show icon as page action for all tabs that already exist
722 chrome.windows.getAll({populate: true}, function(windows) 679 ext.windows.getAll(function(windows) {
723 {
724 for (var i = 0; i < windows.length; i++) 680 for (var i = 0; i < windows.length; i++)
725 for (var j = 0; j < windows[i].tabs.length; j++) 681 windows[i].getAllTabs(function(tabs) {
726 refreshIconAndContextMenu(windows[i].tabs[j]); 682 tabs.forEach(refreshIconAndContextMenu);
683 });
727 }); 684 });
728 685
729 // Update icon if a tab changes location 686 // Update icon if a tab changes location
730 chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) 687 ext.tabs.onBeforeNavigate.addListener(function(tab) {
731 { 688 tab.sendMessage({type: "clickhide-deactivate"});
732 chrome.tabs.sendRequest(tabId, {reqtype: "clickhide-deactivate"}) 689 refreshIconAndContextMenu(tab);
733 if(changeInfo.status == "loading")
734 refreshIconAndContextMenu(tab);
735 });
736
737 // Refresh icon when switching tabs or windows
738 chrome.tabs.onActivated.addListener(function(activeInfo)
739 {
740 refreshIconAndContextMenu(animatedIconTab);
741 chrome.tabs.get(activeInfo.tabId, refreshIconAndContextMenu);
742 });
743 chrome.windows.onFocusChanged.addListener(function(windowId)
744 {
745 refreshIconAndContextMenu(animatedIconTab);
746 chrome.tabs.query({active: true, windowId: windowId}, function(tabs)
747 {
748 tabs.forEach(refreshIconAndContextMenu);
749 });
750 }); 690 });
751 691
752 setTimeout(function() 692 setTimeout(function()
753 { 693 {
754 var notificationToShow = Notification.getNextToShow(); 694 var notificationToShow = Notification.getNextToShow();
755 if (notificationToShow) 695 if (notificationToShow)
756 showNotification(notificationToShow); 696 showNotification(notificationToShow);
757 }, 3 * 60 * 1000); 697 }, 3 * 60 * 1000);
OLDNEW
« no previous file with comments | « .hgsubstate ('k') | block.js » ('j') | block.js » ('J')

Powered by Google App Engine
This is Rietveld