2
This file is part of the "jQuery.Syntax" project, and is distributed under the MIT License.
3
For more information, please see http://www.oriontransfer.co.nz/software/jquery-syntax
5
Copyright (c) 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
7
Permission is hereby granted, free of charge, to any person obtaining a copy
8
of this software and associated documentation files (the "Software"), to deal
9
in the Software without restriction, including without limitation the rights
10
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11
copies of the Software, and to permit persons to whom the Software is
12
furnished to do so, subject to the following conditions:
14
The above copyright notice and this permission notice shall be included in
15
all copies or substantial portions of the Software.
17
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
26
/*global Function: true, ResourceLoader: true, Syntax: true, alert: false, jQuery: true */
28
// ECMAScript 5! Why wasn't this done before!?
29
if (!Function.prototype.bind) {
30
Function.prototype.bind = function (target) {
31
var args = Array.prototype.slice.call(arguments, 1), fn = this;
34
return fn.apply(target, args);
39
function ResourceLoader (loader) {
40
this.dependencies = {};
45
ResourceLoader.prototype._finish = function (name) {
46
var deps = this.dependencies[name];
49
// I'm not sure if this makes me want to cry... or laugh... or kill!?
50
var chain = this._loaded.bind(this, name);
52
for (var i = 0; i < deps.length; i += 1) {
53
chain = this.get.bind(this, deps[i], chain);
62
ResourceLoader.prototype._loaded = function (name) {
63
// When the script has been succesfully loaded, we expect the script
64
// to register with this loader (i.e. this[name]).
65
var resource = this[name], loading = this.loading[name];
67
// Clear the loading list
68
this.loading[name] = null;
71
alert("ResourceLoader: Could not load resource named " + name);
73
for (var i = 0; i < loading.length; i += 1) {
79
// This function must ensure that current cannot be completely loaded until next
80
// is completely loaded.
81
ResourceLoader.prototype.dependency = function (current, next) {
82
// If the resource has completely loaded, then we don't need to queue it
84
if (this[next] && !this.loading[name]) {
88
if (this.dependencies[current]) {
89
this.dependencies[current].push(next);
91
this.dependencies[current] = [next];
95
// This function must be reentrant for the same name and different callbacks.
96
ResourceLoader.prototype.get = function (name, callback) {
97
if (this.loading[name]) {
98
this.loading[name].push(callback)
99
} else if (this[name]) {
100
callback(this[name]);
102
this.loading[name] = [callback];
103
this.loader(name, this._finish.bind(this, name));
115
cacheStyleSheets: true,
119
brushes: new ResourceLoader(function (name, callback) {
120
name = Syntax.aliases[name] || name;
122
Syntax.getResource('jquery.syntax.brush', name, callback);
125
layouts: new ResourceLoader(function (name, callback) {
126
Syntax.getResource('jquery.syntax.layout', name, callback);
129
loader: new ResourceLoader(function (name, callback) {
130
Syntax.getResource('jquery.syntax', name, callback);
133
getStyles: function (path) {
134
var link = jQuery('<link>');
135
jQuery("head").append(link);
137
if (!Syntax.defaultOptions.cacheStyleSheets) {
138
path = path + "?" + Math.random()
148
getScript: function (path, callback) {
149
var script = document.createElement('script');
152
script.onreadystatechange = function() {
153
if (this.onload && (this.readyState == 'loaded' || this.readyState == 'complete')) {
156
// Ensure the function is only called once.
161
// Every other modern browser
162
script.onload = callback;
163
script.type = "text/javascript";
165
if (!Syntax.defaultOptions.cacheScripts)
166
path = path + '?' + Math.random()
170
document.getElementsByTagName('head')[0].appendChild(script);
173
getResource: function (prefix, name, callback) {
174
var basename = prefix + "." + name;
175
var styles = this.styles[basename];
178
for (var i = 0; i < styles.length; i += 1) {
179
this.getStyles(this.root + styles[i]);
183
Syntax.getScript(this.root + basename + '.js', callback);
186
alias: function (name, aliases) {
187
Syntax.aliases[name] = name;
189
for (var i = 0; i < aliases.length; i += 1) {
190
Syntax.aliases[aliases[i]] = name;
194
brushAliases: function (brush) {
197
for (var name in Syntax.aliases) {
198
if (Syntax.aliases[name] === brush) {
206
brushNames: function () {
209
for (var name in Syntax.aliases) {
210
if (name === Syntax.aliases[name]) {
218
extractBrushName: function (className) {
219
// brush names are by default lower case - normalize so we can detect it.
220
className = className.toLowerCase();
222
var match = className.match(/brush-([\S]+)/);
227
var classes = className.split(/ /);
229
if (jQuery.inArray("syntax", classes) !== -1) {
230
for (var i = 0; i < classes.length; i += 1) {
231
var name = Syntax.aliases[classes[i]];
243
detectRoot: function () {
244
if (Syntax.root == null) {
245
// Initialize root based on current script path.
246
var scripts = jQuery('script').filter(function(){
247
return this.src.match(/jquery\.syntax/);
250
var first = scripts.get(0);
253
// Calculate the basename for the given script src.
254
var root = first.src.match(/.*\//);
257
Syntax.root = root[0];
264
if (typeof(console) != "undefined" && console.log) {
265
console.log.apply(console, arguments);
266
} else if (window.console && window.console.log) {
267
window.console.log.apply(window.console, arguments);
272
jQuery.fn.syntax = function (options, callback) {
277
Syntax.loader.get('core', function () {
278
Syntax.highlight(elements, options, callback);
282
jQuery.syntax = function (options, callback) {
283
options = options || {};
284
var context = options.context;
287
Syntax.root = options.root;
292
options = jQuery.extend(Syntax.defaultOptions, options)
294
options.blockSelector = options.blockSelector || 'pre.syntax:not(.highlighted)';
295
options.inlineSelector = options.inlineSelector || 'code.syntax:not(.highlighted)';
297
options.blockLayout = options.blockLayout || 'list';
298
options.inlineLayout = options.inlineLayout || 'inline';
300
// Allow the user to specify callbacks without replacement.
301
if (typeof options.replace == "undefined")
302
options.replace = true;
304
jQuery(options.blockSelector, context).each(function () {
305
jQuery(this).syntax(jQuery.extend({}, options, {
306
brush: Syntax.extractBrushName(this.className),
307
layout: options.blockLayout
311
jQuery(options.inlineSelector, context).each(function () {
312
jQuery(this).syntax(jQuery.extend({}, options, {
313
brush: Syntax.extractBrushName(this.className),
314
layout: options.inlineLayout