request-blocking.js (4718B)
1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 "use strict"; 6 7 const { 8 ADD_BLOCKED_URL, 9 DISABLE_MATCHING_URLS, 10 TOGGLE_BLOCKED_URL, 11 UPDATE_BLOCKED_URL, 12 REMOVE_BLOCKED_URL, 13 REMOVE_ALL_BLOCKED_URLS, 14 ENABLE_ALL_BLOCKED_URLS, 15 DISABLE_ALL_BLOCKED_URLS, 16 TOGGLE_BLOCKING_ENABLED, 17 SYNCED_BLOCKED_URLS, 18 } = require("resource://devtools/client/netmonitor/src/constants.js"); 19 20 function RequestBlocking() { 21 return { 22 blockedUrls: [], 23 blockingSynced: false, 24 blockingEnabled: true, 25 }; 26 } 27 28 function requestBlockingReducer(state = RequestBlocking(), action) { 29 switch (action.type) { 30 case ADD_BLOCKED_URL: 31 return addBlockedUrl(state, action); 32 case REMOVE_BLOCKED_URL: 33 return removeBlockedUrl(state, action); 34 case REMOVE_ALL_BLOCKED_URLS: 35 return removeAllBlockedUrls(state, action); 36 case UPDATE_BLOCKED_URL: 37 return updateBlockedUrl(state, action); 38 case TOGGLE_BLOCKED_URL: 39 return toggleBlockedUrl(state, action); 40 case TOGGLE_BLOCKING_ENABLED: 41 return toggleBlockingEnabled(state, action); 42 case ENABLE_ALL_BLOCKED_URLS: 43 return enableAllBlockedUrls(state, action); 44 case DISABLE_ALL_BLOCKED_URLS: 45 return disableAllBlockedUrls(state, action); 46 case DISABLE_MATCHING_URLS: 47 return disableOrRemoveMatchingUrls(state, action); 48 case SYNCED_BLOCKED_URLS: 49 return syncedBlockedUrls(state, action); 50 default: 51 return state; 52 } 53 } 54 55 function syncedBlockedUrls(state, action) { 56 if (state.blockingSynced == action.synced) { 57 return state; 58 } 59 // Indicates whether the blocked url has been synced 60 // with the server once. We don't need to do it once netmonitor is open. 61 return { 62 ...state, 63 blockingSynced: action.synced, 64 }; 65 } 66 67 function toggleBlockingEnabled(state, action) { 68 return { 69 ...state, 70 blockingEnabled: action.enabled, 71 }; 72 } 73 74 function addBlockedUrl(state, action) { 75 // The user can paste in a list of URLS so we need to cleanse the input 76 // Pasting a list turns new lines into spaces 77 const uniqueUrls = [...new Set(action.url.split(" "))].map(url => url.trim()); 78 79 const newUrls = uniqueUrls 80 // Ensure the URL isn't already blocked 81 .filter(url => url && !state.blockedUrls.some(item => item.url === url)) 82 // Add new URLs as enabled by default 83 .map(url => ({ url, enabled: true })); 84 85 // If the user is trying to block a URL that's currently in the list but disabled, 86 // re-enable the old item 87 const currentBlockedUrls = state.blockedUrls.map(item => 88 uniqueUrls.includes(item.url) ? { url: item.url, enabled: true } : item 89 ); 90 91 const blockedUrls = [...currentBlockedUrls, ...newUrls]; 92 return { 93 ...state, 94 blockedUrls, 95 }; 96 } 97 98 function removeBlockedUrl(state, action) { 99 return { 100 ...state, 101 blockedUrls: state.blockedUrls.filter(item => item.url != action.url), 102 }; 103 } 104 105 function removeAllBlockedUrls(state) { 106 return { 107 ...state, 108 blockedUrls: [], 109 }; 110 } 111 112 function enableAllBlockedUrls(state) { 113 const blockedUrls = state.blockedUrls.map(item => ({ 114 ...item, 115 enabled: true, 116 })); 117 return { 118 ...state, 119 blockedUrls, 120 }; 121 } 122 123 function disableAllBlockedUrls(state) { 124 const blockedUrls = state.blockedUrls.map(item => ({ 125 ...item, 126 enabled: false, 127 })); 128 return { 129 ...state, 130 blockedUrls, 131 }; 132 } 133 134 function updateBlockedUrl(state, action) { 135 const { oldUrl, newUrl } = action; 136 let { blockedUrls } = state; 137 138 if (!blockedUrls.find(item => item.url === newUrl)) { 139 blockedUrls = blockedUrls.map(item => { 140 if (item.url === oldUrl) { 141 return { ...item, url: newUrl }; 142 } 143 return item; 144 }); 145 } else { 146 blockedUrls = blockedUrls.filter(item => item.url != oldUrl); 147 } 148 149 return { 150 ...state, 151 blockedUrls, 152 }; 153 } 154 155 function toggleBlockedUrl(state, action) { 156 const blockedUrls = state.blockedUrls.map(item => { 157 if (item.url === action.url) { 158 return { ...item, enabled: !item.enabled }; 159 } 160 return item; 161 }); 162 163 return { 164 ...state, 165 blockedUrls, 166 }; 167 } 168 169 function disableOrRemoveMatchingUrls(state, action) { 170 const blockedUrls = state.blockedUrls 171 .map(item => { 172 // If the url matches exactly, remove the entry 173 if (action.url === item.url) { 174 return null; 175 } 176 // If just a partial match, disable the entry 177 if (action.url.includes(item.url)) { 178 return { ...item, enabled: false }; 179 } 180 return item; 181 }) 182 .filter(Boolean); 183 184 return { 185 ...state, 186 blockedUrls, 187 }; 188 } 189 190 module.exports = requestBlockingReducer;