mirror of
https://github.com/gohugoio/hugo.git
synced 2025-08-31 22:41:53 +02:00
Create lightweight forks of text/template and html/template
This commit also removes support for Ace and Amber templates. Updates #6594
This commit is contained in:
258
tpl/internal/go_templates/htmltemplate/context.go
Normal file
258
tpl/internal/go_templates/htmltemplate/context.go
Normal file
@@ -0,0 +1,258 @@
|
||||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package template
|
||||
|
||||
import "fmt"
|
||||
|
||||
// context describes the state an HTML parser must be in when it reaches the
|
||||
// portion of HTML produced by evaluating a particular template node.
|
||||
//
|
||||
// The zero value of type context is the start context for a template that
|
||||
// produces an HTML fragment as defined at
|
||||
// https://www.w3.org/TR/html5/syntax.html#the-end
|
||||
// where the context element is null.
|
||||
type context struct {
|
||||
state state
|
||||
delim delim
|
||||
urlPart urlPart
|
||||
jsCtx jsCtx
|
||||
attr attr
|
||||
element element
|
||||
err *Error
|
||||
}
|
||||
|
||||
func (c context) String() string {
|
||||
var err error
|
||||
if c.err != nil {
|
||||
err = c.err
|
||||
}
|
||||
return fmt.Sprintf("{%v %v %v %v %v %v %v}", c.state, c.delim, c.urlPart, c.jsCtx, c.attr, c.element, err)
|
||||
}
|
||||
|
||||
// eq reports whether two contexts are equal.
|
||||
func (c context) eq(d context) bool {
|
||||
return c.state == d.state &&
|
||||
c.delim == d.delim &&
|
||||
c.urlPart == d.urlPart &&
|
||||
c.jsCtx == d.jsCtx &&
|
||||
c.attr == d.attr &&
|
||||
c.element == d.element &&
|
||||
c.err == d.err
|
||||
}
|
||||
|
||||
// mangle produces an identifier that includes a suffix that distinguishes it
|
||||
// from template names mangled with different contexts.
|
||||
func (c context) mangle(templateName string) string {
|
||||
// The mangled name for the default context is the input templateName.
|
||||
if c.state == stateText {
|
||||
return templateName
|
||||
}
|
||||
s := templateName + "$htmltemplate_" + c.state.String()
|
||||
if c.delim != delimNone {
|
||||
s += "_" + c.delim.String()
|
||||
}
|
||||
if c.urlPart != urlPartNone {
|
||||
s += "_" + c.urlPart.String()
|
||||
}
|
||||
if c.jsCtx != jsCtxRegexp {
|
||||
s += "_" + c.jsCtx.String()
|
||||
}
|
||||
if c.attr != attrNone {
|
||||
s += "_" + c.attr.String()
|
||||
}
|
||||
if c.element != elementNone {
|
||||
s += "_" + c.element.String()
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// state describes a high-level HTML parser state.
|
||||
//
|
||||
// It bounds the top of the element stack, and by extension the HTML insertion
|
||||
// mode, but also contains state that does not correspond to anything in the
|
||||
// HTML5 parsing algorithm because a single token production in the HTML
|
||||
// grammar may contain embedded actions in a template. For instance, the quoted
|
||||
// HTML attribute produced by
|
||||
// <div title="Hello {{.World}}">
|
||||
// is a single token in HTML's grammar but in a template spans several nodes.
|
||||
type state uint8
|
||||
|
||||
//go:generate stringer -type state
|
||||
|
||||
const (
|
||||
// stateText is parsed character data. An HTML parser is in
|
||||
// this state when its parse position is outside an HTML tag,
|
||||
// directive, comment, and special element body.
|
||||
stateText state = iota
|
||||
// stateTag occurs before an HTML attribute or the end of a tag.
|
||||
stateTag
|
||||
// stateAttrName occurs inside an attribute name.
|
||||
// It occurs between the ^'s in ` ^name^ = value`.
|
||||
stateAttrName
|
||||
// stateAfterName occurs after an attr name has ended but before any
|
||||
// equals sign. It occurs between the ^'s in ` name^ ^= value`.
|
||||
stateAfterName
|
||||
// stateBeforeValue occurs after the equals sign but before the value.
|
||||
// It occurs between the ^'s in ` name =^ ^value`.
|
||||
stateBeforeValue
|
||||
// stateHTMLCmt occurs inside an <!-- HTML comment -->.
|
||||
stateHTMLCmt
|
||||
// stateRCDATA occurs inside an RCDATA element (<textarea> or <title>)
|
||||
// as described at https://www.w3.org/TR/html5/syntax.html#elements-0
|
||||
stateRCDATA
|
||||
// stateAttr occurs inside an HTML attribute whose content is text.
|
||||
stateAttr
|
||||
// stateURL occurs inside an HTML attribute whose content is a URL.
|
||||
stateURL
|
||||
// stateSrcset occurs inside an HTML srcset attribute.
|
||||
stateSrcset
|
||||
// stateJS occurs inside an event handler or script element.
|
||||
stateJS
|
||||
// stateJSDqStr occurs inside a JavaScript double quoted string.
|
||||
stateJSDqStr
|
||||
// stateJSSqStr occurs inside a JavaScript single quoted string.
|
||||
stateJSSqStr
|
||||
// stateJSRegexp occurs inside a JavaScript regexp literal.
|
||||
stateJSRegexp
|
||||
// stateJSBlockCmt occurs inside a JavaScript /* block comment */.
|
||||
stateJSBlockCmt
|
||||
// stateJSLineCmt occurs inside a JavaScript // line comment.
|
||||
stateJSLineCmt
|
||||
// stateCSS occurs inside a <style> element or style attribute.
|
||||
stateCSS
|
||||
// stateCSSDqStr occurs inside a CSS double quoted string.
|
||||
stateCSSDqStr
|
||||
// stateCSSSqStr occurs inside a CSS single quoted string.
|
||||
stateCSSSqStr
|
||||
// stateCSSDqURL occurs inside a CSS double quoted url("...").
|
||||
stateCSSDqURL
|
||||
// stateCSSSqURL occurs inside a CSS single quoted url('...').
|
||||
stateCSSSqURL
|
||||
// stateCSSURL occurs inside a CSS unquoted url(...).
|
||||
stateCSSURL
|
||||
// stateCSSBlockCmt occurs inside a CSS /* block comment */.
|
||||
stateCSSBlockCmt
|
||||
// stateCSSLineCmt occurs inside a CSS // line comment.
|
||||
stateCSSLineCmt
|
||||
// stateError is an infectious error state outside any valid
|
||||
// HTML/CSS/JS construct.
|
||||
stateError
|
||||
)
|
||||
|
||||
// isComment is true for any state that contains content meant for template
|
||||
// authors & maintainers, not for end-users or machines.
|
||||
func isComment(s state) bool {
|
||||
switch s {
|
||||
case stateHTMLCmt, stateJSBlockCmt, stateJSLineCmt, stateCSSBlockCmt, stateCSSLineCmt:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// isInTag return whether s occurs solely inside an HTML tag.
|
||||
func isInTag(s state) bool {
|
||||
switch s {
|
||||
case stateTag, stateAttrName, stateAfterName, stateBeforeValue, stateAttr:
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
// delim is the delimiter that will end the current HTML attribute.
|
||||
type delim uint8
|
||||
|
||||
//go:generate stringer -type delim
|
||||
|
||||
const (
|
||||
// delimNone occurs outside any attribute.
|
||||
delimNone delim = iota
|
||||
// delimDoubleQuote occurs when a double quote (") closes the attribute.
|
||||
delimDoubleQuote
|
||||
// delimSingleQuote occurs when a single quote (') closes the attribute.
|
||||
delimSingleQuote
|
||||
// delimSpaceOrTagEnd occurs when a space or right angle bracket (>)
|
||||
// closes the attribute.
|
||||
delimSpaceOrTagEnd
|
||||
)
|
||||
|
||||
// urlPart identifies a part in an RFC 3986 hierarchical URL to allow different
|
||||
// encoding strategies.
|
||||
type urlPart uint8
|
||||
|
||||
//go:generate stringer -type urlPart
|
||||
|
||||
const (
|
||||
// urlPartNone occurs when not in a URL, or possibly at the start:
|
||||
// ^ in "^http://auth/path?k=v#frag".
|
||||
urlPartNone urlPart = iota
|
||||
// urlPartPreQuery occurs in the scheme, authority, or path; between the
|
||||
// ^s in "h^ttp://auth/path^?k=v#frag".
|
||||
urlPartPreQuery
|
||||
// urlPartQueryOrFrag occurs in the query portion between the ^s in
|
||||
// "http://auth/path?^k=v#frag^".
|
||||
urlPartQueryOrFrag
|
||||
// urlPartUnknown occurs due to joining of contexts both before and
|
||||
// after the query separator.
|
||||
urlPartUnknown
|
||||
)
|
||||
|
||||
// jsCtx determines whether a '/' starts a regular expression literal or a
|
||||
// division operator.
|
||||
type jsCtx uint8
|
||||
|
||||
//go:generate stringer -type jsCtx
|
||||
|
||||
const (
|
||||
// jsCtxRegexp occurs where a '/' would start a regexp literal.
|
||||
jsCtxRegexp jsCtx = iota
|
||||
// jsCtxDivOp occurs where a '/' would start a division operator.
|
||||
jsCtxDivOp
|
||||
// jsCtxUnknown occurs where a '/' is ambiguous due to context joining.
|
||||
jsCtxUnknown
|
||||
)
|
||||
|
||||
// element identifies the HTML element when inside a start tag or special body.
|
||||
// Certain HTML element (for example <script> and <style>) have bodies that are
|
||||
// treated differently from stateText so the element type is necessary to
|
||||
// transition into the correct context at the end of a tag and to identify the
|
||||
// end delimiter for the body.
|
||||
type element uint8
|
||||
|
||||
//go:generate stringer -type element
|
||||
|
||||
const (
|
||||
// elementNone occurs outside a special tag or special element body.
|
||||
elementNone element = iota
|
||||
// elementScript corresponds to the raw text <script> element
|
||||
// with JS MIME type or no type attribute.
|
||||
elementScript
|
||||
// elementStyle corresponds to the raw text <style> element.
|
||||
elementStyle
|
||||
// elementTextarea corresponds to the RCDATA <textarea> element.
|
||||
elementTextarea
|
||||
// elementTitle corresponds to the RCDATA <title> element.
|
||||
elementTitle
|
||||
)
|
||||
|
||||
//go:generate stringer -type attr
|
||||
|
||||
// attr identifies the current HTML attribute when inside the attribute,
|
||||
// that is, starting from stateAttrName until stateTag/stateText (exclusive).
|
||||
type attr uint8
|
||||
|
||||
const (
|
||||
// attrNone corresponds to a normal attribute or no attribute.
|
||||
attrNone attr = iota
|
||||
// attrScript corresponds to an event handler attribute.
|
||||
attrScript
|
||||
// attrScriptType corresponds to the type attribute in script HTML element
|
||||
attrScriptType
|
||||
// attrStyle corresponds to the style attribute whose value is CSS.
|
||||
attrStyle
|
||||
// attrURL corresponds to an attribute whose value is a URL.
|
||||
attrURL
|
||||
// attrSrcset corresponds to a srcset attribute.
|
||||
attrSrcset
|
||||
)
|
Reference in New Issue
Block a user