@@ -9,7 +9,7 @@ use mdbook::utils::fs::write_file;
99use mdbook:: MDBook ;
1010use pretty_assertions:: assert_eq;
1111use select:: document:: Document ;
12- use select:: predicate:: { Class , Name , Predicate } ;
12+ use select:: predicate:: { Attr , Class , Name , Predicate } ;
1313use std:: collections:: HashMap ;
1414use std:: ffi:: OsStr ;
1515use std:: fs;
@@ -232,7 +232,7 @@ fn entry_ends_with(entry: &DirEntry, ending: &str) -> bool {
232232
233233/// Read the TOC (`book/toc.js`) nested HTML and expose it as a DOM which we
234234/// can search with the `select` crate
235- fn toc_html ( ) -> Result < Document > {
235+ fn toc_js_html ( ) -> Result < Document > {
236236 let temp = DummyBook :: new ( )
237237 . build ( )
238238 . with_context ( || "Couldn't create the dummy book" ) ?;
@@ -252,9 +252,24 @@ fn toc_html() -> Result<Document> {
252252 panic ! ( "cannot find toc in file" )
253253}
254254
255+ /// Read the TOC fallback (`book/toc.html`) HTML and expose it as a DOM which we
256+ /// can search with the `select` crate
257+ fn toc_fallback_html ( ) -> Result < Document > {
258+ let temp = DummyBook :: new ( )
259+ . build ( )
260+ . with_context ( || "Couldn't create the dummy book" ) ?;
261+ MDBook :: load ( temp. path ( ) ) ?
262+ . build ( )
263+ . with_context ( || "Book building failed" ) ?;
264+
265+ let toc_path = temp. path ( ) . join ( "book" ) . join ( "toc.html" ) ;
266+ let html = fs:: read_to_string ( toc_path) . with_context ( || "Unable to read index.html" ) ?;
267+ Ok ( Document :: from ( html. as_str ( ) ) )
268+ }
269+
255270#[ test]
256271fn check_second_toc_level ( ) {
257- let doc = toc_html ( ) . unwrap ( ) ;
272+ let doc = toc_js_html ( ) . unwrap ( ) ;
258273 let mut should_be = Vec :: from ( TOC_SECOND_LEVEL ) ;
259274 should_be. sort_unstable ( ) ;
260275
@@ -276,7 +291,7 @@ fn check_second_toc_level() {
276291
277292#[ test]
278293fn check_first_toc_level ( ) {
279- let doc = toc_html ( ) . unwrap ( ) ;
294+ let doc = toc_js_html ( ) . unwrap ( ) ;
280295 let mut should_be = Vec :: from ( TOC_TOP_LEVEL ) ;
281296
282297 should_be. extend ( TOC_SECOND_LEVEL ) ;
@@ -299,7 +314,7 @@ fn check_first_toc_level() {
299314
300315#[ test]
301316fn check_spacers ( ) {
302- let doc = toc_html ( ) . unwrap ( ) ;
317+ let doc = toc_js_html ( ) . unwrap ( ) ;
303318 let should_be = 2 ;
304319
305320 let num_spacers = doc
@@ -308,6 +323,39 @@ fn check_spacers() {
308323 assert_eq ! ( num_spacers, should_be) ;
309324}
310325
326+ // don't use target="_parent" in JS
327+ #[ test]
328+ fn check_link_target_js ( ) {
329+ let doc = toc_js_html ( ) . unwrap ( ) ;
330+
331+ let num_parent_links = doc
332+ . find (
333+ Class ( "chapter" )
334+ . descendant ( Name ( "li" ) )
335+ . descendant ( Name ( "a" ) . and ( Attr ( "target" , "_parent" ) ) ) ,
336+ )
337+ . count ( ) ;
338+ assert_eq ! ( num_parent_links, 0 ) ;
339+ }
340+
341+ // don't use target="_parent" in IFRAME
342+ #[ test]
343+ fn check_link_target_fallback ( ) {
344+ let doc = toc_fallback_html ( ) . unwrap ( ) ;
345+
346+ let num_parent_links = doc
347+ . find (
348+ Class ( "chapter" )
349+ . descendant ( Name ( "li" ) )
350+ . descendant ( Name ( "a" ) . and ( Attr ( "target" , "_parent" ) ) ) ,
351+ )
352+ . count ( ) ;
353+ assert_eq ! (
354+ num_parent_links,
355+ TOC_TOP_LEVEL . len( ) + TOC_SECOND_LEVEL . len( )
356+ ) ;
357+ }
358+
311359/// Ensure building fails if `create-missing` is false and one of the files does
312360/// not exist.
313361#[ test]
0 commit comments