Last active
December 26, 2015 12:49
-
-
Save rhwood/7154062 to your computer and use it in GitHub Desktop.
Javascript to display Gist in tumblr that specifies an individual file. The Gist URLs for single files need to be slightly different than the per-file permalink. It needs to be in the form https://gist.github.com/{gistId}?file={filename}#file-{filename-with-dashes-for-dots}
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$(document).ready(function() { | |
$('.gist').each(function(i) { | |
var gistUrl = $(this).text(); | |
var fileStart = gistUrl.indexOf('?'); | |
if (fileStart != -1) { | |
var file = gistUrl.substring(fileStart + 1); | |
var fileEnd = file.indexOf('#'); | |
if (fileEnd != -1) { | |
file = file.substring(0, fileEnd); | |
} | |
gistUrl = gistUrl.substring(0, fileStart) + '.js?' + file; | |
} else { | |
gistUrl = gistUrl + '.js'; | |
} | |
writeCapture.html(this, '<script src="' + gistUrl + '"></script>'); | |
}); | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* writeCapture.js v1.0.5 | |
* | |
* @author noah <[email protected]> | |
* | |
*/ | |
(function($,global) { | |
var doc = global.document; | |
function doEvil(code) { | |
var div = doc.createElement('div'); | |
doc.body.insertBefore(div,null); | |
$.replaceWith(div,'<script type="text/javascript">'+code+'</script>'); | |
} | |
// ensure we have our support functions | |
$ = $ || (function(jQuery) { | |
/** | |
* @name writeCaptureSupport | |
* | |
* The support functions writeCapture needs. | |
*/ | |
return { | |
/** | |
* Takes an options parameter that must support the following: | |
* { | |
* url: url, | |
* type: 'GET', // all requests are GET | |
* dataType: "script", // it this is set to script, script tag injection is expected, otherwise, treat as plain text | |
* async: true/false, // local scripts are loaded synchronously by default | |
* success: callback(text,status), // must not pass a truthy 3rd parameter | |
* error: callback(xhr,status,error) // must pass truthy 3rd parameter to indicate error | |
* } | |
*/ | |
ajax: jQuery.ajax, | |
/** | |
* @param {String Element} selector an Element or selector | |
* @return {Element} the first element matching selector | |
*/ | |
$: function(s) { return jQuery(s)[0]; }, | |
/** | |
* @param {String jQuery Element} selector the element to replace. | |
* writeCapture only needs the first matched element to be replaced. | |
* @param {String} content the content to replace | |
* the matched element with. script tags must be evaluated/loaded | |
* and executed if present. | |
*/ | |
replaceWith: function(selector,content) { | |
// jQuery 1.4? has a bug in replaceWith so we can't use it directly | |
var el = jQuery(selector)[0]; | |
var next = el.nextSibling, parent = el.parentNode; | |
jQuery(el).remove(); | |
if ( next ) { | |
jQuery(next).before( content ); | |
} else { | |
jQuery(parent).append( content ); | |
} | |
}, | |
onLoad: function(fn) { | |
jQuery(fn); | |
}, | |
copyAttrs: function(src,dest) { | |
var el = jQuery(dest), attrs = src.attributes; | |
for (var i = 0, len = attrs.length; i < len; i++) { | |
if(attrs[i] && attrs[i].value) { | |
try { | |
el.attr(attrs[i].name,attrs[i].value); | |
} catch(e) { } | |
} | |
} | |
} | |
}; | |
})(global.jQuery); | |
$.copyAttrs = $.copyAttrs || function() {}; | |
$.onLoad = $.onLoad || function() { | |
throw "error: autoAsync cannot be used without jQuery " + | |
"or defining writeCaptureSupport.onLoad"; | |
}; | |
// utilities | |
function each(array,fn) { | |
for(var i =0, len = array.length; i < len; i++) { | |
if( fn(array[i]) === false) return; | |
} | |
} | |
function isFunction(o) { | |
return Object.prototype.toString.call(o) === "[object Function]"; | |
} | |
function isString(o) { | |
return Object.prototype.toString.call(o) === "[object String]"; | |
} | |
function slice(array,start,end) { | |
return Array.prototype.slice.call(array,start || 0,end || array && array.length); | |
} | |
function any(array,fn) { | |
var result = false; | |
each(array,check); | |
function check(it) { | |
return !(result = fn(it)); | |
} | |
return result; | |
} | |
function SubQ(parent) { | |
this._queue = []; | |
this._children = []; | |
this._parent = parent; | |
if(parent) parent._addChild(this); | |
} | |
SubQ.prototype = { | |
_addChild: function(q) { | |
this._children.push(q); | |
}, | |
push: function (task) { | |
this._queue.push(task); | |
this._bubble('_doRun'); | |
}, | |
pause: function() { | |
this._bubble('_doPause'); | |
}, | |
resume: function() { | |
this._bubble('_doResume'); | |
}, | |
_bubble: function(name) { | |
var root = this; | |
while(!root[name]) { | |
root = root._parent; | |
} | |
return root[name](); | |
}, | |
_next: function() { | |
if(any(this._children,runNext)) return true; | |
function runNext(c) { | |
return c._next(); | |
} | |
var task = this._queue.shift(); | |
if(task) { | |
task(); | |
} | |
return !!task; | |
} | |
}; | |
/** | |
* Provides a task queue for ensuring that scripts are run in order. | |
* | |
* The only public methods are push, pause and resume. | |
*/ | |
function Q(parent) { | |
if(parent) { | |
return new SubQ(parent); | |
} | |
SubQ.call(this); | |
this.paused = 0; | |
} | |
Q.prototype = (function() { | |
function f() {} | |
f.prototype = SubQ.prototype; | |
return new f(); | |
})(); | |
Q.prototype._doRun = function() { | |
if(!this.running) { | |
this.running = true; | |
try { | |
// just in case there is a bug, always resume | |
// if paused is less than 1 | |
while(this.paused < 1 && this._next()){} | |
} finally { | |
this.running = false; | |
} | |
} | |
}; | |
Q.prototype._doPause= function() { | |
this.paused++; | |
}; | |
Q.prototype._doResume = function() { | |
this.paused--; | |
this._doRun(); | |
}; | |
// TODO unit tests... | |
function MockDocument() { } | |
MockDocument.prototype = { | |
_html: '', | |
open: function( ) { | |
this._opened = true; | |
if(this._delegate) { | |
this._delegate.open(); | |
} | |
}, | |
write: function(s) { | |
if(this._closed) return; | |
this._written = true; | |
if(this._delegate) { | |
this._delegate.write(s); | |
} else { | |
this._html += s; | |
} | |
}, | |
writeln: function(s) { | |
this.write(s + '\n'); | |
}, | |
close: function( ) { | |
this._closed = true; | |
if(this._delegate) { | |
this._delegate.close(); | |
} | |
}, | |
copyTo: function(d) { | |
this._delegate = d; | |
d.foobar = true; | |
if(this._opened) { | |
d.open(); | |
} | |
if(this._written) { | |
d.write(this._html); | |
} | |
if(this._closed) { | |
d.close(); | |
} | |
} | |
}; | |
// test for IE 6/7 issue (issue 6) that prevents us from using call | |
var canCall = (function() { | |
var f = { f: doc.getElementById }; | |
try { | |
f.f.call(doc,'abc'); | |
return true; | |
} catch(e) { | |
return false; | |
} | |
})(); | |
function unProxy(elements) { | |
each(elements,function(it) { | |
var real = doc.getElementById(it.id); | |
if(!real) { | |
logError('<proxyGetElementById - finish>', | |
'no element in writen markup with id ' + it.id); | |
return; | |
} | |
each(it.el.childNodes,function(it) { | |
real.appendChild(it); | |
}); | |
if(real.contentWindow) { | |
// TODO why is the setTimeout necessary? | |
global.setTimeout(function() { | |
it.el.contentWindow.document. | |
copyTo(real.contentWindow.document); | |
},1); | |
} | |
$.copyAttrs(it.el,real); | |
}); | |
} | |
function getOption(name,options) { | |
if(options && options[name] === false) { | |
return false; | |
} | |
return options && options[name] || self[name]; | |
} | |
function capture(context,options) { | |
var tempEls = [], | |
proxy = getOption('proxyGetElementById',options), | |
forceLast = getOption('forceLastScriptTag',options), | |
writeOnGet = getOption('writeOnGetElementById',options), | |
immediate = getOption('immediateWrites', options), | |
state = { | |
write: doc.write, | |
writeln: doc.writeln, | |
finish: function() {}, | |
out: '' | |
}; | |
context.state = state; | |
doc.write = immediate ? immediateWrite : replacementWrite; | |
doc.writeln = immediate ? immediateWriteln : replacementWriteln; | |
if(proxy || writeOnGet) { | |
state.getEl = doc.getElementById; | |
doc.getElementById = getEl; | |
if(writeOnGet) { | |
findEl = writeThenGet; | |
} else { | |
findEl = makeTemp; | |
state.finish = function() { | |
unProxy(tempEls); | |
}; | |
} | |
} | |
if(forceLast) { | |
state.getByTag = doc.getElementsByTagName; | |
doc.getElementsByTagName = function(name) { | |
var result = slice(canCall ? state.getByTag.call(doc,name) : | |
state.getByTag(name)); | |
if(name === 'script') { | |
result.push( $.$(context.target) ); | |
} | |
return result; | |
}; | |
var f = state.finish; | |
state.finish = function() { | |
f(); | |
doc.getElementsByTagName = state.getByTag; | |
}; | |
} | |
function replacementWrite(s) { | |
state.out += s; | |
} | |
function replacementWriteln(s) { | |
state.out += s + '\n'; | |
} | |
function immediateWrite(s) { | |
var target = $.$(context.target); | |
var div = doc.createElement('div'); | |
target.parentNode.insertBefore(div,target); | |
$.replaceWith(div,sanitize(s)); | |
} | |
function immediateWriteln(s) { | |
var target = $.$(context.target); | |
var div = doc.createElement('div'); | |
target.parentNode.insertBefore(div,target); | |
$.replaceWith(div,sanitize(s) + '\n'); | |
} | |
function makeTemp(id) { | |
var t = doc.createElement('div'); | |
tempEls.push({id:id,el:t}); | |
// mock contentWindow in case it's supposed to be an iframe | |
t.contentWindow = { document: new MockDocument() }; | |
return t; | |
} | |
function writeThenGet(id) { | |
var target = $.$(context.target); | |
var div = doc.createElement('div'); | |
target.parentNode.insertBefore(div,target); | |
$.replaceWith(div,state.out); | |
state.out = ''; | |
return canCall ? state.getEl.call(doc,id) : | |
state.getEl(id); | |
} | |
function getEl(id) { | |
var result = canCall ? state.getEl.call(doc,id) : | |
state.getEl(id); | |
return result || findEl(id); | |
} | |
return state; | |
} | |
function uncapture(state) { | |
doc.write = state.write; | |
doc.writeln = state.writeln; | |
if(state.getEl) { | |
doc.getElementById = state.getEl; | |
} | |
return state.out; | |
} | |
function clean(code) { | |
// IE will execute inline scripts with <!-- (uncommented) on the first | |
// line, but will not eval() them happily | |
return code && code.replace(/^\s*<!(\[CDATA\[|--)/,'').replace(/(\]\]|--)>\s*$/,''); | |
} | |
function ignore() {} | |
function doLog(code,error) { | |
console.error("Error",error,"executing code:",code); | |
} | |
var logError = isFunction(global.console && console.error) ? | |
doLog : ignore; | |
function captureWrite(code,context,options) { | |
var state = capture(context,options); | |
try { | |
doEvil(clean(code)); | |
} catch(e) { | |
logError(code,e); | |
} finally { | |
uncapture(state); | |
} | |
return state; | |
} | |
// copied from jQuery | |
function isXDomain(src) { | |
var parts = /^(\w+:)?\/\/([^\/?#]+)/.exec(src); | |
return parts && ( parts[1] && parts[1] != location.protocol || parts[2] != location.host ); | |
} | |
function attrPattern(name) { | |
return new RegExp('[\\s\\r\\n]'+name+'[\\s\\r\\n]*=[\\s\\r\\n]*(?:(["\'])([\\s\\S]*?)\\1|([^\\s>]+))','i'); | |
} | |
function matchAttr(name) { | |
var regex = attrPattern(name); | |
return function(tag) { | |
var match = regex.exec(tag) || []; | |
return match[2] || match[3]; | |
}; | |
} | |
var SCRIPT_TAGS = /(<script[^>]*>)([\s\S]*?)<\/script>/ig, | |
SCRIPT_2 = /<script[^>]*\/>/ig, | |
SRC_REGEX = attrPattern('src'), | |
SRC_ATTR = matchAttr('src'), | |
TYPE_ATTR = matchAttr('type'), | |
LANG_ATTR = matchAttr('language'), | |
GLOBAL = "__document_write_ajax_callbacks__", | |
DIV_PREFIX = "__document_write_ajax_div-", | |
TEMPLATE = "window['"+GLOBAL+"']['%d']();", | |
callbacks = global[GLOBAL] = {}, | |
TEMPLATE_TAG = '<script type="text/javascript">' + TEMPLATE + '</script>', | |
global_id = 0; | |
function nextId() { | |
return (++global_id).toString(); | |
} | |
function normalizeOptions(options,callback) { | |
var done; | |
if(isFunction(options)) { | |
done = options; | |
options = null; | |
} | |
options = options || {}; | |
done = done || options && options.done; | |
options.done = callback ? function() { | |
callback(done); | |
} : done; | |
return options; | |
} | |
// The global Q synchronizes all sanitize operations. | |
// The only time this synchronization is really necessary is when two or | |
// more consecutive sanitize operations make async requests. e.g., | |
// sanitize call A requests foo, then sanitize B is called and bar is | |
// requested. document.write was replaced by B, so if A returns first, the | |
// content will be captured by B, then when B returns, document.write will | |
// be the original document.write, probably messing up the page. At the | |
// very least, A will get nothing and B will get the wrong content. | |
var GLOBAL_Q = new Q(); | |
var debug = []; | |
var logDebug = window._debugWriteCapture ? function() {} : | |
function (type,src,data) { | |
debug.push({type:type,src:src,data:data}); | |
}; | |
var logString = window._debugWriteCapture ? function() {} : | |
function () { | |
debug.push(arguments); | |
}; | |
function newCallback(fn) { | |
var id = nextId(); | |
callbacks[id] = function() { | |
fn(); | |
delete callbacks[id]; | |
}; | |
return id; | |
} | |
function newCallbackTag(fn) { | |
return TEMPLATE_TAG.replace(/%d/,newCallback(fn)); | |
} | |
/** | |
* Sanitize the given HTML so that the scripts will execute with a modified | |
* document.write that will capture the output and append it in the | |
* appropriate location. | |
* | |
* @param {String} html | |
* @param {Object Function} [options] | |
* @param {Function} [options.done] Called when all the scripts in the | |
* sanitized HTML have run. | |
* @param {boolean} [options.asyncAll] If true, scripts loaded from the | |
* same domain will be loaded asynchronously. This can improve UI | |
* responsiveness, but will delay completion of the scripts and may | |
* cause problems with some scripts, so it defaults to false. | |
*/ | |
function sanitize(html,options,parentQ,parentContext) { | |
// each HTML fragment has it's own queue | |
var queue = parentQ && new Q(parentQ) || GLOBAL_Q; | |
options = normalizeOptions(options); | |
var done = getOption('done',options); | |
var doneHtml = ''; | |
var fixUrls = getOption('fixUrls',options); | |
if(!isFunction(fixUrls)) { | |
fixUrls = function(src) { return src; }; | |
} | |
// if a done callback is passed, append a script to call it | |
if(isFunction(done)) { | |
// no need to proxy the call to done, so we can append this to the | |
// filtered HTML | |
doneHtml = newCallbackTag(function() { | |
queue.push(done); | |
}); | |
} | |
// for each tag, generate a function to load and eval the code and queue | |
// themselves | |
return html.replace(SCRIPT_TAGS,proxyTag).replace(SCRIPT_2,proxyBodyless) + doneHtml; | |
function proxyBodyless(tag) { | |
// hack in a bodyless tag... | |
return proxyTag(tag,tag.substring(0,tag.length-2)+'>',''); | |
} | |
function proxyTag(element,openTag,code) { | |
var src = SRC_ATTR(openTag), | |
type = TYPE_ATTR(openTag) || '', | |
lang = LANG_ATTR(openTag) || '', | |
isJs = (!type && !lang) || // no type or lang assumes JS | |
type.toLowerCase().indexOf('javascript') !== -1 || | |
lang.toLowerCase().indexOf('javascript') !== -1; | |
logDebug('replace',src,element); | |
if(!isJs) { | |
return element; | |
} | |
var id = newCallback(queueScript), divId = DIV_PREFIX + id, | |
run, context = { target: '#' + divId, parent: parentContext }; | |
function queueScript() { | |
queue.push(run); | |
} | |
if(src) { | |
// fix for the inline script that writes a script tag with encoded | |
// ampersands hack (more comon than you'd think) | |
src = fixUrls(src); | |
openTag = openTag.replace(SRC_REGEX,''); | |
if(isXDomain(src)) { | |
// will load async via script tag injection (eval()'d on | |
// it's own) | |
run = loadXDomain; | |
} else { | |
// can be loaded then eval()d | |
if(getOption('asyncAll',options)) { | |
run = loadAsync(); | |
} else { | |
run = loadSync; | |
} | |
} | |
} else { | |
// just eval code and be done | |
run = runInline; | |
} | |
function runInline() { | |
captureHtml(code); | |
} | |
function loadSync() { | |
$.ajax({ | |
url: src, | |
type: 'GET', | |
dataType: 'text', | |
async: false, | |
success: function(html) { | |
captureHtml(html); | |
} | |
}); | |
} | |
function logAjaxError(xhr,status,error) { | |
logError("<XHR for "+src+">",error); | |
queue.resume(); | |
} | |
function setupResume() { | |
return newCallbackTag(function() { | |
queue.resume(); | |
}); | |
} | |
function loadAsync() { | |
var ready, scriptText; | |
function captureAndResume(script,status) { | |
if(!ready) { | |
// loaded before queue run, cache text | |
scriptText = script; | |
return; | |
} | |
try { | |
captureHtml(script, setupResume()); | |
} catch(e) { | |
logError(script,e); | |
} | |
} | |
// start loading the text | |
$.ajax({ | |
url: src, | |
type: 'GET', | |
dataType: 'text', | |
async: true, | |
success: captureAndResume, | |
error: logAjaxError | |
}); | |
return function() { | |
ready = true; | |
if(scriptText) { | |
// already loaded, so don't pause the queue and don't resume! | |
captureHtml(scriptText); | |
} else { | |
queue.pause(); | |
} | |
}; | |
} | |
function loadXDomain(cb) { | |
var state = capture(context,options); | |
queue.pause(); // pause the queue while the script loads | |
logDebug('pause',src); | |
doXDomainLoad(context.target,src,captureAndResume); | |
function captureAndResume(xhr,st,error) { | |
logDebug('out', src, state.out); | |
html(uncapture(state), | |
newCallbackTag(state.finish) + setupResume()); | |
logDebug('resume',src); | |
} | |
} | |
function captureHtml(script, cb) { | |
var state = captureWrite(script,context,options); | |
cb = newCallbackTag(state.finish) + (cb || ''); | |
html(state.out,cb); | |
} | |
function safeOpts(options) { | |
var copy = {}; | |
for(var i in options) { | |
if(options.hasOwnProperty(i)) { | |
copy[i] = options[i]; | |
} | |
} | |
delete copy.done; | |
return copy; | |
} | |
function html(markup,cb) { | |
$.replaceWith(context.target,sanitize(markup,safeOpts(options),queue,context) + (cb || '')); | |
} | |
return '<div style="display: none" id="'+divId+'"></div>' + openTag + | |
TEMPLATE.replace(/%d/,id) + '</script>'; | |
} | |
} | |
function doXDomainLoad(target,url,success) { | |
// TODO what about scripts that fail to load? bad url, etc.? | |
var script = document.createElement("script"); | |
script.src = url; | |
target = $.$(target); | |
var done = false, parent = target.parentNode; | |
// Attach handlers for all browsers | |
script.onload = script.onreadystatechange = function(){ | |
if ( !done && (!this.readyState || | |
this.readyState == "loaded" || this.readyState == "complete") ) { | |
done = true; | |
success(); | |
// Handle memory leak in IE | |
script.onload = script.onreadystatechange = null; | |
parent.removeChild( script ); | |
} | |
}; | |
parent.insertBefore(script,target); | |
} | |
/** | |
* Sanitizes all the given fragments and calls action with the HTML. | |
* The next fragment is not started until the previous fragment | |
* has executed completely. | |
* | |
* @param {Array} fragments array of objects like this: | |
* { | |
* html: '<p>My html with a <script...', | |
* action: function(safeHtml,frag) { doSomethingToInject(safeHtml); }, | |
* options: {} // optional, see #sanitize | |
* } | |
* Where frag is the object. | |
* | |
* @param {Function} [done] Optional. Called when all fragments are done. | |
*/ | |
function sanitizeSerial(fragments,done) { | |
// create a queue for these fragments and make it the parent of each | |
// sanitize call | |
var queue = GLOBAL_Q; | |
each(fragments, function (f) { | |
queue.push(run); | |
function run() { | |
f.action(sanitize(f.html,f.options,queue),f); | |
} | |
}); | |
if(done) { | |
queue.push(done); | |
} | |
} | |
function findLastChild(el) { | |
var n = el; | |
while(n && n.nodeType === 1) { | |
el = n; | |
n = n.lastChild; | |
// last child may not be an element | |
while(n && n.nodeType !== 1) { | |
n = n.previousSibling; | |
} | |
} | |
return el; | |
} | |
/** | |
* Experimental - automatically captures document.write calls and | |
* defers them untill after page load. | |
* @param {Function} [done] optional callback for when all the | |
* captured content has been loaded. | |
*/ | |
function autoCapture(done) { | |
var write = doc.write, | |
writeln = doc.writeln, | |
currentScript, | |
autoQ = []; | |
doc.writeln = function(s) { | |
doc.write(s+'\n'); | |
}; | |
var state; | |
doc.write = function(s) { | |
var scriptEl = findLastChild(doc.body); | |
if(scriptEl !== currentScript) { | |
currentScript = scriptEl; | |
autoQ.push(state = { | |
el: scriptEl, | |
out: [] | |
}); | |
} | |
state.out.push(s); | |
}; | |
$.onLoad(function() { | |
// for each script, append a div immediately after it, | |
// then replace the div with the sanitized output | |
var el, div, out, safe, doneFn; | |
done = normalizeOptions(done); | |
doneFn = done.done; | |
done.done = function() { | |
doc.write = write; | |
doc.writeln = writeln; | |
if(doneFn) doneFn(); | |
}; | |
for(var i = 0, len = autoQ.length; i < len; i++ ) { | |
el = autoQ[i].el; | |
div = doc.createElement('div'); | |
el.parentNode.insertBefore( div, el.nextSibling ); | |
out = autoQ[i].out.join(''); | |
// only the last snippet gets passed the callback | |
safe = len - i === 1 ? sanitize(out,done) : sanitize(out); | |
$.replaceWith(div,safe); | |
} | |
}); | |
} | |
function extsrc(cb) { | |
var scripts = document.getElementsByTagName('script'), | |
s,o, html, q, ext, async, doneCount = 0, | |
done = cb ? newCallbackTag(function() { | |
if(++doneCount >= exts.length) { | |
cb(); | |
} | |
}) : '', | |
exts = []; | |
for(var i = 0, len = scripts.length; i < len; i++) { | |
s = scripts[i]; | |
ext = s.getAttribute('extsrc'); | |
async = s.getAttribute('asyncsrc'); | |
if(ext || async) { | |
exts.push({ext:ext,async:async,s:s}); | |
} | |
} | |
for(i = 0, len = exts.length; i < len; i++) { | |
o = exts[i]; | |
if(o.ext) { | |
html = '<script type="text/javascript" src="'+o.ext+'"> </script>'; | |
$.replaceWith(o.s,sanitize(html) + done); | |
} else if(o.async) { | |
html = '<script type="text/javascript" src="'+o.async+'"> </script>'; | |
$.replaceWith(o.s,sanitize(html,{asyncAll:true}, new Q()) + done); | |
} | |
} | |
} | |
var name = 'writeCapture'; | |
var self = global[name] = { | |
_original: global[name], | |
support: $, | |
/** | |
*/ | |
fixUrls: function(src) { | |
return src.replace(/&/g,'&'); | |
}, | |
noConflict: function() { | |
global[name] = this._original; | |
return this; | |
}, | |
debug: debug, | |
/** | |
* Enables a fun little hack that replaces document.getElementById and | |
* creates temporary elements for the calling code to use. | |
*/ | |
proxyGetElementById: false, | |
// this is only for testing, please don't use these | |
_forTest: { | |
Q: Q, | |
GLOBAL_Q: GLOBAL_Q, | |
$: $, | |
matchAttr: matchAttr, | |
slice: slice, | |
capture: capture, | |
uncapture: uncapture, | |
captureWrite: captureWrite | |
}, | |
replaceWith: function(selector,content,options) { | |
$.replaceWith(selector,sanitize(content,options)); | |
}, | |
html: function(selector,content,options) { | |
var el = $.$(selector); | |
el.innerHTML ='<span/>'; | |
$.replaceWith(el.firstChild,sanitize(content,options)); | |
}, | |
load: function(selector,url,options) { | |
$.ajax({ | |
url: url, | |
dataType: 'text', | |
type: "GET", | |
success: function(content) { | |
self.html(selector,content,options); | |
} | |
}); | |
}, | |
extsrc: extsrc, | |
autoAsync: autoCapture, | |
sanitize: sanitize, | |
sanitizeSerial: sanitizeSerial | |
}; | |
})(this.writeCaptureSupport,this); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment