Permalink
Cannot retrieve contributors at this time
Fetching contributors…

/** | |
* @license | |
* Copyright (C) 2013 Google Inc. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
/** | |
* @fileoverview | |
* <div style="white-space: pre"> | |
* Looks at query parameters to decide which language handlers and style-sheets | |
* to load. | |
* | |
* Query Parameter Format Effect Default | |
* +------------------+---------------+------------------------------+--------+ | |
* | autorun= | true | false | If true then prettyPrint() | "true" | | |
* | | | is called on page load. | | | |
* +------------------+---------------+------------------------------+--------+ | |
* | lang= | language name | Loads the language handler | Can | | |
* | | | named "lang-<NAME>.js". | appear | | |
* | | | See available handlers at | many | | |
* | | | https://github.com/google/ | times. | | |
* | | | code-prettify/tree/master/ | | | |
* | | | src | | | |
* +------------------+---------------+------------------------------+--------+ | |
* | skin= | skin name | Loads the skin stylesheet | none. | | |
* | | | named "<NAME>.css". | | | |
* | | | https://cdn.rawgit.com/ | | | |
* | | | google/code-prettify/master/ | | | |
* | | | styles/index.html | | | |
* +------------------+---------------+------------------------------+--------+ | |
* | callback= | JS identifier | When "prettyPrint" finishes | none | | |
* | | | window.exports[js_ident] is | | | |
* | | | called. | | | |
* | | | The callback must be under | | | |
* | | | exports to reduce the risk | | | |
* | | | of XSS via query parameter | | | |
* | | | injection. | | | |
* +------------------+---------------+------------------------------+--------+ | |
* | |
* Exmaples | |
* .../prettify.js?lang=css&skin=sunburst | |
* 1. Loads the CSS language handler which can be used to prettify CSS | |
* stylesheets, HTML <style> element bodies and style="..." attributes | |
* values. | |
* 2. Loads the sunburst.css stylesheet instead of the default prettify.css | |
* stylesheet. | |
* A gallery of stylesheets is available at | |
* https://cdn.rawgit.com/google/code-prettify/master/styles/index.html | |
* 3. Since autorun=false is not specified, calls prettyPrint() on page load. | |
* </div> | |
*/ | |
(function () { | |
"use strict"; | |
var win = window; | |
var doc = document; | |
var root = doc.documentElement; | |
var head = doc['head'] || doc.getElementsByTagName("head")[0] || root; | |
// From http://javascript.nwbox.com/ContentLoaded/contentloaded.js | |
// Author: Diego Perini (diego.perini at gmail.com) | |
// Summary: cross-browser wrapper for DOMContentLoaded | |
// Updated: 20101020 | |
// License: MIT | |
// Version: 1.2 | |
function contentLoaded(callback) { | |
var addEventListener = doc['addEventListener']; | |
var done = false, top = true, | |
add = addEventListener ? 'addEventListener' : 'attachEvent', | |
rem = addEventListener ? 'removeEventListener' : 'detachEvent', | |
pre = addEventListener ? '' : 'on', | |
init = function(e) { | |
if (e.type == 'readystatechange' && doc.readyState != 'complete') { | |
return; | |
} | |
(e.type == 'load' ? win : doc)[rem](pre + e.type, init, false); | |
if (!done && (done = true)) { callback.call(win, e.type || e); } | |
}, | |
poll = function() { | |
try { | |
root.doScroll('left'); | |
} catch(e) { | |
win.setTimeout(poll, 50); | |
return; | |
} | |
init('poll'); | |
}; | |
if (doc.readyState == 'complete') { | |
callback.call(win, 'lazy'); | |
} else { | |
if (doc.createEventObject && root.doScroll) { | |
try { top = !win.frameElement; } catch(e) { } | |
if (top) { poll(); } | |
} | |
doc[add](pre + 'DOMContentLoaded', init, false); | |
doc[add](pre + 'readystatechange', init, false); | |
win[add](pre + 'load', init, false); | |
} | |
} | |
// Given a list of URLs to stylesheets, loads the first that loads without | |
// triggering an error event. | |
function loadStylesheetsFallingBack(stylesheets) { | |
var n = stylesheets.length; | |
function load(i) { | |
if (i === n) { return; } | |
var link = doc.createElement('link'); | |
link.rel = 'stylesheet'; | |
link.type = 'text/css'; | |
if (i + 1 < n) { | |
// http://pieisgood.org/test/script-link-events/ indicates that many | |
// versions of IE do not support onerror on <link>s, though | |
// http://msdn.microsoft.com/en-us/library/ie/ms535848(v=vs.85).aspx | |
// indicates that recent IEs do support error. | |
link.error = link.onerror = function () { load(i + 1); }; | |
} | |
link.href = stylesheets[i]; | |
head.appendChild(link); | |
} | |
load(0); | |
} | |
var scriptQuery = ''; | |
// Look for the <script> node that loads this script to get its parameters. | |
// This starts looking at the end instead of just considering the last | |
// because deferred and async scripts run out of order. | |
// If the script is loaded twice, then this will run in reverse order. | |
var scripts = doc.getElementsByTagName('script'); | |
for (var i = scripts.length; --i >= 0;) { | |
var script = scripts[i]; | |
var match = script.src.match( | |
/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/); | |
if (match) { | |
scriptQuery = match[1] || ''; | |
// Remove the script from the DOM so that multiple runs at least run | |
// multiple times even if parameter sets are interpreted in reverse | |
// order. | |
script.parentNode.removeChild(script); | |
break; | |
} | |
} | |
// Pull parameters into local variables. | |
var autorun = true; | |
var langs = []; | |
var skins = []; | |
var callbacks = []; | |
scriptQuery.replace( | |
/[?&]([^&=]+)=([^&]+)/g, | |
function (_, name, value) { | |
value = decodeURIComponent(value); | |
name = decodeURIComponent(name); | |
if (name == 'autorun') { autorun = !/^[0fn]/i.test(value); } else | |
if (name == 'lang') { langs.push(value); } else | |
if (name == 'skin') { skins.push(value); } else | |
if (name == 'callback') { callbacks.push(value); } | |
}); | |
// Use https to avoid mixed content warnings in client pages and to | |
// prevent a MITM from rewrite prettify mid-flight. | |
// This only works if this script is loaded via https : something | |
// over which we exercise no control. | |
var LOADER_BASE_URL = | |
'https://cdn.rawgit.com/google/code-prettify/master/loader'; | |
for (var i = 0, n = langs.length; i < n; ++i) (function (lang) { | |
var script = doc.createElement("script"); | |
// Excerpted from jQuery.ajaxTransport("script") to fire events when | |
// a script is finished loading. | |
// Attach handlers for each script | |
script.onload = script.onerror = script.onreadystatechange = function () { | |
if (script && ( | |
!script.readyState || /loaded|complete/.test(script.readyState))) { | |
// Handle memory leak in IE | |
script.onerror = script.onload = script.onreadystatechange = null; | |
--pendingLanguages; | |
checkPendingLanguages(); | |
// Remove the script | |
if (script.parentNode) { | |
script.parentNode.removeChild(script); | |
} | |
script = null; | |
} | |
}; | |
script.type = 'text/javascript'; | |
script.src = LOADER_BASE_URL | |
+ '/lang-' + encodeURIComponent(langs[i]) + '.js'; | |
// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending | |
head.insertBefore(script, head.firstChild); | |
})(langs[i]); | |
var pendingLanguages = langs.length; | |
function checkPendingLanguages() { | |
if (!pendingLanguages) { | |
win.setTimeout(onLangsLoaded, 0); | |
} | |
} | |
var skinUrls = []; | |
for (var i = 0, n = skins.length; i < n; ++i) { | |
skinUrls.push(LOADER_BASE_URL | |
+ '/skins/' + encodeURIComponent(skins[i]) + '.css'); | |
} | |
skinUrls.push(LOADER_BASE_URL + '/prettify.css'); | |
loadStylesheetsFallingBack(skinUrls); | |
var prettyPrint = (function () { | |
include("prettify.js"); | |
return prettyPrint; | |
})(); | |
// If this script is deferred or async and the document is already | |
// loaded we need to wait for language handlers to load before performing | |
// any autorun. | |
function onLangsLoaded() { | |
if (autorun) { | |
contentLoaded( | |
function () { | |
var n = callbacks.length; | |
var callback = n ? function () { | |
for (var i = 0; i < n; ++i) { | |
(function (i) { | |
win.setTimeout( | |
function () { | |
win['exports'][callbacks[i]].apply(win, arguments); | |
}, 0); | |
})(i); | |
} | |
} : void 0; | |
prettyPrint(callback); | |
}); | |
} | |
} | |
checkPendingLanguages(); | |
}()); |