bookmarklet to apply xslt stylesheet to a displayed xml file - bookmarklet

How would I write a bookmarklet that applies a given XSLT stylesheet to XML file that is displayed in, e.g., firefox? The XML Document is already loaded in the browser and displayed without a stylesheet, and the XSLT is available under a fixed URL which should be encoded in the bookmarklet.

Here is an example:
A bookmarklet for applying an XSLT stylesheet to an XML document - just insert the base64 encoded xsl in atob("") - tested on firefox
javascript: (function() {
var parser = new DOMParser();
var ss = parser.parseFromString(atob(""), 'application/xml');
var xsltProcessor = new XSLTProcessor();
xsltProcessor.importStylesheet(ss);
var newdoc = xsltProcessor.transformToDocument(content.document);
var myWindow = window.open("data:text/html," + encodeURIComponent(newdoc.documentElement.innerHTML), "_blank", "");
myWindow.focus();
}());
ref: https://gist.github.com/gosub/c7576b0c99ffdd7e993c

You can add the script to apply xslt on xml in the bookmark within parenthesis of 'javascript()'.
Here is the reference: http://www.w3schools.com/xsl/tryit.asp?filename=cdcatalog
Firstly, host the xslt and xml so as to avoid any access issues of files from javascript.
There are some modifications which are needed in the script:
In the reference above, update the following:
xml=loadXMLDoc("cdcatalog.xml");
xsl=loadXMLDoc("cdcatalog.xsl");
to
xml=loadXMLDoc(window.location.href.toString());
xsl=loadXMLDoc("http://<path>/<filename>.xsl");
Save the output in a file as per the output set in your xslt(xml/html/text) or simply display it in alert for copying and using.
Thanks

Related

kendo ui editor how to modify user selection with range object

Kendo UI 2015.2.805 Kendo UI Editor for Jacascript
I want to extend the kendo ui editor by adding a custom tool that will convert a user selected block that spans two or more paragraphs into block of single spaced text. This can be done by locating all interior p tags and converting them into br tags, taking care not to change the first or last tag.
My problem is working with the range object.
Getting the range is easy:
var range = editor.getRange();
The range object has a start and end container, and a start and end offset (within that container). I can access the text (without markup)
console.log(range.toString());
Oddly, other examples I have seen, including working examples, show that
console.log(range);
will dump the text, however that does not work in my project, I just get the word 'Range', which is the type of the object. This concerns me.
However, all I really need however is a start and end offset in the editor's markup (editor.value()) then I can locate and change the p's to br's.
I've read the telerik documentation and the referenced quirksmode site's explanation of html ranges, and while informative nothing shows how to locate the range withing the text (which seems pretty basic to me).
I suspect I'm overlooking something simple.
Given a range object how can I locate the start and end offset within the editor's content?
EDIT: After additional research it appears much more complex than I anticipated. It seems I must deal with the range and/or selection objects rather than directly with the editor content. Smarter minds than I came up with the range object for reasons I cannot fathom.
Here is what I have so far:
var range = letterEditor.editor.getRange();
var divSelection;
divSelection = range.cloneRange();
//cloning may be needless extra work...
//here manipulate the divSelection to how I want it.
//divSeletion is a range, not sure how to manipulate it
var sel = letterEditor.editor.getSelection()
sel.removeAllRanges();
sel.addRange(divSelection);
EDIT 2:
Based on Tim Down's Solution I came up with this simple test:
var html;
var sel = letterEditor.editor.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
html = container.innerHTML;
}
html = html.replace("</p><p>", "<br/>")
var range = letterEditor.editor.getRange();
range.deleteContents();
var div = document.createElement("div");
div.innerHTML = html;
var frag = document.createDocumentFragment(), child;
while ((child = div.firstChild)) {
frag.appendChild(child);
}
range.insertNode(frag);
The first part, getting the html selection works fine, the second part also works however the editor inserts tags around all lines so the result is incorrect; extra lines including fragments of the selection.
The editor supports a view html popup which shows the editor content as html and it allows for editing the html. If I change the targeted p tags to br's I get the desired result. (The editor does support br as a default line feed vs p, but I want p's most of the time). That I can edit the html with the html viewer tool lets me know this is possible, I just need identify the selection start and end in the editor content, then a simple textual replacement via regex on the editor value would do the trick.
Edit 3:
Poking around kendo.all.max.js I discovered that pressing shift+enter creates a br instead of a p tag for the line feed. I was going to extend it to do just that as a workaround for the single-space tool. I would still like a solution to this if anyone knows, but for now I will instruct users to shift-enter for single spaced blocks of text.
This will accomplish it. Uses Tim Down's code to get html. RegEx could probably be made more efficient. 'Trick' is using split = false in insertHtml.
var sel = letterEditor.editor.getSelection();
if (sel.rangeCount) {
var container = document.createElement("div");
for (var i = 0, len = sel.rangeCount; i < len; ++i) {
container.appendChild(sel.getRangeAt(i).cloneContents());
}
var block = container.innerHTML;
var rgx = new RegExp(/<br class="k-br">/gi);
block = block.replace(rgx, "");
rgx = new RegExp(/<\/p><p>/gi);
block = block.replace(rgx, "<br/>");
rgx = new RegExp(/<\/p>|<p>/gi);
block = block.replace(rgx, "");
letterEditor.editor.exec("insertHtml", { html: block, split: false });
}

Is there any way to set options in beautify extension for Ace Editor?

I've found the beautify extension in Ace editor but I don't see any examples of how to use it. Is there a way to set any options?
Example what I have so far:
var beautiful = ace.require("ace/ext/beautify"); // get extension
var editor = ace.edit("editor"); // reference to our editor
editor.setValue(someCode); // add some code to the editor
beautiful.beautify(editor.session); // beautify the code
When I call this method the code is formatted but it is all unindented / outdented all the way to the left and some spaces are removed. It doesn't look quite right. So I want to know if there are any options. I looked at the code but it is minified. Which is why I'm asking this question here.
Before call:
After call:
UPDATE:
I found an unminifed copy of the extension. It looks like there are no options and it looks like it only works for PHP:
exports.beautify = function(session) {
var iterator = new TokenIterator(session, 0, 0);
var token = iterator.getCurrentToken();
var context = session.$modeId.split("/").pop();
var code = phpTransform(iterator, context);
session.doc.setValue(code);
};
I did not find any options in the beautify.js code for the beautify() method. I found a comment saying that it is not being worked on or supported any more. I do not have the source but it said it was not working and was then abandoned.
It might work alright for JavaScript but is not working well for ActionScript.

PhantomJS - Rendering fails to show all images

I have a phantomjs script that is stepping through the pages of my site.
For each page, I use page = new WebPage() and then page.close() after finishing with the page. (This is a simplified description of the process, and I'm using PhantomJS version 1.9.7.)
While on each page, I use page.renderBase64('PNG') one or more times, and add the results to an array.
When I'm all done, I build a new page and cycle through the array of images, adding each to the page using <img src="data:image/png;base64,.......image.data.......">.
When done, I use page.render(...) to make a PDF file.
This is all working great... except that the images stop appearing in the PDF after about the 20th image - the rest just show as 4x4 pixel black dots
For troubleshooting this...
I've changed the render to output a PNG file, and have the same
problem after the 19th or 20th image.
I've outputted the raw HTML. I
can open that in Chrome, and all the images are visible.
Any ideas why the rendering would be failing?
Solved the issue. Turns out that PhantomJS was still preparing the images when the render was executed. Moving the render into the onLoadFinished handler, as illustrated below, solved the issue. Before, the page.render was being called immediately after the page.content = assignment.
For those interested in doing something similar, here's the gist of the process we are doing:
var htmlForAllPages = [];
then, as we load each page in PhantomJS:
var img = page.renderBase64('PNG');
...
htmlForAllPages.push('<img src="data:image/png;base64,' + img + '">');
...
When done, the final PDF is created... We have a template file ready, with all the required HTML and CSS etc. and simply insert our generated HTML into it:
var fs = require('fs');
var template = fs.read('DocumentationTemplate.html');
var finalHtml = template.replace('INSERTBODYHERE', htmlForAllPages.join('\n'));
var pdfPage = new WebPage();
pdfPage.onLoadFinished = function() {
pdfPage.render('Final.pdf');
pdfPage.close();
};
pdfPage.content = finalHtml;

how to create a new iframe with specify charset in firefox?

firefox
paraent page :charset is utf8
now want to create a iframe page :charset is gbk
but firefox seem can't set characterSet
var doc = window.content.document;
var iframe=doc.createElement("iframe");
iframe.src="about:blank";
iframe.setAttribute("style","display:none;visibility:hidden;");
doc.body.appendChild(iframe);
var d;
if(iframe.contentDocument) {
d = iframe.contentDocument;
} else {
d = iframe.contentWindow.document;
}
d.charset=d.characterSet="GBK";
d.documentElement.innerHTML="<body><span>some GBK</span></body>";
... "IE has scriptable document.charset property which is officially read/
write.
Gecko-based browsers do have read-only document.characterSet property." ...
Reference:
http://forums.asp.net/t/1772657.aspx/1
It doesn't matter what the Iframe's encoding is since there is no decoding happening when you directly set iframe contents to some string. If there is a problem, then the javascript file that contains
d.documentElement.innerHTML="<body><span>some GBK</span></body>";
has been encoded incorrectly or declared in the wrong encoding.

Is there a way to make the nodes draggable/to another parent or child node to rearrange the nodes in d3.js

While searching for hierarchical org chart controls, I came across a post on how to orient the nodes in d3.js, and I was wondering if there 1) was a way to edit the tree/drag children. 2) how to export the edited tree.
To answer your second question, one way is to grab the content of the parent node of your SVG (let's say your SVG is contained in a node with the id my_svg_container), and repackage it as a "true" SVG file that can be opened in an SVG-capable editor like Inkscape or Illustrator:
var rawSvg = $('#my_svg_container').outerHTML();
var result = '<?xml version="1.0" standalone="no"?><!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd"><svg xmlns="http://www.w3.org/2000/svg" version="1.1">' + rawSvg + '</svg>';
The outerHTML() function:
jQuery.fn.outerHTML = function() {
return jQuery('<div />').append(this.eq(0).clone()).html();
};
Then use a hidden web form to POST that result to a CGI script that prints it to the requesting web browser as a file. The form is triggered when a button is clicked or some other event occurs that is set to trigger the form. The browser then queries the user to save the file to the local file system.
If an example form contains the fields svg_data and svg_fn, which contain the SVG result and some filename of your choice, a very basic Perl script might look something like:
#!/usr/bin/perl
use strict;
use warnings;
use CGI;
use CGI::Pretty qw/:standard/;
my $val = param('svg_data');
my $fn = param('svg_fn');
print "Content-Type: application/x-gzip\n";
print "Content-Disposition: attachment; filename=$fn\n";
print "Content-Description: File to download\n\n";
print $val;
You might add some data validation code to make sure you're printing an SVG file and not something else.

Resources