Calling a CSS within Javascript - javascript

I am creating a Safari extension that clears Outlook.com advertisements and other content. I have made two versions of the extension, one with CSS and one Javascript. However, there is a delay when removing the elements with Javascript. I was wondering is it possible to call a CSS file using Javascript so that it removes the elements quicker?
If anyone has made a Safari extension or is familiar with it, how can I make check box that will call a specific CSS file? For example, there is a CSS file called 'ads' and I have checkbox with the 'Key' ads and I want to be able to find a way so that I can call it when the checkbox has been checked.
I hope you understand what I am trying to say :) It is a bit difficult to write what I want to say.
Thanks.
This is the proxy.html file that calls the functions.
<!doctype html>
<html lang="en">
<head>
<script type="text/javascript">
var data = new Object();
safari.application.addEventListener( "message", function( e ) {
if( e.name === "getData" ) {
data.advertisements = safari.extension.settings.getItem( "advertisements" );
};
}, false );
</script>
</head>
<body>
</body>
</html>
Here is the script.js file.
$(function() {
safari.self.addEventListener( "message", function( e ) {
if( e.name === "setData" ) {
handleEvents( e.message );
}
}, false );
safari.self.tab.dispatchMessage( "getData" );
function handleEvents( e ){
if (e.advertisements !='show') {
var customStyles = document.createElement('style');
customStyles.appendChild(document.createTextNode('#RightRailContainer {display: none !important;} .WithRightRail {right: 0 !important;}'));
document.documentElement.insertBefore(customStyles);
}

Yes you can. In JavaScript you can use a function to create DOM elements:
document.createElement("link"); // Create CSS element.
Then you can use .setAttribute(attr, value) to give attributes to the created element. You can do something like this:
var file=document.createElement("link");
file.setAttribute("rel", "stylesheet");
file.setAttribute("type", "text/css");
file.setAttribute("href", "main.css");
Note: You can also set the property directly doing file.[attr] = [value]. For example, this does the same thing as the above code:
var file=document.createElement("link");
file.rel = "stylesheet";
file.type = "text/css";
file.href = "main.css";

Related

Dynamically Switching CSS Files

I get two error messages when trying to load the page with the code below. The error messages are:
"Uncaught TypeError: Cannot set property 'href' of null at HTMLAnchorElement.col.(anonymous function).onclick (http://www.jimbrink.org/:363:17)"
"Uncaught ReferenceError: bindEvents is not defined at (index):375"
I'm trying to create a link that, when clicked, would switch to another css file (with different fonts).
(BONUS QUESTION: Is there a way for the link to toggle between the two stylesheets?)
I've taken this from another StackOverflow question, but I can't seem to get the code to work my situation.
Here's the link:
<li>JB's Fav Font</li>
Here's the js function from the bottom of the page:
<!-- cssswitcher js -->
<script type='text/javascript'>
window.onload = function bindEvents(){
var css=document.getElementById('style');
var col=document.querySelectorAll('a.changeStyle');
/* iterate through collection and assign listener */
for( var n in col )if( col[n].nodeType==1 ) col[n].onclick=function(e){
e.preventDefault();/* prevent jumping to top of page etc */
var el=typeof(e.target)!='undefined' ? e.target : e.srcElement;
/* assign style attributes */
css.href=el.dataset.style;
css.rel=el.dataset.rel;
css.type=el.dataset.type;
/* store reference to style selected in localstorage */
localStorage.setItem( 'style', el.dataset.style );
};
/* if there is a reference to the user's css choice in storage, assign it */
if( localStorage.getItem( 'style' )!=null ) css.href=localStorage.getItem( 'style' );
}
document.addEventListener( 'DOMContentLoaded', bindEvents, false );
</script>
First, start by defining the original style like this:
HTML:
<link id="style" rel="stylesheet" type="text/css" href="style.css" />
Notice the id=style that we'll use to find the element. That might fix your first error.
For the second one, you have to decide whether to use document.addEventListener( 'DOMContentLoaded', bindEvents, false ); or window.onload because they're different functions. This might help you window.onload vs. body.onload vs. document.onready.
So, now we can do some Javascript:
HTML (the links):
<li><button onclick='setStyle("css/style.comicsans.css")'>JB's Fav Font</button></li>
<li><button onclick='setStyle("css/style.other.css")'>Other Font</button></li>
First, notice that I'm only using a parameter to call setStyle function on click, and btw it's better to work with <button>, this way we get a cleaner result.
Javascript:
var cssStyle = document.getElementById('style');
window.onload = function(){
if(localStorage && localStorage.getItem("style"))
cssStyle.href = localStorage.getItem("style");
};
function setStyle(newStyle){
cssStyle.href = newStyle;
if(localStorage)
localStorage.setItem("style", newStyle);
};
BONUS:
But if you are only be using two styles, then try to simplify, and do a shorthand method to do this:
HTML:
<li><button onclick='toggleStyle()'>Toggle</button></li>
<!-- cssswitcher js -->
<script type='text/javascript'>
var cssStyle = document.getElementById('style');
var listStyles = ["css/style.comicsans.css", "css/style.other.css"];
window.onload = function(){
if(localStorage && localStorage.getItem("style"))
cssStyle.href = localStorage.getItem("style");
};
function toggleStyle(){
var previousStyle = cssStyle.href;
if(previousStyle.endsWith(listStyles[0]))
newStyle = listStyles[1];
else
newStyle = listStyles[0];
cssStyle.href = newStyle;
if(localStorage)
localStorage.setItem("style", newStyle);
};
</script>
I did this in one of my projects using JQuery, I hope this will help you :
HTML :
<ul id="projectList">
<li class="project">Lorem Lorem</li>
<li class="project viewed">Lorem Lorem</li>
<li class="project viewed selected">Lorem Lorem</li>
<li class="project viewed selected">Lorem Lorem</li>
<li class="project viewed">Lorem Lorem</li>
</ul>
JavaScript with Dynamic CSS Code :
var data = {
"projectColors": {
"viewedColor": "#fffc20",
"selectedColor": "#ff7920"
}
};
var style = $(document.createElement("style")).attr("type", "text/css");
style.append("#projectList .project.viewed {color: " + data.projectColors.viewedColor + ";}");
style.append("#projectList .project.selected {color: " + data.projectColors.selectedColor + ";}");
style.appendTo("head");
JSFiddle :
https://jsfiddle.net/nikdtu/9gberp5o/

CKEditor - remove script tag with data processor

I am quite new with CKEditor (starting to use it 2 days ago) and I am still fighting with some configuration like removing the tag from editor.
So for example, if a user type in source mode the following:
<script type="text/javascript">alert('hello');</script>
I would like to remove it.
Looking the documentation, I found that this can be done using an HTML filter. I so defined it but it does not work.
var editor = ev.editor;
var dataProcessor = editor.dataProcessor;
var htmlFilter = dataProcessor && dataProcessor.htmlFilter;
htmlFilter.addRules(
{
elements :
{
script : function(element)
{
alert('Found script :' + element.name);
element.remove();
},
img : function( element )
{
alert('Found script :' + element.name);
if ( !element.attributes.alt )
element.attributes.alt = 'Cookingfactory';
}
}
});
The img part is working well but not the script one. I guess I missed something. It even does not display the alert message for script.
Any help would be more than welcome :o)
You can use this :
CKEDITOR.replace('editor1', {
on: {
pluginsLoaded: function(event) {
event.editor.dataProcessor.dataFilter.addRules({
elements: {
script: function(element) {
return false;
}
}
});
}
}
});
If you are using CKEditor 4.1 or above, you may use Advanced Content Filter to allow the content you want.
If you are using CKEditor 4.4 or above, there is an easier way. You can use Disallowed Content to filter content you don't like .
config.disallowedContent = 'script';
As I'm having CKEditor 4, I did the next
CKEDITOR.instances.editor1.config.protectedSource.push( /{.*\".*}/g );
It will ignore quotes in smarty curly brackets

Assigning some style from the styles-box in CKEditor through JavaScript

How can I simulate user-selection of some style from the styles-box, through JS? I want to put some shortcut buttons that assign some of the popular styles with one click.
EDIT:
I don't care if it'll be in-editor button or outer button.
I don't want css-style assignment; I want CKEditor-style assignment (those of the styles-box).
I haven't used CKEditor, but, I saw your question and thought "That would be fun to figure out." Well, here is what I figured out:
(yes, I found terrible documentation, but, that's not the point...I will give them props for commenting their code, though.)
///
// function to add buttons that trigger styles to be applied.
//
// editor - CKEDITOR - instance of editor you want command attached to.
// buttonName - String - name of the button
// buttonLabel - String - humane readable name of the button
// commandName - String - name of command, the way to call this command from CKEDITOR.execCommand()
// styleDefinition - StyleDefinition - obj defining the style you would like to apply when this command is called.
///
var addButtonCommand = function( editor, buttonName, buttonLabel, commandName, styleDefiniton )
{
var style = new CKEDITOR.style( styleDefiniton );
editor.attachStyleStateChange( style, function( state )
{
!editor.readOnly && editor.getCommand( commandName ).setState( state );
});
editor.addCommand( commandName, new CKEDITOR.styleCommand( style ) );
editor.ui.addButton( buttonName,
{
label : buttonLabel,
command : commandName
//adding an icon here should display the button on the toolbar.
//icon : "path to img",
});
};
//Get the editor instance you want to use. Normally the same as the ID of the textarea CKEditor binds to.
var editor1 = CKEDITOR.instances.editor1;
//If you look at ckeditor/_source/plugins/styles/default.js you will see that this selects the first element. That list is read into the array 'default'.
var blueTitleStyle = CKEDITOR.stylesSet.registered.default[0];
//Or, you can define the style like this: See http://dev.ckeditor.com/wiki/Components/Styles for more info on style definitions.
var blueTitleStyle = {
name : 'Blue Title',
element : 'h3',
styles : { 'color' : 'Blue' }
};
addButtonCommand(editor1, 'BlueTitle', 'BlueTitle', 'bluetitle', blueTitleStyle);
Here is a Javascript function to aid your click events:
//function used to execute the command. Only used for calling the command when not calling from a button. (Like an A with an onClick bound to it.)
//pulled this function right out of the api.html example in the ckeditor/_samples dir.
function ExecuteCommand( commandName )
{
// Get the editor instance that we want to interact with.
var oEditor = CKEDITOR.instances.editor1;
// Check the active editing mode.
if ( oEditor.mode == 'wysiwyg' )
{
// Execute the command.
// http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.editor.html#execCommand
oEditor.execCommand( commandName );
}
else
{
alert( 'You must be in WYSIWYG mode!' );
}
}
Now, you can create a link like this:
<a href='#' class='setBlueTitle'>Set Blue Title</a>
and use a bit of jQuery to spice it up:
<script type="text/javascript">
$(document).ready(function(){
$(".setBlueTitle").onClick(function(e){
//stops the click from changing the page and whatever other default action would happen.
e.preventDefault();
ExecuteCommand('bluetitle');
});
});
</script>
I am not 100% sure about the button icon part. I didn't have an icon to try it with. But, according to a few posts, it should work fine. Regardless, the jQuery click binding works.
That should be pretty much it! I had to do quite a bit of digging around to figure this out, but it certainly is satisfying to see it work!
Here's one option
First, you can setup the desired styles you want to try out in a CSS class. Then, you can set the className for the test div when you click that button. Here's a simple example:
test.css:
.bold {
font-weight: bold;
}
.italic {
font-style: italic;
}
test.html
<html>
<head>
<link rel="stylesheet" type="text/css" href="test.css" />
</head>
<body>
<input type="button" onclick="document.getElementById('testStyleDiv').className='bold'" value="bold"/>
<input type="button" onclick="document.getElementById('testStyleDiv').className='italic'" value="italic"/>
<div id="testStyleDiv">foo</div>
</body>
</html>

Using jQuery in a firefox extension

I'm trying to develop a firefox extension which draws a toolbar at the base of every webpage.
Until now i managed to make jQuery work and i proved it by running
$("body",mr.env).css("background","black");
in the mr.on=function().
This code just makes the background color of the webpage black whenever i click the menu item associated with the addon.
But, if i try to run
$('body',mr.env).append( ' <img src="img/check.png" /> ' );
it simply fails. It doesn't show any error in Error Console and the image isn't displayed.
Why is that?
This is my overlay XUL :
<script src="window.js"/>
<link href="style.css" rel="stylesheet" type="text/css" />
<script type="text/javascript" src="jquery-1.4.4.min.js"></script>
<!-- Firefox Tools menu -->
<menupopup id="menu_ToolsPopup">
<menuitem id="menu_crypt_demo" class="" image=""
label="Use DnsResolver?" insertbefore="javascriptConsole" accesskey="o"
oncommand="DnsResolver.onMenuItemCommand(event);">
</menuitem>
</menupopup>
This is the JavaScript file (window.js):
var DnsResolver = {
onLoad: function() {
// initialization code
this.initialized = true;
},
onMenuItemCommand: function() {
testextension.on();
window.open("chrome://dnsresolver/content/window.xul", "", "chrome");
}
};
window.addEventListener("load", function(e) { DnsResolver.onLoad(e); }, false);
if(!testextension){ var testextension={};}
(function(){
var mr=testextension;
mr.on=function(){
mr.loadLibraries(mr);
var jQuery = mr.jQuery;
var $ = function(selector,context){ return new jQuery.fn.init(selector,context||window._content.document); };
$.fn = $.prototype = jQuery.fn;
mr.env=window._content.document;
/*$("body",mr.env).css("background","black");*/
$('body',mr.env).append('<img src="img/check.png" />');
$(mr.env).ready(function(){
// hide and make visible the show
$("span.close a",mr.env).click(function() {
$("#tbar"),mr.env.slideToggle("fast");
$("#tbarshow",mr.env).fadeIn("slow");
});
// show tbar and hide the show bar
$("span.show a",mr.env).click(function() {
$("#tbar",mr.env).slideToggle("fast");
$("#tbarshow",mr.env).fadeOut();
});
});
/*$("body",mr.env).css("background","black");*/
}
// Loading the Jquery from the mozilla subscript method
mr.loadLibraries = function(context){
var loader = Components.classes["#mozilla.org/moz/jssubscript-loader;1"]
.getService(Components.interfaces.mozIJSSubScriptLoader);
loader.loadSubScript("chrome://dnsresolver/content/jquery-1.4.4.min.js",context);
var jQuery = window.jQuery.noConflict(true);
if( typeof(jQuery.fn._init) == 'undefined') { jQuery.fn._init = jQuery.fn.init; }
mr.jQuery = jQuery;
}
})();
Starting with Firefox 3, chrome resources can no longer be referenced from within <img>, <script>, or other elements contained in, or added to, content that was loaded from an untrusted source. This restriction applies to both elements defined by the untrusted source and to elements added by trusted extensions. If such references need to be explicitly allowed, set the contentaccessible flag to yes to obtain the behaviour found in older versions of Firefox.
Use the HTML tab in FireFox to know actually if the img element was added. It probably was added and the problem is with your URL.
I remember when building my FireFox extensions, that files are located through a special protocol (chrome:// I think), where you put the name of the extension and can browse through it.

jQuery: copying element attributes to another attribute of the same element

I've got a list of links, all in the same class, each with a custom argument ("switch-text"). My script should copy the text of the custom argument to the text of each link and replace it ("Pick A" should become "Pick A Please").
It works fine with only 1 link, but when I add several, they all get switched to the first argument. ("Pick B" should be replaced by "Pick B Please", but it doesn't).
I could probably solve this using each(), but I'm preferably looking for a simple, single jQuery line that does it, and I'm baffled I haven't yet found out how to achieve this.
Can somebody help? Thanks!
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<script>
$(document).ready(function() {
$(".switcher").text( $(".switcher").attr("switch-text") );
});
</script>
Pick A<br>
Pick B<br>
You should use each to go through all the elements, and use this to always act on the current one.
$(document).ready(function() {
$(".switcher").each(function(){
$(this).text( $(this).attr("switch-text") );
});
});
Demo
Without jQuery
you need:
Dean Edwards document ready
getElementsByClassName
Code:
readyList.push(function() {
var els = getElementsByClassName("switcher");
for ( var i = els.length; i--; ) {
els[i].innerHTML = els[i].getAttribute("switch-text");
}
});
And change Dean's script to execute functions on document.ready:
function init() {
// ...
// do stuff
for ( var i = 0; i < readyList.length; i++ ) {
if ( typeof readyList[i] === "function" ) {
readyList[i]();
}
}
//..
}
That's it. You've saved a lot of bandwidth. :)
Demo without jQuery

Categories

Resources