A bookmarklet to disable the tinymce visual editor? - javascript

I'm looking for a bookmarklet to disable the tinymce visual editor. This is to say, some code that could be pasted into the address bar to disable the editor (and also bookmarked).
Anyone have any ideas?
The page I want to use it on is using an older version of TinyMce, I think the same version that is used on this page: http://www.imathas.com/editordemo/demo.html
Just to reiterate, I want to remove the TinyMce editor and leave the textarea.
If you would like to see the functionality I am talking about, you could also visit this example page: http://www.matracas.org/sentido/tinymce/examples/full.html and click on the enable / disable buttons below the editor.
The problem here is that the syntax relies on knowing what editor id to put into the .get() function.
tinyMCE.get('elm1').hide();
tinyMCE.get('elm1').show();
The bookmarklet would ideally just use tinMCE's show / hide functionality, but it would work for all editors on a page.

Here you go!
javascript:(function(){var arr=Object.keys(tinyMCE.editors);for(var i=0;i<arr.length;i++){try{tinyMCE.editors[arr[i]].remove();}catch(e){}}})()
More visibly pleasing, but same code:
javascript:
(function(){
var arr=Object.keys(tinyMCE.editors);
for(var i=0;i<arr.length;i++){
try{
tinyMCE.editors[arr[i]].remove();
}
catch(e){
}
}
}
)()

I start all my bookmarklets with jQuery, although this may work better as a greasemonkey script depending on what you're trying to do.
javascript:
function loadScript(url, callback){
var head = document.getElementsByTagName("head")[0];
var script = document.createElement("script");
script.src = url;
var done = false;
script.onload = script.onreadystatechange = function() {
if( !done && ( !this.readyState
|| this.readyState == "loaded"
|| this.readyState == "complete") )
{
done = true;
callback();
script.onload = script.onreadystatechange = null;
head.removeChild( script );
}
};
head.appendChild(script);
}
loadScript("http://code.jquery.com/jquery-latest.js", function(){
jQuery('.mceEditor').remove(); }

I have added a TinyMCE remover to my bookmarklet collection:
http://richardbronosky.github.com/Perfect-Bookmarklets/tinymce.html
It has one major advantage over the others I have seen. It restores the content of the textarea back to what was in the source. I don't know if others have experienced this, but we have a web admin to our CMS and TinyMCE, when removed leaves the code altered. I have resolved this.
Here is the code:
for(var i=0;i<tinymce.editors.length;i++){
var tmpId=tinymce.editors[i].id;
var tmpVal=document.getElementById(tmpId).value;
tinyMCE.execCommand("mceRemoveControl",true,tmpId);
document.getElementById(tmpId).value=tmpVal
}
Also on github:
https://github.com/RichardBronosky/Perfect-Bookmarklets/blob/master/tinymce.html

Related

javascript load css but keep current style

I have the following code that is run after the page loads:
function prepare_bootstrap()
{
console.log("Preparing bootstrap...");
var items = document.body.getElementsByTagName("*");
for (var i = items.length; i--;)
{
items[i].style.cssText = '!important';
}
var style1 = document.createElement("link");
style1.rel = "stylesheet";
style1.href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css";
document.body.appendChild(style1);
var style2 = document.createElement("link");
style2.rel = "stylesheet";
style2.href = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap-theme.min.css";
document.body.appendChild(style2);
var script = document.createElement("script");
script.src = "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js";
script.onload = script.onreadystatechange = function()
{
if (!this.readyState || this.readyState == "loaded" || this.readyState == "complete")
{
prepare_bootstrapdialog();
}
};
document.body.appendChild(script);
}
I am loading bootstrap to allow for nicely formatted popups.
However, the bootstrap overrides almost everything, making the page look messed up.
I tried making every style important, but to be honest, I have no idea what I'm doing.
Is there any way to make css NOT override previous css?
Thanks!
EDIT: As before stated, it is impossible to load bootstrap first as the javascript is part of a bookmarklet.
Have a read of this:
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/style#A_scoped_stylesheet
Will only work in some browsers though, so not an option for an publicly facing site. The best way to do this really would be to not just include bootstrap in its entirety, instead picking out the bits you need and just using them. You can get custom builds of bootstrap here:
http://getbootstrap.com/customize/
You really shouldn't just load css styles that you aren't actively using. Doing so creates more debugging work for you if you encounter styling issues, and also means you're potentially wasting bandwidth.
You should load the bootstrap stylesheet first, that way any stylesheets linked after that will override bootstrap's
(This is making use of the cascading part of CSS)
See https://stackoverflow.com/a/964343/4206206

Dynamic script not loading on history.go()

I have a static html page that I cannot edit- it does refer to a js file though, so what I do is redirect that url request on my IIS server to my js file- where I dynamically inject jQuery so I can use it. Here's the code I use to insert jQuery:
var script = document.createElement( 'script' );
script.src = 'http://code.jquery.com/jquery-1.9.1.js';
script.type = 'text/javascript';
script.onload = jqueryReady; //most browsers
script.onreadystatechange = function () { //ie
if ( this.readyState == 'complete' ) {
jqueryReady();
}
};
This works great except in one specific case- if I call history.go() on the page when the browser is IE and the page is being served up from an internal web server. Hitting F5 also does not reload the page properly. I have to put the cursor in the address bar and hit enter to get it to load right.
Edit: Forgot to mention the obvious- I have a breakpoint in the jqueryReady() function- and it never gets hit- which is where the problem lies...
It works fine from IE in my dev environment if I serve the page up and then fire history.go() (with a button click). It works with chrome, haven't tested firefox.
So is there an alternative to history.go() to fire a 'true' page reload like what hitting enter in the address bar?
This is also a HUGE page - 6000 lines of html (I didn't write it) and jQuery and all javascript is being loaded in the head- I know you are supposed to load js stuff at the end of the page. Maybe this is related? It feels like a timing issue...
Anyone have any thoughts as to things to check/try? Or know what's going on?
Okay found it... so the solution was here
Bottom line is the code I was using isn't correct, this is the recommended approach to dynamically insert a script into a document and then handle the ready event:
var script = document.createElement( "script" );
script.src = "/reporter/scripts/jquery-1.9.1.min.js";
if ( script.addEventListener ) {
script.addEventListener( "load", jqueryReady, false );
}
else if ( script.readyState ) {
script.onreadystatechange = jqueryReady;
}
document.getElementsByTagName( 'head' )[0].appendChild( script );
Additionally, I needed to check if jQuery was loaded in my jqueryReady function:
function jqueryReady() {
// Check if jQuery exists
if ( typeof jQuery != 'undefined' ) {
// do stuff like $(document).ready()
}
}
This seemed to work in all cases that I could find.
Hope this helps someone else!

Detect whether external script has loaded

Using JavaScript, is there a way to detect whether or not an external script (from a third-party vendor) has completely loaded?
The script in question is used to pull in and embed the markup for a list of jobs and, unfortunately, doesn't make use of any variables or functions. It uses document.write to output all of the content that gets embedded in my page.
Ideally, I'd like to display some kind of loading message while I'm waiting for the external script to load, and if it fails to load, display a "We're sorry, check back later..." message.
I'm using jQuery on the site, but this external script is called before I make the jQuery call.
Here's what the document.write stuff from the external script looks like:
document.write('<div class="jt_job_list">');
document.write("
<div class=\"jt_job jt_row2\">
<div class=\"jt_job_position\">
Position Title
</div>
<div class=\"jt_job_location\">City, State</div>
<div class=\"jt_job_company\">Job Company Name</div>
</div>
");
Attach an function to the load event:
<script type="text/javascript" src="whatever.js" onload ="SomeFunction()" />
As far as your loading... problem goes, try displaying a div for loading and then just display:none-ing it in your onload function. Make sure to handle cases where your script fails to load too, though.
Script tags block downloads, so as long as the content dependent on your script is below where your script it loaded, you should be fine. This is true even if the script is in-line in the body of your page.
This website has a great example of how this works.
This obviously does not work if you're loading the scripts asynchronously.
Scripts without async or defer attributes are fetched and executed immediately, before the browser continues to parse the page.
Source: MDN
You could put a script block after it on the page:
<script src="external_script.js"></script>
<script type="text/javascript">
ExternalScriptHasLoaded();
</script>
Thanks for the assistance above, especially ngmiceli for the Steve Souders link!
I decided to take what's probably a "lazy" approach, and also forego the "loading" message:
$(document).ready(function(){
if ($('.jt_job_list').length === 0){
$('#job-board').html("<p>We're sorry, but the Job Board isn't currently available. Please try again in a few minutes.</p>");
};
});
Pretty simple, but I'm looking to see if an element with the .jt_job_list class is in the dom. If it isn't, I display an error message.
This worked for me: it does however, rely on the newer querySelector interface which most modern browsers support. But if you're using really old browsers, you can use getElement... and run a for loop.
function loadJS(file, callback, error, type) {
var _file = file ;
var loaded = document.querySelector('script[src="'+file+'"]') ;
if (loaded) {
loaded.onload = callback ;
loaded.onreadystatechange = callback;
return
}
var script = document.createElement("script");
script.type = (typeof type ==="string" ? type : "application/javascript") ;
script.src = file;
script.async = false ;
script.defer = false ;
script.onload = callback ;
if (error) {
script.onerror = error ;
}
else {
script.onerror = function(e) {
console.error("Script File '" + _file + "' not found :-(");
};
}
script.onreadystatechange = callback;
document.body.appendChild(script);
}
You could give what ever your looking for an ID
and check whether not the ID has been loaded using document.getElementById("ID");
Is that what your looking for not sure I fully understand?

Loading JQuery with Javascript from footer

If you would like to get to the point, here is my question:
Is there any way to call a specific script to load first in javascript?
For more detail, please read below:
I have a javascript file that is loading from the bottom of my HTML <body>. Unfortunately, there is no JQuery in the head, so I have to add it through this javascript file.
What I need to do is add a JQuery lightbox plugin.
My problem is that when I load the page, sometimes JQuery isn't the first thing loaded. So I receive the error "jQuery is not defined". Which will then raise more errors for undefined methods from the plugin.
This doesn't happen all the time, only sometimes. Which makes me think it's a loading/order of operations issue.
Is there any way I can guarantee that my JQuery script is the first thing loaded?
Here is some of my javascript file.
//Get head element
var head = document.getElementsByTagName("head")[0];
//Create and insert JQuery
var jquery = document.createElement('script');
jquery.type = 'text/javascript';
jquery.src = 'http://image.iloqal.com/lib/fe6b/m/1/jquery.1.7.2.js';
head.insertBefore(jquery,head.childNodes[4]);
function thescripts() {
var fancybox = document.createElement('script');
fancybox.type = 'text/javascript';
fancybox.src = 'http://image.iloqal.com/ilejquery.fancybox-1.3.4.pack.js';
head.appendChild(fancybox);
var thebody = document.getElementsByTagName('body')[0];
thebody.appendChild(thediv);
thediv.appendChild(theimg);
//Run fancybox
thebody.onload = function() {
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
}
};
if(jquery.attachEvent){
jquery.attachEvent("onload",thescripts());
} else {
jquery.onload = thescripts();
}
Any help is appreciated!
Try this. Add this piece of code inside your javascript file which is called from your footer.
<script type="text/javascript">
if(typeof jQuery == 'undefined'){
document.write('<script type="text/javascript" src="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.1.min.js"></'+'script>');
}
</script>
This will include jquery if its not loaded. I think this will fix your issue.
Using $(function() {...do your stuff here...}); is the way to go to be sure jQuery is loaded before the script is executed, but you could probably make it harder for yourself and do:
thebody.onload = function() {
RunMyjQuery();
}
function RunMyjQuery() {
if (typeof $ === 'undefined') {
setTimeout(RunMyjQuery, 500);
}else{
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
}
}
You're calling thescripts immediately, although you try not to. Use this:
jquery.onload = thescripts; // notice no parentheses
Also, your thebody.onload strategy will not work. Use $(document).ready instead:
$(document).ready(function{
$('#lightbox').ready(function() {
$("#lightbox").fancybox().trigger('click');
});
});

Defer parsing of JavaScript - Google Page Speed

All of my JavaScript files are already at the bottom but Google Page Speed is giving this suggestion to improve speed:
Defer parsing of JavaScript
88.6KiB of JavaScript is parsed during initial page load. Defer
parsing JavaScript to reduce blocking of page rendering.
http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js
(76.8KiB) http://websiteurl/js/plugins.js (11.7KiB) http://websiteurl/
(109B of inline JavaScript)
This is the my html (example)
<html>
<head>
<!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<head>
<body>
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.5.1.min.js"%3E%3C/script%3E'))</script>
<script src="js/plugins.js"></script>
<script>$(document).ready(function() {
$("#various2").fancybox({
'width': 485,
'height': 691,
});
});</script>
</body>
</html>
What should I do to increase performance by using defer?
Is it only for Google chrome or for all?
If you're looking for page performance then first and foremost you should move those scripts to the bottom of your page to allow the other assets to load.
Also use dns prefetch in the head to set the base domain for google-code
<link rel="dns-prefetch" href="//ajax.googleapis.com">
Since this is just a small piece of code, you could simply add it to your plugins.js file at the bottom then defer the plugins file.
<script src="js/plugins.js" defer></script>
That's what I'd do anyway, all my sites are optimized to 98 and 97 respectively in yslow and page speed.
Hope it helps.
-V
Add in <script type="text/javascript" defer="defer"> tag like that it works for me.
<script type="text/javascript" defer="defer" src="<?php echo $this->getSkinUrl();?>js/jquery.bxslider.js"></script>
I see this is an old question, but since I was looking for a good answer myself, I am going to share the method I currently use.
As far as inline Javascript is concerned, what I do is change all the type attributes to text/deferred-javascript, or something similar, so that the code within the script tag is not evaluated during page load. Then I attach a function to the page onload event; said function finds all the scripts matching the type above and evaluates the code inside using eval(). I know in general eval() is evil but it seems to be helpful here.
For external Javascript files, I do something very similar. Instead of adding the script tags to the page, I record them and insert them one-by-one after page load has completed.
One problem I'm having is that if one of the inline deferred Javascript contains an error (say a parse error), the subsequent scripts are not loaded (but that might depend on my current implementation).
That's probably a generic response/suggestion for when it encounters a certain level of performance.
Although, it specifically mentions jQuery, a plugin, and 109 bytes of inline JavaScript. Do you have any inline JavaScript? Are you also placing your JavaScript includes at the bottom of the <body>?
Example
Loading Performance article
EDIT:
Based on recently posted HTML...
As a test, remove these two items to see if it makes any difference:
<!--[if lt IE 9]><script src="//html5shim.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
<script>!window.jQuery && document.write(unescape('%3Cscript src="js/libs/jquery-1.5.1.min.js"%3E%3C/script%3E'))</script>
Also, the warning message mentions 109 bytes of inline JS, yet I don't see anything like that in the HTML you've posted.
Hi recently we have created an opensource nodejs framework called "elegant framework" that help you building fast web application and we succeeded to get 100% google page speed in both desktop and mobile in all pages :
you can check it at:
https://developers.google.com/speed/pagespeed/insights/?url=getelegant.com
there is a lot of things you can learn from it by viewing the page source also if anything you cannot understand please comment so i can help you with
so far you can try this method:
// Load script element as a child of the body
function loadJS(src, callback) {
var script = document.createElement("script");
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function () {
if (script.readyState == "loaded" || script.readyState == "complete") {
script.onreadystatechange = null;
if (callback) {
callback();
}
}
};
} else { //Others
script.onload = function () {
if (callback) {
callback();
}
};
}
script.src = src;
document.body.appendChild(script);
}
// Load style element as a child of the body
function loadCSS(href,callback) {
var element = document.createElement("link");
element.rel = "stylesheet";
if (element.readyState) { //IE
element.onreadystatechange = function () {
if (element.readyState == "loaded" || script.readyState == "complete") {
element.onreadystatechange = null;
if (callback) {
callback();
}
}
};
} else { //Others
element.onload = function () {
if (callback) {
callback();
}
};
}
element.href = href;
document.body.appendChild(element);
}
// Load All Resources
function loadResources() {
// css
loadCSS("/compressed/code-mirror-style.css?please1");
loadCSS("/compressed/all.css?please2");
// js
loadJS("/compressed/code-mirror.js", function () {
loadJS("/compressed/common.js", function () {
$("[data-lang]").each(function () {
var code = $(this).addClass("code").text();
$(this).empty();
var myCodeMirror = CodeMirror(this, {
value: code,
mode: $(this).attr("data-lang"),
lineNumbers: !$(this).hasClass('inline') && !$(this).hasClass('no-numbers'),
readOnly: true
});
});
});
});
}
// Check for browser support of event handling capability
if (window.addEventListener) {
window.addEventListener("load", loadResources, false);
} else if (window.attachEvent) {
window.attachEvent("onload", loadResources);
} else {
window.onload = loadResources
}

Categories

Resources