I want to write a sample extension to override newtab page with some html content provided from javascript. How to do this ?
Javascript to provide html content here :
function getFavouriteWebsite() {
var historyService = Components.classes["#mozilla.org/browser/nav-history-service;1"].getService(Components.interfaces.nsINavHistoryService);
var query = historyService.getNewQuery();
var options = historyService.getNewQueryOptions();
options.queryType = 0;
options.sortingMode = options.SORT_BY_VISITCOUNT_DESCENDING;
options.maxResults = 6;
var result = historyService.executeQuery(query, options);
result.root.containerOpen = true;
var contentHtml ='';
for (var i = 0; i < result.root.childCount; i++) {
for (var i = 0; i < result.root.childCount; i++) {
contentHtml += "<p>" + (result.root.getChild(i).title == "" ? result.root.getChild(i).uri : result.root.getChild(i).title) + "</p>";
}
}
return contentHtml;
}
To override the newtab page, set the browser.newtab.url preference to some HTML/XUL document. Include whatever scripts in that document to populate the content.
But please do not string-concatenate html fragments together as you'd likely end up with insecure code, but use DOM APIs such as document.createElement(), Node.textContent, Node.setAttribute etc instead.
Related
I am using a javascript on my site, which always inherits the UTM parameters to the links on the site.
However, this is not working, when the links are anchor links to a section of the site and the link the visitor used to visit the page contains the "gclid" parameter from google.
For example:
A visitor uses this link to visit a site:
domain.com?utm_source=test&utm_medium=test&utm_campaign=test&gclid=12345
The button link on the site with the anchor link will look like the following:
domain.com&gclid=12345?utm_source=test&utm_medium=test&utm_campaign=test#anchor
For some reason the "&gclid" part changes its position.
I've tested it with a link without an anchor and in this case the "gclid" parameter doesn't get inherited and the link works.
Of course, the second domain isn't working anymore and leads to a 404 error.
Does someone have an idea what could be the cause for this?
This is the javascript I am using to inherit the UTMs:
(function() {
var utmInheritingDomain = "grundl-institut.de"
utmRegExp = /(\&|\?)utm_[A-Za-z]+=[A-Za-z0-9]+/gi,
links = document.getElementsByTagName("a"),
utms = [
"utm_medium={{URL - utm_medium}}",
"utm_source={{URL - utm_source}}",
"utm_campaign={{URL - utm_campaign}}"
];
for (var index = 0; index < links.length; index += 1) {
var tempLink = links[index].href,
tempParts;
if (tempLink.indexOf(utmInheritingDomain) > 0) {
tempLink = tempLink.replace(utmRegExp, "");
tempParts = tempLink.split("#");
if (tempParts[0].indexOf("?") < 0) {
tempParts[0] += "?" + utms.join("&");
} else {
tempParts[0] += "&" + utms.join("&");
}
tempLink = tempParts.join("#");
}
links[index].href = tempLink;
}
}());
EDIT: It seems like the following script don`t causes this problem:
<script>
(function() {
var domainsToDecorate = [
'domain.com',
],
queryParams = [
'utm_medium',
'utm_source',
'utm_campaign',
]
var links = document.querySelectorAll('a');
for (var linkIndex = 0; linkIndex < links.length; linkIndex++) {
for (var domainIndex = 0; domainIndex < domainsToDecorate.length; domainIndex++) {
if (links[linkIndex].href.indexOf(domainsToDecorate[domainIndex]) > -1 && links[linkIndex].href.indexOf("#") === -1) {
links[linkIndex].href = decorateUrl(links[linkIndex].href);
}
}
}
function decorateUrl(urlToDecorate) {
urlToDecorate = (urlToDecorate.indexOf('?') === -1) ? urlToDecorate + '?' : urlToDecorate + '&';
var collectedQueryParams = [];
for (var queryIndex = 0; queryIndex < queryParams.length; queryIndex++) {
if (getQueryParam(queryParams[queryIndex])) {
collectedQueryParams.push(queryParams[queryIndex] + '=' + getQueryParam(queryParams[queryIndex]))
}
}
return urlToDecorate + collectedQueryParams.join('&');
}
// borrowed from https://stackoverflow.com/questions/831030/
// a function that retrieves the value of a query parameter
function getQueryParam(name) {
if (name = (new RegExp('[?&]' + encodeURIComponent(name) + '=([^&]*)')).exec(window.location.search))
return decodeURIComponent(name[1]);
}
})();
</script>
You really should not change URLs with regexp and string manipulation.
Here is the recommended way
const url = new URL(location.href); // change to tempLink
utms = [
"utm_medium=med",
"utm_source=src",
"utm_campaign=camp"
];
utms.forEach(utm => url.searchParams.set(...utm.split("=")))
console.log(url.toString())
I am getting data over websocket every 10 seconds and i am updating the cells using this function:
agentStatSocket.onmessage = function (e) {
data = JSON.parse(e.data);
//console.log(typeof(data));
for (var i = 0; i < data.length; i++) {
var inboundTd = '#' + data[i]['id'] + '-inbound';
var outboundTd = '#' + data[i]['id'] + '-outbound';
if (data[i]['inboundCalls'] != 0) {
$(inboundTd).html(data[i]['inboundCalls']);
}
if (data[i]['outboundCalls'] != 0) {
$(outboundTd).html(data[i]['outboundCalls']);
}
}
};
This is working pretty fine. However, I see some lag with the table being updated. Currently, there are only 150 rows in the table. I do not know what will be the latency if rows will become 1000 or more.
I have the following questions:
What is the correct approach to design these kinds of tables in which data is changing very frequently? I am not using any library like react or angular. This is plain jQuery.I am using dataTables
jQuery to enhance table view.
One thing to consider is that, in many cases, accessing an element based on an ID is usually a lot quicker in vanilla javascript compared to jquery.
A simple example of that is:
function jsTest() {
for (let i = 0; i < 1000; i++) {
document.getElementById("js").innerHTML = i;
}
}
function jqueryTest() {
for (let i = 0; i < 1000; i++) {
$("#jquery").html(i);
}
}
function startup() {
console.time("javascript");
jsTest();
console.timeEnd("javascript");
console.time("jquery");
jqueryTest();
console.timeEnd("jquery");
}
// For testing purposes only
window.onload = startup;
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
Javascript: <div id="js"></div>
Jquery: <div id="jquery"></div>
So, you could try changing your code to:
agentStatSocket.onmessage = function (e) {
data = JSON.parse(e.data);
//console.log(typeof(data));
for (var i = 0; i < data.length; i++) {
//var inboundTd = '#' + data[i]['id'] + '-inbound';
//var outboundTd = '#' + data[i]['id'] + '-outbound';
var inboundTd = data[i]['id'] + '-inbound';
var outboundTd = data[i]['id'] + '-outbound';
if (data[i]['inboundCalls'] != 0) {
//$(inboundTd).html(data[i]['inboundCalls']);
document.getElementById(inboundTd).innerHTML = data[i]['inboundCalls'];
}
if (data[i]['outboundCalls'] != 0) {
//$(outboundTd).html(data[i]['outboundCalls']);
document.getElementById(outboundTd).innerHTML = data[i]['outboundCalls'];
}
}
};
You can still use jquery for the rest of your code, if you wish, but simple updates to elements that can be targeted by ID are usually quicker with vanilla javascript.
I am using JSON to display info from a site. The book example works which gave me a custom website to get information from worked, but when I replaced the url with Spider man's facebook page, it seems as if the data is processing, but the information does not display. Is there some crucial step that I am missing.
var lastReporttime = 0;
window.onload= function(){
setInterval(handleRefresh,3000);
}
function updateSales(sales) {
var salesDiv= document.getElementById("sales");
for (var i = 0; i < sales.length; i++) {
var sale = sales[i];
var div = document.createElement("div");
div.innerHTML = sale.category + sale.about + "spiderman";
salesDiv.appendChild(div);
}
if (sales.length > 0) { lastReporttime = sales[sales.length-1].time; }
}
function handleRefresh() {
var url = "http://graph.facebook.com/SpiderManDVD"
+ "callback=updateSales"
+ "&lastreporttime=" + lastReporttime
+ "&random="+ (new Date()). getTime();
var newScriptElement= document.createElement("script");
newScriptElement.setAttribute("src", url);
newScriptElement.setAttribute("id", "jsonp");
var oldScriptElement= document.getElementById("jsonp");
var head= document.getElementsByTagName("head")[0];
if (oldScriptElement == null) {
head.appendChild(newScriptElement);
} else {
head.replaceChild(newScriptElement, oldScriptElement);
}
}
Response you received from your book example returns a JSON Array which is perfectly handled in your code.
But response from facebook api returns a JSON object which is breaking your code.
Check both the urls and update the logic inside updateSales to handle both JSON Array as well as JSONObject as per your use case.
Something like this
function updateSales(sales) {
var salesDiv= document.getElementById('sales');
// Check if sales is array or not (One of the crude ways, ofcourse not best but may work for you)
if (typeof sales.length == 'undefined') {
sales = [sales];
}
for (var i = 0; i < sales.length; i++) {
var sale = sales[i];
var div = document.createElement("div");
div.innerHTML = sale.category + sale.about + "spiderman";
salesDiv.appendChild(div);
}
if (sales.length > 0) {
lastReporttime = sales[sales.length-1].time;
}
}
I need to change the content of all "h1" tags in my html file when the page load using javascript.
So I write the following code
window.onload = function () {
var h1html = document.createElement("h1");
var h1htmltext = document.createTextNode("header 1");
h1html.appendChild(h1htmltext);
document.getElementsByTagName("h1").appendChild(h1html);
};
If you're sure you only have one h1 tag you could simply do
window.onload = function () {
document.getElementsByTagName("h1")[0].innerHTML = "header 1";
}
if multiple h1 tags are present you could do
window.onload = function () {
var h1Elems = document.getElementsByTagName("h1");
var pos;
for (pos in h1Elems) {
h1Elems[pos].innerHTML = "header 1";
}
}
Use this:
for(var i = 0, elems = document.getElementsByTagName('h1'); i < elems.length; i++) {
elems[i].innerHTML = "new";
}
fiddle
You need to change the innerHTML of each elements, as such
function changeall(){
var headers=document.getElementsByTagName("h1");
var newheadertext="hello";
for(var i in headers){
headers[i].innerHTML=newheadertext;
}
}
getElementsByTagName returns a node list; you need to loop through it.
var headers = document.getElementsByTagName("h1");
for(var i = 0; i < headers.length; i++) {
var header = headers[i];
var text = document.createTextNode("header 1");
while(header.childNodes.length) {
header.removeChild(header.firstChild);
}
header.appendChild(text);
}
I made a few assumptions there:
You don’t actually want to nest headers
You want to replace the content
You want an old-standards-compliant way
If you don’t need support for old browsers, just use textContent:
var headers = document.getElementsByTagName("h1");
for(var i = 0; i < headers.length; i++) {
headers[i].textContent = "header 1";
}
I am more familiar with CSS coding than with Javascript, so when I was tasked to find a way to display Link URLS during print but not on-screen, I ran into a bit of trouble. Using CSS, I can manage what I want just fine, but thanks to Internet Explorer's quirkiness, I've had to find a javascript solution to my problem.
I was able to solve my dilemma with this code to make the link URLs display on print, and then disappear off the page when print preview was closed.
window.onbeforeprint = function(){
var links = document.getElementsByTagName("a");
for (var i=0; i< links.length; i++){
var theContent = links[i].getAttribute("href");
if (!theContent == ""){
links[i].newContent = " [" + theContent + "] ";
links[i].innerHTML = links[i].innerHTML + links[i].newContent;
}
}
}
window.onafterprint = function(){
var links = document.getElementsByTagName("a");
for (var i=0; i< links.length; i++){
var theContent = links[i].innerHTML;
if (!theContent == ""){
var theBracket = theContent.indexOf(links[i].newContent);
var newContent = theContent.substring(0, theBracket);
links[i].innerHTML = newContent;
}
}
}
However, now my problem becomes that ALL the page link URLs are printed. But, obviously, I don't need to print things like the internal navigation URLs; that just makes the finished product look messy. Is there a way to exclude certain sections of the page, like a UL-list with the ID of Navigation, from the onbeforeprint/onafterprint functions in javascript?
getElementsByTagName can be used as a method of any DOM node.
Thus:
var links = document.getElementById('showURLs').getElementsByTagName('a');
Using an ID on the parent
Simply replace the variable definition for links in your code with the above. Like so:
window.onbeforeprint = function(){
var links = document.getElementById('showURLs').getElementsByTagName('a');
for (var i=0; i< links.length; i++){
var theContent = links[i].getAttribute("href");
if (!theContent == ""){
links[i].newContent = " [" + theContent + "] ";
links[i].innerHTML = links[i].innerHTML + links[i].newContent;
}
}
}
window.onafterprint = function(){
var links = document.getElementById('showURLs').getElementsByTagName('a');
for (var i=0; i< links.length; i++){
var theContent = links[i].innerHTML;
if (!theContent == ""){
var theBracket = theContent.indexOf(links[i].newContent);
var newContent = theContent.substring(0, theBracket);
links[i].innerHTML = newContent;
}
}
}
Excluding children of a specific element
window.onbeforeprint = function(){
var links = document.getElementsByTagName("a");
var exclude = document.getElementById("navBar").getElementsByTagName("a");
for (var i=0; i< links.length; i++) {
if (!in_array(links[i], exclude)) {
var theContent = links[i].getAttribute("href");
if (!theContent == "") {
links[i].newContent = " [" + theContent + "] ";
links[i].innerHTML = links[i].innerHTML + links[i].newContent;
}
}
}
}
We get an array of all links on the page and one of links in the exclusion element (here with an ID of "navBar"). Then, when we are looping through the links on the page, we first check if they're in the exclusion array, and only if they're not we act!
For that conditional we use the bool in_array(needle, haystack) function, which returns true if the needle is found in the haystack (an array), false otherwise. This function is actually an adaptation of PHP's native function - see PHP manual.
function in_array(needle, haystack) {
for (i=0;i<haystack.length;i++) {
if (haystack[i] == needle) {
return true;
}
}
return false;
}
See this JSfiddle I created to test it. If you run print preview in your browser, you'll be able to see the links on the right!
Hope this helps :)