Good morning all,
I've been trying to save to chrome local and sync storage from my options page, without success. I read that I needed to store from a popup or background page, so I moved the code to background and messaged it. From the console I can see that my code is being executed, but still when I look in the Application tab in the Inspector, nothing is being saved. Any assistance appreciated:
chrome.runtime.onMessage.addListener(function(message, callback) {
if (message.data == "saveFeed") {
doSave(message.key, message.value);
};
});
doSave("options", "optionsvalue");
function doSave (key, value) {
chrome.storage.sync.set({key : value}, function () {
console.log("backstore.js saved " + value + " with key " + key);
});
}
Related
I am trying to download a pdf upon clicking a button. But I am not able to download it as it opens in new tab and not downloading it.
Following Solutions I have tried, but nothing seems to be working. Please help me .
1) Listening to the targetcreated, and coverting the page to pdf
browser.on('targetcreated', async (target) => {
if (target.type() !== 'page') {
return;
} else {
let newPage = await target.page();
await page.waitFor(5 * 1000); // To stop proceeding to other clicks in current page
await newPage.waitFor(5 * 1000); // To let it load the pdf
newPage.pdf({path: "./pdfDownloaded/" + new Date().getTime() + ".pdf"})
}
});
Solution did not work as converted pdf is blank
2) Setting flag always_open_pdf_externally: true
puppeteer.use(require('puppeteer-extra-plugin-user-preferences')({userPrefs: {
download: {
prompt_for_download: false,
},
plugins: {
always_open_pdf_externally: true
}
}}))
Solution did not work as Chrome/Chromium crashed with always_open_pdf_externally: true
3) Giving print() in page evaluate, and as the print preview opens find the save button and click .
Solution did not work as it opens prompt asking location to save pdf and Puppeteer has no access to the Operating System driven prompt
I'm going to be honest. I'm way in over my head here.
I need to scrape data from a dynamic site for my employer. Before the data is visible on the page, there are some clicks and waits necessary. Simple PHP scraping won't do. So I found out about this NodeJS + PhantomJS combo. Quite a pain to set up, but I did manage to load a site, run some code and get a result.
I wrote a piece of jQuery which uses timeout loops to wait for some data to be loaded. Eventually I get a js object that I want to write to a file (JSON).
The issue I'm facing.
I build up the the js object inside the PhantomJS .evaluate scope, which runs in a headerless browser, so not directly in my Node.JS server scope. How do I send the variable I built up inside evaluate back to my server so I can write it to my file?
Some example code (I know it's ugly, but it's for illustrative purposes). I use node-phantom-simple as a bridge between Phantom and Node
var phantom = require('node-phantom-simple'),
fs = require('fs'),
webPage = 'https://www.imagemedia.com/printing/business-card-printing/'
phantom.create(function(err, ph) {
return ph.createPage(function(err, page) {
return page.open(webPage, function(err, status) {
page.onConsoleMessage = function(msg) {
console.log(msg);
};
console.log("opened site? ", status);
page.evaluate(function() {
setTimeout(function() {
$('.price-select-cnt').eq(0).find('select').val('1266').change()
timeOutLoop()
function timeOutLoop() {
console.log('looping')
setTimeout(function() {
if ($('#ajax_price_tool div').length != 6) {
timeOutLoop()
} else {
$('.price-select-cnt').eq(1).find('select').val('25')
$('.price-select-cnt').eq(2).find('select').val('Premium Card Stock')
$('.price-select-cnt').eq(3).find('select').val('Standard').change()
timeOutLoop2()
}
}, 100)
}
function timeOutLoop2() {
console.log('looping2')
setTimeout(function() {
if ($('.pricing-cost-cnt').text() == '$0' || $('.pricing-cost-cnt').text() == '') {
timeOutLoop2()
} else {
var price = $('.pricing-cost-cnt').text()
console.log(price)
}
}, 100)
}
}, 4000)
});
});
});
});
function writeJSON(plsWrite) {
var key = 'file'
fs.writeFile('./results/' + key + '.json', plsWrite, 'utf8', function() {
console.log('The JSON file is saved as');
console.log('results/' + key + '.json');
});
}
So do do I write the price this code takes from the website, get it out of the evaluate scope and write it to a file?
While trying to fetch Office 2016 Word document body using Office 2016 Word Add-In, java Script API methods body.getHtml() and body.getOoxml() are not working-;
It is returning error "Debug info: {"errorLocation":"Body.getHtml"}"
Reference document -: http://dev.office.com/reference/add-ins/word/body
Here's my code-:
Word.run(function (context) {
// Create a proxy object for the document body.
var body = context.document.body;
// Queue a commmand to get the HTML contents of the body.
var bodyHTML = body.getHtml();
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
$('#output').text("Body HTML contents: " + bodyHTML.value);
});
})
.catch(function (error) {
$('#output').text("Error: " + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
$('#output').text("Debug info: " + JSON.stringify(error.debugInfo));
}
});
Am I missing something here?
Complete Error Object-:
{"name":"OfficeExtension.Error","code":"AccessDenied","message":"AccessDenied","traceMessages":[],"debugInfo":{"errorLocation":"Body.getHtml"},"stack":"AccessDenied: AccessDenied\n at Anonymous function (https://appsforoffice.microsoft.com/lib/1.1/hosted/word-win32-16.00.js:19:150094)\n at yi (https://appsforoffice.microsoft.com/lib/1.1/hosted/word-win32-16.00.js:19:163912)\n at st (https://appsforoffice.microsoft.com/lib/1.1/hosted/word-win32-16.00.js:19:163999)\n at d (https://appsforoffice.microsoft.com/lib/1.1/hosted/word-win32-16.00.js:19:163819)\n at c (https://appsforoffice.microsoft.com/lib/1.1/hosted/word-win32-16.00.js:19:162405)"}
Error Code 5009 -> The add-in does not have permission to call the specific API.
Already Tried -: https://github.com/OfficeDev/office-js-snippet-explorer/issues/13
No success yet!
Are you using the API Tutorial App in Word to try this sample or have you written your own app?
I just tried the sample in the API Tutorial App (which is available from the Store) and it works just fine.
// Run a batch operation against the Word object model.
Word.run(function (context) {
// Create a proxy object for the document body.
var body = context.document.body;
// Queue a commmand to get the HTML contents of the body.
var bodyHTML = body.getHtml();
// Synchronize the document state by executing the queued commands,
// and return a promise to indicate task completion.
return context.sync().then(function () {
console.log("Body HTML contents: " + bodyHTML.value);
});
})
.catch(function (error) {
console.log("Error: " + JSON.stringify(error));
if (error instanceof OfficeExtension.Error) {
console.log("Debug info: " + JSON.stringify(error.debugInfo));
}
});
I work on a little extension on Google Chrome, I want to create a new tab, go on the url "sample"+i+".com", launch a content script on this url, update the current tab to "sample"+(i+1)+".com", and launch the same script. I looked the Q&A available on stackoverflow and I google it but I didn't found a solution who works. This is my actually code of background.js (it works), it creates two tabs (i=21 and i=22) and load my content script for each url, when I tried to do a chrome.tabs.update Chrome launchs directly a tab with i = 22 (and the script works only one time) :
function extraction(tab) {
for (var i =21; i<23;i++)
{
chrome.storage.sync.set({'extraction' : 1}, function() {}); //for my content script
chrome.tabs.create({url: "http://example.com/"+i+".html"}, function() {});
}
}
chrome.browserAction.onClicked.addListener(function(tab) {extraction(tab);});
If anyone can help me, the content script and manifest.json are not the problem. I want to make that 15000 times so I can't do otherwise.
Thank you.
I guess chrome.tabs.create is an async function so you need to create a separate function so that the i variable is copied each time:
try this:
var func = function(i)
{
chrome.storage.sync.set({'extraction' : 1}, function() {}); //for my content script
chrome.tabs.create({url: "http://example.com/"+i+".html"}, function() {});
}
function extraction(tab) {
for (var i =21; i<23;i++)
{
func(i);
}
}
chrome.browserAction.onClicked.addListener(function(tab) {extraction(tab);});
You need to make sure that the tab finished loading, and that your content script finished running, before updating the tab to the next url. One way to achieve that would be by sending a message from the content script to the background page. You can include the following in your content script:
chrome.extension.sendMessage("finished");
In your background script you can do the following:
var current = 21, end = 23;
chrome.extension.onMessage.addListener(
function(request, sender) {
if( request == "finished" && current <= end ) {
chrome.tabs.update( sender.tab.id,
{url: "http://example.com/"+current+".html"});
current++;
}
}
);
chrome.tabs.create({url: "http://example.com/"+current+".html"});
I have a popup, call 'welcome.html', the thing I would like to do is when the user select a text, and click my plugin, it will use some of the page information, and print back to the welcome.html. For example, the web site title, and the text which the user selected and the url. But how can I pass value to that welcome.html? Thank you.
I do a lot of this in my extension as it mines a lot of data enabling the user to easily copy it to their clipboard.
Since you're looking for a lot less data it's even simpler. When your popup is being loaded you can call the following function to retrieve the information you require;
function getData(callback) {
chrome.tabs.getSelected(null, function (tab) {
var data = {
selection: '',
title: tab.title,
url: tab.url
};
/*
* We can't call content scripts on some pages and the process will get
* stuck if we try.
*/
if (tab.url.indexOf('chrome') === 0 ||
tab.url.indexOf('https://chrome.google.com/webstore') === 0) {
callback(data);
} else {
chrome.tabs.sendRequest(tab.id, {}, function (response) {
data.selection = response.selection;
callback(data);
});
}
});
}
Ensure you pass in a callback function which will be called once all the data has been extracted;
getData(function (data) {
console.log('Title: ' + data.title);
console.log('URL: ' + data.url);
console.log('Selected Text: ' + data.selection);
// Display the data instead
});
As you may have noticed the getData function sends a request to the selected tab. A content script will need to be injected in to the page in order for this to work so be sure you've configured your manifest correctly or injected it programmatically prior to calling getData or it won't work. The script that will need to be injected should resemble the following;
(function () {
chrome.extension.onRequest.addListener(function (request, sender,
sendResponse) {
sendResponse({
selection: window.getSelection().toString()
});
});
})();
This simply returns the currently selected text. One concern is that this data look-up could potentially cause a slight pause while the popup is rendered but you should test this yourself and experiment with it but there are solutions.
This should cover all you need to know so good luck and let me know if you need any further help as I'm aware this could be slightly overwhelming if you're new to Chrome extensions.