I have an error in Javascript with an A href - javascript

I don't understand why this an issue.
Could someone explain the issue and may be a possible fix.
Thank you.
Error:
XHTML element "a" is not allowed as child of XHTML element "script" in this context
Code:
<script type="text/javascript">
// Andy Langton's show/hide/mini-accordion - updated 23/11/2009
// Latest version # http://andylangton.co.uk/jquery-show-hide
// this tells jquery to run the function below once the DOM is ready
$(document).ready(function() {
// choose text for the show/hide link - can contain HTML (e.g. an image)
var showText='More Info';
var hideText='Less Info';
// initialise the visibility check
var is_visible = false;
// append show/hide links to the element directly preceding the element with a class of "toggle"
***$('.toggle').prev().append(' ('+showText+')');***
// hide all of the elements with a class of 'toggle'
$('.toggle').hide();
// capture clicks on the toggle links
$('a.toggleLink').click(function() {
// switch visibility
is_visible = !is_visible;
// change the link depending on whether the element is shown or hidden
$(this).html( (!is_visible) ? showText : hideText);
// toggle the display - uncomment the next line for a basic "accordion" style
//$('.toggle').hide();$('a.toggleLink').html(showText);
$(this).parent().next('.toggle').toggle('slow');
// return false so any link destination is not followed
return false;
});
});
<script>

There are differences between HTML and XHTML. In XHTML, scripts don't have a CDATA content type: the contents is treated exactly the same as any other element. It's not just a NetBeans issue.
So, there are several solutions:
Put the script in a separate file, so that its contents will not be mangled by the XML parser. This is the best solution, as it doesn't have any drawbacks. It works for HTML and XHTML.
Make sure the contents don't contain any < or & signs. Also make sure that editing the script will not introduce < or & signs later on. Replace them with their entity references: < and & respectively.
If the script doesn't contain ]]>, you can put the whole content in a <![CDATA[ .. ]]> block. This may even work in HTML in some browsers, but as <![CDATA[ is not formally defined as part of the HTML standard, this method is (officially) not HTML compatible.

Related

How can I add linenums dynamically to Google Code prettify?

I have this fiddle. I am trying to format some code and am having trouble inserting and removing line numbers dynamically. It seems on the first page load the line numbers appear but once I click run then I can't get them back. On my website they don't show at all. I would like to let users click a button and turn on/off the line numbers dynamically:
<body>
<pre id="pre">
<script type="text/javascript">
// Say hello world until the user starts questioning
// the meaningfulness of their existence.
function helloWorld(world) {
for (var i = 42; --i >= 0;) {
alert('Hello ' + String(world));
}
}
</script>
<style>
p { color: pink }
b { color: blue }
u { color: "umber" }
</style>
</pre>
<button id="button">My button</button>
</body>
$(document).ready(function(){
$("#button").on("click", function(){
$("#pre").addClass("prettyprint").addClass("linenums").addClass("lang-js");
$("#pre").html(PR.prettyPrintOne($("#pre").html()));
});
});
Thanks!
EDIT: Note that this is different than How to add line numbers to all lines in Google Prettify?. In mine, the line numbers show up at first if I add linenums class to the pre tag manually. Problem is turning them on/off with jquery doesn't work.
By calling prettyPrintOne you're essentially circumventing the class based initialisation. That method has arguments that tell prettify how to behave.
You're trying to modify how prettify behaves with classes but prettify ignores that because it only cares about the arguments which are null, therefore they fallback to internal defaults.
See the source documenting the method:
/**
* Pretty print a chunk of code.
* #param {string} sourceCodeHtml The HTML to pretty print.
* #param {string} opt_langExtension The language name to use.
* Typically, a filename extension like 'cpp' or 'java'.
* #param {number|boolean} opt_numberLines True to number lines,
* or the 1-indexed number of the first line in sourceCodeHtml.
* #return {string} code as html, but prettier
*/
prettyPrintOne is essentially for parsing some code passed to it as a string, and returning the result, with the options controlled by those arguments. Conversely prettyPrint will traverse the DOM looking for the classes you're adding, behaving according to the classes it finds. As you want to toggle, you'll want to keep using prettyPrintOne so that we can have control of when to show prettified output, and when to show the original - more on that later.
As an aside, you're telling prettify to format JS when what you've got there is HTML including JS in script tags and CSS in style tags. So you'll want to use HTML as the lang extension, not JS.
Anyway, all you need to do is adjust your call to the below, additionally adding the prettify class solely so your prettify theme CSS applies:
$("#pre").html( PR.prettyPrintOne($("#pre").html(), "html", true) )
.addClass("prettyprint");
Et voila:
As for toggling, you just need to adjust the logic so that you store the original HTML somewhere on prettify-ing and restore it next time the button is clicked:
$("#button").on("click", function() {
// Cache jquery object
var $pre = $("#pre");
// If the element has a prettyprint class, it's already been manually
// prettified
if (!$pre.hasClass("prettyprint")) {
// Element hasn't been prettified, store the html in jQuery data
$pre.data("original-html", $pre.html());
// Manually prettify
$pre.html(PR.prettyPrintOne($pre.html(), "html", true))
.addClass("prettyprint");
} else {
// Element has been prettified, restore the orginal html stored in jQuery
// data and remove the prettyprint class, back to where we started
$pre.html($pre.data("original-html"))
.removeClass("prettyprint");
// Remove the jQuery data entry for our original HTML, so next time we
// start fresh
$pre.data("original-html", null);
}
});
Here's a jsfiddle showing that in action: https://jsfiddle.net/joshdavenport/68thqus1/27/

Displaying and highlighting a particular line in HTML

I am trying to implement a webpage which should have expected to have the following properties.
The HTML page contains many lines of text (thousands of lines), basically a log file.
Upon a desired action, line which is related to the action should be highlighted and shown . (exactly the way that would happen if you click on corresponding source button of a logged variable in chrome inspect element.)
This seems to be very basic but I couldn't figure out how! May be I am missing some literary terms.
Thank you.
You need to do a few things:
$("li").each(function(i, element) {
var li = $(element);
if (li.text() == "Orange") {
li.addClass("selected");
// Get position of selected element relative to top of document
var position = li.offset().top;
// Get the height of the window
var windowHeight = $(window).height();
// Scroll to and center the selected element in the viewport
$("body").scrollTop(position - (windowHeight/2));
}
});
See DEMO.
There are many ways to go about this. But is there any class tags in the logged source or is just one large text block?
If there are class or id tags on the html you can use javascript or jquery to do this.
document.getElementById('myText');
or in jquery
var element = $("#myText");
//example css changes
element.css("position","center");
element.css("color","red");
Then change the css style on those html elements.

Find the div containing the current script [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How may I reference the script tag that loaded the currently-executing script?
I am trying to make a javascript function that includes a html doc on a page via AJAX, as a way of making a PHP-esque include() with no serverside interaction. I want the script to include the file at the location on the page the function is called from. Here's my function (assuming ajax is a valid xmlhttp object):
function include(src, elem){
ajax.open('GET', src, false);
ajax.send(null);
elem.innerHTML = ajax.responseText;
}
So this would print the contents of "src.html" in the div when it is clicked:
<div onclick="include('src.html', this);"> </div>
But I want it to load when the page does. Considering there is no onload event for divs I have to include the script in the div, which is fine:
<div id=write>
<script>include('src.html', this);</script>
</div>
But then the script has no reference to the div it is called from. Sure I could put an id on the div and pass that to the function, but I don't want to. I want to be able to call this from any unidentified element. Any ideas?
You could change your div (or other element(s)) to use a data- attribute to specify what script to run:
<div data-include="src.html"></div>
And then run a script onload of the page (or in a script block just before the closing </body> tag) that finds all elements with that attribute.
var elements = document.querySelectorAll("[data-include]");
for (var i = 0; i < elements.length; i++)
include(elements[i].getAttribute("data-include"), elements[i]);
Here's a demo of the above (with a dummy include() function that just puts the required source url string in the element rather than doing Ajax, but it shows the elements are selected correctly): http://jsfiddle.net/nnnnnn/gm2LN/
For simplicity I've used querySelectorAll() to select the elements, but note that it isn't supported in IE7 and older. But obviously you can substitute whatever other element selection method you like if you want or need to support older browsers.
Here:
<div id=write>
<script>include('src.html', this);</script>
</div>
"this" points to the window object.
I think of putting an id to the script element and doing something like this:
<div id=write>
<script id='test'>include('src.html', document.getElementById('test').parentNode);</script>
</div>
Now elem in "include" function will point to the div containing the script element. In this case you are still relying on id but not on the div's side
When the page is loaded, all scripts will be executed sequencially, as soon as they are parsed. Therefore, you just need to get the last script that is apparent in the DOM to get the currently executed script:
var script = document.scripts[document.scripts.length-1];
ajax(url, function successCallback(html) {
script.insertAdjacentHTML("afterend", html);
});
(Demo to test - notice that document.scripts needs FF 9+)
However, I see no reason not to use serverside include().
nnnnnn was on the money, but I modified it ever so softly. I ended up making an include tag with a src attribute. On pageload I loop through all the "include" tags and fill them with the data from their src attribute:
function include(src, elem){
ajax.open('GET', src, false);
ajax.send(null);
elem.innerHTML = ajax.responseText;
}
window.onload = function(){
var includes = document.getElementsByTagName('include');
for(var i = 0; i <= includes.length; i++){
var elem = includes[i];
var src = elem.getAttribute('src');
include(src, elem);
}
}
Then anywhere I want to include a html file I just include my custom element:
<include src='includeme.html'> </include>
In practice this produces a bit of popup but for my application that's fine.
Thanks for the help!

Changing content CSS on the run in TinyMCE or CKEditor

I have a form in which I want to edit a HTML template. It has 2 textareas, one for the HTML and another one for the CSS.
I'd like to use either TinyMCE or CKEditor for the HTML textarea.
Is there any way to change the content CSS in either of them to match the CSS in the CSS textarea on the run, so when I change the CSS it is automatically loaded into the editor?
Thanks.
I have no experience with CKEditor, but i know that it is possible with TinyMce. What you need to do is to write an own plugin which will provide the necessary functionality.
OnNodeChange in the 2nd textarea (the one with your css) you need to update the head of the first editors iframe. This code snippet to be executed on a special action (for example onNodeChange) should point you into the right direction:
var DEBUG = false;
var css_code = tinymce.editors[1].getContent(); // get content of 2nd editorinstance on page (your css)
iframe_id = tinymce.editors[0].id+'_ifr';
with(document.getElementById(iframe_id).contentWindow){
var h=document.getElementsByTagName("head");
if (!h.length) {
if (DEBUG) console.log('length of h is null');
return;
}
var newStyleSheet=document.createElement("style");
newStyleSheet.type="text/css";
h[0].appendChild(newStyleSheet);
try{
if (typeof newStyleSheet.styleSheet !== "undefined") {
newStyleSheet.styleSheet.cssText = css_code;
}
else {
newStyleSheet.appendChild(document.createTextNode(css_code));
newStyleSheet.innerHTML=css_code;
}
}
Be aware that this code will add a new style sheet everytime it is called - yielding in increasing the editor iframes head. So i think best practice is to clean up the last inserted style before appliing the new one. Removing the last Node of the head shozld be sufficient.

jQuery + InnovaStudio WYSIWYG Editor

I am trying to avoid hard-coding each instance of this WYSIWYG editor so I am using jQuery to create an each() loop based on function name. Annoyingly InnovaStudio seems to explode when I try.
Documentation
Attempt #1
<script type="text/javascript">
/*
id = $(this).attr('id');
if(id.length == 0)
{
id = 'wysiwyg-' + wysiwyg_count;
$(this).attr('id', id);
}
WYSIWYG[wysiwyg_count] = new InnovaEditor('WYSIWYG[' + wysiwyg_count + ']');
WYSIWYG[wysiwyg_count].REPLACE(id);
*/
var demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1');
console.log('loop');
</script>
Effect
Works fine, but of course only works for a single instance of the editor. If I want multiple instances I need to use an each.
Attempt #2:
<script type="text/javascript">
var wysiwyg_count = 1;
//var WYSIWYG = [];
var demo;
(function($) {
$(function() {
$('.wysiwyg-simple').each(function(){
/*
id = $(this).attr('id');
if(id.length == 0)
{
id = 'wysiwyg-' + wysiwyg_count;
$(this).attr('id', id);
}
WYSIWYG[wysiwyg_count] = new InnovaEditor('WYSIWYG[' + wysiwyg_count + ']');
WYSIWYG[wysiwyg_count].REPLACE(id);
*/
demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1');
console.log('loop');
});
});
})(jQuery);
</script>
Effect
Replaces the entire HTML body of my page with JUST WYSIWYG related code and complains as no JS is available (not even Firebug, so can't debug).
Notice that I am hardcoding the name still. I only have one instance on the page I am testing it on, so when I get this hard-coded name working I will get the commented out code working along the same lines.
Does anybody know what the hell is going on here?
Solution: Don't bother trying to use InnovaStudio, went with CKEditor instead.
Even though you went for CKEditor you might be interested in a solution. You can supply a second argument to the REPLACE function. This second argument should also be a id, id from a element able to accept html output (like div, span, p).
demo = new InnovaEditor('demo');
demo.REPLACE('wysiwyg-1', 'wysiwyg-1-replaceDiv');
When the second argument is left out, InnovaStudio, writes the html output to the document by simply using:
document.write();
Hope this helps!
Why don't you use their own initialization code since version 4.3:
<textarea class="innovaeditor">
content here...
</textarea>
<script>
oUtil.initializeEditor("innovaeditor",
{width:"700px", height:"450px"}
);
</script>
The method is oUtil.initializeEditor(selector, option). The first parameter is selector and second is editor properties in JSON format.
The selector can be:
Css class name, if class name is specified all textareas with specified class name will be replaced with editor.
Textarea Id. If it is an Id, a prefix '#' must be added, for example oUtil.initializeEditor("#mytextarea").
Textarea object.
The second parameter is editor's properties. All valid editor's properties can be specified here for example width, height, cmdAssetManager, toolbarMode, etc.
Note that this method can be called from page onload or document ready event or during page load (as long as the object referred by selector are already rendered). This method available automatically when the page include the editor script.

Categories