I have the following code that is pulling from inline JS on a webpage to pull the webID. This is being used for a Chrome extension that will display just the site's webID when clicked:
// payload.js script --> insert into the current tab after the popout has loaded
window.addEventListener('load', function (evt) {
chrome.extension.getBackgroundPage().chrome.tabs.executeScript(null, {
file: 'payload.js'
});;
});
//popout.html
chrome.runtime.onMessage.addListener(function (message) {
document.getElementById('body').innerHTML = message;
chrome.tabs.executeScript({
code: '(' + (() => {
for (var el of document.querySelectorAll('script[if="inlineJs"]'))
{
var m = el.textContent.match(/"([^"]*webId*[^"]*)"/);
var webid = m
if (webid) return webid[1];
else {return document.getElementById('body').innerHTML = "This is not a CDK site";}
}
}) + ')()',
}, results => {
if (!chrome.runtime.lastError && results) {
document.getElementById('body').textContent = decodeURI(results[0]);
}
});
});
Currently this returns the following:
{"cache":{"Co.context.configCtx":{"webId":"gmps-salvadore","locale":"en_US","version":"LIVE","page":"HomePage","secureSiteId":"b382ca78958d10048eda00145edef68b"},"features":{"directivePerfSwitch":true,"enable.directive.localisation":true,"enable.directive.thumbnailGallery":true,"enable.new.newstaticmap":false,"disable.forms.webId":false,"use.hydra.popup.title.override.via.url":true,"enable.directive.geoloc.enableHighAccuracy":true,"use.hydra.theme.service":true,"disable.ajax.options.contentType":false,"dealerLocator.map.use.markerClustering":true,"hydra.open.login.popup.on.cs.click":false,"hydra.consumerlogin.use.secure.cookie":true,"use.hydra.directive.vertical.thumbnailGallery.onpopup":true,"hydra.encrypt.data.to.login.service":true,"disable.dealerlocator.fix.loading":false,"use.hydra.date.formatting":true,"use.hydra.optimized.style.directive.updates":false,"hydra.click.pmp.button.on.myaccount.page":true,"use.hydra.fix.invalid.combination.of.filters":true,"disable.vsr.view.from.preference":false}},"store":{"properties":{"routePrefix":"/hydra-graph"}}}
I would like it to just return the 'gmps-salvadore'. This would be used on multiple sites and the webID will change from site to site with differing prefixes from "lex" to "motp". Is it possible to have the extension only pull the webID from various sites?
Related
I am new to Microsoft Office addins and JS. I am trying to develop a Microsoft Word add-in that converts selected text in the document into QR code. So my problem is getting selected text in the document as simple string.
Nothing I tried so far worked. Here is a link for getting the whole text in a document that helped a bit: Word Add-in Get full Document text?. What I need is how to get selected text as a string. I need your help please. I tried the following:
txt = "";
await Word.run(async (context) => {
var documentBody = context.document.body;
context.load(documentBody);
return context.sync().then(function () {
console.log(documentBody.text); //full document text
console.log(document.getSelection.text); //selected only
txt = documentBody.text.getSelection();
});
});
Check the Script Lab. The first sample in Word does exactly what you need:
$("#run").click(() => tryCatch(run));
function run() {
return Word.run(function(context) {
var range = context.document.getSelection();
range.font.color = "red";
range.load("text");
return context.sync().then(function() {
console.log('The selected text was "' + range.text + '".');
});
});
}
/** Default helper for invoking an action and handling errors. */
function tryCatch(callback) {
Promise.resolve()
.then(callback)
.catch(function(error) {
// Note: In a production add-in, you'd want to notify the user through your add-in's UI.
console.error(error);
});
}
I have a working prototype of an extension that works on Chrome but when I try to run it on Firefox i get the following error:
Unchecked lastError value: Error: Could not establish connection. Receiving end does not exist.
I use this code to differentiate between browsers:
window.namespace = (function () {
return window.msBrowser ||
window.browser ||
window.chrome;
})();
the following part is to detect when the user clicks on the extension icon (so that I know to activate it):
let show_floater = false; // to know if extension should be active
window.namespace.browserAction.onClicked.addListener(function(tab) {
buttonClicked(tab);
});
function buttonClicked(tab) {
show_floater = !show_floater;
console.log('coding intensifies');
// Send message to content_script of tab.id
window.namespace.tabs.sendMessage(tab.id, show_floater); // <-- ERROR IS HERE
}
All this code is in my background script.
The handling of the message in my content script is as follows
window.namespace.runtime.onMessage.addListener(gotMessage);
let injected = false;
function gotMessage(show_floater, sender, sendResponse) {
// Here I just do stuff
console.log("I'm working here!");
}
Online I saw that people that had this problem usually did not include <all_urls> in the manifest. In my case I already had that so I'm kinda lost here. From my understanding both Chrome and Firefox should use the same methods to send and receive messages. Is my way of distinguishing between browsers flawed?
CHANGES
Here I found a solution.
Background:
chrome.browserAction.onClicked.addListener(function (event) {
chrome.tabs.executeScript(null, {
file: 'js/content.js', /* my content script */ }, () => {
connect() //this is where I call my function to establish a
connection });
});
});
function connect() {
chrome.tabs.query({ active: true, currentWindow: true }, (tabs) => {
const port = chrome.tabs.connect(tabs[0].id);
show_floater = !show_floater;
port.postMessage(show_floater);
// port.onMessage.addListener((response) => {
// html = response.html;
// title = response.title;
// description = response.description;
// });
});
contentscript:
chrome.runtime.onConnect.addListener((port) => {
port.onMessage.addListener((show_floater) => {
else if (!injected) {
injected = true;
let link = document.createElement("link");
link.className = 'beebole_css';
link.href = "https://localhost/css/test.css";
link.type = "text/css";
link.rel = "stylesheet";
document.querySelector("head").appendChild(link);
let s = document.createElement("script");
s.className = 'beebole_js';
s.src = "https://localhost/js/test.js";
s.type = 'text/javascript';
// document.body.appendChild(s);
document.querySelector('body').appendChild(s);
}
});
});
Again, this code works perfectly on Chrome but on Firefox it give the following error:
Loading failed for the <script> with source “https://localhost/js/test.js”.
I suggest you use https://github.com/mozilla/webextension-polyfill for cross browser compatibility.
I am trying to load fingerprintjs in my chrome extension and for some reason it is not loading.
The documentation says to use this approach, which works fine in standalone web sites, just not in chrome extensions
<script>
function initFingerprintJS() {
FingerprintJS.load().then(fp => {
// The FingerprintJS agent is ready.
// Get a visitor identifier when you'd like to.
fp.get().then(result => {
// This is the visitor identifier:
const visitorId = result.visitorId;
console.log("visitorId", visitorId);
});
});
}
</script>
<script async src="fp.min.js" onload="initFingerprintJS();"></script>
For chrome extension I added created a JS file initFingerprint.js that holds the init code like so:
var visitorId = null; //will hold the actual fingerprint
function initFingerprintJS() {
console.log("inside initFingerprintJS");
FingerprintJS.load().then(fp => {
console.log("loaded initFingerprintJS");
fp.get().then(result => {
console.log("initFingerprintJS got result", result)
visitorId = result.visitorId; // This is the visitor identifier
console.log("visitorId", visitorId);
});
});
}
initFingerprintJS();
In background.html, I added this:
<script async src="fp.min.js"></script>
<script async src="initFingerprint.js"></script>
I have tried with async in there and not in there, but still no luck. This line will print, but none of the other lines below it.
inside initFingerprintJS
What am I doing wrong? I appreciate any help. thank you
Remove <script> tag for fp.min.js from the html and create the script element yourself in initFingerprint.js so you can use the onload event directly:
loadScript('fp.min.js').then(initFingerprintJS);
function loadScript(url) {
return new Promise((resolve, reject) => {
const el = document.createElement('script');
el.onload = resolve;
el.onerror = reject;
el.src = url;
document.documentElement.appendChild(el);
});
}
async function initFingerprintJS() {
visitorId = await (await FingerprintJS.load()).get();
console.log('visitorId', visitorId);
}
I'm working on a browser extension that needs to be constantly running, even after an automatic refresh in the background. The problem is, that the page randomly automatically unloads and the script just shuts off. I need to find a way to keep the content script on at all times. Here's part of the code:
// content.js:
function run(fn) {
if(typeof(Worker) !== "undefined") {
if(typeof(w) == "undefined") {
w = new Worker(URL.createObjectURL(new Blob(['('+fn+')()'])));
}
w.onmessage = function(event) {
if (isNaN(grabbedmin) && ID) {
bump() // Note: the bump function refreshes in the page.
w.terminate();
}
if ($("[href='/server/bump/" + ID + "']").text().includes("Bump")) {
bump()
w.terminate();
}
document.getElementById("bumpcount").innerHTML = "Autobumper Enabled: " + getCurrentTimestamp();
if (numberwow == grabbedmin) {
bump()
w.terminate();
}
};
}
}
The code above basically gets run every minute by this worker:
// content.js:
const worker = run(function() {
var i = 0;
function timedCount() {
i = i + 1;
postMessage(i);
setTimeout(function(){timedCount()},1000);
}
timedCount();
});
Is there a way for background.js to detect that content.js is not running (or that the page is unloaded) when it should be and then reload it?
Note: You can find the script here: https://github.com/Theblockbuster1/disboard-auto-bump
After looking through the docs and looking at examples, I put this together:
chrome.tabs.query({
url: ["*://disboard.org/*dashboard/servers", "*://disboard.org/*dashboard/servers/"] // finds matching tabs
}, function(tabs) {
tabs.forEach(tab => {
chrome.tabs.update(tab.id,{autoDiscardable:false});
});
});
chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) {
// checks if the browser automatically re-enabled autoDiscarding and disables it
if (changeInfo.autoDiscardable == true) chrome.tabs.update(tabId,{autoDiscardable:false});
});
I have a website which resides in a directory. On a particular user operation that website's javascript needs to get the body from an 'external' HTML document which resides in an immediate subdirectory of the primary webpage.
Example:
Primary webpage directory
|___ TutorialFiles (the 'external' HTML document subdirectory)
When the user clicks on a link it executes its OnClick() javascript function.
The following is what I am trying to use, but it is not working.
function DisplayDocument(thisDoc) {
//alert("Display " + thisDoc + " Doc Here!");
var loc = window.location.pathname;
var dir = loc.substring(0, loc.lastIndexOf('/'));
var HTMLDoc = "./TutorialFiles" + "/" + thisDoc;
var HTMLDocContent = getBody(HTMLDoc);
document.getElementById("page_content_wrapper").innerHTML = getBody(HTMLDocContent);
return false;
}
function getBody(content) {
var x = content.indexOf("<body");
x = content.indexOf(">", x);
var y = content.lastIndexOf("</body>");
return content.slice(x + 1, y);
}
That above javascript code does not 'see' the external document in the subdirectory TutorialFiles and therefore cannot get its 'body'.
What am I doing wrong?
Thanks
You can load the html files using XMLHttpRequest. Here is a code snippet based on your code that loads an external html into the page.
To adapt to your case simply change the serverPath to you own server and it should work:
var serverPath = 'https://raw.githubusercontent.com/h5bp/html5-boilerplate/master/dist/';
var loadHtml = function(path, callback) {
var xhr = new XMLHttpRequest();
xhr.open('GET', path, true);
xhr.onreadystatechange = function() {
if (this.readyState !== 4) return;
if (this.status !== 200) return;
callback(this.responseText);
};
xhr.send();
};
var displayHtml = function(file) {
loadHtml(serverPath + file, function(html) {
document.querySelector('.page_content_wrapper').innerHTML = html;
});
return false;
};
<button onclick="displayHtml('index.html');">Load html</button>
<div class="page_content_wrapper"></div>
Well, once again when all of the suggestions did not do what I needed, I ended up resolving the issue myself.
What I ended up with used some code that was already working for me in controlling my Sidebar menu onClick() events. I had not thought to use that for this additional functionality, but it worked.
The Sidebar onClick=MenuClick('TutorialFiles/' & & ',' & & "')"
So with a codebehind searchBtn() function I merely built the the onClick() methods for the links found in the Search results to the same thing and it began working.
//--- Function to Load 'External' HTML Page (doc) into Content Wrapper ---
function MenuClick(doc, displayText) {
var MasterPgPrefix = "";
var titlebox = document.getElementById(MasterPgPrefix + 'txtTutorialTitle');
titlebox.value = displayText;
titlebox.style.visibility = "visible";
titlebox.style.display = "block";
var Tutorial = doc;
var DisplayObj = "<object id='ThisObj' type='text/html' data='" + Tutorial + "' style='min-width:100%; min-height: 101%; overflow: hidden'></object>";
document.getElementById("page_content_wrapper").innerHTML = DisplayObj;
}
Thank you for your advise and suggestions.