Skip to content

Commit

Permalink
SelfContained: don't use data URIs for script or style.
Browse files Browse the repository at this point in the history
Instead, just use script or style tags with the content inside.
The old method with data URIs prevents certain optimizations
outside pandoc.

Exception: data URIs are still used when a script contains
`</script>` or a style contains `</`.

Closes #3423.

Also, in MIME, use application/javascript (not
application/x-javascript).
  • Loading branch information
jgm committed Feb 24, 2017
1 parent 0e8b19e commit 7c0a80c
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 11 deletions.
2 changes: 1 addition & 1 deletion src/Text/Pandoc/MIME.hs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ mimeTypesList = -- List borrowed from happstack-server.
,("jpeg","image/jpeg")
,("jfif","image/jpeg")
,("jpg","image/jpeg")
,("js","application/x-javascript")
,("js","application/javascript")
,("kar","audio/midi")
,("key","application/pgp-keys")
,("kil","application/x-killustrator")
Expand Down
46 changes: 36 additions & 10 deletions src/Text/Pandoc/SelfContained.hs
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,12 @@ makeDataURI (mime, raw) =
then mime ++ ";charset=utf-8"
else mime -- mime type already has charset

convertTag :: PandocMonad m => Maybe String -> Tag String -> m (Tag String)
convertTag :: PandocMonad m => Maybe String -> Tag String -> m [Tag String]
convertTag sourceURL t@(TagOpen tagname as)
| tagname `elem`
["img", "embed", "video", "input", "audio", "source", "track"] = do
as' <- mapM processAttribute as
return $ TagOpen tagname as'
return [TagOpen tagname as']
where processAttribute (x,y) =
if x == "src" || x == "data-src" || x == "href" || x == "poster"
then do
Expand All @@ -81,17 +81,43 @@ convertTag sourceURL t@(TagOpen tagname as)
else return (x,y)
convertTag sourceURL t@(TagOpen "script" as) =
case fromAttrib "src" t of
[] -> return t
[] -> return [t]
src -> do
enc <- getDataURI sourceURL (fromAttrib "type" t) src
return $ TagOpen "script" (("src",enc) : [(x,y) | (x,y) <- as, x /= "src"])
let typeAttr = fromAttrib "type" t
res <- getData sourceURL typeAttr src
case res of
Left dataUri -> return [TagOpen "script"
(("src",dataUri) : [(x,y) | (x,y) <- as, x /= "src"])]
Right (mime, bs)
| (mime == "text/javascript" ||
mime == "application/javascript" ||
mime == "application/x-javascript") &&
not ("</" `B.isInfixOf` bs) ->
return [
TagOpen "script" [("type", typeAttr)|not (null typeAttr)]
, TagText (toString bs)
, TagClose "script" ]
| otherwise -> return [TagOpen "script"
(("src",makeDataURI (mime, bs)) :
[(x,y) | (x,y) <- as, x /= "src"])]
convertTag sourceURL t@(TagOpen "link" as) =
case fromAttrib "href" t of
[] -> return t
[] -> return [t]
src -> do
enc <- getDataURI sourceURL (fromAttrib "type" t) src
return $ TagOpen "link" (("href",enc) : [(x,y) | (x,y) <- as, x /= "href"])
convertTag _ t = return t
res <- getData sourceURL (fromAttrib "type" t) src
case res of
Left dataUri -> return [TagOpen "link"
(("href",dataUri) : [(x,y) | (x,y) <- as, x /= "href"])]
Right (mime, bs)
| mime == "text/css" && not ("</" `B.isInfixOf` bs) ->
return [
TagOpen "style" [("type", "text/css")]
, TagText (toString bs)
, TagClose "style" ]
| otherwise -> return [TagOpen "link"
(("href",makeDataURI (mime, bs)) :
[(x,y) | (x,y) <- as, x /= "href"])]
convertTag _ t = return [t]

cssURLs :: PandocMonad m
=> Maybe String -> FilePath -> ByteString -> m ByteString
Expand Down Expand Up @@ -184,5 +210,5 @@ getData sourceURL mimetype src = do
makeSelfContained :: PandocMonad m => WriterOptions -> String -> m String
makeSelfContained opts inp = do
let tags = parseTags inp
out' <- mapM (convertTag (writerSourceURL opts)) tags
out' <- concat <$> mapM (convertTag (writerSourceURL opts)) tags
return $ renderTags' out'

0 comments on commit 7c0a80c

Please sign in to comment.