// DataURI minifies a data URI and calls a minifier by the specified mediatype. Specifications: https://www.ietf.org/rfc/rfc2397.txt. func DataURI(m Minifier, dataURI []byte) []byte { if mediatype, data, err := parse.DataURI(dataURI); err == nil { dataURI, _ = Bytes(m, string(mediatype), data) base64Len := len(";base64") + base64.StdEncoding.EncodedLen(len(dataURI)) asciiLen := len(dataURI) for _, c := range dataURI { if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' || c == '_' || c == '.' || c == '~' || c == ' ' { asciiLen++ } else { asciiLen += 2 } if asciiLen > base64Len { break } } if asciiLen > base64Len { encoded := make([]byte, base64Len-len(";base64")) base64.StdEncoding.Encode(encoded, dataURI) dataURI = encoded mediatype = append(mediatype, []byte(";base64")...) } else { dataURI = []byte(url.QueryEscape(string(dataURI))) dataURI = bytes.Replace(dataURI, []byte("\""), []byte("\\\""), -1) } if len(mediatype) >= len("text/plain") && bytes.HasPrefix(mediatype, []byte("text/plain")) { mediatype = mediatype[len("text/plain"):] } dataURI = append(append(append([]byte("data:"), mediatype...), ','), dataURI...) } return dataURI }
// DataURI minifies a data URI and calls a minifier by the specified mediatype. Specifications: https://www.ietf.org/rfc/rfc2397.txt. func DataURI(m *M, dataURI []byte) []byte { if mediatype, data, err := parse.DataURI(dataURI); err == nil { dataURI, _ = m.Bytes(string(mediatype), data) base64Len := len(";base64") + base64.StdEncoding.EncodedLen(len(dataURI)) asciiLen := len(dataURI) for i := 0; i < len(dataURI); i++ { c := dataURI[i] if 'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' || '0' <= c && c <= '9' || c == '-' || c == '_' || c == '.' || c == '~' || c == ' ' { asciiLen++ } else { asciiLen += 2 } if asciiLen > base64Len { break } } if asciiLen > base64Len { encoded := make([]byte, base64Len-len(";base64")) base64.StdEncoding.Encode(encoded, dataURI) dataURI = encoded mediatype = append(mediatype, []byte(";base64")...) } else { dataURI = []byte(url.QueryEscape(string(dataURI))) dataURI = bytes.Replace(dataURI, []byte("\""), []byte("\\\""), -1) } if len("text/plain") <= len(mediatype) && parse.EqualFold(mediatype[:len("text/plain")], []byte("text/plain")) { mediatype = mediatype[len("text/plain"):] } for i := 0; i+len(";charset=us-ascii") <= len(mediatype); i++ { // must start with semicolon and be followed by end of mediatype or semicolon if mediatype[i] == ';' && parse.EqualFold(mediatype[i+1:i+len(";charset=us-ascii")], []byte("charset=us-ascii")) && (i+len(";charset=us-ascii") >= len(mediatype) || mediatype[i+len(";charset=us-ascii")] == ';') { mediatype = append(mediatype[:i], mediatype[i+len(";charset=us-ascii"):]...) break } } dataURI = append(append(append([]byte("data:"), mediatype...), ','), dataURI...) } return dataURI }