Skip to content

Commit 934e37a

Browse files
Rollup merge of #50632 - GuillaumeGomez:minification, r=ollie27
Add minification process r? @QuietMisdreavus
2 parents 91c648b + e2db0a5 commit 934e37a

File tree

6 files changed

+170
-60
lines changed

6 files changed

+170
-60
lines changed

src/Cargo.lock

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustdoc/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,4 @@ path = "lib.rs"
1010
[dependencies]
1111
pulldown-cmark = { version = "0.1.2", default-features = false }
1212
tempdir = "0.3"
13+
minifier = "0.0.11"

src/librustdoc/html/render.rs

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ use html::item_type::ItemType;
7676
use html::markdown::{self, Markdown, MarkdownHtml, MarkdownSummaryLine};
7777
use html::{highlight, layout};
7878

79+
use minifier;
80+
7981
/// A pair of name and its optional document.
8082
pub type NameDoc = (String, Option<String>);
8183

@@ -513,7 +515,8 @@ pub fn run(mut krate: clean::Crate,
513515
css_file_extension: Option<PathBuf>,
514516
renderinfo: RenderInfo,
515517
sort_modules_alphabetically: bool,
516-
themes: Vec<PathBuf>) -> Result<(), Error> {
518+
themes: Vec<PathBuf>,
519+
enable_minification: bool) -> Result<(), Error> {
517520
let src_root = match krate.src {
518521
FileName::Real(ref p) => match p.parent() {
519522
Some(p) => p.to_path_buf(),
@@ -665,7 +668,7 @@ pub fn run(mut krate: clean::Crate,
665668
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
666669
CURRENT_LOCATION_KEY.with(|s| s.borrow_mut().clear());
667670

668-
write_shared(&cx, &krate, &*cache, index)?;
671+
write_shared(&cx, &krate, &*cache, index, enable_minification)?;
669672

670673
// And finally render the whole crate's documentation
671674
cx.krate(krate)
@@ -744,7 +747,8 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
744747
fn write_shared(cx: &Context,
745748
krate: &clean::Crate,
746749
cache: &Cache,
747-
search_index: String) -> Result<(), Error> {
750+
search_index: String,
751+
enable_minification: bool) -> Result<(), Error> {
748752
// Write out the shared files. Note that these are shared among all rustdoc
749753
// docs placed in the output directory, so this needs to be a synchronized
750754
// operation with respect to all other rustdocs running around.
@@ -836,16 +840,20 @@ themePicker.onblur = handleThemeButtonsBlur;
836840
.join(",")).as_bytes(),
837841
)?;
838842

839-
write(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
840-
include_bytes!("static/main.js"))?;
841-
write(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
842-
include_bytes!("static/settings.js"))?;
843+
write_minify(cx.dst.join(&format!("main{}.js", cx.shared.resource_suffix)),
844+
include_str!("static/main.js"),
845+
enable_minification)?;
846+
write_minify(cx.dst.join(&format!("settings{}.js", cx.shared.resource_suffix)),
847+
include_str!("static/settings.js"),
848+
enable_minification)?;
843849

844850
{
845851
let mut data = format!("var resourcesSuffix = \"{}\";\n",
846-
cx.shared.resource_suffix).into_bytes();
847-
data.extend_from_slice(include_bytes!("static/storage.js"));
848-
write(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)), &data)?;
852+
cx.shared.resource_suffix);
853+
data.push_str(include_str!("static/storage.js"));
854+
write_minify(cx.dst.join(&format!("storage{}.js", cx.shared.resource_suffix)),
855+
&data,
856+
enable_minification)?;
849857
}
850858

851859
if let Some(ref css) = cx.shared.css_file_extension {
@@ -1042,6 +1050,14 @@ fn write(dst: PathBuf, contents: &[u8]) -> Result<(), Error> {
10421050
Ok(try_err!(fs::write(&dst, contents), &dst))
10431051
}
10441052

1053+
fn write_minify(dst: PathBuf, contents: &str, enable_minification: bool) -> Result<(), Error> {
1054+
if enable_minification {
1055+
write(dst, minifier::js::minify(contents).as_bytes())
1056+
} else {
1057+
write(dst, contents.as_bytes())
1058+
}
1059+
}
1060+
10451061
/// Takes a path to a source file and cleans the path to it. This canonicalizes
10461062
/// things like ".." to components which preserve the "top down" hierarchy of a
10471063
/// static HTML tree. Each component in the cleaned path will be passed as an

src/librustdoc/html/static/main.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@
202202
onEach(e.getElementsByTagName('span'), function(i_e) {
203203
removeClass(i_e, 'line-highlighted');
204204
});
205-
})
205+
});
206206
for (i = from; i <= to; ++i) {
207207
addClass(document.getElementById(i), 'line-highlighted');
208208
}
@@ -1972,7 +1972,7 @@
19721972
hasClass(next.nextElementSibling, 'docblock')))) {
19731973
insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]);
19741974
}
1975-
}
1975+
};
19761976
onEach(document.getElementsByClassName('method'), func);
19771977
onEach(document.getElementsByClassName('impl'), func);
19781978
onEach(document.getElementsByClassName('impl-items'), function(e) {

src/librustdoc/lib.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ extern crate test as testing;
4848
extern crate rustc_errors as errors;
4949
extern crate pulldown_cmark;
5050
extern crate tempdir;
51+
extern crate minifier;
5152

5253
extern crate serialize as rustc_serialize; // used by deriving
5354

@@ -299,6 +300,11 @@ pub fn opts() -> Vec<RustcOptGroup> {
299300
"How errors and other messages are produced",
300301
"human|json|short")
301302
}),
303+
unstable("disable-minification", |o| {
304+
o.optflag("",
305+
"disable-minification",
306+
"Disable minification applied on JS files")
307+
}),
302308
]
303309
}
304310

@@ -480,6 +486,7 @@ pub fn main_args(args: &[String]) -> isize {
480486
let linker = matches.opt_str("linker").map(PathBuf::from);
481487
let sort_modules_alphabetically = !matches.opt_present("sort-modules-by-appearance");
482488
let resource_suffix = matches.opt_str("resource-suffix");
489+
let enable_minification = !matches.opt_present("disable-minification");
483490

484491
let edition = matches.opt_str("edition").unwrap_or("2015".to_string());
485492
let edition = match edition.parse() {
@@ -523,7 +530,8 @@ pub fn main_args(args: &[String]) -> isize {
523530
css_file_extension,
524531
renderinfo,
525532
sort_modules_alphabetically,
526-
themes)
533+
themes,
534+
enable_minification)
527535
.expect("failed to generate documentation");
528536
0
529537
}

src/tools/rustdoc-js/tester.js

Lines changed: 122 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -12,73 +12,148 @@ const fs = require('fs');
1212

1313
const TEST_FOLDER = 'src/test/rustdoc-js/';
1414

15+
function getNextStep(content, pos, stop) {
16+
while (pos < content.length && content[pos] !== stop &&
17+
(content[pos] === ' ' || content[pos] === '\t' || content[pos] === '\n')) {
18+
pos += 1;
19+
}
20+
if (pos >= content.length) {
21+
return null;
22+
}
23+
if (content[pos] !== stop) {
24+
return pos * -1;
25+
}
26+
return pos;
27+
}
28+
1529
// Stupid function extractor based on indent.
1630
function extractFunction(content, functionName) {
17-
var x = content.split('\n');
18-
var in_func = false;
1931
var indent = 0;
20-
var lines = [];
21-
22-
for (var i = 0; i < x.length; ++i) {
23-
if (in_func === false) {
24-
var splitter = "function " + functionName + "(";
25-
if (x[i].trim().startsWith(splitter)) {
26-
in_func = true;
27-
indent = x[i].split(splitter)[0].length;
28-
lines.push(x[i]);
29-
}
30-
} else {
31-
lines.push(x[i]);
32-
if (x[i].trim() === "}" && x[i].split("}")[0].length === indent) {
33-
return lines.join("\n");
32+
var splitter = "function " + functionName + "(";
33+
34+
while (true) {
35+
var start = content.indexOf(splitter);
36+
if (start === -1) {
37+
break;
38+
}
39+
var pos = start;
40+
while (pos < content.length && content[pos] !== ')') {
41+
pos += 1;
42+
}
43+
if (pos >= content.length) {
44+
break;
45+
}
46+
pos = getNextStep(content, pos + 1, '{');
47+
if (pos === null) {
48+
break;
49+
} else if (pos < 0) {
50+
content = content.slice(-pos);
51+
continue;
52+
}
53+
while (pos < content.length) {
54+
if (content[pos] === '"' || content[pos] === "'") {
55+
var stop = content[pos];
56+
var is_escaped = false;
57+
do {
58+
if (content[pos] === '\\') {
59+
pos += 2;
60+
} else {
61+
pos += 1;
62+
}
63+
} while (pos < content.length &&
64+
(content[pos] !== stop || content[pos - 1] === '\\'));
65+
} else if (content[pos] === '{') {
66+
indent += 1;
67+
} else if (content[pos] === '}') {
68+
indent -= 1;
69+
if (indent === 0) {
70+
return content.slice(start, pos + 1);
71+
}
3472
}
73+
pos += 1;
3574
}
75+
content = content.slice(start + 1);
3676
}
3777
return null;
3878
}
3979

4080
// Stupid function extractor for array.
4181
function extractArrayVariable(content, arrayName) {
42-
var x = content.split('\n');
43-
var found_var = false;
44-
var lines = [];
45-
46-
for (var i = 0; i < x.length; ++i) {
47-
if (found_var === false) {
48-
var splitter = "var " + arrayName + " = [";
49-
if (x[i].trim().startsWith(splitter)) {
50-
found_var = true;
51-
i -= 1;
52-
}
53-
} else {
54-
lines.push(x[i]);
55-
if (x[i].endsWith('];')) {
56-
return lines.join("\n");
82+
var splitter = "var " + arrayName;
83+
while (true) {
84+
var start = content.indexOf(splitter);
85+
if (start === -1) {
86+
break;
87+
}
88+
var pos = getNextStep(content, start, '=');
89+
if (pos === null) {
90+
break;
91+
} else if (pos < 0) {
92+
content = content.slice(-pos);
93+
continue;
94+
}
95+
pos = getNextStep(content, pos, '[');
96+
if (pos === null) {
97+
break;
98+
} else if (pos < 0) {
99+
content = content.slice(-pos);
100+
continue;
101+
}
102+
while (pos < content.length) {
103+
if (content[pos] === '"' || content[pos] === "'") {
104+
var stop = content[pos];
105+
do {
106+
if (content[pos] === '\\') {
107+
pos += 2;
108+
} else {
109+
pos += 1;
110+
}
111+
} while (pos < content.length &&
112+
(content[pos] !== stop || content[pos - 1] === '\\'));
113+
} else if (content[pos] === ']' &&
114+
pos + 1 < content.length &&
115+
content[pos + 1] === ';') {
116+
return content.slice(start, pos + 2);
57117
}
118+
pos += 1;
58119
}
120+
content = content.slice(start + 1);
59121
}
60122
return null;
61123
}
62124

63125
// Stupid function extractor for variable.
64126
function extractVariable(content, varName) {
65-
var x = content.split('\n');
66-
var found_var = false;
67-
var lines = [];
68-
69-
for (var i = 0; i < x.length; ++i) {
70-
if (found_var === false) {
71-
var splitter = "var " + varName + " = ";
72-
if (x[i].trim().startsWith(splitter)) {
73-
found_var = true;
74-
i -= 1;
75-
}
76-
} else {
77-
lines.push(x[i]);
78-
if (x[i].endsWith(';')) {
79-
return lines.join("\n");
127+
var splitter = "var " + varName;
128+
while (true) {
129+
var start = content.indexOf(splitter);
130+
if (start === -1) {
131+
break;
132+
}
133+
var pos = getNextStep(content, start, '=');
134+
if (pos === null) {
135+
break;
136+
} else if (pos < 0) {
137+
content = content.slice(-pos);
138+
continue;
139+
}
140+
while (pos < content.length) {
141+
if (content[pos] === '"' || content[pos] === "'") {
142+
var stop = content[pos];
143+
do {
144+
if (content[pos] === '\\') {
145+
pos += 2;
146+
} else {
147+
pos += 1;
148+
}
149+
} while (pos < content.length &&
150+
(content[pos] !== stop || content[pos - 1] === '\\'));
151+
} else if (content[pos] === ';') {
152+
return content.slice(start, pos + 1);
80153
}
154+
pos += 1;
81155
}
156+
content = content.slice(start + 1);
82157
}
83158
return null;
84159
}
@@ -101,7 +176,7 @@ function loadThings(thingsToLoad, kindOfLoad, funcToCall, fileContent) {
101176
for (var i = 0; i < thingsToLoad.length; ++i) {
102177
var tmp = funcToCall(fileContent, thingsToLoad[i]);
103178
if (tmp === null) {
104-
console.error('enable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
179+
console.error('unable to find ' + kindOfLoad + ' "' + thingsToLoad[i] + '"');
105180
process.exit(1);
106181
}
107182
content += tmp;

0 commit comments

Comments
 (0)