mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-11-03 03:02:26 -06:00
[bugfix] Markdown formatting updates (#743)
* add minify dependency specifically for markdown * rearrange markdown formatting * update markdown tests
This commit is contained in:
parent
f2a6ae3ef8
commit
879b4abde7
42 changed files with 7259 additions and 19 deletions
137
vendor/github.com/tdewolff/minify/v2/html/buffer.go
generated
vendored
Normal file
137
vendor/github.com/tdewolff/minify/v2/html/buffer.go
generated
vendored
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
package html
|
||||
|
||||
import (
|
||||
"github.com/tdewolff/parse/v2"
|
||||
"github.com/tdewolff/parse/v2/html"
|
||||
)
|
||||
|
||||
// Token is a single token unit with an attribute value (if given) and hash of the data.
|
||||
type Token struct {
|
||||
html.TokenType
|
||||
Hash Hash
|
||||
Data []byte
|
||||
Text []byte
|
||||
AttrVal []byte
|
||||
Traits traits
|
||||
Offset int
|
||||
}
|
||||
|
||||
// TokenBuffer is a buffer that allows for token look-ahead.
|
||||
type TokenBuffer struct {
|
||||
r *parse.Input
|
||||
l *html.Lexer
|
||||
|
||||
buf []Token
|
||||
pos int
|
||||
|
||||
attrBuffer []*Token
|
||||
}
|
||||
|
||||
// NewTokenBuffer returns a new TokenBuffer.
|
||||
func NewTokenBuffer(r *parse.Input, l *html.Lexer) *TokenBuffer {
|
||||
return &TokenBuffer{
|
||||
r: r,
|
||||
l: l,
|
||||
buf: make([]Token, 0, 8),
|
||||
}
|
||||
}
|
||||
|
||||
func (z *TokenBuffer) read(t *Token) {
|
||||
t.Offset = z.r.Offset()
|
||||
t.TokenType, t.Data = z.l.Next()
|
||||
t.Text = z.l.Text()
|
||||
if t.TokenType == html.AttributeToken {
|
||||
t.Offset += 1 + len(t.Text) + 1
|
||||
t.AttrVal = z.l.AttrVal()
|
||||
if len(t.AttrVal) > 1 && (t.AttrVal[0] == '"' || t.AttrVal[0] == '\'') {
|
||||
t.Offset++
|
||||
t.AttrVal = t.AttrVal[1 : len(t.AttrVal)-1] // quotes will be readded in attribute loop if necessary
|
||||
}
|
||||
t.Hash = ToHash(t.Text)
|
||||
t.Traits = attrMap[t.Hash]
|
||||
} else if t.TokenType == html.StartTagToken || t.TokenType == html.EndTagToken {
|
||||
t.AttrVal = nil
|
||||
t.Hash = ToHash(t.Text)
|
||||
t.Traits = tagMap[t.Hash] // zero if not exist
|
||||
} else {
|
||||
t.AttrVal = nil
|
||||
t.Hash = 0
|
||||
t.Traits = 0
|
||||
}
|
||||
}
|
||||
|
||||
// Peek returns the ith element and possibly does an allocation.
|
||||
// Peeking past an error will panic.
|
||||
func (z *TokenBuffer) Peek(pos int) *Token {
|
||||
pos += z.pos
|
||||
if pos >= len(z.buf) {
|
||||
if len(z.buf) > 0 && z.buf[len(z.buf)-1].TokenType == html.ErrorToken {
|
||||
return &z.buf[len(z.buf)-1]
|
||||
}
|
||||
|
||||
c := cap(z.buf)
|
||||
d := len(z.buf) - z.pos
|
||||
p := pos - z.pos + 1 // required peek length
|
||||
var buf []Token
|
||||
if 2*p > c {
|
||||
buf = make([]Token, 0, 2*c+p)
|
||||
} else {
|
||||
buf = z.buf
|
||||
}
|
||||
copy(buf[:d], z.buf[z.pos:])
|
||||
|
||||
buf = buf[:p]
|
||||
pos -= z.pos
|
||||
for i := d; i < p; i++ {
|
||||
z.read(&buf[i])
|
||||
if buf[i].TokenType == html.ErrorToken {
|
||||
buf = buf[:i+1]
|
||||
pos = i
|
||||
break
|
||||
}
|
||||
}
|
||||
z.pos, z.buf = 0, buf
|
||||
}
|
||||
return &z.buf[pos]
|
||||
}
|
||||
|
||||
// Shift returns the first element and advances position.
|
||||
func (z *TokenBuffer) Shift() *Token {
|
||||
if z.pos >= len(z.buf) {
|
||||
t := &z.buf[:1][0]
|
||||
z.read(t)
|
||||
return t
|
||||
}
|
||||
t := &z.buf[z.pos]
|
||||
z.pos++
|
||||
return t
|
||||
}
|
||||
|
||||
// Attributes extracts the gives attribute hashes from a tag.
|
||||
// It returns in the same order pointers to the requested token data or nil.
|
||||
func (z *TokenBuffer) Attributes(hashes ...Hash) []*Token {
|
||||
n := 0
|
||||
for {
|
||||
if t := z.Peek(n); t.TokenType != html.AttributeToken {
|
||||
break
|
||||
}
|
||||
n++
|
||||
}
|
||||
if len(hashes) > cap(z.attrBuffer) {
|
||||
z.attrBuffer = make([]*Token, len(hashes))
|
||||
} else {
|
||||
z.attrBuffer = z.attrBuffer[:len(hashes)]
|
||||
for i := range z.attrBuffer {
|
||||
z.attrBuffer[i] = nil
|
||||
}
|
||||
}
|
||||
for i := z.pos; i < z.pos+n; i++ {
|
||||
attr := &z.buf[i]
|
||||
for j, hash := range hashes {
|
||||
if hash == attr.Hash {
|
||||
z.attrBuffer[j] = attr
|
||||
}
|
||||
}
|
||||
}
|
||||
return z.attrBuffer
|
||||
}
|
||||
543
vendor/github.com/tdewolff/minify/v2/html/hash.go
generated
vendored
Normal file
543
vendor/github.com/tdewolff/minify/v2/html/hash.go
generated
vendored
Normal file
|
|
@ -0,0 +1,543 @@
|
|||
package html
|
||||
|
||||
// generated by hasher -type=Hash -file=hash.go; DO NOT EDIT, except for adding more constants to the list and rerun go generate
|
||||
|
||||
// uses github.com/tdewolff/hasher
|
||||
//go:generate hasher -type=Hash -file=hash.go
|
||||
|
||||
// Hash defines perfect hashes for a predefined list of strings
|
||||
type Hash uint32
|
||||
|
||||
// Unique hash definitions to be used instead of strings
|
||||
const (
|
||||
A Hash = 0x1 // a
|
||||
Abbr Hash = 0x37a04 // abbr
|
||||
About Hash = 0x5 // about
|
||||
Accept Hash = 0x1106 // accept
|
||||
Accept_Charset Hash = 0x110e // accept-charset
|
||||
Action Hash = 0x23f06 // action
|
||||
Address Hash = 0x5a07 // address
|
||||
Align Hash = 0x32705 // align
|
||||
Alink Hash = 0x7005 // alink
|
||||
Allowfullscreen Hash = 0x2ad0f // allowfullscreen
|
||||
Amp_Boilerplate Hash = 0x610f // amp-boilerplate
|
||||
Area Hash = 0x1e304 // area
|
||||
Article Hash = 0x2707 // article
|
||||
Aside Hash = 0xb405 // aside
|
||||
Async Hash = 0xac05 // async
|
||||
Audio Hash = 0xd105 // audio
|
||||
Autofocus Hash = 0xe409 // autofocus
|
||||
Autoplay Hash = 0x10808 // autoplay
|
||||
Axis Hash = 0x11004 // axis
|
||||
B Hash = 0x101 // b
|
||||
Background Hash = 0x300a // background
|
||||
Base Hash = 0x19604 // base
|
||||
Bb Hash = 0x37b02 // bb
|
||||
Bdi Hash = 0x7503 // bdi
|
||||
Bdo Hash = 0x31f03 // bdo
|
||||
Bgcolor Hash = 0x12607 // bgcolor
|
||||
Blockquote Hash = 0x13e0a // blockquote
|
||||
Body Hash = 0xd04 // body
|
||||
Br Hash = 0x37c02 // br
|
||||
Button Hash = 0x14806 // button
|
||||
Canvas Hash = 0xb006 // canvas
|
||||
Caption Hash = 0x21f07 // caption
|
||||
Charset Hash = 0x1807 // charset
|
||||
Checked Hash = 0x1b307 // checked
|
||||
Cite Hash = 0xfb04 // cite
|
||||
Class Hash = 0x15905 // class
|
||||
Classid Hash = 0x15907 // classid
|
||||
Clear Hash = 0x2b05 // clear
|
||||
Code Hash = 0x19204 // code
|
||||
Codebase Hash = 0x19208 // codebase
|
||||
Codetype Hash = 0x1a408 // codetype
|
||||
Col Hash = 0x12803 // col
|
||||
Colgroup Hash = 0x1bb08 // colgroup
|
||||
Color Hash = 0x12805 // color
|
||||
Cols Hash = 0x1cf04 // cols
|
||||
Colspan Hash = 0x1cf07 // colspan
|
||||
Compact Hash = 0x1ec07 // compact
|
||||
Content Hash = 0x28407 // content
|
||||
Controls Hash = 0x20108 // controls
|
||||
Data Hash = 0x1f04 // data
|
||||
Datalist Hash = 0x1f08 // datalist
|
||||
Datatype Hash = 0x4d08 // datatype
|
||||
Dd Hash = 0x5b02 // dd
|
||||
Declare Hash = 0xb707 // declare
|
||||
Default Hash = 0x7f07 // default
|
||||
DefaultChecked Hash = 0x1730e // defaultChecked
|
||||
DefaultMuted Hash = 0x7f0c // defaultMuted
|
||||
DefaultSelected Hash = 0x8a0f // defaultSelected
|
||||
Defer Hash = 0x9805 // defer
|
||||
Del Hash = 0x10503 // del
|
||||
Details Hash = 0x15f07 // details
|
||||
Dfn Hash = 0x16c03 // dfn
|
||||
Dialog Hash = 0xa606 // dialog
|
||||
Dir Hash = 0x7603 // dir
|
||||
Disabled Hash = 0x18008 // disabled
|
||||
Div Hash = 0x18703 // div
|
||||
Dl Hash = 0x1b902 // dl
|
||||
Dt Hash = 0x23102 // dt
|
||||
Em Hash = 0x4302 // em
|
||||
Embed Hash = 0x4905 // embed
|
||||
Enabled Hash = 0x26c07 // enabled
|
||||
Enctype Hash = 0x1fa07 // enctype
|
||||
Face Hash = 0x5604 // face
|
||||
Fieldset Hash = 0x21408 // fieldset
|
||||
Figcaption Hash = 0x21c0a // figcaption
|
||||
Figure Hash = 0x22606 // figure
|
||||
Footer Hash = 0xdb06 // footer
|
||||
For Hash = 0x23b03 // for
|
||||
Form Hash = 0x23b04 // form
|
||||
Formaction Hash = 0x23b0a // formaction
|
||||
Formnovalidate Hash = 0x2450e // formnovalidate
|
||||
Frame Hash = 0x28c05 // frame
|
||||
Frameborder Hash = 0x28c0b // frameborder
|
||||
H1 Hash = 0x2e002 // h1
|
||||
H2 Hash = 0x25302 // h2
|
||||
H3 Hash = 0x25502 // h3
|
||||
H4 Hash = 0x25702 // h4
|
||||
H5 Hash = 0x25902 // h5
|
||||
H6 Hash = 0x25b02 // h6
|
||||
Head Hash = 0x2d204 // head
|
||||
Header Hash = 0x2d206 // header
|
||||
Hgroup Hash = 0x25d06 // hgroup
|
||||
Hidden Hash = 0x26806 // hidden
|
||||
Hr Hash = 0x32d02 // hr
|
||||
Href Hash = 0x32d04 // href
|
||||
Hreflang Hash = 0x32d08 // hreflang
|
||||
Html Hash = 0x27304 // html
|
||||
Http_Equiv Hash = 0x2770a // http-equiv
|
||||
I Hash = 0x2401 // i
|
||||
Icon Hash = 0x28304 // icon
|
||||
Id Hash = 0xb602 // id
|
||||
Iframe Hash = 0x28b06 // iframe
|
||||
Img Hash = 0x29703 // img
|
||||
Inert Hash = 0xf605 // inert
|
||||
Inlist Hash = 0x29a06 // inlist
|
||||
Input Hash = 0x2a405 // input
|
||||
Ins Hash = 0x2a903 // ins
|
||||
Ismap Hash = 0x11205 // ismap
|
||||
Itemscope Hash = 0xfc09 // itemscope
|
||||
Kbd Hash = 0x7403 // kbd
|
||||
Keygen Hash = 0x1f606 // keygen
|
||||
Label Hash = 0xbe05 // label
|
||||
Lang Hash = 0x33104 // lang
|
||||
Language Hash = 0x33108 // language
|
||||
Legend Hash = 0x2c506 // legend
|
||||
Li Hash = 0x2302 // li
|
||||
Link Hash = 0x7104 // link
|
||||
Longdesc Hash = 0xc208 // longdesc
|
||||
Main Hash = 0xf404 // main
|
||||
Manifest Hash = 0x2bc08 // manifest
|
||||
Map Hash = 0xee03 // map
|
||||
Mark Hash = 0x2cb04 // mark
|
||||
Math Hash = 0x2cf04 // math
|
||||
Max Hash = 0x2d803 // max
|
||||
Maxlength Hash = 0x2d809 // maxlength
|
||||
Media Hash = 0xa405 // media
|
||||
Menu Hash = 0x12204 // menu
|
||||
Meta Hash = 0x2e204 // meta
|
||||
Meter Hash = 0x2f705 // meter
|
||||
Method Hash = 0x2fc06 // method
|
||||
Multiple Hash = 0x30208 // multiple
|
||||
Muted Hash = 0x30a05 // muted
|
||||
Name Hash = 0xa204 // name
|
||||
Nav Hash = 0x32403 // nav
|
||||
Nohref Hash = 0x32b06 // nohref
|
||||
Noresize Hash = 0x13608 // noresize
|
||||
Noscript Hash = 0x14d08 // noscript
|
||||
Noshade Hash = 0x16e07 // noshade
|
||||
Novalidate Hash = 0x2490a // novalidate
|
||||
Nowrap Hash = 0x1d506 // nowrap
|
||||
Object Hash = 0xd506 // object
|
||||
Ol Hash = 0xcb02 // ol
|
||||
Open Hash = 0x32104 // open
|
||||
Optgroup Hash = 0x35608 // optgroup
|
||||
Option Hash = 0x30f06 // option
|
||||
Output Hash = 0x206 // output
|
||||
P Hash = 0x501 // p
|
||||
Param Hash = 0xf005 // param
|
||||
Pauseonexit Hash = 0x1160b // pauseonexit
|
||||
Picture Hash = 0x1c207 // picture
|
||||
Plaintext Hash = 0x1da09 // plaintext
|
||||
Poster Hash = 0x26206 // poster
|
||||
Pre Hash = 0x35d03 // pre
|
||||
Prefix Hash = 0x35d06 // prefix
|
||||
Profile Hash = 0x36407 // profile
|
||||
Progress Hash = 0x34208 // progress
|
||||
Property Hash = 0x31508 // property
|
||||
Q Hash = 0x14301 // q
|
||||
Rb Hash = 0x2f02 // rb
|
||||
Readonly Hash = 0x1e408 // readonly
|
||||
Rel Hash = 0xbc03 // rel
|
||||
Required Hash = 0x22a08 // required
|
||||
Resource Hash = 0x1c708 // resource
|
||||
Rev Hash = 0x7803 // rev
|
||||
Reversed Hash = 0x7808 // reversed
|
||||
Rows Hash = 0x9c04 // rows
|
||||
Rowspan Hash = 0x9c07 // rowspan
|
||||
Rp Hash = 0x6a02 // rp
|
||||
Rt Hash = 0x2802 // rt
|
||||
Rtc Hash = 0xf903 // rtc
|
||||
Ruby Hash = 0xe004 // ruby
|
||||
Rules Hash = 0x12c05 // rules
|
||||
S Hash = 0x1c01 // s
|
||||
Samp Hash = 0x6004 // samp
|
||||
Scope Hash = 0x10005 // scope
|
||||
Scoped Hash = 0x10006 // scoped
|
||||
Script Hash = 0x14f06 // script
|
||||
Scrolling Hash = 0xc809 // scrolling
|
||||
Seamless Hash = 0x19808 // seamless
|
||||
Section Hash = 0x13007 // section
|
||||
Select Hash = 0x16506 // select
|
||||
Selected Hash = 0x16508 // selected
|
||||
Shape Hash = 0x19f05 // shape
|
||||
Size Hash = 0x13a04 // size
|
||||
Slot Hash = 0x20804 // slot
|
||||
Small Hash = 0x2ab05 // small
|
||||
Sortable Hash = 0x2ef08 // sortable
|
||||
Source Hash = 0x1c906 // source
|
||||
Span Hash = 0x9f04 // span
|
||||
Src Hash = 0x34903 // src
|
||||
Srcset Hash = 0x34906 // srcset
|
||||
Start Hash = 0x2505 // start
|
||||
Strong Hash = 0x29e06 // strong
|
||||
Style Hash = 0x2c205 // style
|
||||
Sub Hash = 0x31d03 // sub
|
||||
Summary Hash = 0x33907 // summary
|
||||
Sup Hash = 0x34003 // sup
|
||||
Svg Hash = 0x34f03 // svg
|
||||
Tabindex Hash = 0x2e408 // tabindex
|
||||
Table Hash = 0x2f205 // table
|
||||
Target Hash = 0x706 // target
|
||||
Tbody Hash = 0xc05 // tbody
|
||||
Td Hash = 0x1e02 // td
|
||||
Template Hash = 0x4208 // template
|
||||
Text Hash = 0x1df04 // text
|
||||
Textarea Hash = 0x1df08 // textarea
|
||||
Tfoot Hash = 0xda05 // tfoot
|
||||
Th Hash = 0x2d102 // th
|
||||
Thead Hash = 0x2d105 // thead
|
||||
Time Hash = 0x12004 // time
|
||||
Title Hash = 0x15405 // title
|
||||
Tr Hash = 0x1f202 // tr
|
||||
Track Hash = 0x1f205 // track
|
||||
Translate Hash = 0x20b09 // translate
|
||||
Truespeed Hash = 0x23209 // truespeed
|
||||
Type Hash = 0x5104 // type
|
||||
Typemustmatch Hash = 0x1a80d // typemustmatch
|
||||
Typeof Hash = 0x5106 // typeof
|
||||
U Hash = 0x301 // u
|
||||
Ul Hash = 0x8302 // ul
|
||||
Undeterminate Hash = 0x370d // undeterminate
|
||||
Usemap Hash = 0xeb06 // usemap
|
||||
Valign Hash = 0x32606 // valign
|
||||
Value Hash = 0x18905 // value
|
||||
Valuetype Hash = 0x18909 // valuetype
|
||||
Var Hash = 0x28003 // var
|
||||
Video Hash = 0x35205 // video
|
||||
Visible Hash = 0x36b07 // visible
|
||||
Vlink Hash = 0x37205 // vlink
|
||||
Vocab Hash = 0x37705 // vocab
|
||||
Wbr Hash = 0x37e03 // wbr
|
||||
Xmlns Hash = 0x2eb05 // xmlns
|
||||
Xmp Hash = 0x36203 // xmp
|
||||
)
|
||||
|
||||
// String returns the hash' name.
|
||||
func (i Hash) String() string {
|
||||
start := uint32(i >> 8)
|
||||
n := uint32(i & 0xff)
|
||||
if start+n > uint32(len(_Hash_text)) {
|
||||
return ""
|
||||
}
|
||||
return _Hash_text[start : start+n]
|
||||
}
|
||||
|
||||
// ToHash returns the hash whose name is s. It returns zero if there is no
|
||||
// such hash. It is case sensitive.
|
||||
func ToHash(s []byte) Hash {
|
||||
if len(s) == 0 || len(s) > _Hash_maxLen {
|
||||
return 0
|
||||
}
|
||||
h := uint32(_Hash_hash0)
|
||||
for i := 0; i < len(s); i++ {
|
||||
h ^= uint32(s[i])
|
||||
h *= 16777619
|
||||
}
|
||||
if i := _Hash_table[h&uint32(len(_Hash_table)-1)]; int(i&0xff) == len(s) {
|
||||
t := _Hash_text[i>>8 : i>>8+i&0xff]
|
||||
for i := 0; i < len(s); i++ {
|
||||
if t[i] != s[i] {
|
||||
goto NEXT
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
NEXT:
|
||||
if i := _Hash_table[(h>>16)&uint32(len(_Hash_table)-1)]; int(i&0xff) == len(s) {
|
||||
t := _Hash_text[i>>8 : i>>8+i&0xff]
|
||||
for i := 0; i < len(s); i++ {
|
||||
if t[i] != s[i] {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
return i
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
const _Hash_hash0 = 0x9acb0442
|
||||
const _Hash_maxLen = 15
|
||||
const _Hash_text = "aboutputargetbodyaccept-charsetdatalistarticlearbackgroundet" +
|
||||
"erminatemplatembedatatypeofaceaddressamp-boilerplatealinkbdi" +
|
||||
"reversedefaultMutedefaultSelectedeferowspanamedialogasyncanv" +
|
||||
"asideclarelabelongdescrollingaudiobjectfooterubyautofocusema" +
|
||||
"paramainertcitemscopedelautoplayaxismapauseonexitimenubgcolo" +
|
||||
"rulesectionoresizeblockquotebuttonoscriptitleclassidetailsel" +
|
||||
"ectedfnoshadefaultCheckedisabledivaluetypecodebaseamlesshape" +
|
||||
"codetypemustmatcheckedlcolgroupicturesourcecolspanowraplaint" +
|
||||
"extareadonlycompactrackeygenctypecontrolslotranslatefieldset" +
|
||||
"figcaptionfigurequiredtruespeedformactionformnovalidateh2h3h" +
|
||||
"4h5h6hgrouposterhiddenabledhtmlhttp-equivaricontentiframebor" +
|
||||
"derimginlistronginputinsmallowfullscreenmanifestylegendmarkm" +
|
||||
"atheadermaxlength1metabindexmlnsortablemetermethodmultiplemu" +
|
||||
"tedoptionpropertysubdopenavalignohreflanguagesummarysuprogre" +
|
||||
"ssrcsetsvgvideoptgrouprefixmprofilevisiblevlinkvocabbrwbr"
|
||||
|
||||
var _Hash_table = [1 << 9]Hash{
|
||||
0x0: 0x1df08, // textarea
|
||||
0x4: 0x32d02, // hr
|
||||
0x8: 0x1c207, // picture
|
||||
0xb: 0x18905, // value
|
||||
0xf: 0x2e408, // tabindex
|
||||
0x12: 0x15905, // class
|
||||
0x15: 0x37e03, // wbr
|
||||
0x18: 0x1a80d, // typemustmatch
|
||||
0x1a: 0x1b902, // dl
|
||||
0x1d: 0xf903, // rtc
|
||||
0x1e: 0x25702, // h4
|
||||
0x22: 0x2ef08, // sortable
|
||||
0x24: 0x4208, // template
|
||||
0x25: 0x28c0b, // frameborder
|
||||
0x28: 0x37a04, // abbr
|
||||
0x29: 0x28b06, // iframe
|
||||
0x2a: 0x610f, // amp-boilerplate
|
||||
0x2c: 0x1e408, // readonly
|
||||
0x30: 0x23f06, // action
|
||||
0x33: 0x28c05, // frame
|
||||
0x35: 0x12c05, // rules
|
||||
0x36: 0x30208, // multiple
|
||||
0x38: 0x31f03, // bdo
|
||||
0x39: 0x1d506, // nowrap
|
||||
0x3e: 0x21408, // fieldset
|
||||
0x3f: 0x7503, // bdi
|
||||
0x46: 0x7f0c, // defaultMuted
|
||||
0x49: 0x35205, // video
|
||||
0x4c: 0x19808, // seamless
|
||||
0x4d: 0x13608, // noresize
|
||||
0x4f: 0xb602, // id
|
||||
0x51: 0x25d06, // hgroup
|
||||
0x52: 0x23102, // dt
|
||||
0x55: 0x12805, // color
|
||||
0x56: 0x34003, // sup
|
||||
0x59: 0x370d, // undeterminate
|
||||
0x5a: 0x35608, // optgroup
|
||||
0x5b: 0x2d206, // header
|
||||
0x5c: 0xb405, // aside
|
||||
0x5f: 0x10005, // scope
|
||||
0x60: 0x101, // b
|
||||
0x61: 0xcb02, // ol
|
||||
0x64: 0x32b06, // nohref
|
||||
0x65: 0x1da09, // plaintext
|
||||
0x66: 0x20804, // slot
|
||||
0x67: 0x11004, // axis
|
||||
0x68: 0x12803, // col
|
||||
0x69: 0x32606, // valign
|
||||
0x6c: 0x2d105, // thead
|
||||
0x70: 0x34906, // srcset
|
||||
0x71: 0x26806, // hidden
|
||||
0x76: 0x1bb08, // colgroup
|
||||
0x78: 0x34f03, // svg
|
||||
0x7b: 0x2cb04, // mark
|
||||
0x7e: 0x33104, // lang
|
||||
0x81: 0x1cf04, // cols
|
||||
0x86: 0x5a07, // address
|
||||
0x8b: 0xf404, // main
|
||||
0x8c: 0x4302, // em
|
||||
0x8f: 0x32d08, // hreflang
|
||||
0x93: 0x1b307, // checked
|
||||
0x94: 0x25902, // h5
|
||||
0x95: 0x301, // u
|
||||
0x96: 0x32705, // align
|
||||
0x97: 0x14301, // q
|
||||
0x99: 0xd506, // object
|
||||
0x9b: 0x28407, // content
|
||||
0x9d: 0xc809, // scrolling
|
||||
0x9f: 0x36407, // profile
|
||||
0xa0: 0x34903, // src
|
||||
0xa1: 0xda05, // tfoot
|
||||
0xa3: 0x2f705, // meter
|
||||
0xa4: 0x37705, // vocab
|
||||
0xa6: 0xd04, // body
|
||||
0xa8: 0x19204, // code
|
||||
0xac: 0x20108, // controls
|
||||
0xb0: 0x2ab05, // small
|
||||
0xb1: 0x18008, // disabled
|
||||
0xb5: 0x5604, // face
|
||||
0xb6: 0x501, // p
|
||||
0xb9: 0x2302, // li
|
||||
0xbb: 0xe409, // autofocus
|
||||
0xbf: 0x27304, // html
|
||||
0xc2: 0x4d08, // datatype
|
||||
0xc6: 0x35d06, // prefix
|
||||
0xcb: 0x35d03, // pre
|
||||
0xcc: 0x1106, // accept
|
||||
0xd1: 0x23b03, // for
|
||||
0xd5: 0x29e06, // strong
|
||||
0xd6: 0x9c07, // rowspan
|
||||
0xd7: 0x25502, // h3
|
||||
0xd8: 0x2cf04, // math
|
||||
0xde: 0x16e07, // noshade
|
||||
0xdf: 0x19f05, // shape
|
||||
0xe1: 0x10006, // scoped
|
||||
0xe3: 0x706, // target
|
||||
0xe6: 0x21c0a, // figcaption
|
||||
0xe9: 0x1df04, // text
|
||||
0xea: 0x1c708, // resource
|
||||
0xec: 0xee03, // map
|
||||
0xf0: 0x29a06, // inlist
|
||||
0xf1: 0x16506, // select
|
||||
0xf2: 0x1f606, // keygen
|
||||
0xf3: 0x5106, // typeof
|
||||
0xf6: 0xb006, // canvas
|
||||
0xf7: 0x30f06, // option
|
||||
0xf8: 0xbe05, // label
|
||||
0xf9: 0xbc03, // rel
|
||||
0xfb: 0x1f04, // data
|
||||
0xfd: 0x6004, // samp
|
||||
0x100: 0x110e, // accept-charset
|
||||
0x101: 0xeb06, // usemap
|
||||
0x103: 0x2bc08, // manifest
|
||||
0x109: 0xa204, // name
|
||||
0x10a: 0x14806, // button
|
||||
0x10b: 0x2b05, // clear
|
||||
0x10e: 0x33907, // summary
|
||||
0x10f: 0x2e204, // meta
|
||||
0x110: 0x33108, // language
|
||||
0x112: 0x300a, // background
|
||||
0x113: 0x2707, // article
|
||||
0x116: 0x23b0a, // formaction
|
||||
0x119: 0x1, // a
|
||||
0x11b: 0x5, // about
|
||||
0x11c: 0xfc09, // itemscope
|
||||
0x11e: 0x14d08, // noscript
|
||||
0x11f: 0x15907, // classid
|
||||
0x120: 0x36203, // xmp
|
||||
0x121: 0x19604, // base
|
||||
0x123: 0x1c01, // s
|
||||
0x124: 0x36b07, // visible
|
||||
0x126: 0x37b02, // bb
|
||||
0x127: 0x9c04, // rows
|
||||
0x12d: 0x2450e, // formnovalidate
|
||||
0x131: 0x1f205, // track
|
||||
0x135: 0x18703, // div
|
||||
0x136: 0xac05, // async
|
||||
0x137: 0x31508, // property
|
||||
0x13a: 0x16c03, // dfn
|
||||
0x13e: 0xf605, // inert
|
||||
0x142: 0x10503, // del
|
||||
0x144: 0x25302, // h2
|
||||
0x147: 0x2c205, // style
|
||||
0x149: 0x29703, // img
|
||||
0x14a: 0xc05, // tbody
|
||||
0x14b: 0x7603, // dir
|
||||
0x14c: 0x2eb05, // xmlns
|
||||
0x14e: 0x1f08, // datalist
|
||||
0x14f: 0x32d04, // href
|
||||
0x150: 0x1f202, // tr
|
||||
0x151: 0x13e0a, // blockquote
|
||||
0x152: 0x18909, // valuetype
|
||||
0x155: 0xdb06, // footer
|
||||
0x157: 0x14f06, // script
|
||||
0x158: 0x1cf07, // colspan
|
||||
0x15d: 0x1730e, // defaultChecked
|
||||
0x15f: 0x2490a, // novalidate
|
||||
0x164: 0x1a408, // codetype
|
||||
0x165: 0x2c506, // legend
|
||||
0x16b: 0x1160b, // pauseonexit
|
||||
0x16c: 0x21f07, // caption
|
||||
0x16f: 0x26c07, // enabled
|
||||
0x173: 0x26206, // poster
|
||||
0x175: 0x30a05, // muted
|
||||
0x176: 0x11205, // ismap
|
||||
0x178: 0x2a903, // ins
|
||||
0x17a: 0xe004, // ruby
|
||||
0x17b: 0x37c02, // br
|
||||
0x17c: 0x8a0f, // defaultSelected
|
||||
0x17d: 0x7403, // kbd
|
||||
0x17f: 0x1c906, // source
|
||||
0x182: 0x9f04, // span
|
||||
0x184: 0x2d803, // max
|
||||
0x18a: 0x5b02, // dd
|
||||
0x18b: 0x13a04, // size
|
||||
0x18c: 0xa405, // media
|
||||
0x18d: 0x19208, // codebase
|
||||
0x18f: 0x4905, // embed
|
||||
0x192: 0x5104, // type
|
||||
0x193: 0xf005, // param
|
||||
0x194: 0x25b02, // h6
|
||||
0x197: 0x28304, // icon
|
||||
0x198: 0x12607, // bgcolor
|
||||
0x199: 0x2ad0f, // allowfullscreen
|
||||
0x19a: 0x12004, // time
|
||||
0x19b: 0x7803, // rev
|
||||
0x19d: 0x34208, // progress
|
||||
0x19e: 0x22606, // figure
|
||||
0x1a0: 0x6a02, // rp
|
||||
0x1a2: 0xa606, // dialog
|
||||
0x1a4: 0x2802, // rt
|
||||
0x1a7: 0x1e304, // area
|
||||
0x1a8: 0x7808, // reversed
|
||||
0x1aa: 0x32104, // open
|
||||
0x1ac: 0x2d204, // head
|
||||
0x1ad: 0x7005, // alink
|
||||
0x1af: 0x28003, // var
|
||||
0x1b0: 0x15f07, // details
|
||||
0x1b1: 0x2401, // i
|
||||
0x1b3: 0x1e02, // td
|
||||
0x1b4: 0xb707, // declare
|
||||
0x1b5: 0x8302, // ul
|
||||
0x1ba: 0x2fc06, // method
|
||||
0x1bd: 0x13007, // section
|
||||
0x1be: 0x22a08, // required
|
||||
0x1c2: 0x9805, // defer
|
||||
0x1c3: 0x37205, // vlink
|
||||
0x1c4: 0x15405, // title
|
||||
0x1c5: 0x2770a, // http-equiv
|
||||
0x1c6: 0x1fa07, // enctype
|
||||
0x1c7: 0x1ec07, // compact
|
||||
0x1c8: 0x2d809, // maxlength
|
||||
0x1c9: 0x16508, // selected
|
||||
0x1cc: 0xd105, // audio
|
||||
0x1cd: 0xc208, // longdesc
|
||||
0x1d1: 0xfb04, // cite
|
||||
0x1da: 0x2505, // start
|
||||
0x1de: 0x2d102, // th
|
||||
0x1df: 0x10808, // autoplay
|
||||
0x1e2: 0x7104, // link
|
||||
0x1e3: 0x206, // output
|
||||
0x1e5: 0x12204, // menu
|
||||
0x1e6: 0x2a405, // input
|
||||
0x1eb: 0x32403, // nav
|
||||
0x1ec: 0x31d03, // sub
|
||||
0x1ee: 0x1807, // charset
|
||||
0x1ef: 0x7f07, // default
|
||||
0x1f3: 0x2f205, // table
|
||||
0x1f4: 0x23b04, // form
|
||||
0x1f5: 0x23209, // truespeed
|
||||
0x1f6: 0x2f02, // rb
|
||||
0x1fb: 0x20b09, // translate
|
||||
0x1fd: 0x2e002, // h1
|
||||
}
|
||||
513
vendor/github.com/tdewolff/minify/v2/html/html.go
generated
vendored
Normal file
513
vendor/github.com/tdewolff/minify/v2/html/html.go
generated
vendored
Normal file
|
|
@ -0,0 +1,513 @@
|
|||
// Package html minifies HTML5 following the specifications at http://www.w3.org/TR/html5/syntax.html.
|
||||
package html
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
|
||||
"github.com/tdewolff/minify/v2"
|
||||
"github.com/tdewolff/parse/v2"
|
||||
"github.com/tdewolff/parse/v2/buffer"
|
||||
"github.com/tdewolff/parse/v2/html"
|
||||
)
|
||||
|
||||
var (
|
||||
gtBytes = []byte(">")
|
||||
isBytes = []byte("=")
|
||||
spaceBytes = []byte(" ")
|
||||
doctypeBytes = []byte("<!doctype html>")
|
||||
jsMimeBytes = []byte("application/javascript")
|
||||
cssMimeBytes = []byte("text/css")
|
||||
htmlMimeBytes = []byte("text/html")
|
||||
svgMimeBytes = []byte("image/svg+xml")
|
||||
formMimeBytes = []byte("application/x-www-form-urlencoded")
|
||||
mathMimeBytes = []byte("application/mathml+xml")
|
||||
dataSchemeBytes = []byte("data:")
|
||||
jsSchemeBytes = []byte("javascript:")
|
||||
httpBytes = []byte("http")
|
||||
radioBytes = []byte("radio")
|
||||
onBytes = []byte("on")
|
||||
textBytes = []byte("text")
|
||||
noneBytes = []byte("none")
|
||||
submitBytes = []byte("submit")
|
||||
allBytes = []byte("all")
|
||||
rectBytes = []byte("rect")
|
||||
dataBytes = []byte("data")
|
||||
getBytes = []byte("get")
|
||||
autoBytes = []byte("auto")
|
||||
oneBytes = []byte("one")
|
||||
inlineParams = map[string]string{"inline": "1"}
|
||||
)
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
|
||||
// Minifier is an HTML minifier.
|
||||
type Minifier struct {
|
||||
KeepComments bool
|
||||
KeepConditionalComments bool
|
||||
KeepDefaultAttrVals bool
|
||||
KeepDocumentTags bool
|
||||
KeepEndTags bool
|
||||
KeepQuotes bool
|
||||
KeepWhitespace bool
|
||||
}
|
||||
|
||||
// Minify minifies HTML data, it reads from r and writes to w.
|
||||
func Minify(m *minify.M, w io.Writer, r io.Reader, params map[string]string) error {
|
||||
return (&Minifier{}).Minify(m, w, r, params)
|
||||
}
|
||||
|
||||
// Minify minifies HTML data, it reads from r and writes to w.
|
||||
func (o *Minifier) Minify(m *minify.M, w io.Writer, r io.Reader, _ map[string]string) error {
|
||||
var rawTagHash Hash
|
||||
var rawTagMediatype []byte
|
||||
|
||||
omitSpace := true // if true the next leading space is omitted
|
||||
inPre := false
|
||||
|
||||
attrMinifyBuffer := buffer.NewWriter(make([]byte, 0, 64))
|
||||
attrByteBuffer := make([]byte, 0, 64)
|
||||
|
||||
z := parse.NewInput(r)
|
||||
defer z.Restore()
|
||||
|
||||
l := html.NewLexer(z)
|
||||
tb := NewTokenBuffer(z, l)
|
||||
for {
|
||||
t := *tb.Shift()
|
||||
switch t.TokenType {
|
||||
case html.ErrorToken:
|
||||
if _, err := w.Write(nil); err != nil {
|
||||
return err
|
||||
}
|
||||
if l.Err() == io.EOF {
|
||||
return nil
|
||||
}
|
||||
return l.Err()
|
||||
case html.DoctypeToken:
|
||||
w.Write(doctypeBytes)
|
||||
case html.CommentToken:
|
||||
if o.KeepComments {
|
||||
w.Write(t.Data)
|
||||
} else if o.KeepConditionalComments && 6 < len(t.Text) && (bytes.HasPrefix(t.Text, []byte("[if ")) || bytes.HasSuffix(t.Text, []byte("[endif]")) || bytes.HasSuffix(t.Text, []byte("[endif]--"))) {
|
||||
// [if ...] is always 7 or more characters, [endif] is only encountered for downlevel-revealed
|
||||
// see https://msdn.microsoft.com/en-us/library/ms537512(v=vs.85).aspx#syntax
|
||||
if bytes.HasPrefix(t.Data, []byte("<!--[if ")) && bytes.HasSuffix(t.Data, []byte("<![endif]-->")) { // downlevel-hidden
|
||||
begin := bytes.IndexByte(t.Data, '>') + 1
|
||||
end := len(t.Data) - len("<![endif]-->")
|
||||
w.Write(t.Data[:begin])
|
||||
if err := o.Minify(m, w, buffer.NewReader(t.Data[begin:end]), nil); err != nil {
|
||||
return minify.UpdateErrorPosition(err, z, t.Offset)
|
||||
}
|
||||
w.Write(t.Data[end:])
|
||||
} else {
|
||||
w.Write(t.Data) // downlevel-revealed or short downlevel-hidden
|
||||
}
|
||||
} else if 1 < len(t.Text) && t.Text[0] == '#' {
|
||||
// SSI tags
|
||||
w.Write(t.Data)
|
||||
}
|
||||
case html.SvgToken:
|
||||
if err := m.MinifyMimetype(svgMimeBytes, w, buffer.NewReader(t.Data), nil); err != nil {
|
||||
if err != minify.ErrNotExist {
|
||||
return minify.UpdateErrorPosition(err, z, t.Offset)
|
||||
}
|
||||
w.Write(t.Data)
|
||||
}
|
||||
case html.MathToken:
|
||||
if err := m.MinifyMimetype(mathMimeBytes, w, buffer.NewReader(t.Data), nil); err != nil {
|
||||
if err != minify.ErrNotExist {
|
||||
return minify.UpdateErrorPosition(err, z, t.Offset)
|
||||
}
|
||||
w.Write(t.Data)
|
||||
}
|
||||
case html.TextToken:
|
||||
// CSS and JS minifiers for inline code
|
||||
if rawTagHash != 0 {
|
||||
if rawTagHash == Style || rawTagHash == Script || rawTagHash == Iframe {
|
||||
var mimetype []byte
|
||||
var params map[string]string
|
||||
if rawTagHash == Iframe {
|
||||
mimetype = htmlMimeBytes
|
||||
} else if len(rawTagMediatype) > 0 {
|
||||
mimetype, params = parse.Mediatype(rawTagMediatype)
|
||||
} else if rawTagHash == Script {
|
||||
mimetype = jsMimeBytes
|
||||
} else if rawTagHash == Style {
|
||||
mimetype = cssMimeBytes
|
||||
}
|
||||
if err := m.MinifyMimetype(mimetype, w, buffer.NewReader(t.Data), params); err != nil {
|
||||
if err != minify.ErrNotExist {
|
||||
return minify.UpdateErrorPosition(err, z, t.Offset)
|
||||
}
|
||||
w.Write(t.Data)
|
||||
}
|
||||
} else {
|
||||
w.Write(t.Data)
|
||||
}
|
||||
} else if inPre {
|
||||
w.Write(t.Data)
|
||||
} else {
|
||||
t.Data = parse.ReplaceMultipleWhitespaceAndEntities(t.Data, EntitiesMap, TextRevEntitiesMap)
|
||||
|
||||
// whitespace removal; trim left
|
||||
if omitSpace && parse.IsWhitespace(t.Data[0]) {
|
||||
t.Data = t.Data[1:]
|
||||
}
|
||||
|
||||
// whitespace removal; trim right
|
||||
omitSpace = false
|
||||
if len(t.Data) == 0 {
|
||||
omitSpace = true
|
||||
} else if parse.IsWhitespace(t.Data[len(t.Data)-1]) {
|
||||
omitSpace = true
|
||||
i := 0
|
||||
for {
|
||||
next := tb.Peek(i)
|
||||
// trim if EOF, text token with leading whitespace or block token
|
||||
if next.TokenType == html.ErrorToken {
|
||||
t.Data = t.Data[:len(t.Data)-1]
|
||||
omitSpace = false
|
||||
break
|
||||
} else if next.TokenType == html.TextToken {
|
||||
// this only happens when a comment, doctype or phrasing end tag (only for !o.KeepWhitespace) was in between
|
||||
// remove if the text token starts with a whitespace
|
||||
if len(next.Data) > 0 && parse.IsWhitespace(next.Data[0]) {
|
||||
t.Data = t.Data[:len(t.Data)-1]
|
||||
omitSpace = false
|
||||
}
|
||||
break
|
||||
} else if next.TokenType == html.StartTagToken || next.TokenType == html.EndTagToken {
|
||||
if o.KeepWhitespace {
|
||||
break
|
||||
}
|
||||
// remove when followed up by a block tag
|
||||
if next.Traits&nonPhrasingTag != 0 {
|
||||
t.Data = t.Data[:len(t.Data)-1]
|
||||
omitSpace = false
|
||||
break
|
||||
} else if next.TokenType == html.StartTagToken {
|
||||
break
|
||||
}
|
||||
}
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
w.Write(t.Data)
|
||||
}
|
||||
case html.StartTagToken, html.EndTagToken:
|
||||
rawTagHash = 0
|
||||
hasAttributes := false
|
||||
if t.TokenType == html.StartTagToken {
|
||||
if next := tb.Peek(0); next.TokenType == html.AttributeToken {
|
||||
hasAttributes = true
|
||||
}
|
||||
if t.Traits&rawTag != 0 {
|
||||
// ignore empty script and style tags
|
||||
if !hasAttributes && (t.Hash == Script || t.Hash == Style) {
|
||||
if next := tb.Peek(1); next.TokenType == html.EndTagToken {
|
||||
tb.Shift()
|
||||
tb.Shift()
|
||||
break
|
||||
}
|
||||
}
|
||||
rawTagHash = t.Hash
|
||||
rawTagMediatype = nil
|
||||
|
||||
// do not minify content of <style amp-boilerplate>
|
||||
if hasAttributes && t.Hash == Style {
|
||||
if attrs := tb.Attributes(Amp_Boilerplate); attrs[0] != nil {
|
||||
rawTagHash = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if t.Hash == Template {
|
||||
omitSpace = true // EndTagToken
|
||||
}
|
||||
|
||||
if t.Hash == Pre {
|
||||
inPre = t.TokenType == html.StartTagToken
|
||||
}
|
||||
|
||||
// remove superfluous tags, except for html, head and body tags when KeepDocumentTags is set
|
||||
if !hasAttributes && (!o.KeepDocumentTags && (t.Hash == Html || t.Hash == Head || t.Hash == Body) || t.Hash == Colgroup) {
|
||||
break
|
||||
} else if t.TokenType == html.EndTagToken {
|
||||
omitEndTag := false
|
||||
if !o.KeepEndTags {
|
||||
if t.Hash == Thead || t.Hash == Tbody || t.Hash == Tfoot || t.Hash == Tr || t.Hash == Th ||
|
||||
t.Hash == Td || t.Hash == Option || t.Hash == Dd || t.Hash == Dt || t.Hash == Li ||
|
||||
t.Hash == Rb || t.Hash == Rt || t.Hash == Rtc || t.Hash == Rp {
|
||||
omitEndTag = true // omit end tags
|
||||
} else if t.Hash == P {
|
||||
i := 0
|
||||
for {
|
||||
next := tb.Peek(i)
|
||||
i++
|
||||
// continue if text token is empty or whitespace
|
||||
if next.TokenType == html.TextToken && parse.IsAllWhitespace(next.Data) {
|
||||
continue
|
||||
}
|
||||
if next.TokenType == html.ErrorToken || next.TokenType == html.EndTagToken && next.Traits&keepPTag == 0 || next.TokenType == html.StartTagToken && next.Traits&omitPTag != 0 {
|
||||
omitEndTag = true // omit p end tag
|
||||
}
|
||||
break
|
||||
}
|
||||
} else if t.Hash == Optgroup {
|
||||
i := 0
|
||||
for {
|
||||
next := tb.Peek(i)
|
||||
i++
|
||||
// continue if text token
|
||||
if next.TokenType == html.TextToken {
|
||||
continue
|
||||
}
|
||||
if next.TokenType == html.ErrorToken || next.Hash != Option {
|
||||
omitEndTag = true // omit optgroup end tag
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if t.Traits&nonPhrasingTag != 0 {
|
||||
omitSpace = true // omit spaces after block elements
|
||||
} else if o.KeepWhitespace || t.Traits&objectTag != 0 {
|
||||
omitSpace = false
|
||||
}
|
||||
|
||||
if !omitEndTag {
|
||||
if len(t.Data) > 3+len(t.Text) {
|
||||
t.Data[2+len(t.Text)] = '>'
|
||||
t.Data = t.Data[:3+len(t.Text)]
|
||||
}
|
||||
w.Write(t.Data)
|
||||
}
|
||||
|
||||
// skip text in select and optgroup tags
|
||||
if t.Hash == Option || t.Hash == Optgroup {
|
||||
if next := tb.Peek(0); next.TokenType == html.TextToken {
|
||||
tb.Shift()
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
if o.KeepWhitespace || t.Traits&objectTag != 0 {
|
||||
omitSpace = false
|
||||
} else if t.Traits&nonPhrasingTag != 0 {
|
||||
omitSpace = true // omit spaces after block elements
|
||||
}
|
||||
|
||||
w.Write(t.Data)
|
||||
|
||||
if hasAttributes {
|
||||
if t.Hash == Meta {
|
||||
attrs := tb.Attributes(Content, Http_Equiv, Charset, Name)
|
||||
if content := attrs[0]; content != nil {
|
||||
if httpEquiv := attrs[1]; httpEquiv != nil {
|
||||
httpEquiv.AttrVal = parse.TrimWhitespace(httpEquiv.AttrVal)
|
||||
if charset := attrs[2]; charset == nil && parse.EqualFold(httpEquiv.AttrVal, []byte("content-type")) {
|
||||
content.AttrVal = minify.Mediatype(content.AttrVal)
|
||||
if bytes.Equal(content.AttrVal, []byte("text/html;charset=utf-8")) {
|
||||
httpEquiv.Text = nil
|
||||
content.Text = []byte("charset")
|
||||
content.Hash = Charset
|
||||
content.AttrVal = []byte("utf-8")
|
||||
}
|
||||
}
|
||||
}
|
||||
if name := attrs[3]; name != nil {
|
||||
name.AttrVal = parse.TrimWhitespace(name.AttrVal)
|
||||
if parse.EqualFold(name.AttrVal, []byte("keywords")) {
|
||||
content.AttrVal = bytes.ReplaceAll(content.AttrVal, []byte(", "), []byte(","))
|
||||
} else if parse.EqualFold(name.AttrVal, []byte("viewport")) {
|
||||
content.AttrVal = bytes.ReplaceAll(content.AttrVal, []byte(" "), []byte(""))
|
||||
for i := 0; i < len(content.AttrVal); i++ {
|
||||
if content.AttrVal[i] == '=' && i+2 < len(content.AttrVal) {
|
||||
i++
|
||||
if n := parse.Number(content.AttrVal[i:]); n > 0 {
|
||||
minNum := minify.Number(content.AttrVal[i:i+n], -1)
|
||||
if len(minNum) < n {
|
||||
copy(content.AttrVal[i:i+len(minNum)], minNum)
|
||||
copy(content.AttrVal[i+len(minNum):], content.AttrVal[i+n:])
|
||||
content.AttrVal = content.AttrVal[:len(content.AttrVal)+len(minNum)-n]
|
||||
}
|
||||
i += len(minNum)
|
||||
}
|
||||
i-- // mitigate for-loop increase
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if t.Hash == Script {
|
||||
attrs := tb.Attributes(Src, Charset)
|
||||
if attrs[0] != nil && attrs[1] != nil {
|
||||
attrs[1].Text = nil
|
||||
}
|
||||
} else if t.Hash == Input {
|
||||
attrs := tb.Attributes(Type, Value)
|
||||
if t, value := attrs[0], attrs[1]; t != nil && value != nil {
|
||||
isRadio := parse.EqualFold(t.AttrVal, radioBytes)
|
||||
if !isRadio && len(value.AttrVal) == 0 {
|
||||
value.Text = nil
|
||||
} else if isRadio && parse.EqualFold(value.AttrVal, onBytes) {
|
||||
value.Text = nil
|
||||
}
|
||||
}
|
||||
} else if t.Hash == A {
|
||||
attrs := tb.Attributes(Id, Name)
|
||||
if id, name := attrs[0], attrs[1]; id != nil && name != nil {
|
||||
if bytes.Equal(id.AttrVal, name.AttrVal) {
|
||||
name.Text = nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// write attributes
|
||||
for {
|
||||
attr := *tb.Shift()
|
||||
if attr.TokenType != html.AttributeToken {
|
||||
break
|
||||
} else if attr.Text == nil {
|
||||
continue // removed attribute
|
||||
}
|
||||
|
||||
val := attr.AttrVal
|
||||
if attr.Traits&trimAttr != 0 {
|
||||
val = parse.ReplaceMultipleWhitespaceAndEntities(val, EntitiesMap, nil)
|
||||
val = parse.TrimWhitespace(val)
|
||||
} else {
|
||||
val = parse.ReplaceEntities(val, EntitiesMap, nil)
|
||||
}
|
||||
if t.Traits != 0 {
|
||||
if len(val) == 0 && (attr.Hash == Class ||
|
||||
attr.Hash == Dir ||
|
||||
attr.Hash == Id ||
|
||||
attr.Hash == Name ||
|
||||
attr.Hash == Action && t.Hash == Form) {
|
||||
continue // omit empty attribute values
|
||||
}
|
||||
if attr.Traits&caselessAttr != 0 {
|
||||
val = parse.ToLower(val)
|
||||
if attr.Hash == Enctype || attr.Hash == Codetype || attr.Hash == Accept || attr.Hash == Type && (t.Hash == A || t.Hash == Link || t.Hash == Embed || t.Hash == Object || t.Hash == Source || t.Hash == Script || t.Hash == Style) {
|
||||
val = minify.Mediatype(val)
|
||||
}
|
||||
}
|
||||
if rawTagHash != 0 && attr.Hash == Type {
|
||||
rawTagMediatype = parse.Copy(val)
|
||||
}
|
||||
|
||||
// default attribute values can be omitted
|
||||
if !o.KeepDefaultAttrVals && (attr.Hash == Type && (t.Hash == Script && jsMimetypes[string(val)] ||
|
||||
t.Hash == Style && bytes.Equal(val, cssMimeBytes) ||
|
||||
t.Hash == Link && bytes.Equal(val, cssMimeBytes) ||
|
||||
t.Hash == Input && bytes.Equal(val, textBytes) ||
|
||||
t.Hash == Button && bytes.Equal(val, submitBytes)) ||
|
||||
attr.Hash == Language && t.Hash == Script ||
|
||||
attr.Hash == Method && bytes.Equal(val, getBytes) ||
|
||||
attr.Hash == Enctype && bytes.Equal(val, formMimeBytes) ||
|
||||
attr.Hash == Colspan && bytes.Equal(val, oneBytes) ||
|
||||
attr.Hash == Rowspan && bytes.Equal(val, oneBytes) ||
|
||||
attr.Hash == Shape && bytes.Equal(val, rectBytes) ||
|
||||
attr.Hash == Span && bytes.Equal(val, oneBytes) ||
|
||||
attr.Hash == Clear && bytes.Equal(val, noneBytes) ||
|
||||
attr.Hash == Frameborder && bytes.Equal(val, oneBytes) ||
|
||||
attr.Hash == Scrolling && bytes.Equal(val, autoBytes) ||
|
||||
attr.Hash == Valuetype && bytes.Equal(val, dataBytes) ||
|
||||
attr.Hash == Media && t.Hash == Style && bytes.Equal(val, allBytes)) {
|
||||
continue
|
||||
}
|
||||
|
||||
if attr.Hash == Style {
|
||||
// CSS minifier for attribute inline code
|
||||
val = parse.TrimWhitespace(val)
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(cssMimeBytes, attrMinifyBuffer, buffer.NewReader(val), inlineParams); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return minify.UpdateErrorPosition(err, z, attr.Offset)
|
||||
}
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
} else if len(attr.Text) > 2 && attr.Text[0] == 'o' && attr.Text[1] == 'n' {
|
||||
// JS minifier for attribute inline code
|
||||
val = parse.TrimWhitespace(val)
|
||||
if len(val) >= 11 && parse.EqualFold(val[:11], jsSchemeBytes) {
|
||||
val = val[11:]
|
||||
}
|
||||
attrMinifyBuffer.Reset()
|
||||
if err := m.MinifyMimetype(jsMimeBytes, attrMinifyBuffer, buffer.NewReader(val), nil); err == nil {
|
||||
val = attrMinifyBuffer.Bytes()
|
||||
} else if err != minify.ErrNotExist {
|
||||
return minify.UpdateErrorPosition(err, z, attr.Offset)
|
||||
}
|
||||
if len(val) == 0 {
|
||||
continue
|
||||
}
|
||||
} else if attr.Traits&urlAttr != 0 { // anchors are already handled
|
||||
val = parse.TrimWhitespace(val)
|
||||
if 5 < len(val) {
|
||||
if parse.EqualFold(val[:4], httpBytes) {
|
||||
if val[4] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "http" {
|
||||
val = val[5:]
|
||||
} else {
|
||||
parse.ToLower(val[:4])
|
||||
}
|
||||
} else if (val[4] == 's' || val[4] == 'S') && val[5] == ':' {
|
||||
if m.URL != nil && m.URL.Scheme == "https" {
|
||||
val = val[6:]
|
||||
} else {
|
||||
parse.ToLower(val[:5])
|
||||
}
|
||||
}
|
||||
} else if parse.EqualFold(val[:5], dataSchemeBytes) {
|
||||
val = minify.DataURI(m, val)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
w.Write(spaceBytes)
|
||||
w.Write(attr.Text)
|
||||
if len(val) > 0 && attr.Traits&booleanAttr == 0 {
|
||||
w.Write(isBytes)
|
||||
|
||||
// use double quotes for RDFa attributes
|
||||
isXML := attr.Hash == Vocab || attr.Hash == Typeof || attr.Hash == Property || attr.Hash == Resource || attr.Hash == Prefix || attr.Hash == Content || attr.Hash == About || attr.Hash == Rev || attr.Hash == Datatype || attr.Hash == Inlist
|
||||
|
||||
// no quotes if possible, else prefer single or double depending on which occurs more often in value
|
||||
var quote byte
|
||||
|
||||
if 0 < len(attr.Data) && (attr.Data[len(attr.Data)-1] == '\'' || attr.Data[len(attr.Data)-1] == '"') {
|
||||
quote = attr.Data[len(attr.Data)-1]
|
||||
}
|
||||
val = html.EscapeAttrVal(&attrByteBuffer, val, quote, o.KeepQuotes, isXML)
|
||||
w.Write(val)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
_ = tb.Shift() // StartTagClose
|
||||
}
|
||||
w.Write(gtBytes)
|
||||
|
||||
// skip text in select and optgroup tags
|
||||
if t.Hash == Select || t.Hash == Optgroup {
|
||||
if next := tb.Peek(0); next.TokenType == html.TextToken {
|
||||
tb.Shift()
|
||||
}
|
||||
}
|
||||
|
||||
// keep space after phrasing tags (<i>, <span>, ...) FontAwesome etc.
|
||||
if t.TokenType == html.StartTagToken && t.Traits&nonPhrasingTag == 0 {
|
||||
if next := tb.Peek(0); next.Hash == t.Hash && next.TokenType == html.EndTagToken {
|
||||
omitSpace = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
1346
vendor/github.com/tdewolff/minify/v2/html/table.go
generated
vendored
Normal file
1346
vendor/github.com/tdewolff/minify/v2/html/table.go
generated
vendored
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Add a link
Reference in a new issue