Global HTML Safari Extension - javascript

I am creating a Safari Extension which removes certain elements from some websites. However, because I have a lot of elements to remove it is getting a bit slow. I have seen that you can add a 'Global Page File' which handles all the logic and can increase the speed. Is it possible to put all the logic for the element removing in a HTML and then create a script which says that variable is true? I know there is something about an event listener but I'm not sure how to use it.
Example HTML
<html>
<head>
<script type="text/javascript">
var data = document.createElement('style');
data.appendChild(document.createTextNode( '#id {display: none !important}' ));
document.documentElement.insertBefore(data);
};
</script>
</head>
</html>
Example js file
data = true

Related

Get the actual target of a js href

I want to analyze all of the hrefs in a given HTML page.
Analyzing static and relative ones is easy with document.links.
However, when I have a js code in the href, it gets complicated. For example:
<head>
<SCRIPT language="JavaScript">
<!--hide
function openwindow()
{
window.open('xyz.htm','jav','width=400,height=300,resizable=yes');
}
//-->
</SCRIPT>
Open a New Window
</head>
(code sample taken from https://blog.udemy.com/javascript-href/)
I would have liked to know that his certain anchor element is linking to 'xyz.htm'
Obviously, the number of ways to link to a different page in js is probably to vast to generalize. But is there some tool or trick to get as close as possible?

How do I take code from Codepen, and use it locally?

How do I take the code from codepen, and use it locally in my text-editor?
http://codepen.io/mfields/pen/BhILt
I am trying to have a play with this creation locally, but when I open it in chrome, I get a blank white page with nothing going on.
<!DOCTYPE HTML>
<html>
<head>
<script> src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.2/jquery.min.js"></script>
<script type="text/javascript" src="celtic.js"></script>
<link rel="stylesheet" type="text/css" src="celtic.css"></link>
</head>
<body>
<canvas id="animation" width="400" height="400"></canvas>
</body>
</html>
I have copy, pasted and saved the css and js into different files and saved them, then tried to link them into the html file as I have shown above.
I have also included the jquery library as I understand a lot of the codepen creations use it.
The only console error I'm getting is
Uncaught TypeError: Cannot read property 'getContext' of null
which is linking to my js file, line 4
(function(){
var canvas = document.getElementById( 'animation' ),
c = canvas.getContext( '2d' ),
Sorry if this is dumb, but I'm new to all this.
I'm sure this is basic as hell. Any help would be awesome!
Joe Fitter is right, but I think is better to export your pen (use the export to export.zip option for using your pen locally). This will give you a working version of your pen without having to copy and paste the CSS, JavaScript and HTML code and without having to make changes on it for making it work.
Right click on the result frame and choose View Frame source. And you can copy the source code and paste it in your own text-editor.
It seems your javascript is running before the HTML has finished loading. If you can use jQuery put the js inside of this;
$( document ).ready(function() {
// js goes in here.
});
either u can try this....
function init() {
// Run your javascript code here
}
document.addEventListener("DOMContentLoaded", init, false);
looks like you are calling the JS before the DOM is loaded.
try wrapping it in a
$(function() {
// your code here
});
which is the same as
$(document).ready(function() {
// your code here
});
if you are using jQuery.
or you could include the <script> tag after the content, just before the closing body tag, this will ensure the content has been rendered before the JS is executed
Or you could name the function in your JS and execute it onLoad of the body:
<body onLoad="yourFunction();">
To download the computed html of a codepen, go to the codepen of your choice,
then click the "Change View" button and go to the "full page" mode.
Now depends on your browser.
Firefox
display the source code (Cmd+u) and go at the very bottom.
Look for the last iframe and click on the value of the src attribute.
There you go.
Chrome
Right click in the page (not the codepen header) and choose the View FRAME source (not the view PAGE source) option.
There you go.

Modal popup window's contents not being rewritten in IE after load

I'm trying what should have been a simple operation: when a user clicks a link a modal window pops up that's populated with some appropriate data in a string. Here's the HTML for the window:
<!DOCTYPE HTML>
<html>
<head>
<title>Modal Display Window</title>
</head>
<body>
<div id="modal_display_block">REPLACE THIS</div>
</body>
</html>
And this is the Javascript function that calls and populates the window:
function displayCenterBlock(data) {
DispWin = window.open("modal_window.html", "", 'toolbar=no,status=no,width=300,height=300');
DispWin.onload = function() {
DispWin.document.getElementById('modal_display_block').innerHTML = data;
}
}
This works great in every browser I've tried except Internet Explorer. In IE the innerHTML does not get rewritten by the data. Is there some IE-specific trick or tweak I need to apply to get this working in that browser?
Many thanks in advance!
ON EDIT: I've discovered that if I move the element rewrite line out of the onload function it then works fine in IE but not in other browsers. It appears my options are to use some conditional code to rewrite at once for IE and to wait for page load for all other browsers, or to abandon the rewrite element approach and just use a document.write. I get from forum searches people like to discourage document.write but that's looking pretty appealing right now.
Okay, for better or worse this code achieves the goal and appears to work cross browser, even in IE.
DispWin = window.open("", "Display", 'toolbar=no,status=no,width=300,height=300');
DispWin.document.open();
DispWin.document.write(data);
DispWin.document.close();
DispWin.focus();
I get that document.write can re-write the whole page, and that is sometimes bad, but in this case that is exactly what I want: a single small page displaying only what was passed in the data argument. I can style it inline.

when and where to put javascript in html

I am new to Java script. I am practicing code.When i put my code in the head section, then i get element null, and when i put it inside body, but before element, then i also get null, but if i put it inside body, but after element then i get the element. I want to ask why i am getting null in case of the first two cases. Here is my code
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<script type="text/javascript" src="js/attributes.js"></script> // null
</head>
<body>
<script type="text/javascript" src="js/attributes.js"></script> // null
<a id="braingialink"
onclick="return showAttributes();"
href="http://www.braingia.org" >Steve Suehring's Web Site
</a>
<script type="text/javascript" src="js/attributes.js"></script> // ok
</body>
Here is my javascript
var a1 = document.getElementById("braingialink"); //get null in first two cases
window.alert(a1.getAttribute("href"));
a1.setAttribute("href", "www.google.com");
window.alert(a1.getAttribute("href"));
function showAttributes() {
var e = document.getElementById("braingialink");
var elementList = "";
for (var element in e) {
/**
* Sometimes, especially when first programming with JavaScript, you might not know what
* attributes are available for a given element. But you don’t have to worry about that, because
* of a loop that calls the getAttribute() method.
*/
var attrib = e.getAttribute(element);
elementList = elementList + element + ": " + attrib + "\n";
} //end of for()
alert(elementList);
} //end of function showAttributes
And also tell me, placing <script type="text/javascript" src="js/attributes.js"></script>
after the a element, is the same as i write script in the script tag , like
Steve Suehring's Web Site
<script type="text/javascript">
var a1 = document.getElementById("braingialink");
alert(a1.getAttribute("href"));
a1.setAttribute("href","http://www.microsoft.com");
alert(a1.getAttribute("href"));
</script>
Are both things mean to same?
Thanks
The browser parses the document from top to bottom, and if it encounters a <script> block (whether inline script or inclusion of an external JS file) it runs that JavaScript before parsing any more of the document. If that particular code block tries to refer to any elements it can only access the ones above it in the source, i.e., the ones already parsed.
The document.getElementById() method returns null if no element is found for the id you supply, so if you try to use it to access elements below it in the source they've not yet been parsed and can't be found.
The two most common practices to deal with this are:
Put all of your script at the bottom of the <body> such that when it runs all of the elements will have been parsed.
Create an "onload" handler, that is, define a function that will be run as soon as the document finishes loading. You can do this from a script block in the <head> - the JavaScript that defines the onload function is run immediately, but then the function is executed later after everything has loaded.
Following is the simplest way to do option 2:
window.onload = function() {
var x = document.getElementById("x");
// other element manipulation here
};
There is nothing stopping you doing 1 and 2 in the same document, along with throwing some <script> blocks in the middle of the document, but most people find it neater to keep all their code in the one spot.
You're getting null in the head because the DOM has not loaded - your objects are nonexistent at that time. Use this:
window.onload = function () {
// Your code
}
Oh and also take a look at the .ready() function of jQuery here. It would certainly help the headache later on.
Normally you should put script blocks inside the head tag. You can put them in the body tag if you have a special reason, for example to make the script load later because it comes from a slow server.
The reason that you can't access the element, is that the code runs before the browser has parsed the code for the element, so the element simply doesn't exist yet.
You use the load event to run the code after the document is loaded:
window.onload = function() {
// here you put the code that needs to access the elements
}
see http://www.w3schools.com/js/ and http://www.w3schools.com/js/js_whereto.asp
You can place an unlimited number of scripts in your document, and you can have scripts in both the body and the head section at the same time.
It is a common practice to put all functions in the head section, or at the bottom of the page. This way they are all in one place and do not interfere with page content.
You need to understand how web browsers load resources into a page. Firefox -> Firebug add-on Net tab shows the timeline of how resources are loaded. If you are using jQuery or something like it (and you aught to) - then stick your code inside $(document).ready(function() { .. } - that will ensure the page has fully loaded.
Also, it's a good practise to to include your custom js last thing before </body> tag - that way page DOM would have loaded.
Have a read if you want to understand this deeper:
http://www.goodreads.com/book/show/6438581-even-faster-web-sites
and
http://www.goodreads.com/book/show/1681559.High_Performance_Web_Sites
Best would be right before the closing body tag, to not disturb the page loading and rendering at all! It's also recommended by google, for example for analytics snippet and also by facebook!
you get nulls because your script executes while the browser is still loading the page. Since the page might not yet have all elements rendered, you get nulls. you need to run the script when the page has finished loading.
put your script in to the HEAD element, and invoke it on body's onload event.

How can I dynamically add an <object> tag with JavaScript in IE?

I have to add either an embed tag for Firefox or an object tag for Internet Explorer with JavaScript to address the appropriate ActiveX / Plugin depending on the browser. The plugin could be missing and needs to get downloaded in this case. The dynamically added embed tag for Firefox works as expected. The dynamically added object tag for Internet Explorer seems to do nothing at all. The object tag needs the following attributes to function properly.
id ="SomeId"
classid = "CLSID:{GUID}"
codebase = "http://www.MyActicexSource.com/MyCuteActivex.CAB#Version=2,0,0,1"
Even a general working idea or method would be nice.
Thanks!
I needed to do this same thing and simply place all of the HTML needed for the OBJECT tag in a string in JavaScript and simply replace the innerHTML of a div tag with the OBJECT HTML and it works in IE just fine.
// something akin to this:
document.getElementById(myDivId).innerHTML = "<OBJECT id='foo' classid='CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95'.....etc";
That should work, it does just fine for me - I use it to embed Windows Media Player in a page.
UPDATE: You would run the above code after the page loads via an event handler that either runs on the page's load event or maybe in response to a user's click. The only thing you need to do is have an empty DIV tag or some other type of tag that would allow us to inject the HTML code via that element's innerHTML property.
UPDATE: Apparently you need more help than I thought you needed? Maybe this will help:
Have your BODY tag look like this: <body onload="loadAppropriatePlugin()">
Have somewhere in your page, where you want this thing to load, an empty DIV tag with an id attribute of something like "Foo" or whatever.
Have code like this in a <script> tag in your <head> section:
function getIEVersion() { // or something like this
var ua = window.navigator.userAgent;
var msie = ua.indexOf("MSIE ");
return ((msie > 0) ? parseInt(ua.substring(msie+5, ua.indexOf(".", msie))) : 0);
}
function loadAppropriatePlugin() {
if(getIEVersion() != 0) { // this means we are in IE
document.getElementById("Foo").innerHTML = "<OBJECT id='foo' classid='CLSID:22d6f312-b0f6-11d0-94ab-0080c74c7e95'.....etc";
} else {
// if you want to maybe do the same for FF and load that stuff...
}
}
Does that help?
var object = document.createelement('object')
object.setAttribute('id','name')
object.setAttribute('clssid','CLSID:{}')
And the same for other parameters.
Two ways.
1) Just do a document.write where ever you want it
<script type="text/javascript">
<!--
document.write("<object id=\"SomeId\" classid=\"CLSID:{GUID}\" codebase=\"http://www.MyActicexSource.com/MyCuteActivex.CAB#Version=2,0,0,1\"></object>");
-->
</script>
2) Edit a tag's innerHTML property.
<div id="my-div"></div>
<script type="text/javascript">
<!--
document.getElementById("my-div").innerHTML = "<object id=\"SomeId\" classid=\"CLSID:{GUID}\" codebase=\"http://www.MyActicexSource.com/MyCuteActivex.CAB#Version=2,0,0,1\"></object>";
-->
</script>
EDIT: Just a note, it is best to not use JavaScript to do this, since people with JavaScript enabled will never see the object. It would be better to just place it in your HTML.

Categories