Chrome Extension Manifest V3 Fill Form Data In An External iFrame - javascript

I am creating a chrome extension that autofills forms on a webpage. Similar to this post I am running into the following error:
Error handling response: Error: Blocked a frame with origin "<URL_OF_WEBSITE>" from accessing a cross-origin frame.
at chrome-extension://lmhbdbgimlffldbbijpmbinppkeopclf/content.js:56:45
I have tried the suggested answer of using "all_frames": true as well as "match_origin_as_fallback": true but I still receive the same error message.
Any ideas of what may be going on would be appreciated as I know there are plenty of extensions that do perform these steps perfectly.
manifest.json
{
"name": "Extension Autofill",
"version": "1.0",
"manifest_version": 3,
"action": {
"default_popup": "ext/popup.html",
"default_title": "Extension Autofill"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [
{
"matches": ["<all_urls>"],
"all_frames": true,
"match_origin_as_fallback": true,
"js": ["content.js"]
}
],
"permissions": ["storage", "tabs", "activeTab", "declarativeContent"]
}
content.js - Attempt 1
let ifr = document.getElementsByTagName("iframe")[1];
if(ifr){
ifr.contentWindow.document.getElementById('name').value = "John Doe";
}
content.js - Attempt 2
function imitateKeyInput(el, keyChar) {
const keyboardEventInit = {
bubbles:false,
cancelable:false,
composed:false,
key:'',
code:'',
location:0
};
let keyDownEvent = new KeyboardEvent("keydown", keyboardEventInit);
el.dispatchEvent(keyDownEvent);
el.value = keyChar;
let keyUpEvent = new KeyboardEvent("keyup", keyboardEventInit);
el.dispatchEvent(keyUpEvent);
let inputChangeEvent = new Event('change', { bubbles: true });
el.dispatchEvent(inputChangeEvent);
}
const el = document.querySelector('#name');
if(el) {
el.focus();
imitateKeyInput(el, 'John Doe');
} else {
console.log("element NOT FOUND);
}
Javascript Context
Content script verified to be in target iFrame.
Tested on: Edge Version 109.0.1518.70 & Chrome Version 109.0.5414.120

Related

Chrome Extension Content-Script as Listener & Popup as Sender, But Gives Receiving End Does Not Exist

Answer Found
This extension is for google meet. What I have written in manifest.json is wrong, line "matches": ["*://*.meet.google.com/*"], should be "matches": ["*://meet.google.com/*"],
Original Question
I have this chrome extension, I want to let my contentScript.js to search for an element (tag) in a webpage when I press a button in popup.html. I set the sending message part in popup.js and the sending seems to work fine. But when I tried to receive it on the contentScript.js, console.log gives me Unchecked runtime.lastError: Could not establish connection. Receiving end does not exist.
May someone please help me, any suggestions are welcome.
Code snippets:
popup.js
retrieveTabId();
function retrieveTabId() {
chrome.tabs.query({currentWindow: true, active: true}, function (tabs) {
var activeTab = tabs[0];
console.log("tabID", activeTab.id);
tabId = activeTab.id;
});
}
document.getElementById("btn").addEventListener('click', function (){
chrome.tabs.sendMessage(tabId, {type: "listener"}, function(response) {
console.log((response.success));
});
console.log("tabID", tabId);
})
content-script.js
chrome.runtime.onMessage.addListener(
function (request, sender, sendResponse) {
if (request.type == 'listener') {
try {
let textarea = document.getElementsByTagName('textarea');
if (textarea.length == 0) {
sendResponse({success: false});
}
else {
console.log('find node -- textarea' + textarea);
sendResponse({success: true});
}
}
catch (e){
console.log(e);
sendResponse({success: false});
}
}
}
);
manifest.json
{
"name": "name",
"description": "Build an Extension!",
"version": "1.0",
"manifest_version": 3,
"permissions": ["storage", "activeTab", "scripting", "downloads", "notifications", "<all_urls>", "tabs"],
"action": {
"default_popup": "popup.html"
},
"background": {
"service_worker": "background.js"
},
"content_scripts": [{
"matches": ["*://*.meet.google.com/*"],
"js": ["contentScript.js"]
}]
}

Save As Dialog not showing in Chrome Extension

I'm developing chrome extension for my coworkers and myself. The goal is to download single image by clicking a button at behance.net.
The problem is that some of my coworkers using "Ask where to save each file before downloading" option, so the code doesn't work for them. I don't use this option, so download is successfull for me.
I've tried to set different options for chrome.downloads.download(), but I got nothing. Save As dialog not showing.
Manifest
{
"name": "Begrab",
"description": "Download pics right from Behance",
"version": "1.0",
"manifest_version": 3,
"background": {
"service_worker": "background.js"
},
"permissions": ["activeTab", "downloads","tabs", "background"],
"content_scripts": [
{
"matches": ["https://*.behance.net/*"],
"run_at": "document_end",
"css": ["content.css"],
"js": ["content.js"]
}
]}
content.js
window.setTimeout(()=> {
codeRun();
}, 1000)
let projectLinks = document.querySelectorAll('.ProjectCoverNeue-coverLink-102')
Array.from(projectLinks).forEach(projectLink => {
projectLink.addEventListener('click', function(){
window.setTimeout(()=> {
codeRun();
}, 4000)
})
})
function codeRun() {
let imageParents = document.querySelectorAll('.js-project-lightbox-link');
Array.from(imageParents).forEach(imageParent => {
let button = document.createElement('a'),
buttonCopy = document.createElement('a'),
buttonsWrap = document.createElement('div'),
img = imageParent.querySelector('img'),
controls = imageParent.querySelector('.project-module__actions');
if(img) {
button.innerText = "Download";
button.className = "begrab__btn";
buttonsWrap.className = "begrab__wrap";
buttonsWrap.appendChild(button);
imageParent.appendChild(buttonsWrap)
button.addEventListener('click', (e) => {
let param = {src: img.src,
fileName: window.location.href};
e.stopPropagation()
chrome.runtime.sendMessage(param);
});
}
});
}
background.js
chrome.runtime.onMessage.addListener(
function(arg, sender, sendResponse) {
if(arg.src){
chrome.downloads.download({
url: arg.src,
conflictAction: "prompt"
}, function (downloadId) {
console.log(downloadId);
});
}
});
Did anyone face the same problem? Hope that somebody would help me. Thanks!
After some debugging i found out that the user is canceling the download for some reason.
The onChanged event outputs the following:
{
"error": {
"current": "USER_CANCELED"
},
"id": 1,
"state": {
"current": "interrupted",
"previous": "in_progress"
}
}
The only way i was able to get it work was downgrading the manifest to v2:
{
"manifest_version": 2,
"background": {
"persistent": true,
"scripts": [
"background.js"
]
}
}
I don't know if this is an option for you.

How to make Firefox WebExtension use microphone

I've been trying to make Firefox Extension which needs to have an ability for user to record a voice message.
I've made a web page which does work, but when I put the same code in the extension (with all the proper manifest.json changes), it doesn't work. It simply doesn't ask user for access to microphone.
I went through extension examples on Firefox site but I can't find the solution.
How can the extension, if it can, access users microphone?
Code:
window.addEventListener('load', initAudio);
And the initAudio function:
function initAudio() {
console.log("initAudio");
if (!navigator.getUserMedia)
navigator.getUserMedia = navigator.webkitGetUserMedia || navigator.mediaDevices.mozGetUserMedia;
if (!navigator.cancelAnimationFrame)
navigator.cancelAnimationFrame = navigator.webkitCancelAnimationFrame || navigator.mozCancelAnimationFrame;
if (!navigator.requestAnimationFrame)
navigator.requestAnimationFrame = navigator.webkitRequestAnimationFrame || navigator.mozRequestAnimationFrame;
console.log("initAudio");
navigator.mediaDevices.getUserMedia(
{
"audio": {
"mandatory": {
"googEchoCancellation": "false",
"googAutoGainControl": "false",
"googNoiseSuppression": "false",
"googHighpassFilter": "false"
},
"optional": []
},
}, gotStream, function (e) {
console.log('Error getting audio');
$("#controls").css("background", "red");
console.log(e);
});
}
I don't get console output
Error getting audio
But I also don't get the console output from gotStream function.
Later, I have an HTML object which triggers the recording process:
<img id="record" src="./res/icons/mic.png" class="">
with it's accompanying Javascript code:
$(document).ready(function () {
$("#record").click(function () {
console.log("trigerred", this);
toggleRecording(this);
});
});
function toggleRecording does get trigerred properly, but it can't work since Recorder object is not initalized (it gets initalized in gotStream function).
Here is the manifest.json file:
{
"manifest_version": 2,
"name": "Speech",
"version": "1.1",
"description": "blank desript",
"icons": {
"16": "popup/res/icons/icon16.png",
"32": "popup/res/icons/icon32.png",
"48": "popup/res/icons/icon48.png",
"128": "popup/res/icons/icon128.png"
},
"permissions": [
"storage"
],
"browser_action": {
"default_icon": {
"32": "popup/res/icons/icon.png"
},
"default_title": "Speech",
"default_popup": "popup/popup.html"
},
"content_scripts": [
{
"js": [
"popup/res/script/jquery-3.2.1.js",
"popup/res/script/audiodisplay.js",
"popup/res/script/recorder.js",
"popup/res/script/recorderWorker.js",
"popup/res/script/resampler.js",
"popup/res/script/main.js"
],
"matches": [ "<all_urls>" ],
"match_about_blank": true,
"all_frames": true
}
],
"content_security_policy": [
"script-src 'unsafe-inline'"
]
}

Chrome Extension Access Xively

How can I access a Xively Feed through chrome extension. I am building a simple extension which will block websites depending on the value that is currently displayed on my Xively Feed. However I unsure on how to access the Xively feed without Html, I've looked at the XivelyJS library which I have used before but in a HTML page. However my extension needs to be independent of HTML.
Code Below is my attempt at using XivelyJS however I would be appreciative of an easier or better method.
Background.js:
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: true};
},
{urls: ["*://www.facebook.com/*", "*://www.twitter.com/*"]},
["blocking"]);
// Set your API key first
// Get feed content
xively.setKey( "APIKEY" );
function ReadData(){
var reading = xively.datastream.get ("832936337", "Reading", callback (data));
console.log(reading);
console.log(data);
setTimeout(ReadData,3000);
}
ReadData();
Manifest.json:
{
"manifest_version": 2,
"name": "SiteBlockerFyp",
"description": "Block Respective Sites",
"version": "1",
"permissions": [
"webRequest",
"webRequestBlocking",
"*://www.facebook.com/*","*://www.twitter.com/*"
],
"content_scripts": [
{
"matches": ["*://www.facebook.com/*"],
"js": ["jquery.min.js", "xivelyjs.min.js"]
}
],
"background": {"scripts": ["background.js"]}
}
Found that I could access the values like so :
chrome.webRequest.onBeforeRequest.addListener(
function(details) {
return {cancel: true};
console.log(details.url);
},
{urls: ["*://www.twitter.com/*"]},
["blocking"]);
// Set your API key first
// Get feed content
xively.setKey( "APIKEY" );
console.log("XIVELY LOADED");
var feedID = 832936337, // Feed ID
datastreamID = "Reading"; // Datastream ID
data = "null"; // Your element on the page
dataUpdated= "null";
console.log("READ ");
xively.datastream.get (feedID, datastreamID, function ( datastream ) {
data = datastream["current_value"];
console.log(data);
xively.datastream.subscribe( feedID, datastreamID, function ( event , datastream_updated ) {
dataUpdated = datastream_updated["current_value"] ;
console.log(dataUpdated);
});
});
chrome.tabs.query({'active': true, 'windowId': chrome.windows.WINDOW_ID_CURRENT},
function(tabs){
console.log(tabs[0].url);
if (tabs[0].url == "*www.twitter.com*") {
alert("Twitter");
}
}
);
subscribing also gave me updates as they occurred. However using background.js as a background script in the manifest means it wont run across all pages so I still trying to figure this one out, Content-scripts is apparently the way to go.
{
"manifest_version": 2,
"name": "SiteBlockerFyp",
"description": "Block Respective Sites",
"version": "1",
"permissions": [
"webRequest",
"webRequestBlocking",
"*://www.twitter.com/*",
"tabs"
],
"content_scripts": [
{
"matches": ["<all_urls>"],
"js": ["jquery.min.js", "xivelyjs.min.js", "background.js"]
}
]
}

How can I call functions defined in a Chrome Extension from regular websites?

I'd like to make a website that is not part of the chrome plugin but rather just uses some API that the plugin exposes to it. Is this possible and if so, how do I do it? I googled this question and was unable to find anything.
I'm trying to use content scripts but nothing happens. Can someone explain what's wrong here?
manifest.json
{
"manifest_version": 2,
"name": "Hello World Extension",
"description": "This extension prints hello world.",
"version": "1.0",
"background": {
"page": "background.html"
},
"browser_action": {
"default_icon": "img/icon.png",
"default_popup": "popup.html"
},
"content_scripts": [
{
"matches": ["http://locahost:8888/*"],
"js": ["EmotivAPI.js"]
}
]
}
EmotivAPI.js
var port = chrome.runtime.connect();
console.log("Hello?");
window.addEventListener("message", function (event) {
// We only accept messages from ourselves
if (event.source != window)
return;
if (event.data.type && (event.data.type == "FROM_PAGE")) {
console.log("Content script received: " + event.data.text);
port.postMessage(event.data.text);
alert("recieved!");
}
}, false);
js in the webpage
window.sayHello = function () {
window.postMessage({ type: "FROM_PAGE", text: "Hello from webpage!" }, "*");
}
console.log('Emotiv extension loaded.');
}
I'm calling window.sayHello() from the console
Content Scripts can help you in this case.
The content script will be injected into a page:
"content_scripts": [
{
"matches": ["http://www.google.com/*"], // try with "http://localhost:*/*" or "http://localhost:*"
"css": ["mystyles.css"],
"js": ["content_script.js"]
}
]
If you want to inject the code only sometimes, use the permissions field instead
/* in manifest.json */
"permissions": [
"tabs", "http://*/*"
],
In you extension html file, you can then execute the script by:
chrome.tabs.executeScript(null, {file: "content_script.js"});

Categories