diff --git a/src/_locales/en/messages.json b/src/_locales/en/messages.json index e3b58d4372e49..7af5f793934eb 100644 --- a/src/_locales/en/messages.json +++ b/src/_locales/en/messages.json @@ -1043,6 +1043,10 @@ "message": "Block element in frame...", "description": "An entry in the browser's contextual menu" }, + "contextMenuSubscribeToList": { + "message": "Subscribe to filter list...", + "description": "An entry in the browser's contextual menu" + }, "contextMenuTemporarilyAllowLargeMediaElements": { "message": "Temporarily allow large media elements", "description": "A context menu entry, present when large media elements have been blocked on the current site" diff --git a/src/js/contextmenu.js b/src/js/contextmenu.js index 80b2ed7a7569c..75ec7d36cd117 100644 --- a/src/js/contextmenu.js +++ b/src/js/contextmenu.js @@ -72,6 +72,32 @@ const onBlockElementInFrame = function(details, tab) { /******************************************************************************/ +const onSubscribeToList = function(details) { + let parsedURL; + try { + parsedURL = new URL(details.linkUrl); + } + catch(ex) { + } + if ( parsedURL instanceof URL === false ) { return; } + const url = parsedURL.searchParams.get('location'); + if ( url === null ) { return; } + const title = parsedURL.searchParams.get('title') || '?'; + const hash = µBlock.selectedFilterLists.indexOf(parsedURL) !== -1 + ? '#subscribed' + : ''; + vAPI.tabs.open({ + url: + `/asset-viewer.html` + + `?url=${encodeURIComponent(url)}` + + `&title=${encodeURIComponent(title)}` + + `&subscribe=1${hash}`, + select: true, + }); +}; + +/******************************************************************************/ + const onTemporarilyAllowLargeMediaElements = function(details, tab) { if ( tab === undefined ) { return; } let pageStore = µBlock.pageStoreFromTabId(tab.id); @@ -88,6 +114,9 @@ const onEntryClicked = function(details, tab) { if ( details.menuItemId === 'uBlock0-blockElementInFrame' ) { return onBlockElementInFrame(details, tab); } + if ( details.menuItemId === 'uBlock0-subscribeToList' ) { + return onSubscribeToList(details); + } if ( details.menuItemId === 'uBlock0-temporarilyAllowLargeMediaElements' ) { return onTemporarilyAllowLargeMediaElements(details, tab); } @@ -106,6 +135,12 @@ const menuEntries = { title: vAPI.i18n('contextMenuBlockElementInFrame'), contexts: ['frame'], }, + subscribeToList: { + id: 'uBlock0-subscribeToList', + title: vAPI.i18n('contextMenuSubscribeToList'), + contexts: ['link'], + targetUrlPatterns: [ 'abp:*' ], + }, temporarilyAllowLargeMediaElements: { id: 'uBlock0-temporarilyAllowLargeMediaElements', title: vAPI.i18n('contextMenuTemporarilyAllowLargeMediaElements'), @@ -134,6 +169,7 @@ const update = function(tabId = undefined) { if ( newBits & 0x01 ) { usedEntries.push(menuEntries.blockElement); usedEntries.push(menuEntries.blockElementInFrame); + usedEntries.push(menuEntries.subscribeToList); } if ( newBits & 0x02 ) { usedEntries.push(menuEntries.temporarilyAllowLargeMediaElements);