forked from htmlpreview/htmlpreview.github.com
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathhtmlpreview.js
134 lines (123 loc) · 5.73 KB
/
htmlpreview.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
var HTMLPreview = {
content: '',
previewform: document.getElementById('previewform'),
file: function() {
return location.search.substring(1); //Get everything after the ?
},
raw: function() {
return HTMLPreview.file().replace(/\/\/github\.com/, '//raw.githubusercontent.com').replace(/\/blob\//, '/'); //Get URL of the raw file
},
replaceAssets: function() {
var frame, a, link, script, i, href, src;
frame = document.querySelectorAll('iframe[src],frame[src]');
for(i = 0; i < frame.length; ++i) {
src = frame[i].src; //Get absolute URL
if(src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
frame[i].src = '//' + location.hostname + location.pathname + '?' + src; //Then rewrite URL so it can be loaded using YQL
}
}
a = document.querySelectorAll('a[href]');
for(i = 0; i < a.length; ++i) {
href = a[i].href; //Get absolute URL
if(href.indexOf('#') > 0) { //Check if it's an anchor
a[i].href = '//' + location.hostname + location.pathname + location.search + '#' + a[i].hash.substring(1); //Then rewrite URL with support for empty anchor
}
else if((href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) && (href.indexOf('.html') > 0 || href.indexOf('.htm') > 0)) { //Check if it's from raw.github.com or bitbucket.org and to HTML files
a[i].href = '//' + location.hostname + location.pathname + '?' + href; //Then rewrite URL so it can be loaded using YQL
}
}
if(document.querySelectorAll('frameset').length)
return; //Don't replace CSS/JS if it's a frameset, because it will be erased by document.write()
link = document.querySelectorAll('link[rel=stylesheet]');
for(i = 0; i < link.length; ++i) {
href = link[i].href; //Get absolute URL
if(href.indexOf('//raw.githubusercontent.com') > 0 || href.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
HTMLPreview.send(href, 'loadCSS'); //Then load it using YQL
}
}
script = document.querySelectorAll('script');
for(i = 0; i < script.length; ++i) {
src = script[i].src; //Get absolute URL
if(src.indexOf('//raw.githubusercontent.com') > 0 || src.indexOf('//bitbucket.org') > 0) { //Check if it's from raw.github.com or bitbucket.org
HTMLPreview.send(src, 'loadJS'); //Then load it using YQL
}
else if(!src && script[i].innerHTML.indexOf('HTMLPreview') < 0) { //Move all inline scripts except HTMLPreview.replaceAssets()
document.write(script[i].outerHTML);
}
}
},
loadHTML: function(data) {
if(data
&& data.query
&& data.query.diagnostics
&& data.query.diagnostics.redirect) {
HTMLPreview.send(data.query.diagnostics.redirect.content, 'loadHTML');
}
else if(data
&& data.query
&& data.query.results
&& data.query.results.resources
&& data.query.results.resources.content
&& data.query.results.resources.status == 200) {
HTMLPreview.content = data.query.results.resources.content.replace(/<head>/i, '<head><base href="' + HTMLPreview.raw() + '">').replace(/<\/body>/i, '<script src="//' + location.hostname + '/htmlpreview.min.js"></script><script>HTMLPreview.replaceAssets();</script></body>').replace(/<\/head>\s*<frameset/gi, '<script src="//' + location.hostname + '/htmlpreview.min.js"></script><script>document.addEventListener("DOMContentLoaded",HTMLPreview.replaceAssets,false);</script></head><frameset'); //Add <base> just after <head> and inject <script> just before </body> or </head> if <frameset>
setTimeout(function() {
document.open();
document.write(HTMLPreview.content);
document.close();
}, 50); //Delay updating document to have it cleared before
}
else if(data
&& data.error
&& data.error.description) {
HTMLPreview.previewform.innerHTML = data.error.description;
}
else
HTMLPreview.previewform.innerHTML = 'Error: Cannot load file ' + HTMLPreview.raw();
},
loadCSS: function(data) {
if(data
&& data.query
&& data.query.diagnostics
&& data.query.diagnostics.redirect) {
HTMLPreview.send(data.query.diagnostics.redirect.content, 'loadCSS');
}
else if(data
&& data.query
&& data.query.results
&& data.query.results.resources
&& data.query.results.resources.content
&& data.query.results.resources.status == 200) {
document.write('<style>' + data.query.results.resources.content.replace(/url\((?:'|")?([^\/][^:'"\)]+)(?:'|")?\)/gi, 'url(' + data.query.results.resources.url.replace(/[^\/]+\.css.*$/gi, '') + '$1)') + '</style>'); //If relative URL in CSS background-image property, then concatenate URL to CSS directory
}
},
loadJS: function(data) {
if(data
&& data.query
&& data.query.diagnostics
&& data.query.diagnostics.redirect) {
HTMLPreview.send(data.query.diagnostics.redirect.content, 'loadJS');
}
else if(data
&& data.query
&& data.query.results
&& data.query.results.resources
&& data.query.results.resources.content
&& data.query.results.resources.status == 200) {
document.write('<script>' + data.query.results.resources.content + '</script>');
}
},
send: function(file, callback) {
document.write('<script src="//query.yahooapis.com/v1/public/yql?q=select%20*%20from%20data.headers%20where%20url%3D%22' + encodeURIComponent(file) + '%22&format=json&diagnostics=true&env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys&callback=HTMLPreview.' + callback + '"></script>'); //Get content using YQL
},
submitform: function() {
location.href = '/?' + document.getElementById('file').value;
return false;
},
init: function() {
HTMLPreview.previewform.onsubmit = HTMLPreview.submitform;
if(HTMLPreview.file()) {
HTMLPreview.previewform.innerHTML = '<p>Loading...</p>';
HTMLPreview.send(HTMLPreview.raw(), 'loadHTML');
}
}
}