tinylog is a minimalistic logging platform JavaScript library I created which is primarily intended for online IDEs and implementing console.log() for browsers without native consoles. There is also a lite version intended for embedding in other JavaScript libraries. One such library that embeds tinylog lite is Processing.js, which uses it to implement Processing’s println().
There are also online demos of using tinylog that you can try out. The tinylog saved log viewer demo only works in browsers that support the W3C File API which is only Firefox as of now.
async.js is a library that aims to make it so you don’t have to mess with callbacks when making applications in JavaScript 1.7 or higher by using the yield statement to pause function execution.
Examples
Please note that user interaction with the page is not blocked during the course of any of these examples.
A node.next(eventType) method
The node.next(eventType) method would pause a function until the specified event is fired on the node that next was called on and would return the captured event object.
var listenForNextEventDispatch = function ([node, eventType], callback) {
var listener = function (event) {
node.removeEventListener(eventType, listener, false);
callback(event);
};
node.addEventListener(eventType, listener, false);
};
Node.prototype.next = function (eventType) {
return [listenForNextEventDispatch, [this, eventType]];
};
You could now then the following in an asynced function to handle the next click event on the document.
var clickEvent = yield document.next("click");
// handle click event here
Asking the user for their impressions of async.js
The following code does not use any obtrusive and annoying functions like prompt or alert yet still can utilize execution-blocking features.
yield to.request("feedback", "POST", (
yield to.prompt("What are your impressions of async.js?")
));
yield to.inform("Thanks for your feedback!");
// do more stuff here
As opposed to the following, which is functionally equivalent to the previous code but doesn’t use async.js’s blocking features.
async.prompt(
["What are your impressions of async.js?"],
function (response) {
async.request(
["feedback", "POST", response],
function () {
async.inform(
["Thanks for your feedback!"],
function () {
// do more stuff here
}
);
}
);
}
);
That’s a lot of callbacks, all of which are implied when you use async.js.
Creating an async.js module for thatFunctionThatUsesCallbacks
async.yourMethodName = function ([aParameterThatFunctionUses], callback) {
thatFunctionThatUsesCallbacks(aParameterThatFunctionUses, callback);
};
You could then use yield to.yourMethodName(aParameterThatFunctionUses) and immediately start writing code that depends onthatFunctionThatUsesCallbacks function after the statement.
I recently implemented fully-featured cross-(HTML5-supporting)-browser loadFont() and text() functions in Processing.js. This implementation does not suffer from the limitation of the old implementation that only supported SVG fonts and writing text from already-installed fonts only worked recent Mozilla-based browsers. I also revamped the entire library, fixing a few hundred errors, changing and optimizing many Processing method implementations, and getting rid of all of the implied global variable leaks. Included is an image gallery of the same Processing program being run using Processing and Processing.js. The one showing only the outputted image was saved directly from a canvas element. You can also try out fonts in Processing.js at this demo page. The demo page does not use the same font as in the screenshot but it is similar. If your browser does not support @font-face CSS rules but does support the canvas text API, your system default monospace font will be used instead.
I just made another E4X DOM library, but this one is intended to implement the optional features in the ECMA-357 standard that are not implemented by Mozilla in JavaScript. The library is named e4x.js due to, for the most part, it only implementing stuff already specified in E4X. The only difference between the standard and my implementation is that the XML.xpath(xpathExpression) method also supports numeric, string, and boolean result types.
I have created a small JavaScript toolkit named e4x-dom.js for making it easy to manipulate the DOM with E4X.
The following methods are implemented on XML objects by e4x-dom.js:
node()
- Returns the HTML node representation of the XML.
over(element or selector)
- Either overwrites
element or every element matched by the CSS selector with node().
overId(id)
- Same as
over(document.getElementById(id)) but also preserves the the id of the element being overwritten in the element replacing it.
fill(element or selector)
- Removes every child node of
element or every element matched by the CSS selector. Then node() is appended to all of the emptied elements.
fillId(id)
- Same as
fill(document.getElementById(id))
appendTo(element or selector)
- Appends
node() to element or every element matched by the CSS selector.
appendToId(id)
- Same as
appendTo(document.getElementById(id)).
insertBefore(element or selector)
- Inserts
node() before element or every element matched by the CSS selector.
insertBeforeId(id)
- Same as
insertBefore(document.getElementById(id)).
insertAfter(element or selector)
- Inserts
node() after element or every element matched by the CSS selector.
insertAfterId(id)
- Same as
insertAfter(document.getElementById(id)).
The following are examples of using the toolkit:
var img = <img
src={prompt("Enter an image URI")}
longdesc={prompt("Describe the image")}
id="foobar"
/>;
img.@alt = img.@longdesc;
img.appendTo(document.body);
<h1>The image was <em>removed</em>.</em>.overId("foobar");
<![CDATA[And then this text node filled the header]]>.fill("#foobar");
// the CDATA isn't itself put into the document but the data inside it is escaped so it
// works in HTML and XHTML
<h1><![CDATA[<html> in here is <escaped>]]></h1>.insertBefore(document.body.firstChild);
// if you just want to create an element quickly, do xml.node()
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100"/>.node(); // SVG node
<div/>.node(); // div node
// DOM methods are forwarded to .node()[method]()
<canvas/>.getContext("2d");
<foo bar="baz"/>.getAttribute("bar") === "baz"; // same as getting .@bar
// mass-modifications with CSS selectors
<strong>Absolute links are <em>not</em> allowed</strong>
.over('a[href^="http://"], a[href^="https://"], a[href^="//"]');
if (user.hasEditPrivileges) {
// wikipedia-style "put an edit link at the start of each section"
<a href={"/edit?page=" + page.id}>[edit]</a>.insertAfter('h2');
}
// <![CDATA[]]> nodes directly accessed are converted to text nodes:
<![CDATA[
This is a text node.
<html> is escaped inside it.
]]>.appendTo("#some-element");