File indexing completed on 2024-04-28 05:32:49
0001 /* 0002 Copyright (C) 2020 Kai Uwe Broulik <kde@broulik.de> 0003 0004 This program is free software; you can redistribute it and/or 0005 modify it under the terms of the GNU General Public License as 0006 published by the Free Software Foundation; either version 3 of 0007 the License, or (at your option) any later version. 0008 0009 This program is distributed in the hope that it will be useful, 0010 but WITHOUT ANY WARRANTY; without even the implied warranty of 0011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0012 GNU General Public License for more details. 0013 0014 You should have received a copy of the GNU General Public License 0015 along with this program. If not, see <http://www.gnu.org/licenses/>. 0016 */ 0017 0018 let defaultFaviconData = ""; 0019 0020 function getFavicon(url) { 0021 return new Promise((resolve) => { 0022 let xhr = new XMLHttpRequest(); 0023 xhr.onreadystatechange = function() { 0024 if (xhr.readyState !== XMLHttpRequest.DONE) { 0025 return; 0026 } 0027 0028 if (!xhr.response) { 0029 return resolve(); 0030 } 0031 0032 let reader = new FileReader(); 0033 reader.onloadend = () => { 0034 resolve(reader.result); 0035 } 0036 reader.readAsDataURL(xhr.response); 0037 } 0038 const favIconUrl = "chrome://favicon/size/16@" + window.devicePixelRatio + "x/" + url; 0039 xhr.open("GET", favIconUrl); 0040 xhr.responseType = "blob"; 0041 xhr.send(); 0042 }); 0043 } 0044 0045 addCallback("historyrunner", "find", (message) => { 0046 const query = message.query; 0047 0048 chrome.permissions.contains({ 0049 permissions: ["history"] 0050 }, (granted) => { 0051 if (!granted) { 0052 sendPortMessage("historyrunner", "found", { 0053 query, 0054 error: "NO_PERMISSION" 0055 }); 0056 return; 0057 } 0058 0059 chrome.history.search({ 0060 text: query, 0061 maxResults: 15, 0062 // By default searches only the past 24 hours but we want everything 0063 startTime: 0 0064 }, (results) => { 0065 let promises = []; 0066 0067 // Collect open tabs for each history item URL to filter them out below 0068 results.forEach((result) => { 0069 promises.push(new Promise((resolve) => { 0070 chrome.tabs.query({ 0071 url: result.url 0072 }, (tabs) => { 0073 if (chrome.runtime.lastError || !tabs) { 0074 return resolve([]); 0075 } 0076 0077 resolve(tabs); 0078 }); 0079 })); 0080 }); 0081 0082 Promise.all(promises).then((tabs) => { 0083 // Now filter out the entries with corresponding tabs we found earlier 0084 results = results.filter((result, index) => { 0085 return tabs[index].length === 0; 0086 }); 0087 0088 // Now fetch all favicons from special favicon provider URL 0089 // There's no public API for this. 0090 // chrome://favicon/ works on Chrome "by accident", and for 0091 // Firefox' page-icon: scheme there is https://bugzilla.mozilla.org/show_bug.cgi?id=1315616 0092 if (IS_FIREFOX) { 0093 return; 0094 } 0095 0096 promises = []; 0097 results.forEach((result) => { 0098 promises.push(getFavicon(result.url)); 0099 }); 0100 0101 return Promise.all(promises); 0102 }).then((favicons) => { 0103 if (favicons) { 0104 favicons.forEach((favicon, index) => { 0105 if (favicon) { 0106 results[index].favIconUrl = favicon; 0107 } 0108 }); 0109 0110 // Now get the default favicon if we don't have it already... 0111 if (!defaultFaviconData) { 0112 return getFavicon(""); 0113 } 0114 } 0115 }).then((faviconData) => { 0116 if (faviconData) { 0117 defaultFaviconData = faviconData; 0118 } 0119 0120 if (defaultFaviconData) { 0121 // ...and remove icon from all results that have the default one 0122 results.forEach((result) => { 0123 if (result.favIconUrl === defaultFaviconData) { 0124 result.favIconUrl = ""; 0125 } 0126 }); 0127 } 0128 0129 sendPortMessage("historyrunner", "found", { 0130 query, 0131 results 0132 }); 0133 }); 0134 0135 }); 0136 }); 0137 }); 0138 0139 addCallback("historyrunner", "run", (message) => { 0140 const url = message.url; 0141 0142 chrome.tabs.create({ 0143 url 0144 }); 0145 }); 0146 0147 addCallback("historyrunner", "requestPermission", () => { 0148 chrome.tabs.create({ 0149 url: chrome.runtime.getURL("permission_request.html") + "?permission=history" 0150 }); 0151 });