reactjs - Pokreni skriptu unutar nove kartice kreirane s chrome.tabs.create()
Kako izvršiti skriptu koristeći chrome.tabs.executeScript() u kartici koju sam stvorio koristeći chrome.tabs.create(). Pretražio sam i čini se da nijedno od rješenja ne radi.
Ovo je moj trenutni kod.
runContentScript(){
chrome.tabs.create({url: "https://google.com/", active: true});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab){
chrome.tabs.executeScript(tab.id!, {file: "tracking.js"});
});
}
Moj manifest je također ispravno postavljen.
UREDI: Dodan je cijeli kod jer nisam siguran da li nešto ometa funkciju runContentScript.
import React, { Component } from 'react';
import 'bootstrap/dist/css/bootstrap.min.css';
import { ListGroup } from 'react-bootstrap';
import './Cart.css';
import logo from './greenlake_logo.png';
import { url } from 'inspector';
class ProductList extends Component<{}, {products: any[][]}> {
constructor(props: any){
super(props);
this.addProduct.bind(this);
this.runContentScript.bind(this);
this.checkIfPathsExists.bind(this)
this.loadProductPage.bind(this);
this.removeLocalStorage.bind(this);
this.state = {products: []};
}
setLocalStorage(values: any[]){
chrome.storage.sync.set({'productList': values});
}
async appendLocalStorage(product: any[]){
var promisedStorageValues = new Promise(function(resolve, reject){
chrome.storage.sync.get('productList', function(result){
resolve(result.productList);
})
});
const values: any = await promisedStorageValues;
const newValues: any[] = [];
for(let i=0; i < values.length; i++){
newValues.push(values[i]);
}
newValues.push(product);
this.setLocalStorage(newValues);
this.readLocalStorage();
}
async removeLocalStorage(product: any[]){
var promisedStorageValues = new Promise(function(resolve, reject){
chrome.storage.sync.get('productList', function(result){
resolve(result.productList);
})
});
const values: any = await promisedStorageValues;
values.splice(values.indexOf(product, 0), 1);
this.setLocalStorage(values);
this.readLocalStorage();
}
async readLocalStorage(){
var promisedStorageValues = new Promise(function(resolve, reject){
chrome.storage.sync.get('productList', function(result){
resolve(result.productList);
})
});
const values: any = await promisedStorageValues;
this.setState({products: values});
}
async addProduct(){
var promisedURL = new Promise(function(resolve, reject){
chrome.tabs.query({active: true, currentWindow: true}, function(tabs){
resolve([tabs[0].url, tabs[0].favIconUrl, tabs[0].title]);
})
});
const urlInformation: any = await promisedURL;
const urlFavicon: any = urlInformation[1];
const urlProduct: any = urlInformation[0]
var workaroundHost: any = new URL(urlInformation[0]);
const urlHost: any = workaroundHost.host;
const urlTitle: any = urlInformation[2];
const urlPrice: any = 'placeholder';
this.appendLocalStorage([urlProduct, urlFavicon, urlTitle, urlPrice, urlHost]);
}
loadProductPage(url: string){
chrome.tabs.create({url: url, active: true});
}
runContentScript(urlProduct: string){
chrome.tabs.create({url: urlProduct}, createdTab => {
chrome.tabs.onUpdated.addListener(function _(tabId, info, tab) {
if (tabId === createdTab.id && info.url) {
chrome.tabs.onUpdated.removeListener(_);
chrome.tabs.executeScript(tabId, {file: 'tracking.js'});
}
});
});
}
loadPath(url: string){
fetch("http://127.0.0.1:5000/getpath/" + url)
.then(response => response.json())
.then(response => {
console.log('loadPath: ' + response)
})
}
checkIfPathsExists(){
for(let i=0; i < this.state.products.length; i++){
const urlHost: string = this.state.products[i][4];
let formattedHost = urlHost.split('.')[1];
const status = fetch("http://127.0.0.1:5000/checkpath/" + formattedHost)
.then(response => response.json())
.then(response => {if(response == true){this.loadPath(formattedHost)}else{this.runContentScript(this.state.products[i][0])}});
}
}
componentDidMount(){
this.readLocalStorage();
}
render(){
return (
<div>
<div className="logoDiv">
<img src={logo} width="128" height="64" />
</div>
<div className="centeredDiv">
{this.state.products.map(product => {return (
<div>
<ListGroup horizontal id="Test">
<ListGroup.Item className="ProductListLogo" onClick={() => this.loadProductPage(product[0])}><img src={product[1]} width="32" height="32"></img></ListGroup.Item>
<ListGroup.Item className="ProductListProduct">{product[2]}</ListGroup.Item>
<ListGroup.Item className="ProductListPrice">{product[3]}</ListGroup.Item>
<ListGroup.Item className="ProductListAction" onClick={() => this.removeLocalStorage(product)}>X</ListGroup.Item>
</ListGroup>
<div className="spacerLine"/>
</div>
)})}
</div>
<div className="actionDiv">
<ListGroup horizontal>
<ListGroup.Item className="ActionButtons" onClick={() => this.addProduct()}>Add To Cart</ListGroup.Item>
<ListGroup.Item className="ActionButtons" onClick={() => this.checkIfPathsExists()}>Checkout</ListGroup.Item>
</ListGroup>
</div>
</div>
);
}
}
class Cart extends Component {
render(){
return (
<div className="containerDiv">
<div>
<ProductList />
</div>
</div>
)
}
}
export default Cart;
RIJEŠENJE Trebate dodati "active: false" jer se prilikom stvaranja kartice automatski fokusira na nju i zatvara ekstenziju ako nije drugačije navedeno. Povratna funkcija stoga se nikada ne poziva.
chrome.tabs.create({url: urlProduct, active: false}, createdTab => {
chrome.tabs.onUpdated.addListener(function _(tabId, info, tab) {
if (tabId === createdTab.id && info.url) {
chrome.tabs.onUpdated.removeListener(_);
chrome.tabs.executeScript(tabId, {file: 'tracking.js'});
}
});
});
Odgovor #1
Pretpostavljajući da permissions u manifest.json uključuje "https://google.com/" (ili širi obrazac), ovdje postoje tri problema.
1. Zaobilazno rješenje za Chrome bug pri preusmjeravanju
crbug.com/820080: chrome.tabs.executeScript može ne uspjeti ako proslijeđeni tab prolazi kroz navigaciju glavnog okvira. Specifikujete https://google.com/, ali tamo nema stranice, ona preusmjerava na https://www.google.com/ što ne vidite u novom Chromeu jer skriva www. Ili omogućite prikaz pune URL adrese ili koristite location.href u konzoli za razvojne alate da vidite stvarni URL.
Presuda: budući da bilo koja stranica može odlučiti izvršiti preusmjeravanje iz bilo kojeg razloga, pouzdano rješenje je koristiti chrome.tabs.onUpdated, ali to učinite ispravno, vidi dolje.
2. Ispravno koristite chrome.tabs.onUpdated
- Koristite ID stvorenog taba u povratnom pozivu kako biste ograničili onUpdated samo na taj tab
- Odjavite slušatelja kako biste spriječili nakupljanje slušatelja što bi uzrokovalo pogreške
3. Spriječite automatsko zatvaranje skočnog prozora
Otvaranje aktivne/fokusirane kartice zatvara trenutno prikazani dodatak, potpuno ga prekida, tako da se povratna funkcija za create() neće izvršiti jer se poziva asinhrono.
Zaobilazno rješenje.
Jednostavno rješenje je otvoriti karticu kao neaktivnu, a zatim se usredotočiti na nju:
chrome.tabs.create({url: 'https://google.com/', active: false}, createdTab => { chrome.tabs.onUpdated.addListener(function _(tabId, info, tab) { if (tabId === createdTab.id && info.url) { chrome.tabs.onUpdated.removeListener(_); chrome.tabs.executeScript(tabId, {file: 'tracking.js'}, () => { chrome.tabs.update(tabId, {active: true}); // the above will close the popup if it doesn't have its own devtools open }); } }); });Rješenje.
Pouzdano rješenje je napraviti to u pozadinskom skriptu jer gore navedeno zaobilazno rješenje može ne uspjeti ako neki drugi dodatak mijenja zadano ponašanje novih kartica i prisilno fokusira vašu karticu, što automatski zatvara skočni prozor i uništava zaobilazno rješenje.
popup.js:
chrome.runtime.sendMessage({ cmd: 'openTab', url: 'https://google.com/', script: 'tracking.js', });background.js:
chrome.runtime.onMessage.addListener((msg, sender, sendResponse) => { if (msg.cmd === 'openTab') { chrome.tabs.create({url: msg.url}, createdTab => { chrome.tabs.onUpdated.addListener(function _(tabId, info, tab) { if (tabId === createdTab.id && info.url) { chrome.tabs.onUpdated.removeListener(_); chrome.tabs.executeScript(tabId, {file: msg.script}); } }); }); } });
Odgovor #2
Možete koristiti chrome.tabs.create funkciju povratnog poziva.
runContentScript(){
chrome.tabs.create({url: 'https://google.com/', active: true}, tab => {
chrome.tabs.executeScript(tab.id, {file: 'tracking.js'});
});
}
