I've a problem with permissions, I want to inject my javascript into a page served from https, http and file
Below the manifest file
{
"background":{
"scripts":["background.js"]
},
"permissions":["tabs"],
"browser_action": {
"default_icon": "img/icone.png",
"default_title": "displayer."
},
"icons" : {
"128" : "img/icone_128.png",
"48" : "img/icone_48.png",
"32" : "img/icone_32.png",
"24" : "img/icone_24.png",
"16" : "img/icone_16.png"
},
"manifest_version": 2,
"name": "displayer.",
"description": "This extension helps you to compare your wireframe with your current coded page..",
"version": "1.0.1"
}
And the injected javascript (background.js)
chrome.browserAction.onClicked.addListener(function (tab) { //Fired when User Clicks ICON
if (tab.url.indexOf("http://*/*, https://*/*, file://*/*") != -1) { // Inspect whether the place where user clicked matches with our list of URL
chrome.tabs.executeScript(tab.id,
{"file": "contentscript.js"},
function () { // Execute your code
console.log("Script Executed .. "); // Notification on Completion
});
chrome.tabs.insertCSS(null, {file: "grid.css"});
}
});
I already tried to "permissions" :["https:///, http:///, file:///"], but it doesn't work.
Any help is much appreciated.
The fastest way to provide all the permissions is to include, literally, "<all_urls>" into the permissions set.
In general, read the match pattern documentation.
Your other problem is pointed out by Rob W in the comments: indexOf('http://*/*') searches for literally that string, with asterisks.
You can do, as he recommended, tab.url.indexOf('http:') == 0 and so on.
Related
I have a chrome extension, that changes the appereance of the wikipedia page. Now I want to change the image there. I want to replace it with one stored local in my chrome-extension. I want to change some HTML code to display my image. My manifest.json looks like this
{
"name" : "name",
"version": "0.0.1",
"manifest_version": 2,
"description" : "some desc",
"web_accessible_resources" : [
"images/*.png"
],
"content_scripts" : [
{
"css": ["style.css"],
"js": ["imgreplace.js"],
"matches" : ["*://www.wikipedia.de/"]
}
]
}
imgreplace.js
document.getElementsByClassName("wikipedia-logo").innerHTML = this.innerHTML + '<img src="chrome-extension://__MSG_##extension_id__/images/wikipedia_logo.png" title="Wikipedia" alt="Wikipedia"/>'
If I refresh the page nothing happens. No Error.
I've also tried it with the function injectAdjacentHTML, but I get the error injectAdjacentHTML is not a function.
How can I replace it?
Tell me, if you need anything of my code.
I fixed some bugs.
imgreplace.js
const path = chrome.runtime.getURL("images/wikipedia_logo.png");
document.getElementsByClassName("wikipedia-logo")[0].innerHTML +=
'<a href="https://www.wikipedia.org/"><img src="'
+ path + '" title="Wikipedia" alt="Wikipedia"/></a>';
This version does essentially the same thing as #NorioYamamoto's version; it's just a little cleaner.
The original WP logo is briefly visible, I don't know how to prevent that. If you use an SVG instead of a PNG, the change happens so quickly that you can barely see the original logo (YMMV).
manifest.json
{
"manifest_version": 3,
"name" : "Replace Wikipedia Logo",
"version": "0.0.1",
"content_scripts" : [
{
"js": ["imgreplace.js"],
"matches" : ["*://*.wikipedia.de/*"]
}
],
"web_accessible_resources" : [
{
"resources": ["/images/*.png"],
"matches": ["*://*.wikipedia.de/*"]
}
]
}
imgreplace.js
try {
let logo_selector = "#mainbox > div.wikipedia-logo > a > img";
let logo_imgs = document.querySelectorAll(logo_selector);
if (logo_imgs.length == 0) {
throw `The CSS selector "${logo_selector}" didn't find any elements.`;
}
else if (logo_imgs.length == 1) {
logo_imgs[0].src = chrome.runtime.getURL("/images/wikipedia_logo.svg");
}
else {
throw `The CSS selector "${logo_selector}" found more than one element.`;
}
}
catch(e) {
console.error(e);
}
How can I access the container that appears when I write a url in the address bar? I have a search engine, I just need to show an icon plus a url in the panel
researching I could only get a basic javascript
function createMenuItem(engines) {
for (let engine of engines) {
browser.menus.create({
id: engine.name,
title: engine.name,
contexts: ["selection"]
});
}
}
browser.search.get().then(createMenuItem);
browser.menus.onClicked.addListener((info, tab) => {
browser.search.search({
query: info.selectionText,
engine: info.menuItemId
});
});
//php get variable code
if(isset($_GET["term"])) {
$term = $_GET["term"];
} else {
header('location: '.$url.'');
}
//json
"search_url": "https://127.0.0.1/search/search?term={term}"
result
I tried it with
${term}
$term
{term}
term
You'll notice that the browser.search namespace only has two functions: get() and search() but nothing to add or modify search engines.
Instead, you declare the search engine as a search_provider in your extension's manifest.json file.
Mozilla provides an example for how to add a search engine here. The manifest.json included in the example speaks for itself.
manifest.json
{
"manifest_version": 2,
"name": "Discogs search engine",
"description": "Adds a search engine that searches discogs.com",
"version": "1.0",
"applications": {
"gecko": {
"strict_min_version": "55"
}
},
"chrome_settings_overrides": {
"search_provider": {
"name": "Discogs",
"search_url": "https://www.discogs.com/search/?q={searchTerms}",
"keyword": "disc",
"favicon_url": "https://www.discogs.com/favicon.ico",
"is_default": false,
"encoding": "UTF-8"
}
}
}
Trying to add hovers to add hovers to my VS Code extension. I was able to syntax highlighting and commands to work, but stuck on adding this hover feature.
I think my blocker is how to properly implement the HoverProvider API. I'm doing a simple test below for a hover provider that activates when a series of tokens are recognized as the keyword HELLO. The hover I've implemented in my testing. I'm using vsce package to package and test my extension locally.
My command for the extension works, but when I hover over the word "HELLO", my hover does not appear.
./client/extension.js
const vscode = require('vscode');
function activate(context) {
console.log('Congratulations, your extension "star-rod" is now active!');
let disposable = vscode.commands.registerCommand('extension.mamar', () => {
vscode.window.showInformationMessage("The Star Rod... is powerful beyond belief. It can grant any wish. For as long as we can remember, Bowser has been making wishes like, for instance... 'I'd like to trounce Mario' or 'I want Princess Peach to like me.' Of course, Stars ignore such selfish wishes. As a result, his wishes were never granted.");
});
context.subscriptions.push(disposable);
vscode.languages.registerHoverProvider('javascript', {
provideHover(document, position, token) {
const range = document.getWordRangeAtPosition(position);
const word = document.getText(range);
if (word == "HELLO") {
return new vscode.Hover({
language: "Hello language",
value: "Hello Value"
});
}
}
});
}
function deactivate() { }
module.exports = {
activate,
deactivate
}
./package.json
{
"name": "star-rod-script",
"publisher": "sonicspiral",
"displayName": "Star Rod Script",
"description": "Syntax highlighting for Paper Mario 64 ROM patching tool",
"version": "1.0.1",
"repository": {
"type": "git",
"url": "https://github.com/gregdegruy/star-rod.git"
},
"categories": [
"Programming Languages"
],
"activationEvents": [
"onCommand:extension.mamar",
"onLanguage:star-rod-script"
],
"engines": {
"vscode": "^1.31.0"
},
"main": "./client/extension.js",
"contributes": {
"capabilities": {
"hoverProvider": "true"
},
"commands": [
{
"command": "extension.mamar",
"title": "Mamar"
}
],
"languages": [
{
"id": "star-rod-script",
"extensions": [
".bpat",
".bscr",
".mpat",
".mscr"
],
"aliases": [
"Star Rod Script",
"mscr"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "star-rod-script",
"scopeName": "source.mscr",
"path": "./syntaxes/mscr.tmLanguage.json"
}
]
},
"devDependencies": {
"js-yaml": "^3.12.1",
"vscode": "^1.1.29"
}
}
Your code allowed me to get Hovers working in my first extension. I think your mistake is having javascript as the selector: vscode.DocumentSelector. Is that there from code you copied? That should probably be set to star-rod-script for your extension.
I also don't have "capabilities": {"hoverProvider": "true"} in mine. I changed your code to:
disposable = vscode.languages.registerHoverProvider('star-rod-script', { // or 'star rod script'
//....
});
context.subscriptions.push(disposable);
I don't know the nuances of how you apply your extension to certain documents, but it doesn't look like you're trying to apply the hover to javascript docs. You need the selector to include the docs your extension works with. In my case that's covered by my extension name which is the language mode that shows up in the vscode status bar. More info on document-selectors.
Not sure if it's needed, but I also took the return and pushed it onto the subscriptions array. Works without that, but I think that's proper??
Your package.json looks a bit odd. I bet your extension is not activated. The "contributes/capabilites" value is something I haven't seen before. Remove that and instead change your activationEvents to:
"activationEvents": [
"onLanguage:star-rod-script"
],
I have the following code. This is what it does. When you highlight/select some text on a webpage by clicking and dragging, right click to see the context menu, and when the menu item is clicked, the highlighted text shows up in an alert box. I want to modify this code so that the user doesn't have to highlight any text by click and drag. All they have to do is right click on a word and choose the context menu item. The word/text they right clicked on should appear as alert.
let contextMenuItem = {
"id": "helloWorld",
"title": "Hello World",
"contexts": ["selection"]
};
chrome.contextMenus.removeAll(function() {
chrome.contextMenus.create(contextMenuItem);
});
chrome.contextMenus.onClicked.addListener(function(clickData) {
let inputString = clickData.selectionText;
alert(inputString);
})
First of all, extensions have a "strict" permission model. When you give permission for contextMenus, you are limited to the following contexts:
"all", "page", "frame", "selection", "link", "editable", "image", "video", "audio", "launcher", "browser_action", or "page_action"
Bad UX
If it had a "word" or even a "text" context, it creates a non consistent user experience. Users are not familiar with right click doing actions on text within a web browser.
If you wanted such action, you need to introduce a content-script to add a mouse event to "automatically" select that word using the JavaScript Selection APIs. If you wanted this, you need to expose more "permissions" to your extension to support this experience. Users might not like that.
Example
If this is the experience the extension needs, just create a content-script which automatically selects that word. Something like this will work, which will create a caret range from the mouse position and modify its selection to that word. Note, within the permissions, I just enabled google.com, this is where the content script will inject.
contentscript.js
document.addEventListener('mouseup', (e) => {
if (e.button !== 2) {
return
}
const selection = window.getSelection()
selection.removeAllRanges()
const range = document.caretRangeFromPoint(e.clientX, e.clientY)
range.expand('word')
selection.addRange(range)
});
background.js
const menu = chrome.contextMenus.create({
'id': 'helloWorld',
'title': 'Hello "%s"',
'contexts': ['selection']
})
chrome.contextMenus.onClicked.addListener((clickData) => {
const inputString = clickData.selectionText
console.log(inputString)
});
manifest.json
{
"name": "contextMenus",
"version": "1.0",
"minimum_chrome_version": "35.0",
"manifest_version": 2,
"permissions": [
"contextMenus"
],
"background": {
"scripts": [
"background.js"
]
},
"content_scripts": [
{
"matches": ["https://*.google.com/*"],
"js": ["contentscript.js"]
}
]
}
I am currently developing a Chrome Extension and I want that the pageAction icon appears for an amount of URL's (around 500).
In my background.js file (among other code), I have this:
// Called when the url of a tab changes
function checkForValidUrl(tabId, changeInfo, tab) {
// If the tabs url starts with "http://specific_domain"
if (tab.url.indexOf('http://specific_domain') == 0) {
// Shows the page action
chrome.pageAction.show(tabId);
}
};
// Listen for any changes to the URL of any tab
chrome.tabs.onUpdated.addListener(checkForValidUrl);
I can get it to work on a specific site already, but I want to change the 'http://specific_domain' to a list of permitted sites, like a white list. I have access to a JSON file that is online.
Here's a snippet of it:
{
"antelife.com": {
"fbid": "AntElifecom",
"type": "store",
"name": "AntElife"
},
"amazon.com": {
"fbid": "Amazon",
"type": "store",
"name": "Amazon"
},
"ebay.com": {
"fbid": "eBay",
"type": "store",
"name": "eBay"
},
"mobilegeeks.com": {
"fbid": "mobilegeekscom",
"type": "publisher",
"name": "Mobile Geeks"
}
}
I want to extract the domains, and somehow iterate for all of them and if they are on the list, the pageAction icon should appear. Something like this:
function checkForValidUrl(tabId, changeInfo, tab) {
for (var i = 0, iLength = whiteListUrl.length; i < iLength; i++) {
if (tab.url.indexOf('http://www.'+whiteListUrl[i]) > -1) {
chrome.pageAction.show(tabId);
notification.show();
break;
}
}
};
chrome.tabs.onUpdated.addListener(checkForValidUrl);
Any kind of help should be useful. Many thanks.
If you have a json string you can get url's list in this way;
var urlObj = JSON.parse(jsonString);
var whiteListUrl = Object.keys(urlObj);