Chrome Extension ContextMenu for PDF - javascript

I'm developing a extension for the chrome browser and i want to add a specified contextmenu for pdf documents. I also add to specified contextmenus for the type "page" and "image".
If i set the type to "all" then there is a contextmenu, but not specified for pdf documents.
Is it possible to add a specified contextmenu for pdf documents or should i use a the type "all" an it make switch case in the clickEventHandler?!
See more at:
http://developer.chrome.com/extensions/contextMenus.html
These are the "file" types:
contexts ( optional array of enum of "all", "page", "frame", "selection", "link", "editable", "image", "video", "audio", or "launcher" )

I'm guessing that you want to add a context menu only when a PDF is shown in a tab, right? Just asking because I thought at first that you wanted to add the context menu on links to PDF files, which is indeed possible*. (as you probably know)
I couldn't find a way to do this directly, however one alternative could be to listen to chrome.tabs.onActivated and add or remove your context menu based on if the current URL matches a PDF file. One drawback is that it means asking for the tabs permission which might looks scary to users. ("This extension can access your tabs and browsing activity" or something like that)
*for the curious, you do it like this:
chrome.contextMenus.create({
title: "Hello world",
contexts: ["link"],
targetUrlPatterns: ["*://*/*.pdf"]
});
(you would add the other options that interest you of course)

This functions works for me for pdf documents:
chrome.tabs.onActivated.addListener(function (info) {
var tab = chrome.tabs.get(info.tabId, function (tab) {
if (tab.url.indexOf(".pdf") > 0) {
chrome.contextMenus.create({
"id": "1",
title: "Just for PDF Documents",
contexts: ["all"],
onclick: function (e) {
}
});
} else {
chrome.contextMenus.remove("1", null);
}
});
});
Maybe the line
if (tab.url.indexOf(".pdf") > 0) {
should edit with a expression!

Current answers are not perfect:
The way to remove context menus
Not work well with new open pdf file or multiple windows
let g_contextMenus = [{
id: "test",
title: "test"
}];
function createContextMenus() {
for (var menu of g_contextMenus) {
chrome.contextMenus.create({
id: menu["id"],
type: "normal",
title: menu["title"],
contexts: ["all"]
});
}
}
createContextMenus();
function updateContextMenu(tabId) {
chrome.tabs.get(tabId, function(tab) {
var suffix = tab.url.slice(-4);
var isPdf = suffix.toLowerCase() == ".pdf";
for (var menu of g_contextMenus) {
chrome.contextMenus.update(menu["id"], { visible: isPdf })
}
});
};
/**
* Switch tab
**/
chrome.tabs.onActivated.addListener(function(info) {
updateContextMenu(info.tabId);
});
/**
* New open file
**/
chrome.tabs.onUpdated.addListener(function(tabId, info, tab) {
var suffix = tab.url.slice(-4);
if (info.status == "complete" && suffix.toLowerCase() == ".pdf") {
updateContextMenu(tabId);
}
});
/**
* Multiple window/New window
**/
chrome.windows.onFocusChanged.addListener(function(winId) {
chrome.tabs.query({ lastFocusedWindow: true, active: true }, function(tabs) {
updateContextMenu(tabs[0].id);
});
});
References:
How to get the currently opened tab's URL in my page action popup?
Check if Item is already in the Context Menu

Related

Is there any way to change the title and save type of file dialog on electron?

I've created a button for downloading and saving a file returned from an api endpoint.
In common browser, after clicking the button, a save file dialog appears with title Save As and Save as type displayed by file's extension. But in electron, the title seems to be a file url (in my case it shows blob://https:... cause mine is created with URL.createObjectURl).
So is that any options I need to set to a tag to make the dialog title is Save As and correct the save type of file (without using native dialog of electron)?
...
<a hidden href='/' ref={downloadRef}>download</a>
<button onClick={handleSaveFile}>download</button>
...
const handleSaveFiles = (file: Blob, fileName: string): void => {
const fileDownloadUrl = window.URL.createObjectURL(file);
if (downloadRef.current) {
downloadRef.current.href = fileDownloadUrl;
downloadRef.current.download = fileName;
downloadRef.current.click();
}
};
Actually, the dialog opened when clicking that button already is electron's dialog, then I could edit the title and filters by will-download event.
...
this.browserWindow = new BrowserWindow(option);
...
this.browserWindow.webContents.session.on('will-download', (event, item) => {
let filters = [];
switch (item.getMimeType()) {
case 'text/csv':
filters = [{ name: 'Microsoft Excel Comma Separated Values File', extensions: ['csv'] }];
break;
case 'application/octet-stream':
filters = [{ name: 'Zip archive', extensions: ['zip'] }];
break;
default:
break;
}
item.setSaveDialogOptions({
title: 'Save As',
filters: [...filters, { name: 'All Files', extensions: ['*'] }],
});
});
Refer to https://www.electronjs.org/docs/latest/api/download-item#downloaditemsetsavedialogoptionsoptions

CKFinder: Change the default view when switching between resource types

I'm setting up CKFinder as a file browser for CKEditor and would like the defaultViewType to be different for each Resource Type. For example, when browsing the Images resource it should show thumbnails, but when browsing the Files resource it should display the "compact" view.
I have tried the following configuration, but it just shows thumbnails for both Files and Images:
defaultViewType: "thumbnails",
defaultViewType_Files: "compact"
I had considered writing a small plugin via the onInit function along the following lines:
onInit: function(finder) {
finder.on("folder:getFiles:before", function(event) {
var folder = finder.request("folder:getActive");
var resource = folder.getPath({full: true}).replace(/:.*$/, "");
switch (resource) {
case "Files":
finder.request("files.changeView", "compact");
break;
case "Images":
finder.request("files.changeView", "thumbnails");
break;
});
}
But I'm not sure what request type to fire (files.changeView or similar doesn't exist).
Is it possible to achieve this either with config options or a plugin?
I'm not sure if you are still interested but this should help you get started:
http://docs.cksource.com/ckfinder3/#!/api/CKFinder.Application-event-settings_change_GROUP_NAME
http://docs.cksource.com/ckfinder3/#!/api/CKFinder.Application-event-contextMenu_file_GROUP
http://docs.cksource.com/ckfinder3/#!/api/CKFinder.Application-request-settings_setValue
finder.on( 'folder:getFiles:before', function( evt ) {
//console.log(evt.data.folder);
if( evt.data.folder.attributes.resourceType == 'Images' )
finder.request( 'settings:setValue', {
group: 'files',
name: 'viewType',
value: 'thumbnails'
} );
else
finder.request( 'settings:setValue', {
group: 'files',
name: 'viewType',
value: 'list'
} );
}, null, null, 0 );

How do you call arbitrary functions using addRules with declarativeContent listeners in Chrome Extensions?

I am trying to change an extension I'm working on from a browser action to a page action. Currently, the extension detects a tab change and, if the URL of the tab is on our domains, makes a request for JSON data for status information, so it can make the good icon or the bad icon appear as a status indicator. My browser action code was this:
chrome.tabs.onActivated.addListener(function(activeInfo) {
chrome.tabs.get(activeInfo.tabId, function(tab) {
var url = tab.url,
matches = url.match(/(domain1)|(domain2)\.com/g);
if (url && matches) {
// Query for JSON data and change the icon based on it.
loadReach(url);
} else {
// Change the icon bad
}
});
});
I have the basic listeners in place to insert the declarativeContent listener and show the initial icon, but am unsure where to put my callback that makes the query for the JSON data:
// When the extension is installed or upgraded ...
chrome.runtime.onInstalled.addListener(function() {
// Replace all rules ...
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
// With a new rule ...
chrome.declarativeContent.onPageChanged.addRules([
{
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostContains: 'domain1.com' },
}),
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostContains: 'domain2.com' },
})
],
// And shows the extension's page action.
actions: [ new chrome.declarativeContent.ShowPageAction() ]
}
]);
});
});
Where in the second codeblock would I be able to run that callback, or is it not supported by this method?

Have chrome extension display on certain page using page action

I'm trying to make a chrome extension for the Pinterest.
I followed the examples I found from the Chrome extension sample (the one with displaying icon in the omnibox when there is a 'g' in the url) and changed the file a bit to make it display the icon when the site has "pinterest.com" in it. Here is the code:
manifest.json:
"permissions": [
"tabs",
"http://*.pinterest.com/"
]
background.js, I copied most of the code from the example online:
function showPinterestAction(tabId, ChangeInfo, tab) {
if(tab.url.indexOf('pinterest.com') > -1){
chrome.pageAction.show(tabId);
}
/* This doesn't work. tab.url return undefine to me :( */
};
chrome.tabs.onUpdated.addListener(function(tabId, change, tab) {
if (change.status == "complete") {
showPinterestAction(tabId);
}
});
chrome.tabs.onActivated.addListener(function(tabId, info) {
selectedId = tabId;
showPinterestAction(tabId);
});
// Ensure the current selected tab is set up.
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
alert(tabs[0].id);
showPinterestAction(tabs[0].id);
});
It is not displaying the icon at the right page. If I try to alert(tab.url) it gives me undefined. Can someone please tell me what's wrong with my code?
Well, you're only ever calling showPinterestAction with one parameter, tabId.
No surprises, therefore, that tab parameter is simply undefined. The signature of showPinterestAction follows the tab update callback, but you're not using it like one.
You can modify showPinterestAction to pull the data it needs:
function showPinterestAction(tabId) {
chrome.tabs.get(tabId, function(tab){
if(tab.url.indexOf('pinterest.com') > -1){
chrome.pageAction.show(tabId);
}
});
};
You also probably want to make your match pattern more general: "*://*.pinterest.com/*" should cover your use case.
Alternatively, instead of latching on to multiple tabs events, you can use declarativeContent API - it was created for this.
var rule = {
conditions: [
new chrome.declarativeContent.PageStateMatcher({
pageUrl: { hostSuffix: 'pinterest.com' }
})
],
actions: [ new chrome.declarativeContent.ShowPageAction() ]
};
chrome.runtime.onInstalled.addListener(function(details) {
chrome.declarativeContent.onPageChanged.removeRules(undefined, function() {
chrome.declarativeContent.onPageChanged.addRules([rule]);
});
});
In this case you will not need "heavy" permissions like "tabs" or host permissions. Your manifest only needs
"permissions": [
"declarativeContent",
"activeTab"
]
for this to work.

Display Notification When New Page Load in chrome extensions

I am developing an extension in google chrome.I want to show desktop notification when any new page loads in currently active tab.
But my written code is not working properly.
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo) {
if (changeInfo.status === 'complete') {
chrome.tabs.executeScript(tabId, {
chrome.notifications.create(‘id1’, {
type: ‘basic’,
iconUrl: ‘icon.png’,
title: ‘Review Baed Surfing’,
message: ‘Check URL now by clicking FAKE URL icon infront on Address Bar!’,
priority: 0
},
function() { /* Error checking goes here */}
);
});
}
});
I think you only need to call chrome.notifications.create() in background script and chrome.tabs.executeScript only accept file url or code (css, js) to inject.
And you could check the following items when the notification doesn't show as expected:
Add "notification" to permissions in manifest.json.
"permissions": ["notifications"]
Notifications API only supports Windows, Chrome OS and Mac currently.
The 'option' parameter of create function must include a notification title, message and iconUrl. The rich notification will not work properly without any error if you missed any one of them.
var opt = {
type: "basic",
title: "Primary Title",
message: "Primary message to display",
iconUrl: "url_to_small_icon"
}
Hope this is helpful.
[SOLVED]
i make following changes in code
chrome.tabs.onUpdated.addListener( function (tabId, changeInfo, tab) {
if (changeInfo.status == 'complete' && tab.active) {
chrome.notifications.create('id1',{
type: 'basic',
iconUrl: 'icon.png',
title: 'Review Baed Surfing',
message: 'Check URL now by clicking FAKE URL icon infront on Address Bar!',
priority: 0
},
function() { /* Error checking goes here */}
);
}
});
Now it works properly.
Thank You,

Categories