Is there a way i can access local resources inside a script?
I need to access data.url('layout.html'), data.url('icon.png') and data.url('style.css') inside the contentScript handler.
exports.main = function() {
require("widget").Widget({
onClick: function() {
tabs.activeTab.attach({
contentScriptFile: [ data.url('jquery.js')],
contentScript:
"setTimeout(function(){ alert('asd');}, 100);",
});
}
});
}
I've ended up using cssUrl = data.url('alert.css'). In main.js i set this up, and in the script running client-side add a script having href=cssUrl.
Use contentScriptOptions to pass it to the content script, like this:
//main.js
contentScriptFile: [ data.url('jquery.js')],
contentScriptOptions: {
cssUrl: data.url('alert.css')
}
// jquery.js
console.log(self.options.cssUrl)
Related
I am trying to figure out how to add a script to a page via my simple chrome extension. Currently I have a script, mycoolscript.js which is a local file to my extension and I am using the following code (snippets including manifest) to add it to the current page.
I feel like I am close, the script tag is added to the head tag but when the onload fires I am seeing stating that coolObject is not defined. coolObject is returned from mycoolscript to the window. If I build a page manually or use tampermonkey this works perfectly. Any suggestions on what I might be doing wrong here?
manifest.json
"content_scripts": [
{
"matches": ["<all_urls>"],
"css": ["contentScript.css"],
"js": ["contentScript.js"]
}],
"web_accessible_resources": [
{
"resources": ["mycoolscript.js"],
"matches": ["<all_urls>"]
}
]
contentScript.js
function addMyCoolScript(){
var s = document.createElement('script');
s.src = chrome.runtime.getURL('mycoolscript.js');
(document.head || document.documentElement).appendChild(s);
s.onload = function () {
s.parentNode.removeChild(s);
onScriptLoaded();
};
}
function onScriptLoaded() {
let apikey = "ABC123"
let baseUrl = "example.com"
coolObject.initialize(apikey, {
baseUrl: baseUrl,
});
coolObject.runStartup();
coolObject.openSession();
}
I'm attempting to implement workbox to precache image and video assets on a website.
I've created a service worker file. It appears to be successfully referenced and used in my application. The service worker:
import { clientsClaim, setCacheNameDetails } from 'workbox-core';
import { precacheAndRoute, addRoute } from 'workbox-precaching';
const context = self; // eslint-disable-line no-restricted-globals
setCacheNameDetails({ precache: 'app' });
// eslint-disable-next-line no-restricted-globals, no-underscore-dangle
precacheAndRoute(self.__WB_MANIFEST);
context.addEventListener('install', (event) => {
event.waitUntil(
caches.open('dive').then((cache) => {
console.log(cache);
}),
);
});
context.addEventListener('activate', (event) => {
console.log('sw active');
});
context.addEventListener('fetch', async (event) => {
console.log(event.request.url);
});
context.addEventListener('message', ({ data }) => {
const { type, payload } = data;
if (type === 'cache') {
payload.forEach((url) => {
addRoute(url);
});
const manifest = payload.map((url) => (
{
url,
revision: null,
}
));
console.log('attempting to precache and route manifest', JSON.stringify(manifest));
precacheAndRoute(manifest);
}
});
context.skipWaiting();
clientsClaim();
The application uses workbox-window to load, reference and message the service worker. The app looks like:
import { Workbox } from 'workbox-window';
workbox = new Workbox('/sw.js');
workbox.register();
workbox.messageSW({
type: 'cache',
payload: [
{ url: 'https://media0.giphy.com/media/Ju7l5y9osyymQ/giphy.gif' }
],
});
This project is using vue with vue-cli. It has a webpack config which allows plugins to be sent added to webpack. The config looks like:
const { InjectManifest } = require('workbox-webpack-plugin');
const path = require('path');
module.exports = {
configureWebpack: {
plugins: [
new InjectManifest({
swSrc: path.join(__dirname, 'lib/services/Asset-Cache.serviceworker.js'),
swDest: 'Asset-Cache.serviceworker.js',
}),
],
},
};
I can see messages are successfully sent to the service worker and contain the correct payload. BUT, the assets never show up in Chrome dev tools cache storage. I also never see any workbox logging related to the assets sent via messageSW. I've also tested by disabling my internet, the assets don't appear to be loading into the cache. What am I doing wrong here?
I found the workbox docs to be a little unclear and have also tried to delete the message event handler from the service worker. Then, send messages to the service worker like this:
workbox.messageSW({
type: 'CACHE_URLS',
payload: { urlsToCache: [ 'https://media0.giphy.com/media/Ju7l5y9osyymQ/giphy.gif'] },
});
This also appears to have no effect on the cache.
The precache portion of precacheAndRoute() works by adding install and activate listeners to the current service worker, taking advantage of the service worker lifecycle. This will effectively be a no-op if the service worker has already finished installing and activating by the time it's called, which may be the case if you trigger it conditionally via a message handler.
We should probably warn folks about this ineffective usage of precacheAndRoute() in our Workbox development builds; I've filed an issue to track that.
I'm trying to do a Youtube API and I feel like I got everything working except this gapi and res thing? It says gapi is not defined. How can I make this work?
function tplawesome(e,t){res=e;for(var n=0;n<t.length;n++){res=res.replace(/\{\{(.*?)\}\}/g,function(e,r){return t[n][r]})}return res}
$(function() {
$("form").on("submit", function(e) {
e.preventDefault();
// prepare the request
var request = gapi.client.youtube.search.list({
part: "snippet",
type: "video",
q: encodeURIComponent($("#search").val()).replace(/%20/g, "+"),
maxResults: 3,
order: "viewCount",
publishedAfter: "2015-01-01T00:00:00Z"
});
// execute the request
request.execute(function(response) {
var results = response.result;
$("#results").html("");
$.each(results.items, function(index, item) {
$.get("tpl/item.html", function(data) {
$("#results").append(tplawesome(data, [{"title":item.snippet.title, "videoid":item.id.videoId}]));
});
});
resetVideoHeight();
});
});
$(window).on("resize", resetVideoHeight);
});
function resetVideoHeight() {
$(".video").css("height", $("#results").width() * 9/16);
}
function init() {
gapi.client.setApiKey("AIzaSyD646m4ZfK5yKBZj9p95LohN-PTUnRHBRY");
gapi.client.load("youtube", "v3", function() {
});
}
gapi is an object created by the Google API javascript library that manages all interactions (i.e. does all the heavy lifting of the requests) for you. If the object is not defined, you may not have included the library itself in your page. Somewhere in your HTML, you'll need a script tag that loads the library located at:
https://apis.google.com/js/client.js
Note that, in loading the library with a script tag, you should also pass it a callback ... this is a function that will be automatically called as soon as the library is done loading. So in your case, your init() method is that callback, and so your script tag would look like this:
<script src="https://apis.google.com/js/client.js?onload=init"></script>
The browser will get the library, load it, then run init() when the library is done loading, and all will be ready for your form to execute when triggered.
I have a custom generator and am writing some tests for it. Before the app.run() call I already have a app.options['skip-install'] = true to prevent npm from running. But I need it to auto-overwrite files too.
Part way through the install I get a [?] Overwrite client/file.js? (Ynaxdh) and need it to auto-answer it for me.
I have tried app.options.force = true but that doesn't seem to do anything.
I'm running in app install with this:
function installApp(obj, opts, done) {
helpers.mockPrompt(obj.app, opts);
obj.app.options['skip-install'] = true;
obj.app.run({}, function () {
async.series([
function (cb) {
if (opts._extras.addPage) {
installAppPage(obj, cb);
} else {
cb();
}
}
], done);
});
}
Then I want to run a sub-generator with this:
function installAppPage(obj, done) {
helpers.mockPrompt(obj.page, {
pageName: 'webPage',
pageType: 'web'
});
obj.page.args = ['--force']; // This isn't working
obj.page.options.force; // This isn't working either
obj.page.run([], function () {
helpers.mockPrompt(obj.page, {
pageName: 'mobilePage',
pageType: 'mobile'
});
obj.page.run({}, function () {
done();
});
});
}
The sub-generator for the page modifies a file. I need to to just overwrite it so I can test it. How do I force it? I can't be prompted while running the tests, it needs to be automated.
I think you're looking for conflicter.force
obj.page.conflicter.force = true;
I' writing a addon that add functionality to a site.
But I need to parse variables between .js
main.js:
pageMod.PageMod({
include: ["*"],
contentScriptWhen: 'end',
contentScriptFile: data.url("MyContent.js"),
contentScriptOptions: {
showOptions: true,
dataUrl: data.url("MyContent.js") // To parse the URL-Path
}
});
MyContent.js:
//to read the URL like resource://.....:
var dataUrl=self.options.dataUrl.substring(0,self.options.dataUrl.lastIndexOf("/")+1)
var script = document.createElement("script");
script.type = "text/javascript";
script.src = dataUrl+"scripts.js";
window.document.head.appendChild(script);
The variable dataUrl exist in MyContent.js but not in MyScripts.js
I need the variable dataUrl in MyScripts.js to know the url for some images saved in the data-folder.
How can I define global variables that can been accessed from all scripts?
with worker can I comunicate between main.js and MyContent.js, but not with MyScripts.js