Browse Source

refactor: unexport symbols

Julien Voisin 8 months ago
parent
commit
566670cc06
36 changed files with 369 additions and 376 deletions
  1. 0 7
      internal/config/config.go
  2. 3 0
      internal/config/options.go
  3. 5 5
      internal/metric/metric.go
  4. 11 11
      internal/reader/atom/atom_03.go
  5. 13 12
      internal/reader/atom/atom_03_adapter.go
  6. 20 20
      internal/reader/atom/atom_10.go
  7. 12 12
      internal/reader/atom/atom_10_adapter.go
  8. 10 10
      internal/reader/atom/atom_common.go
  9. 3 3
      internal/reader/atom/parser.go
  10. 4 4
      internal/reader/opml/handler.go
  11. 1 0
      internal/reader/opml/opml.go
  12. 4 4
      internal/reader/opml/parser.go
  13. 43 36
      internal/reader/opml/parser_test.go
  14. 5 5
      internal/reader/opml/serializer.go
  15. 10 10
      internal/reader/opml/serializer_test.go
  16. 4 11
      internal/reader/opml/subscription.go
  17. 3 7
      internal/reader/rdf/adapter.go
  18. 3 2
      internal/reader/rdf/parser.go
  19. 6 6
      internal/reader/rdf/rdf.go
  20. 12 16
      internal/reader/rss/adapter.go
  21. 3 3
      internal/reader/rss/atom.go
  22. 2 2
      internal/reader/rss/feedburner.go
  23. 3 2
      internal/reader/rss/parser.go
  24. 3 3
      internal/reader/rss/podcast.go
  25. 25 25
      internal/reader/rss/rss.go
  26. 2 1
      internal/reader/sanitizer/sanitizer.go
  27. 88 88
      internal/reader/sanitizer/sanitizer_test.go
  28. 7 7
      internal/reader/sanitizer/srcset.go
  29. 19 19
      internal/reader/subscription/finder.go
  30. 12 12
      internal/reader/subscription/finder_test.go
  31. 6 6
      internal/reader/subscription/subscription.go
  32. 5 5
      internal/ui/form/auth.go
  33. 12 12
      internal/ui/form/settings.go
  34. 6 6
      internal/ui/view/view.go
  35. 1 1
      internal/worker/pool.go
  36. 3 3
      internal/worker/worker.go

+ 0 - 7
internal/config/config.go

@@ -1,7 +0,0 @@
-// SPDX-FileCopyrightText: Copyright The Miniflux Authors. All rights reserved.
-// SPDX-License-Identifier: Apache-2.0
-
-package config // import "miniflux.app/v2/internal/config"
-
-// Opts holds parsed configuration options.
-var Opts *options

+ 3 - 0
internal/config/options.go

@@ -100,6 +100,9 @@ type option struct {
 	Value any
 }
 
+// Opts holds parsed configuration options.
+var Opts *options
+
 // options contains configuration options.
 type options struct {
 	HTTPS                              bool

+ 5 - 5
internal/metric/metric.go

@@ -135,14 +135,14 @@ var (
 	)
 )
 
-// Collector represents a metric collector.
-type Collector struct {
+// collector represents a metric collector.
+type collector struct {
 	store           *storage.Storage
 	refreshInterval int
 }
 
 // NewCollector initializes a new metric collector.
-func NewCollector(store *storage.Storage, refreshInterval int) *Collector {
+func NewCollector(store *storage.Storage, refreshInterval int) *collector {
 	prometheus.MustRegister(BackgroundFeedRefreshDuration)
 	prometheus.MustRegister(ScraperRequestDuration)
 	prometheus.MustRegister(ArchiveEntriesDuration)
@@ -158,11 +158,11 @@ func NewCollector(store *storage.Storage, refreshInterval int) *Collector {
 	prometheus.MustRegister(dbConnectionsMaxIdleTimeClosedGauge)
 	prometheus.MustRegister(dbConnectionsMaxLifetimeClosedGauge)
 
-	return &Collector{store, refreshInterval}
+	return &collector{store, refreshInterval}
 }
 
 // GatherStorageMetrics polls the database to fetch metrics.
-func (c *Collector) GatherStorageMetrics() {
+func (c *collector) GatherStorageMetrics() {
 	for range time.Tick(time.Duration(c.refreshInterval) * time.Second) {
 		slog.Debug("Collecting metrics from the database")
 

+ 11 - 11
internal/reader/atom/atom_03.go

@@ -10,7 +10,7 @@ import (
 )
 
 // Specs: http://web.archive.org/web/20060811235523/http://www.mnot.net/drafts/draft-nottingham-atom-format-02.html
-type Atom03Feed struct {
+type atom03Feed struct {
 	Version string `xml:"version,attr"`
 
 	// The "atom:id" element's content conveys a permanent, globally unique identifier for the feed.
@@ -21,14 +21,14 @@ type Atom03Feed struct {
 	// The "atom:title" element is a Content construct that conveys a human-readable title for the feed.
 	// atom:feed elements MUST contain exactly one atom:title element.
 	// If the feed describes a Web resource, its content SHOULD be the same as that resource's title.
-	Title Atom03Content `xml:"http://purl.org/atom/ns# title"`
+	Title atom03Content `xml:"http://purl.org/atom/ns# title"`
 
 	// The "atom:link" element is a Link construct that conveys a URI associated with the feed.
 	// The nature of the relationship as well as the link itself is determined by the element's content.
 	// atom:feed elements MUST contain at least one atom:link element with a rel attribute value of "alternate".
 	// atom:feed elements MUST NOT contain more than one atom:link element with a rel attribute value of "alternate" that has the same type attribute value.
 	// atom:feed elements MAY contain additional atom:link elements beyond those described above.
-	Links AtomLinks `xml:"http://purl.org/atom/ns# link"`
+	Links atomLinks `xml:"http://purl.org/atom/ns# link"`
 
 	// The "atom:author" element is a Person construct that indicates the default author of the feed.
 	// atom:feed elements MUST contain exactly one atom:author element,
@@ -38,10 +38,10 @@ type Atom03Feed struct {
 
 	// The "atom:entry" element's represents an individual entry that is contained by the feed.
 	// atom:feed elements MAY contain one or more atom:entry elements.
-	Entries []Atom03Entry `xml:"http://purl.org/atom/ns# entry"`
+	Entries []atom03Entry `xml:"http://purl.org/atom/ns# entry"`
 }
 
-type Atom03Entry struct {
+type atom03Entry struct {
 	// The "atom:id" element's content conveys a permanent, globally unique identifier for the entry.
 	// It MUST NOT change over time, even if other representations of the entry (such as a web representation pointed to by the entry's atom:link element) are relocated.
 	// If the same entry is syndicated in two atom:feeds published by the same entity, the entry's atom:id MUST be the same in both feeds.
@@ -50,7 +50,7 @@ type Atom03Entry struct {
 	// The "atom:title" element is a Content construct that conveys a human-readable title for the entry.
 	// atom:entry elements MUST have exactly one "atom:title" element.
 	// If an entry describes a Web resource, its content SHOULD be the same as that resource's title.
-	Title Atom03Content `xml:"title"`
+	Title atom03Content `xml:"title"`
 
 	// The "atom:modified" element is a Date construct that indicates the time that the entry was last modified.
 	// atom:entry elements MUST contain an atom:modified element, but MUST NOT contain more than one.
@@ -73,15 +73,15 @@ type Atom03Entry struct {
 	// atom:entry elements MUST contain at least one atom:link element with a rel attribute value of "alternate".
 	// atom:entry elements MUST NOT contain more than one atom:link element with a rel attribute value of "alternate" that has the same type attribute value.
 	// atom:entry elements MAY contain additional atom:link elements beyond those described above.
-	Links AtomLinks `xml:"link"`
+	Links atomLinks `xml:"link"`
 
 	// The "atom:summary" element is a Content construct that conveys a short summary, abstract or excerpt of the entry.
 	// atom:entry elements MAY contain an atom:created element, but MUST NOT contain more than one.
-	Summary Atom03Content `xml:"summary"`
+	Summary atom03Content `xml:"summary"`
 
 	// The "atom:content" element is a Content construct that conveys the content of the entry.
 	// atom:entry elements MAY contain one or more atom:content elements.
-	Content Atom03Content `xml:"content"`
+	Content atom03Content `xml:"content"`
 
 	// The "atom:author" element is a Person construct that indicates the default author of the entry.
 	// atom:entry elements MUST contain exactly one atom:author element,
@@ -90,7 +90,7 @@ type Atom03Entry struct {
 	Author AtomPerson `xml:"author"`
 }
 
-type Atom03Content struct {
+type atom03Content struct {
 	// Content constructs MAY have a "type" attribute, whose value indicates the media type of the content.
 	// When present, this attribute's value MUST be a registered media type [RFC2045].
 	// If not present, its value MUST be considered to be "text/plain".
@@ -113,7 +113,7 @@ type Atom03Content struct {
 	InnerXML string `xml:",innerxml"`
 }
 
-func (a *Atom03Content) Content() string {
+func (a *atom03Content) content() string {
 	content := ""
 
 	switch a.Mode {

+ 13 - 12
internal/reader/atom/atom_03_adapter.go

@@ -14,15 +14,16 @@ import (
 	"miniflux.app/v2/internal/urllib"
 )
 
-type Atom03Adapter struct {
-	atomFeed *Atom03Feed
+type atom03Adapter struct {
+	atomFeed *atom03Feed
 }
 
-func NewAtom03Adapter(atomFeed *Atom03Feed) *Atom03Adapter {
-	return &Atom03Adapter{atomFeed}
+// TODO No need for a constructor, as it's only used in this package
+func NewAtom03Adapter(atomFeed *atom03Feed) *atom03Adapter {
+	return &atom03Adapter{atomFeed}
 }
 
-func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
+func (a *atom03Adapter) buildFeed(baseURL string) *model.Feed {
 	feed := new(model.Feed)
 
 	// Populate the feed URL.
@@ -36,7 +37,7 @@ func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
 	}
 
 	// Populate the site URL.
-	siteURL := a.atomFeed.Links.OriginalLink()
+	siteURL := a.atomFeed.Links.originalLink()
 	if siteURL != "" {
 		if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
 			feed.SiteURL = absoluteSiteURL
@@ -46,7 +47,7 @@ func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
 	}
 
 	// Populate the feed title.
-	feed.Title = a.atomFeed.Title.Content()
+	feed.Title = a.atomFeed.Title.content()
 	if feed.Title == "" {
 		feed.Title = feed.SiteURL
 	}
@@ -55,7 +56,7 @@ func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
 		entry := model.NewEntry()
 
 		// Populate the entry URL.
-		entry.URL = atomEntry.Links.OriginalLink()
+		entry.URL = atomEntry.Links.originalLink()
 		if entry.URL != "" {
 			if absoluteEntryURL, err := urllib.AbsoluteURL(feed.SiteURL, entry.URL); err == nil {
 				entry.URL = absoluteEntryURL
@@ -63,13 +64,13 @@ func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
 		}
 
 		// Populate the entry content.
-		entry.Content = atomEntry.Content.Content()
+		entry.Content = atomEntry.Content.content()
 		if entry.Content == "" {
-			entry.Content = atomEntry.Summary.Content()
+			entry.Content = atomEntry.Summary.content()
 		}
 
 		// Populate the entry title.
-		entry.Title = atomEntry.Title.Content()
+		entry.Title = atomEntry.Title.content()
 		if entry.Title == "" {
 			entry.Title = sanitizer.TruncateHTML(entry.Content, 100)
 		}
@@ -101,7 +102,7 @@ func (a *Atom03Adapter) BuildFeed(baseURL string) *model.Feed {
 		}
 
 		// Generate the entry hash.
-		for _, value := range []string{atomEntry.ID, atomEntry.Links.OriginalLink()} {
+		for _, value := range []string{atomEntry.ID, atomEntry.Links.originalLink()} {
 			if value != "" {
 				entry.Hash = crypto.SHA256(value)
 				break

+ 20 - 20
internal/reader/atom/atom_10.go

@@ -19,7 +19,7 @@ import (
 // Specs:
 // https://tools.ietf.org/html/rfc4287
 // https://validator.w3.org/feed/docs/atom.html
-type Atom10Feed struct {
+type atom10Feed struct {
 	XMLName xml.Name `xml:"http://www.w3.org/2005/Atom feed"`
 
 	// The "atom:id" element conveys a permanent, universally unique
@@ -37,11 +37,11 @@ type Atom10Feed struct {
 	// readable title for an entry or feed.
 	//
 	// atom:feed elements MUST contain exactly one atom:title element.
-	Title Atom10Text `xml:"http://www.w3.org/2005/Atom title"`
+	Title atom10Text `xml:"http://www.w3.org/2005/Atom title"`
 
 	// The "atom:subtitle" element is a Text construct that
 	// contains a human-readable description or subtitle for the feed.
-	Subtitle Atom10Text `xml:"http://www.w3.org/2005/Atom subtitle"`
+	Subtitle atom10Text `xml:"http://www.w3.org/2005/Atom subtitle"`
 
 	// The "atom:author" element is a Person construct that indicates the
 	// author of the entry or feed.
@@ -49,7 +49,7 @@ type Atom10Feed struct {
 	// atom:feed elements MUST contain one or more atom:author elements,
 	// unless all of the atom:feed element's child atom:entry elements
 	// contain at least one atom:author element.
-	Authors AtomPersons `xml:"http://www.w3.org/2005/Atom author"`
+	Authors atomPersons `xml:"http://www.w3.org/2005/Atom author"`
 
 	// The "atom:icon" element's content is an IRI reference [RFC3987] that
 	// identifies an image that provides iconic visual identification for a
@@ -71,7 +71,7 @@ type Atom10Feed struct {
 	// atom:feed elements MUST NOT contain more than one atom:link
 	// element with a rel attribute value of "alternate" that has the
 	// same combination of type and hreflang attribute values.
-	Links AtomLinks `xml:"http://www.w3.org/2005/Atom link"`
+	Links atomLinks `xml:"http://www.w3.org/2005/Atom link"`
 
 	// The "atom:category" element conveys information about a category
 	// associated with an entry or feed.  This specification assigns no
@@ -79,12 +79,12 @@ type Atom10Feed struct {
 	//
 	// atom:feed elements MAY contain any number of atom:category
 	// elements.
-	Categories AtomCategories `xml:"http://www.w3.org/2005/Atom category"`
+	Categories atomCategories `xml:"http://www.w3.org/2005/Atom category"`
 
-	Entries []Atom10Entry `xml:"http://www.w3.org/2005/Atom entry"`
+	Entries []atom10Entry `xml:"http://www.w3.org/2005/Atom entry"`
 }
 
-type Atom10Entry struct {
+type atom10Entry struct {
 	// The "atom:id" element conveys a permanent, universally unique
 	// identifier for an entry or feed.
 	//
@@ -100,7 +100,7 @@ type Atom10Entry struct {
 	// readable title for an entry or feed.
 	//
 	// atom:entry elements MUST contain exactly one atom:title element.
-	Title Atom10Text `xml:"http://www.w3.org/2005/Atom title"`
+	Title atom10Text `xml:"http://www.w3.org/2005/Atom title"`
 
 	// The "atom:published" element is a Date construct indicating an
 	// instant in time associated with an event early in the life cycle of
@@ -118,7 +118,7 @@ type Atom10Entry struct {
 	// atom:entry elements MUST NOT contain more than one atom:link
 	// element with a rel attribute value of "alternate" that has the
 	// same combination of type and hreflang attribute values.
-	Links AtomLinks `xml:"http://www.w3.org/2005/Atom link"`
+	Links atomLinks `xml:"http://www.w3.org/2005/Atom link"`
 
 	// atom:entry elements MUST contain an atom:summary element in either
 	// of the following cases:
@@ -131,17 +131,17 @@ type Atom10Entry struct {
 	//
 	// atom:entry elements MUST NOT contain more than one atom:summary
 	// element.
-	Summary Atom10Text `xml:"http://www.w3.org/2005/Atom summary"`
+	Summary atom10Text `xml:"http://www.w3.org/2005/Atom summary"`
 
 	// atom:entry elements MUST NOT contain more than one atom:content
 	// element.
-	Content Atom10Text `xml:"http://www.w3.org/2005/Atom content"`
+	Content atom10Text `xml:"http://www.w3.org/2005/Atom content"`
 
 	// The "atom:author" element is a Person construct that indicates the
 	// author of the entry or feed.
 	//
 	// atom:entry elements MUST contain one or more atom:author elements
-	Authors AtomPersons `xml:"http://www.w3.org/2005/Atom author"`
+	Authors atomPersons `xml:"http://www.w3.org/2005/Atom author"`
 
 	// The "atom:category" element conveys information about a category
 	// associated with an entry or feed.  This specification assigns no
@@ -149,7 +149,7 @@ type Atom10Entry struct {
 	//
 	// atom:entry elements MAY contain any number of atom:category
 	// elements.
-	Categories AtomCategories `xml:"http://www.w3.org/2005/Atom category"`
+	Categories atomCategories `xml:"http://www.w3.org/2005/Atom category"`
 
 	media.MediaItemElement
 }
@@ -160,14 +160,14 @@ type Atom10Entry struct {
 // Text: https://datatracker.ietf.org/doc/html/rfc4287#section-3.1.1.1
 // HTML: https://datatracker.ietf.org/doc/html/rfc4287#section-3.1.1.2
 // XHTML: https://datatracker.ietf.org/doc/html/rfc4287#section-3.1.1.3
-type Atom10Text struct {
+type atom10Text struct {
 	Type             string               `xml:"type,attr"`
 	CharData         string               `xml:",chardata"`
 	InnerXML         string               `xml:",innerxml"`
-	XHTMLRootElement AtomXHTMLRootElement `xml:"http://www.w3.org/1999/xhtml div"`
+	XHTMLRootElement atomXHTMLRootElement `xml:"http://www.w3.org/1999/xhtml div"`
 }
 
-func (a *Atom10Text) Body() string {
+func (a *atom10Text) body() string {
 	var content string
 
 	if strings.EqualFold(a.Type, "xhtml") {
@@ -179,7 +179,7 @@ func (a *Atom10Text) Body() string {
 	return strings.TrimSpace(content)
 }
 
-func (a *Atom10Text) Title() string {
+func (a *atom10Text) title() string {
 	var content string
 
 	switch {
@@ -194,14 +194,14 @@ func (a *Atom10Text) Title() string {
 	return strings.TrimSpace(content)
 }
 
-func (a *Atom10Text) xhtmlContent() string {
+func (a *atom10Text) xhtmlContent() string {
 	if a.XHTMLRootElement.XMLName.Local == "div" {
 		return a.XHTMLRootElement.InnerXML
 	}
 	return a.InnerXML
 }
 
-type AtomXHTMLRootElement struct {
+type atomXHTMLRootElement struct {
 	XMLName  xml.Name `xml:"div"`
 	InnerXML string   `xml:",innerxml"`
 }

+ 12 - 12
internal/reader/atom/atom_10_adapter.go

@@ -19,10 +19,10 @@ import (
 )
 
 type Atom10Adapter struct {
-	atomFeed *Atom10Feed
+	atomFeed *atom10Feed
 }
 
-func NewAtom10Adapter(atomFeed *Atom10Feed) *Atom10Adapter {
+func NewAtom10Adapter(atomFeed *atom10Feed) *Atom10Adapter {
 	return &Atom10Adapter{atomFeed}
 }
 
@@ -40,7 +40,7 @@ func (a *Atom10Adapter) BuildFeed(baseURL string) *model.Feed {
 	}
 
 	// Populate the site URL.
-	siteURL := a.atomFeed.Links.OriginalLink()
+	siteURL := a.atomFeed.Links.originalLink()
 	if siteURL != "" {
 		if absoluteSiteURL, err := urllib.AbsoluteURL(baseURL, siteURL); err == nil {
 			feed.SiteURL = absoluteSiteURL
@@ -50,13 +50,13 @@ func (a *Atom10Adapter) BuildFeed(baseURL string) *model.Feed {
 	}
 
 	// Populate the feed title.
-	feed.Title = a.atomFeed.Title.Body()
+	feed.Title = a.atomFeed.Title.body()
 	if feed.Title == "" {
 		feed.Title = feed.SiteURL
 	}
 
 	// Populate the feed description.
-	feed.Description = a.atomFeed.Subtitle.Body()
+	feed.Description = a.atomFeed.Subtitle.body()
 
 	// Populate the feed icon.
 	if a.atomFeed.Icon != "" {
@@ -79,7 +79,7 @@ func (a *Atom10Adapter) populateEntries(siteURL string) model.Entries {
 		entry := model.NewEntry()
 
 		// Populate the entry URL.
-		entry.URL = atomEntry.Links.OriginalLink()
+		entry.URL = atomEntry.Links.originalLink()
 		if entry.URL != "" {
 			if absoluteEntryURL, err := urllib.AbsoluteURL(siteURL, entry.URL); err == nil {
 				entry.URL = absoluteEntryURL
@@ -87,16 +87,16 @@ func (a *Atom10Adapter) populateEntries(siteURL string) model.Entries {
 		}
 
 		// Populate the entry content.
-		entry.Content = atomEntry.Content.Body()
+		entry.Content = atomEntry.Content.body()
 		if entry.Content == "" {
-			entry.Content = atomEntry.Summary.Body()
+			entry.Content = atomEntry.Summary.body()
 			if entry.Content == "" {
 				entry.Content = atomEntry.FirstMediaDescription()
 			}
 		}
 
 		// Populate the entry title.
-		entry.Title = atomEntry.Title.Title()
+		entry.Title = atomEntry.Title.title()
 		if entry.Title == "" {
 			entry.Title = sanitizer.TruncateHTML(entry.Content, 100)
 			if entry.Title == "" {
@@ -105,9 +105,9 @@ func (a *Atom10Adapter) populateEntries(siteURL string) model.Entries {
 		}
 
 		// Populate the entry author.
-		authors := atomEntry.Authors.PersonNames()
+		authors := atomEntry.Authors.personNames()
 		if len(authors) == 0 {
-			authors = a.atomFeed.Authors.PersonNames()
+			authors = a.atomFeed.Authors.personNames()
 		}
 		sort.Strings(authors)
 		authors = slices.Compact(authors)
@@ -152,7 +152,7 @@ func (a *Atom10Adapter) populateEntries(siteURL string) model.Entries {
 		}
 
 		// Generate the entry hash.
-		for _, value := range []string{atomEntry.ID, atomEntry.Links.OriginalLink()} {
+		for _, value := range []string{atomEntry.ID, atomEntry.Links.originalLink()} {
 			if value != "" {
 				entry.Hash = crypto.SHA256(value)
 				break

+ 10 - 10
internal/reader/atom/atom_common.go

@@ -30,9 +30,9 @@ func (a *AtomPerson) PersonName() string {
 	return strings.TrimSpace(a.Email)
 }
 
-type AtomPersons []*AtomPerson
+type atomPersons []*AtomPerson
 
-func (a AtomPersons) PersonNames() []string {
+func (a atomPersons) personNames() []string {
 	var names []string
 	authorNamesMap := make(map[string]bool)
 
@@ -56,9 +56,9 @@ type AtomLink struct {
 	Title  string `xml:"title,attr"`
 }
 
-type AtomLinks []*AtomLink
+type atomLinks []*AtomLink
 
-func (a AtomLinks) OriginalLink() string {
+func (a atomLinks) originalLink() string {
 	for _, link := range a {
 		if strings.EqualFold(link.Rel, "alternate") {
 			return strings.TrimSpace(link.Href)
@@ -72,7 +72,7 @@ func (a AtomLinks) OriginalLink() string {
 	return ""
 }
 
-func (a AtomLinks) firstLinkWithRelation(relation string) string {
+func (a atomLinks) firstLinkWithRelation(relation string) string {
 	for _, link := range a {
 		if strings.EqualFold(link.Rel, relation) {
 			return strings.TrimSpace(link.Href)
@@ -82,7 +82,7 @@ func (a AtomLinks) firstLinkWithRelation(relation string) string {
 	return ""
 }
 
-func (a AtomLinks) firstLinkWithRelationAndType(relation string, contentTypes ...string) string {
+func (a atomLinks) firstLinkWithRelationAndType(relation string, contentTypes ...string) string {
 	for _, link := range a {
 		if strings.EqualFold(link.Rel, relation) {
 			for _, contentType := range contentTypes {
@@ -96,7 +96,7 @@ func (a AtomLinks) firstLinkWithRelationAndType(relation string, contentTypes ..
 	return ""
 }
 
-func (a AtomLinks) findAllLinksWithRelation(relation string) []*AtomLink {
+func (a atomLinks) findAllLinksWithRelation(relation string) []*AtomLink {
 	var links []*AtomLink
 
 	for _, link := range a {
@@ -116,7 +116,7 @@ func (a AtomLinks) findAllLinksWithRelation(relation string) []*AtomLink {
 // meaning to the content (if any) of this element.
 //
 // Specs: https://datatracker.ietf.org/doc/html/rfc4287#section-4.2.2
-type AtomCategory struct {
+type atomCategory struct {
 	// The "term" attribute is a string that identifies the category to
 	// which the entry or feed belongs. Category elements MUST have a
 	// "term" attribute.
@@ -134,9 +134,9 @@ type AtomCategory struct {
 	Label string `xml:"label,attr"`
 }
 
-type AtomCategories []AtomCategory
+type atomCategories []atomCategory
 
-func (ac AtomCategories) CategoryNames() []string {
+func (ac atomCategories) CategoryNames() []string {
 	var categories []string
 
 	for _, category := range ac {

+ 3 - 3
internal/reader/atom/parser.go

@@ -15,13 +15,13 @@ import (
 func Parse(baseURL string, r io.ReadSeeker, version string) (*model.Feed, error) {
 	switch version {
 	case "0.3":
-		atomFeed := new(Atom03Feed)
+		atomFeed := new(atom03Feed)
 		if err := xml_decoder.NewXMLDecoder(r).Decode(atomFeed); err != nil {
 			return nil, fmt.Errorf("atom: unable to parse Atom 0.3 feed: %w", err)
 		}
-		return NewAtom03Adapter(atomFeed).BuildFeed(baseURL), nil
+		return NewAtom03Adapter(atomFeed).buildFeed(baseURL), nil
 	default:
-		atomFeed := new(Atom10Feed)
+		atomFeed := new(atom10Feed)
 		if err := xml_decoder.NewXMLDecoder(r).Decode(atomFeed); err != nil {
 			return nil, fmt.Errorf("atom: unable to parse Atom 1.0 feed: %w", err)
 		}

+ 4 - 4
internal/reader/opml/handler.go

@@ -23,9 +23,9 @@ func (h *Handler) Export(userID int64) (string, error) {
 		return "", err
 	}
 
-	subscriptions := make(SubcriptionList, 0, len(feeds))
+	subscriptions := make(subcriptionList, 0, len(feeds))
 	for _, feed := range feeds {
-		subscriptions = append(subscriptions, &Subcription{
+		subscriptions = append(subscriptions, &subcription{
 			Title:        feed.Title,
 			FeedURL:      feed.FeedURL,
 			SiteURL:      feed.SiteURL,
@@ -34,12 +34,12 @@ func (h *Handler) Export(userID int64) (string, error) {
 		})
 	}
 
-	return Serialize(subscriptions), nil
+	return serialize(subscriptions), nil
 }
 
 // Import parses and create feeds from an OPML import.
 func (h *Handler) Import(userID int64, data io.Reader) error {
-	subscriptions, err := Parse(data)
+	subscriptions, err := parse(data)
 	if err != nil {
 		return err
 	}

+ 1 - 0
internal/reader/opml/opml.go

@@ -16,6 +16,7 @@ type opmlDocument struct {
 	Outlines opmlOutlineCollection `xml:"body>outline"`
 }
 
+// TODO remove as this is only used in the opml package
 func NewOPMLDocument() *opmlDocument {
 	return &opmlDocument{}
 }

+ 4 - 4
internal/reader/opml/parser.go

@@ -11,8 +11,8 @@ import (
 	"miniflux.app/v2/internal/reader/encoding"
 )
 
-// Parse reads an OPML file and returns a SubcriptionList.
-func Parse(data io.Reader) (SubcriptionList, error) {
+// parse reads an OPML file and returns a SubcriptionList.
+func parse(data io.Reader) (subcriptionList, error) {
 	opmlDocument := NewOPMLDocument()
 	decoder := xml.NewDecoder(data)
 	decoder.Entity = xml.HTMLEntity
@@ -27,10 +27,10 @@ func Parse(data io.Reader) (SubcriptionList, error) {
 	return getSubscriptionsFromOutlines(opmlDocument.Outlines, ""), nil
 }
 
-func getSubscriptionsFromOutlines(outlines opmlOutlineCollection, category string) (subscriptions SubcriptionList) {
+func getSubscriptionsFromOutlines(outlines opmlOutlineCollection, category string) (subscriptions subcriptionList) {
 	for _, outline := range outlines {
 		if outline.IsSubscription() {
-			subscriptions = append(subscriptions, &Subcription{
+			subscriptions = append(subscriptions, &subcription{
 				Title:        outline.GetTitle(),
 				FeedURL:      outline.FeedURL,
 				SiteURL:      outline.GetSiteURL(),

+ 43 - 36
internal/reader/opml/parser_test.go

@@ -8,6 +8,13 @@ import (
 	"testing"
 )
 
+// equals compare two subscriptions.
+func (s subcription) equals(subscription *subcription) bool {
+	return s.Title == subscription.Title && s.SiteURL == subscription.SiteURL &&
+		s.FeedURL == subscription.FeedURL && s.CategoryName == subscription.CategoryName &&
+		s.Description == subscription.Description
+}
+
 func TestParseOpmlWithoutCategories(t *testing.T) {
 	data := `<?xml version="1.0" encoding="ISO-8859-1"?>
 	<opml version="2.0">
@@ -32,10 +39,10 @@ func TestParseOpmlWithoutCategories(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "CNET News.com", FeedURL: "http://news.com.com/2547-1_3-0-5.xml", SiteURL: "http://news.com.com/", Description: "Tech news and business reports by CNET News.com. Focused on information technology, core topics include computers, hardware, software, networking, and Internet media."})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "CNET News.com", FeedURL: "http://news.com.com/2547-1_3-0-5.xml", SiteURL: "http://news.com.com/", Description: "Tech news and business reports by CNET News.com. Focused on information technology, core topics include computers, hardware, software, networking, and Internet media."})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -44,7 +51,7 @@ func TestParseOpmlWithoutCategories(t *testing.T) {
 		t.Fatalf("Wrong number of subscriptions: %d instead of %d", len(subscriptions), 13)
 	}
 
-	if !subscriptions[0].Equals(expected[0]) {
+	if !subscriptions[0].equals(expected[0]) {
 		t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[0], expected[0])
 	}
 }
@@ -67,12 +74,12 @@ func TestParseOpmlWithCategories(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "My Category 1"})
-	expected = append(expected, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "My Category 1"})
-	expected = append(expected, &Subcription{Title: "Feed 3", FeedURL: "http://example.org/feed3/", SiteURL: "http://example.org/3", CategoryName: "My Category 2"})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "My Category 1"})
+	expected = append(expected, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "My Category 1"})
+	expected = append(expected, &subcription{Title: "Feed 3", FeedURL: "http://example.org/feed3/", SiteURL: "http://example.org/3", CategoryName: "My Category 2"})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -82,7 +89,7 @@ func TestParseOpmlWithCategories(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -101,11 +108,11 @@ func TestParseOpmlWithEmptyTitleAndEmptySiteURL(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "http://example.org/1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: ""})
-	expected = append(expected, &Subcription{Title: "http://example.org/feed2/", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/feed2/", CategoryName: ""})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "http://example.org/1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: ""})
+	expected = append(expected, &subcription{Title: "http://example.org/feed2/", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/feed2/", CategoryName: ""})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -115,7 +122,7 @@ func TestParseOpmlWithEmptyTitleAndEmptySiteURL(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -139,11 +146,11 @@ func TestParseOpmlVersion1(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "Category 1"})
-	expected = append(expected, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "Category 2"})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "Category 1"})
+	expected = append(expected, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "Category 2"})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -153,7 +160,7 @@ func TestParseOpmlVersion1(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -173,11 +180,11 @@ func TestParseOpmlVersion1WithoutOuterOutline(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: ""})
-	expected = append(expected, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: ""})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: ""})
+	expected = append(expected, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: ""})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -187,7 +194,7 @@ func TestParseOpmlVersion1WithoutOuterOutline(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -214,12 +221,12 @@ func TestParseOpmlVersion1WithSeveralNestedOutlines(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "Some Category"})
-	expected = append(expected, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "Some Category"})
-	expected = append(expected, &Subcription{Title: "Feed 3", FeedURL: "http://example.org/feed3/", SiteURL: "http://example.org/3", CategoryName: "Another Category"})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/", SiteURL: "http://example.org/1", CategoryName: "Some Category"})
+	expected = append(expected, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed2/", SiteURL: "http://example.org/2", CategoryName: "Some Category"})
+	expected = append(expected, &subcription{Title: "Feed 3", FeedURL: "http://example.org/feed3/", SiteURL: "http://example.org/3", CategoryName: "Another Category"})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -229,7 +236,7 @@ func TestParseOpmlVersion1WithSeveralNestedOutlines(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -249,10 +256,10 @@ func TestParseOpmlWithInvalidCharacterEntity(t *testing.T) {
 	</opml>
 	`
 
-	var expected SubcriptionList
-	expected = append(expected, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/a&b", SiteURL: "http://example.org/c&d", CategoryName: "Feed 1"})
+	var expected subcriptionList
+	expected = append(expected, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed1/a&b", SiteURL: "http://example.org/c&d", CategoryName: "Feed 1"})
 
-	subscriptions, err := Parse(bytes.NewBufferString(data))
+	subscriptions, err := parse(bytes.NewBufferString(data))
 	if err != nil {
 		t.Fatal(err)
 	}
@@ -262,7 +269,7 @@ func TestParseOpmlWithInvalidCharacterEntity(t *testing.T) {
 	}
 
 	for i := range len(subscriptions) {
-		if !subscriptions[i].Equals(expected[i]) {
+		if !subscriptions[i].equals(expected[i]) {
 			t.Errorf(`Subscription is different: "%v" vs "%v"`, subscriptions[i], expected[i])
 		}
 	}
@@ -270,7 +277,7 @@ func TestParseOpmlWithInvalidCharacterEntity(t *testing.T) {
 
 func TestParseInvalidXML(t *testing.T) {
 	data := `garbage`
-	_, err := Parse(bytes.NewBufferString(data))
+	_, err := parse(bytes.NewBufferString(data))
 	if err == nil {
 		t.Error("Parse should generate an error")
 	}

+ 5 - 5
internal/reader/opml/serializer.go

@@ -12,8 +12,8 @@ import (
 	"time"
 )
 
-// Serialize returns a SubcriptionList in OPML format.
-func Serialize(subscriptions SubcriptionList) string {
+// serialize returns a SubcriptionList in OPML format.
+func serialize(subscriptions subcriptionList) string {
 	var b bytes.Buffer
 	writer := bufio.NewWriter(&b)
 	writer.WriteString(xml.Header)
@@ -31,7 +31,7 @@ func Serialize(subscriptions SubcriptionList) string {
 	return b.String()
 }
 
-func convertSubscriptionsToOPML(subscriptions SubcriptionList) *opmlDocument {
+func convertSubscriptionsToOPML(subscriptions subcriptionList) *opmlDocument {
 	opmlDocument := NewOPMLDocument()
 	opmlDocument.Version = "2.0"
 	opmlDocument.Header.Title = "Miniflux"
@@ -62,8 +62,8 @@ func convertSubscriptionsToOPML(subscriptions SubcriptionList) *opmlDocument {
 	return opmlDocument
 }
 
-func groupSubscriptionsByFeed(subscriptions SubcriptionList) map[string]SubcriptionList {
-	groups := make(map[string]SubcriptionList)
+func groupSubscriptionsByFeed(subscriptions subcriptionList) map[string]subcriptionList {
+	groups := make(map[string]subcriptionList)
 
 	for _, subscription := range subscriptions {
 		groups[subscription.CategoryName] = append(groups[subscription.CategoryName], subscription)

+ 10 - 10
internal/reader/opml/serializer_test.go

@@ -9,13 +9,13 @@ import (
 )
 
 func TestSerialize(t *testing.T) {
-	var subscriptions SubcriptionList
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed/1", SiteURL: "http://example.org/1", CategoryName: "Category 1"})
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed/2", SiteURL: "http://example.org/2", CategoryName: "Category 1"})
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 3", FeedURL: "http://example.org/feed/3", SiteURL: "http://example.org/3", CategoryName: "Category 2"})
+	var subscriptions subcriptionList
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed/1", SiteURL: "http://example.org/1", CategoryName: "Category 1"})
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed/2", SiteURL: "http://example.org/2", CategoryName: "Category 1"})
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 3", FeedURL: "http://example.org/feed/3", SiteURL: "http://example.org/3", CategoryName: "Category 2"})
 
-	output := Serialize(subscriptions)
-	feeds, err := Parse(bytes.NewBufferString(output))
+	output := serialize(subscriptions)
+	feeds, err := parse(bytes.NewBufferString(output))
 	if err != nil {
 		t.Error(err)
 	}
@@ -48,10 +48,10 @@ func TestNormalizedCategoriesOrder(t *testing.T) {
 		{"Category 1", "Category 3"},
 	}
 
-	var subscriptions SubcriptionList
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 1", FeedURL: "http://example.org/feed/1", SiteURL: "http://example.org/1", CategoryName: orderTests[0].naturalOrderName})
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 2", FeedURL: "http://example.org/feed/2", SiteURL: "http://example.org/2", CategoryName: orderTests[1].naturalOrderName})
-	subscriptions = append(subscriptions, &Subcription{Title: "Feed 3", FeedURL: "http://example.org/feed/3", SiteURL: "http://example.org/3", CategoryName: orderTests[2].naturalOrderName})
+	var subscriptions subcriptionList
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 1", FeedURL: "http://example.org/feed/1", SiteURL: "http://example.org/1", CategoryName: orderTests[0].naturalOrderName})
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 2", FeedURL: "http://example.org/feed/2", SiteURL: "http://example.org/2", CategoryName: orderTests[1].naturalOrderName})
+	subscriptions = append(subscriptions, &subcription{Title: "Feed 3", FeedURL: "http://example.org/feed/3", SiteURL: "http://example.org/3", CategoryName: orderTests[2].naturalOrderName})
 
 	feeds := convertSubscriptionsToOPML(subscriptions)
 

+ 4 - 11
internal/reader/opml/subscription.go

@@ -3,8 +3,8 @@
 
 package opml // import "miniflux.app/v2/internal/reader/opml"
 
-// Subcription represents a feed that will be imported or exported.
-type Subcription struct {
+// subcription represents a feed that will be imported or exported.
+type subcription struct {
 	Title        string
 	SiteURL      string
 	FeedURL      string
@@ -12,12 +12,5 @@ type Subcription struct {
 	Description  string
 }
 
-// Equals compare two subscriptions.
-func (s Subcription) Equals(subscription *Subcription) bool {
-	return s.Title == subscription.Title && s.SiteURL == subscription.SiteURL &&
-		s.FeedURL == subscription.FeedURL && s.CategoryName == subscription.CategoryName &&
-		s.Description == subscription.Description
-}
-
-// SubcriptionList is a list of subscriptions.
-type SubcriptionList []*Subcription
+// subcriptionList is a list of subscriptions.
+type subcriptionList []*subcription

+ 3 - 7
internal/reader/rdf/adapter.go

@@ -16,15 +16,11 @@ import (
 	"miniflux.app/v2/internal/urllib"
 )
 
-type RDFAdapter struct {
-	rdf *RDF
+type rdfAdapter struct {
+	rdf *rdf
 }
 
-func NewRDFAdapter(rdf *RDF) *RDFAdapter {
-	return &RDFAdapter{rdf}
-}
-
-func (r *RDFAdapter) BuildFeed(baseURL string) *model.Feed {
+func (r *rdfAdapter) buildFeed(baseURL string) *model.Feed {
 	feed := &model.Feed{
 		Title:       stripTags(r.rdf.Channel.Title),
 		FeedURL:     strings.TrimSpace(baseURL),

+ 3 - 2
internal/reader/rdf/parser.go

@@ -13,10 +13,11 @@ import (
 
 // Parse returns a normalized feed struct from a RDF feed.
 func Parse(baseURL string, data io.ReadSeeker) (*model.Feed, error) {
-	xmlFeed := new(RDF)
+	xmlFeed := new(rdf)
 	if err := xml.NewXMLDecoder(data).Decode(xmlFeed); err != nil {
 		return nil, fmt.Errorf("rdf: unable to parse feed: %w", err)
 	}
 
-	return NewRDFAdapter(xmlFeed).BuildFeed(baseURL), nil
+	adapter := &rdfAdapter{xmlFeed}
+	return adapter.buildFeed(baseURL), nil
 }

+ 6 - 6
internal/reader/rdf/rdf.go

@@ -9,21 +9,21 @@ import (
 	"miniflux.app/v2/internal/reader/dublincore"
 )
 
-// RDF sepcs: https://web.resource.org/rss/1.0/spec
-type RDF struct {
+// rdf sepcs: https://web.resource.org/rss/1.0/spec
+type rdf struct {
 	XMLName xml.Name   `xml:"http://www.w3.org/1999/02/22-rdf-syntax-ns# RDF"`
-	Channel RDFChannel `xml:"channel"`
-	Items   []RDFItem  `xml:"item"`
+	Channel rdfChannel `xml:"channel"`
+	Items   []rdfItem  `xml:"item"`
 }
 
-type RDFChannel struct {
+type rdfChannel struct {
 	Title       string `xml:"title"`
 	Link        string `xml:"link"`
 	Description string `xml:"description"`
 	dublincore.DublinCoreChannelElement
 }
 
-type RDFItem struct {
+type rdfItem struct {
 	Title       string `xml:"http://purl.org/rss/1.0/ title"`
 	Link        string `xml:"link"`
 	Description string `xml:"description"`

+ 12 - 16
internal/reader/rss/adapter.go

@@ -19,15 +19,11 @@ import (
 	"miniflux.app/v2/internal/urllib"
 )
 
-type RSSAdapter struct {
-	rss *RSS
+type rssAdapter struct {
+	rss *rss
 }
 
-func NewRSSAdapter(rss *RSS) *RSSAdapter {
-	return &RSSAdapter{rss}
-}
-
-func (r *RSSAdapter) BuildFeed(baseURL string) *model.Feed {
+func (r *rssAdapter) buildFeed(baseURL string) *model.Feed {
 	feed := &model.Feed{
 		Title:       html.UnescapeString(strings.TrimSpace(r.rss.Channel.Title)),
 		FeedURL:     strings.TrimSpace(baseURL),
@@ -145,7 +141,7 @@ func (r *RSSAdapter) BuildFeed(baseURL string) *model.Feed {
 	return feed
 }
 
-func findFeedAuthor(rssChannel *RSSChannel) string {
+func findFeedAuthor(rssChannel *rssChannel) string {
 	var author string
 	switch {
 	case rssChannel.ItunesAuthor != "":
@@ -165,7 +161,7 @@ func findFeedAuthor(rssChannel *RSSChannel) string {
 	return strings.TrimSpace(sanitizer.StripTags(author))
 }
 
-func findFeedTags(rssChannel *RSSChannel) []string {
+func findFeedTags(rssChannel *rssChannel) []string {
 	tags := make([]string, 0)
 
 	for _, tag := range rssChannel.Categories {
@@ -189,7 +185,7 @@ func findFeedTags(rssChannel *RSSChannel) []string {
 	return tags
 }
 
-func findEntryTitle(rssItem *RSSItem) string {
+func findEntryTitle(rssItem *rssItem) string {
 	title := rssItem.Title.Content
 
 	if rssItem.DublinCoreTitle != "" {
@@ -199,7 +195,7 @@ func findEntryTitle(rssItem *RSSItem) string {
 	return html.UnescapeString(html.UnescapeString(strings.TrimSpace(title)))
 }
 
-func findEntryURL(rssItem *RSSItem) string {
+func findEntryURL(rssItem *rssItem) string {
 	for _, link := range []string{rssItem.FeedBurnerLink, rssItem.Link} {
 		if link != "" {
 			return strings.TrimSpace(link)
@@ -222,7 +218,7 @@ func findEntryURL(rssItem *RSSItem) string {
 	return ""
 }
 
-func findEntryContent(rssItem *RSSItem) string {
+func findEntryContent(rssItem *rssItem) string {
 	for _, value := range []string{
 		rssItem.DublinCoreContent,
 		rssItem.Description,
@@ -237,7 +233,7 @@ func findEntryContent(rssItem *RSSItem) string {
 	return ""
 }
 
-func findEntryDate(rssItem *RSSItem) time.Time {
+func findEntryDate(rssItem *rssItem) time.Time {
 	value := rssItem.PubDate
 	if rssItem.DublinCoreDate != "" {
 		value = rssItem.DublinCoreDate
@@ -260,7 +256,7 @@ func findEntryDate(rssItem *RSSItem) time.Time {
 	return time.Now()
 }
 
-func findEntryAuthor(rssItem *RSSItem) string {
+func findEntryAuthor(rssItem *rssItem) string {
 	var author string
 
 	switch {
@@ -283,7 +279,7 @@ func findEntryAuthor(rssItem *RSSItem) string {
 	return strings.TrimSpace(sanitizer.StripTags(author))
 }
 
-func findEntryTags(rssItem *RSSItem) []string {
+func findEntryTags(rssItem *rssItem) []string {
 	tags := make([]string, 0)
 
 	for _, tag := range rssItem.Categories {
@@ -303,7 +299,7 @@ func findEntryTags(rssItem *RSSItem) []string {
 	return tags
 }
 
-func findEntryEnclosures(rssItem *RSSItem, siteURL string) model.EnclosureList {
+func findEntryEnclosures(rssItem *rssItem, siteURL string) model.EnclosureList {
 	enclosures := make(model.EnclosureList, 0)
 	duplicates := make(map[string]bool)
 

+ 3 - 3
internal/reader/rss/atom.go

@@ -7,14 +7,14 @@ import (
 	"miniflux.app/v2/internal/reader/atom"
 )
 
-type AtomAuthor struct {
+type atomAuthor struct {
 	Author atom.AtomPerson `xml:"http://www.w3.org/2005/Atom author"`
 }
 
-func (a *AtomAuthor) PersonName() string {
+func (a *atomAuthor) PersonName() string {
 	return a.Author.PersonName()
 }
 
-type AtomLinks struct {
+type atomLinks struct {
 	Links []*atom.AtomLink `xml:"http://www.w3.org/2005/Atom link"`
 }

+ 2 - 2
internal/reader/rss/feedburner.go

@@ -3,8 +3,8 @@
 
 package rss // import "miniflux.app/v2/internal/reader/rss"
 
-// FeedBurnerItemElement represents FeedBurner XML elements.
-type FeedBurnerItemElement struct {
+// feedBurnerItemElement represents FeedBurner XML elements.
+type feedBurnerItemElement struct {
 	FeedBurnerLink          string `xml:"http://rssnamespace.org/feedburner/ext/1.0 origLink"`
 	FeedBurnerEnclosureLink string `xml:"http://rssnamespace.org/feedburner/ext/1.0 origEnclosureLink"`
 }

+ 3 - 2
internal/reader/rss/parser.go

@@ -13,11 +13,12 @@ import (
 
 // Parse returns a normalized feed struct from a RSS feed.
 func Parse(baseURL string, data io.ReadSeeker) (*model.Feed, error) {
-	rssFeed := new(RSS)
+	rssFeed := new(rss)
 	decoder := xml.NewXMLDecoder(data)
 	decoder.DefaultSpace = "rss"
 	if err := decoder.Decode(rssFeed); err != nil {
 		return nil, fmt.Errorf("rss: unable to parse feed: %w", err)
 	}
-	return NewRSSAdapter(rssFeed).BuildFeed(baseURL), nil
+	adapter := &rssAdapter{rssFeed}
+	return adapter.buildFeed(baseURL), nil
 }

+ 3 - 3
internal/reader/rss/podcast.go

@@ -10,20 +10,20 @@ import (
 	"strings"
 )
 
-var ErrInvalidDurationFormat = errors.New("rss: invalid duration format")
+var errInvalidDurationFormat = errors.New("rss: invalid duration format")
 
 func getDurationInMinutes(rawDuration string) (int, error) {
 	var sumSeconds int
 
 	durationParts := strings.Split(rawDuration, ":")
 	if len(durationParts) > 3 {
-		return 0, ErrInvalidDurationFormat
+		return 0, errInvalidDurationFormat
 	}
 
 	for i, durationPart := range durationParts {
 		durationPartValue, err := strconv.Atoi(durationPart)
 		if err != nil {
-			return 0, ErrInvalidDurationFormat
+			return 0, errInvalidDurationFormat
 		}
 
 		sumSeconds += int(math.Pow(60, float64(len(durationParts)-i-1))) * durationPartValue

+ 25 - 25
internal/reader/rss/rss.go

@@ -15,15 +15,15 @@ import (
 )
 
 // Specs: https://www.rssboard.org/rss-specification
-type RSS struct {
+type rss struct {
 	// Version is the version of the RSS specification.
 	Version string `xml:"rss version,attr"`
 
 	// Channel is the main container for the RSS feed.
-	Channel RSSChannel `xml:"rss channel"`
+	Channel rssChannel `xml:"rss channel"`
 }
 
-type RSSChannel struct {
+type rssChannel struct {
 	// Title is the name of the channel.
 	Title string `xml:"rss title"`
 
@@ -64,10 +64,10 @@ type RSSChannel struct {
 	DocumentationURL string `xml:"rss docs"`
 
 	// Cloud is a web service that supports the rssCloud interface which can be implemented in HTTP-POST, XML-RPC or SOAP 1.1.
-	Cloud *RSSCloud `xml:"rss cloud"`
+	Cloud *rssCloud `xml:"rss cloud"`
 
 	// Image specifies a GIF, JPEG or PNG image that can be displayed with the channel.
-	Image *RSSImage `xml:"rss image"`
+	Image *rssImage `xml:"rss image"`
 
 	// TTL is a number of minutes that indicates how long a channel can be cached before refreshing from the source.
 	TTL string `xml:"rss ttl"`
@@ -83,14 +83,14 @@ type RSSChannel struct {
 	SkipDays []string `xml:"rss skipDays>day"`
 
 	// Items is a collection of items.
-	Items []RSSItem `xml:"rss item"`
+	Items []rssItem `xml:"rss item"`
 
-	AtomLinks
+	atomLinks
 	itunes.ItunesChannelElement
 	googleplay.GooglePlayChannelElement
 }
 
-type RSSCloud struct {
+type rssCloud struct {
 	Domain            string `xml:"domain,attr"`
 	Port              string `xml:"port,attr"`
 	Path              string `xml:"path,attr"`
@@ -98,7 +98,7 @@ type RSSCloud struct {
 	Protocol          string `xml:"protocol,attr"`
 }
 
-type RSSImage struct {
+type rssImage struct {
 	// URL is the URL of a GIF, JPEG or PNG image that represents the channel.
 	URL string `xml:"url"`
 
@@ -109,9 +109,9 @@ type RSSImage struct {
 	Link string `xml:"link"`
 }
 
-type RSSItem struct {
+type rssItem struct {
 	// Title is the title of the item.
-	Title InnerContent `xml:"rss title"`
+	Title innerContent `xml:"rss title"`
 
 	// Link is the URL of the item.
 	Link string `xml:"rss link"`
@@ -120,7 +120,7 @@ type RSSItem struct {
 	Description string `xml:"rss description"`
 
 	// Author is the email address of the author of the item.
-	Author RSSAuthor `xml:"rss author"`
+	Author rssAuthor `xml:"rss author"`
 
 	// <category> is an optional sub-element of <item>.
 	// It has one optional attribute, domain, a string that identifies a categorization taxonomy.
@@ -133,7 +133,7 @@ type RSSItem struct {
 	// <enclosure> is an optional sub-element of <item>.
 	// It has three required attributes. url says where the enclosure is located,
 	// length says how big it is in bytes, and type says what its type is, a standard MIME type.
-	Enclosures []RSSEnclosure `xml:"rss enclosure"`
+	Enclosures []rssEnclosure `xml:"rss enclosure"`
 
 	// <guid> is an optional sub-element of <item>.
 	// It's a string that uniquely identifies the item.
@@ -149,7 +149,7 @@ type RSSItem struct {
 	//
 	// isPermaLink is optional, its default value is true.
 	// If its value is false, the guid may not be assumed to be a url, or a url to anything in particular.
-	GUID RSSGUID `xml:"rss guid"`
+	GUID rssGUID `xml:"rss guid"`
 
 	// <pubDate> is the publication date of the item.
 	// Its value is a string in RFC 822 format.
@@ -158,30 +158,30 @@ type RSSItem struct {
 	// <source> is an optional sub-element of <item>.
 	// Its value is the name of the RSS channel that the item came from, derived from its <title>.
 	// It has one required attribute, url, which contains the URL of the RSS channel.
-	Source RSSSource `xml:"rss source"`
+	Source rssSource `xml:"rss source"`
 
 	dublincore.DublinCoreItemElement
-	FeedBurnerItemElement
+	feedBurnerItemElement
 	media.MediaItemElement
-	AtomAuthor
-	AtomLinks
+	atomAuthor
+	atomLinks
 	itunes.ItunesItemElement
 	googleplay.GooglePlayItemElement
 }
 
-type RSSAuthor struct {
+type rssAuthor struct {
 	XMLName xml.Name
 	Data    string `xml:",chardata"`
 	Inner   string `xml:",innerxml"`
 }
 
-type RSSEnclosure struct {
+type rssEnclosure struct {
 	URL    string `xml:"url,attr"`
 	Type   string `xml:"type,attr"`
 	Length string `xml:"length,attr"`
 }
 
-func (enclosure *RSSEnclosure) Size() int64 {
+func (enclosure *rssEnclosure) Size() int64 {
 	if strings.TrimSpace(enclosure.Length) == "" {
 		return 0
 	}
@@ -189,21 +189,21 @@ func (enclosure *RSSEnclosure) Size() int64 {
 	return size
 }
 
-type RSSGUID struct {
+type rssGUID struct {
 	Data        string `xml:",chardata"`
 	IsPermaLink string `xml:"isPermaLink,attr"`
 }
 
-type RSSSource struct {
+type rssSource struct {
 	URL  string `xml:"url,attr"`
 	Name string `xml:",chardata"`
 }
 
-type InnerContent struct {
+type innerContent struct {
 	Content string
 }
 
-func (ic *InnerContent) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
+func (ic *innerContent) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error {
 	var content strings.Builder
 
 	for {

+ 2 - 1
internal/reader/sanitizer/sanitizer.go

@@ -197,7 +197,8 @@ type SanitizerOptions struct {
 	OpenLinksInNewTab bool
 }
 
-func SanitizeHTMLWithDefaultOptions(baseURL, rawHTML string) string {
+// TODO: replace with SanitizeHTML, as it's only used in tests.
+func sanitizeHTMLWithDefaultOptions(baseURL, rawHTML string) string {
 	return SanitizeHTML(baseURL, rawHTML, &SanitizerOptions{
 		OpenLinksInNewTab: true,
 	})

+ 88 - 88
internal/reader/sanitizer/sanitizer_test.go

@@ -27,7 +27,7 @@ func BenchmarkSanitize(b *testing.B) {
 	}
 	for b.Loop() {
 		for _, v := range testCases {
-			SanitizeHTMLWithDefaultOptions(v[0], v[1])
+			sanitizeHTMLWithDefaultOptions(v[0], v[1])
 		}
 	}
 }
@@ -40,7 +40,7 @@ func FuzzSanitizer(f *testing.F) {
 			i++
 		}
 
-		out := SanitizeHTMLWithDefaultOptions("", orig)
+		out := sanitizeHTMLWithDefaultOptions("", orig)
 
 		tok = html.NewTokenizer(strings.NewReader(out))
 		j := 0
@@ -56,7 +56,7 @@ func FuzzSanitizer(f *testing.F) {
 
 func TestValidInput(t *testing.T) {
 	input := `<p>This is a <strong>text</strong> with an image: <img src="http://example.org/" alt="Test" loading="lazy">.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if input != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
@@ -66,7 +66,7 @@ func TestValidInput(t *testing.T) {
 func TestImgWithWidthAndHeightAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="10" height="20">`
 	expected := `<img src="https://example.org/image.png" width="10" height="20" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -76,7 +76,7 @@ func TestImgWithWidthAndHeightAttribute(t *testing.T) {
 func TestImgWithWidthAttributeLargerThanMinifluxLayout(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="1200" height="675">`
 	expected := `<img src="https://example.org/image.png" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -86,7 +86,7 @@ func TestImgWithWidthAttributeLargerThanMinifluxLayout(t *testing.T) {
 func TestImgWithIncorrectWidthAndHeightAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="10px" height="20px">`
 	expected := `<img src="https://example.org/image.png" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -96,7 +96,7 @@ func TestImgWithIncorrectWidthAndHeightAttribute(t *testing.T) {
 func TestImgWithIncorrectWidthAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="10px" height="20">`
 	expected := `<img src="https://example.org/image.png" height="20" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -106,7 +106,7 @@ func TestImgWithIncorrectWidthAttribute(t *testing.T) {
 func TestImgWithEmptyWidthAndHeightAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="" height="">`
 	expected := `<img src="https://example.org/image.png" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -116,7 +116,7 @@ func TestImgWithEmptyWidthAndHeightAttribute(t *testing.T) {
 func TestImgWithIncorrectHeightAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="10" height="20px">`
 	expected := `<img src="https://example.org/image.png" width="10" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -126,7 +126,7 @@ func TestImgWithIncorrectHeightAttribute(t *testing.T) {
 func TestImgWithNegativeWidthAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="-10" height="20">`
 	expected := `<img src="https://example.org/image.png" height="20" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -136,7 +136,7 @@ func TestImgWithNegativeWidthAttribute(t *testing.T) {
 func TestImgWithNegativeHeightAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" width="10" height="-20">`
 	expected := `<img src="https://example.org/image.png" width="10" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -146,7 +146,7 @@ func TestImgWithNegativeHeightAttribute(t *testing.T) {
 func TestImgWithTextDataURL(t *testing.T) {
 	input := `<img src="data:text/plain;base64,SGVsbG8sIFdvcmxkIQ==" alt="Example">`
 	expected := ``
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -156,7 +156,7 @@ func TestImgWithTextDataURL(t *testing.T) {
 func TestImgWithDataURL(t *testing.T) {
 	input := `<img src="data:image/gif;base64,test" alt="Example">`
 	expected := `<img src="data:image/gif;base64,test" alt="Example" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -166,7 +166,7 @@ func TestImgWithDataURL(t *testing.T) {
 func TestImgWithSrcsetAttribute(t *testing.T) {
 	input := `<img srcset="example-320w.jpg, example-480w.jpg 1.5x,   example-640w.jpg 2x, example-640w.jpg 640w" src="example-640w.jpg" alt="Example">`
 	expected := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" src="http://example.org/example-640w.jpg" alt="Example" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -176,7 +176,7 @@ func TestImgWithSrcsetAttribute(t *testing.T) {
 func TestImgWithSrcsetAndNoSrcAttribute(t *testing.T) {
 	input := `<img srcset="example-320w.jpg, example-480w.jpg 1.5x,   example-640w.jpg 2x, example-640w.jpg 640w" alt="Example">`
 	expected := `<img srcset="http://example.org/example-320w.jpg, http://example.org/example-480w.jpg 1.5x, http://example.org/example-640w.jpg 2x, http://example.org/example-640w.jpg 640w" alt="Example" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -203,7 +203,7 @@ func TestImgWithFetchPriorityAttribute(t *testing.T) {
 	}
 
 	for _, tc := range cases {
-		output := SanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
+		output := sanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
 		if output != tc.expected {
 			t.Errorf(`Wrong output for input %q: expected %q, got %q`, tc.input, tc.expected, output)
 		}
@@ -213,7 +213,7 @@ func TestImgWithFetchPriorityAttribute(t *testing.T) {
 func TestImgWithInvalidFetchPriorityAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" fetchpriority="invalid">`
 	expected := `<img src="https://example.org/image.png" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
@@ -223,7 +223,7 @@ func TestImgWithInvalidFetchPriorityAttribute(t *testing.T) {
 func TestNonImgWithFetchPriorityAttribute(t *testing.T) {
 	input := `<p fetchpriority="high">Text</p>`
 	expected := `<p>Text</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
@@ -250,7 +250,7 @@ func TestImgWithDecodingAttribute(t *testing.T) {
 	}
 
 	for _, tc := range cases {
-		output := SanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
+		output := sanitizeHTMLWithDefaultOptions("http://example.org/", tc.input)
 		if output != tc.expected {
 			t.Errorf(`Wrong output for input %q: expected %q, got %q`, tc.input, tc.expected, output)
 		}
@@ -260,7 +260,7 @@ func TestImgWithDecodingAttribute(t *testing.T) {
 func TestImgWithInvalidDecodingAttribute(t *testing.T) {
 	input := `<img src="https://example.org/image.png" decoding="invalid">`
 	expected := `<img src="https://example.org/image.png" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
@@ -270,7 +270,7 @@ func TestImgWithInvalidDecodingAttribute(t *testing.T) {
 func TestNonImgWithDecodingAttribute(t *testing.T) {
 	input := `<p decoding="async">Text</p>`
 	expected := `<p>Text</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: expected %q, got %q`, expected, output)
@@ -280,7 +280,7 @@ func TestNonImgWithDecodingAttribute(t *testing.T) {
 func TestSourceWithSrcsetAndMedia(t *testing.T) {
 	input := `<picture><source media="(min-width: 800px)" srcset="elva-800w.jpg"></picture>`
 	expected := `<picture><source media="(min-width: 800px)" srcset="http://example.org/elva-800w.jpg"></picture>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -290,7 +290,7 @@ func TestSourceWithSrcsetAndMedia(t *testing.T) {
 func TestMediumImgWithSrcset(t *testing.T) {
 	input := `<img alt="Image for post" class="t u v ef aj" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" width="2730" height="3407">`
 	expected := `<img alt="Image for post" src="https://miro.medium.com/max/5460/1*aJ9JibWDqO81qMfNtqgqrw.jpeg" srcset="https://miro.medium.com/max/552/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 276w, https://miro.medium.com/max/1000/1*aJ9JibWDqO81qMfNtqgqrw.jpeg 500w" sizes="500px" loading="lazy">`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if output != expected {
 		t.Errorf(`Wrong output: %s`, output)
@@ -299,7 +299,7 @@ func TestMediumImgWithSrcset(t *testing.T) {
 
 func TestSelfClosingTags(t *testing.T) {
 	input := `<p>This <br> is a <strong>text</strong> <br/>with an image: <img src="http://example.org/" alt="Test" loading="lazy"/>.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if input != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
@@ -308,7 +308,7 @@ func TestSelfClosingTags(t *testing.T) {
 
 func TestTable(t *testing.T) {
 	input := `<table><tr><th>A</th><th colspan="2">B</th></tr><tr><td>C</td><td>D</td><td>E</td></tr></table>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if input != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, input, output)
@@ -318,7 +318,7 @@ func TestTable(t *testing.T) {
 func TestRelativeURL(t *testing.T) {
 	input := `This <a href="/test.html">link is relative</a> and this image: <img src="../folder/image.png"/>`
 	expected := `This <a href="http://example.org/test.html" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">link is relative</a> and this image: <img src="http://example.org/folder/image.png" loading="lazy"/>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -328,7 +328,7 @@ func TestRelativeURL(t *testing.T) {
 func TestProtocolRelativeURL(t *testing.T) {
 	input := `This <a href="//static.example.org/index.html">link is relative</a>.`
 	expected := `This <a href="https://static.example.org/index.html" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">link is relative</a>.`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -338,7 +338,7 @@ func TestProtocolRelativeURL(t *testing.T) {
 func TestInvalidTag(t *testing.T) {
 	input := `<p>My invalid <z>tag</z>.</p>`
 	expected := `<p>My invalid tag.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -348,7 +348,7 @@ func TestInvalidTag(t *testing.T) {
 func TestVideoTag(t *testing.T) {
 	input := `<p>My valid <video src="videofile.webm" autoplay poster="posterimage.jpg">fallback</video>.</p>`
 	expected := `<p>My valid <video src="http://example.org/videofile.webm" poster="http://example.org/posterimage.jpg" controls>fallback</video>.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -358,7 +358,7 @@ func TestVideoTag(t *testing.T) {
 func TestAudioAndSourceTag(t *testing.T) {
 	input := `<p>My music <audio controls="controls"><source src="foo.wav" type="audio/wav"></audio>.</p>`
 	expected := `<p>My music <audio controls><source src="http://example.org/foo.wav" type="audio/wav"></audio>.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -368,7 +368,7 @@ func TestAudioAndSourceTag(t *testing.T) {
 func TestUnknownTag(t *testing.T) {
 	input := `<p>My invalid <unknown>tag</unknown>.</p>`
 	expected := `<p>My invalid tag.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -378,7 +378,7 @@ func TestUnknownTag(t *testing.T) {
 func TestInvalidNestedTag(t *testing.T) {
 	input := `<p>My invalid <z>tag with some <em>valid</em> tag</z>.</p>`
 	expected := `<p>My invalid tag with some <em>valid</em> tag.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -390,7 +390,7 @@ func TestInvalidIFrame(t *testing.T) {
 
 	input := `<iframe src="http://example.org/"></iframe>`
 	expected := ``
-	output := SanitizeHTMLWithDefaultOptions("http://example.com/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -402,7 +402,7 @@ func TestSameDomainIFrame(t *testing.T) {
 
 	input := `<iframe src="http://example.com/test"></iframe>`
 	expected := ``
-	output := SanitizeHTMLWithDefaultOptions("http://example.com/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: %q != %q`, expected, output)
@@ -414,7 +414,7 @@ func TestInvidiousIFrame(t *testing.T) {
 
 	input := `<iframe src="https://yewtu.be/watch?v=video_id"></iframe>`
 	expected := `<iframe src="https://yewtu.be/watch?v=video_id" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.com/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: %q != %q`, expected, output)
@@ -432,7 +432,7 @@ func TestCustomYoutubeEmbedURL(t *testing.T) {
 
 	input := `<iframe src="https://www.invidious.custom/embed/1234"></iframe>`
 	expected := `<iframe src="https://www.invidious.custom/embed/1234" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.com/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: %q != %q`, expected, output)
@@ -444,7 +444,7 @@ func TestIFrameWithChildElements(t *testing.T) {
 
 	input := `<iframe src="https://www.youtube.com/"><p>test</p></iframe>`
 	expected := `<iframe src="https://www.youtube.com/" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.com/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.com/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -474,7 +474,7 @@ func TestLinkWithNoTarget(t *testing.T) {
 func TestAnchorLink(t *testing.T) {
 	input := `<p>This link is <a href="#some-anchor">an anchor</a></p>`
 	expected := `<p>This link is <a href="#some-anchor">an anchor</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -484,7 +484,7 @@ func TestAnchorLink(t *testing.T) {
 func TestInvalidURLScheme(t *testing.T) {
 	input := `<p>This link is <a src="file:///etc/passwd">not valid</a></p>`
 	expected := `<p>This link is not valid</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -494,7 +494,7 @@ func TestInvalidURLScheme(t *testing.T) {
 func TestAPTURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="apt:some-package?channel=test">valid</a></p>`
 	expected := `<p>This link is <a href="apt:some-package?channel=test" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -504,7 +504,7 @@ func TestAPTURIScheme(t *testing.T) {
 func TestBitcoinURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W">valid</a></p>`
 	expected := `<p>This link is <a href="bitcoin:175tWpb8K1S7NmH4Zx6rewF9WQrcZv245W" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -514,7 +514,7 @@ func TestBitcoinURIScheme(t *testing.T) {
 func TestCallToURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="callto:12345679">valid</a></p>`
 	expected := `<p>This link is <a href="callto:12345679" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -524,7 +524,7 @@ func TestCallToURIScheme(t *testing.T) {
 func TestFeedURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="feed://example.com/rss.xml">valid</a></p>`
 	expected := `<p>This link is <a href="feed://example.com/rss.xml" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -532,7 +532,7 @@ func TestFeedURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="feed:https://example.com/rss.xml">valid</a></p>`
 	expected = `<p>This link is <a href="feed:https://example.com/rss.xml" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -542,7 +542,7 @@ func TestFeedURIScheme(t *testing.T) {
 func TestGeoURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="geo:13.4125,103.8667">valid</a></p>`
 	expected := `<p>This link is <a href="geo:13.4125,103.8667" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -552,7 +552,7 @@ func TestGeoURIScheme(t *testing.T) {
 func TestItunesURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="itms://itunes.com/apps/my-app-name">valid</a></p>`
 	expected := `<p>This link is <a href="itms://itunes.com/apps/my-app-name" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -560,7 +560,7 @@ func TestItunesURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="itms-apps://itunes.com/apps/my-app-name">valid</a></p>`
 	expected = `<p>This link is <a href="itms-apps://itunes.com/apps/my-app-name" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -570,7 +570,7 @@ func TestItunesURIScheme(t *testing.T) {
 func TestMagnetURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&amp;xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7">valid</a></p>`
 	expected := `<p>This link is <a href="magnet:?xt.1=urn:sha1:YNCKHTQCWBTRNJIV4WNAE52SJUQCZO5C&amp;xt.2=urn:sha1:TXGCZQTH26NL6OUQAJJPFALHG2LTGBC7" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -580,7 +580,7 @@ func TestMagnetURIScheme(t *testing.T) {
 func TestMailtoURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="mailto:jsmith@example.com?subject=A%20Test&amp;body=My%20idea%20is%3A%20%0A">valid</a></p>`
 	expected := `<p>This link is <a href="mailto:jsmith@example.com?subject=A%20Test&amp;body=My%20idea%20is%3A%20%0A" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -590,7 +590,7 @@ func TestMailtoURIScheme(t *testing.T) {
 func TestNewsURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="news://news.server.example/*">valid</a></p>`
 	expected := `<p>This link is <a href="news://news.server.example/*" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -598,7 +598,7 @@ func TestNewsURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="news:example.group.this">valid</a></p>`
 	expected = `<p>This link is <a href="news:example.group.this" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -606,7 +606,7 @@ func TestNewsURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="nntp://news.server.example/example.group.this">valid</a></p>`
 	expected = `<p>This link is <a href="nntp://news.server.example/example.group.this" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -616,7 +616,7 @@ func TestNewsURIScheme(t *testing.T) {
 func TestRTMPURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="rtmp://mycompany.com/vod/mp4:mycoolvideo.mov">valid</a></p>`
 	expected := `<p>This link is <a href="rtmp://mycompany.com/vod/mp4:mycoolvideo.mov" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -626,7 +626,7 @@ func TestRTMPURIScheme(t *testing.T) {
 func TestSIPURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="sip:+1-212-555-1212:1234@gateway.com;user=phone">valid</a></p>`
 	expected := `<p>This link is <a href="sip:+1-212-555-1212:1234@gateway.com;user=phone" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -634,7 +634,7 @@ func TestSIPURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="sips:alice@atlanta.com?subject=project%20x&amp;priority=urgent">valid</a></p>`
 	expected = `<p>This link is <a href="sips:alice@atlanta.com?subject=project%20x&amp;priority=urgent" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -644,7 +644,7 @@ func TestSIPURIScheme(t *testing.T) {
 func TestSkypeURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="skype:echo123?call">valid</a></p>`
 	expected := `<p>This link is <a href="skype:echo123?call" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -654,7 +654,7 @@ func TestSkypeURIScheme(t *testing.T) {
 func TestSpotifyURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="spotify:track:2jCnn1QPQ3E8ExtLe6INsx">valid</a></p>`
 	expected := `<p>This link is <a href="spotify:track:2jCnn1QPQ3E8ExtLe6INsx" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -664,7 +664,7 @@ func TestSpotifyURIScheme(t *testing.T) {
 func TestSteamURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="steam://settings/account">valid</a></p>`
 	expected := `<p>This link is <a href="steam://settings/account" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -674,7 +674,7 @@ func TestSteamURIScheme(t *testing.T) {
 func TestSubversionURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="svn://example.org">valid</a></p>`
 	expected := `<p>This link is <a href="svn://example.org" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -682,7 +682,7 @@ func TestSubversionURIScheme(t *testing.T) {
 
 	input = `<p>This link is <a href="svn+ssh://example.org">valid</a></p>`
 	expected = `<p>This link is <a href="svn+ssh://example.org" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -692,7 +692,7 @@ func TestSubversionURIScheme(t *testing.T) {
 func TestTelURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="tel:+1-201-555-0123">valid</a></p>`
 	expected := `<p>This link is <a href="tel:+1-201-555-0123" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -702,7 +702,7 @@ func TestTelURIScheme(t *testing.T) {
 func TestWebcalURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="webcal://example.com/calendar.ics">valid</a></p>`
 	expected := `<p>This link is <a href="webcal://example.com/calendar.ics" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -712,7 +712,7 @@ func TestWebcalURIScheme(t *testing.T) {
 func TestXMPPURIScheme(t *testing.T) {
 	input := `<p>This link is <a href="xmpp:user@host?subscribe&amp;type=subscribed">valid</a></p>`
 	expected := `<p>This link is <a href="xmpp:user@host?subscribe&amp;type=subscribed" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">valid</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -722,7 +722,7 @@ func TestXMPPURIScheme(t *testing.T) {
 func TestBlacklistedLink(t *testing.T) {
 	input := `<p>This image is not valid <img src="https://stats.wordpress.com/some-tracker"></p>`
 	expected := `<p>This image is not valid </p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -732,7 +732,7 @@ func TestBlacklistedLink(t *testing.T) {
 func TestLinkWithTrackers(t *testing.T) {
 	input := `<p>This link has trackers <a href="https://example.com/page?utm_source=newsletter">Test</a></p>`
 	expected := `<p>This link has trackers <a href="https://example.com/page" rel="noopener noreferrer" referrerpolicy="no-referrer" target="_blank">Test</a></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -742,7 +742,7 @@ func TestLinkWithTrackers(t *testing.T) {
 func TestImageSrcWithTrackers(t *testing.T) {
 	input := `<p>This image has trackers <img src="https://example.org/?id=123&utm_source=newsletter&utm_medium=email&fbclid=abc123"></p>`
 	expected := `<p>This image has trackers <img src="https://example.org/?id=123" loading="lazy"></p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -752,7 +752,7 @@ func TestImageSrcWithTrackers(t *testing.T) {
 func Test1x1PixelTracker(t *testing.T) {
 	input := `<p><img src="https://tracker1.example.org/" height="1" width="1"> and <img src="https://tracker2.example.org/" height="1" width="1"/></p>`
 	expected := `<p> and </p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -762,7 +762,7 @@ func Test1x1PixelTracker(t *testing.T) {
 func Test0x0PixelTracker(t *testing.T) {
 	input := `<p><img src="https://tracker1.example.org/" height="0" width="0"> and <img src="https://tracker2.example.org/" height="0" width="0"/></p>`
 	expected := `<p> and </p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -772,7 +772,7 @@ func Test0x0PixelTracker(t *testing.T) {
 func TestXmlEntities(t *testing.T) {
 	input := `<pre>echo "test" &gt; /etc/hosts</pre>`
 	expected := `<pre>echo &#34;test&#34; &gt; /etc/hosts</pre>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -782,7 +782,7 @@ func TestXmlEntities(t *testing.T) {
 func TestEspaceAttributes(t *testing.T) {
 	input := `<td rowspan="<b>test</b>">test</td>`
 	expected := `<td rowspan="&lt;b&gt;test&lt;/b&gt;">test</td>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -792,7 +792,7 @@ func TestEspaceAttributes(t *testing.T) {
 func TestReplaceYoutubeURL(t *testing.T) {
 	input := `<iframe src="http://www.youtube.com/embed/test123?version=3&#038;rel=1&#038;fs=1&#038;autohide=2&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent"></iframe>`
 	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -802,7 +802,7 @@ func TestReplaceYoutubeURL(t *testing.T) {
 func TestReplaceSecureYoutubeURL(t *testing.T) {
 	input := `<iframe src="https://www.youtube.com/embed/test123"></iframe>`
 	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -812,7 +812,7 @@ func TestReplaceSecureYoutubeURL(t *testing.T) {
 func TestReplaceSecureYoutubeURLWithParameters(t *testing.T) {
 	input := `<iframe src="https://www.youtube.com/embed/test123?rel=0&amp;controls=0"></iframe>`
 	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -822,7 +822,7 @@ func TestReplaceSecureYoutubeURLWithParameters(t *testing.T) {
 func TestReplaceYoutubeURLAlreadyReplaced(t *testing.T) {
 	input := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin"></iframe>`
 	expected := `<iframe src="https://www.youtube-nocookie.com/embed/test123?rel=0&amp;controls=0" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -832,7 +832,7 @@ func TestReplaceYoutubeURLAlreadyReplaced(t *testing.T) {
 func TestReplaceProtocolRelativeYoutubeURL(t *testing.T) {
 	input := `<iframe src="//www.youtube.com/embed/Bf2W84jrGqs" width="560" height="314" allowfullscreen="allowfullscreen"></iframe>`
 	expected := `<iframe src="https://www.youtube-nocookie.com/embed/Bf2W84jrGqs" width="560" height="314" allowfullscreen="allowfullscreen" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -851,7 +851,7 @@ func TestReplaceYoutubeURLWithCustomURL(t *testing.T) {
 
 	input := `<iframe src="https://www.youtube.com/embed/test123?version=3&#038;rel=1&#038;fs=1&#038;autohide=2&#038;showsearch=0&#038;showinfo=1&#038;iv_load_policy=1&#038;wmode=transparent"></iframe>`
 	expected := `<iframe src="https://invidious.custom/embed/test123?version=3&amp;rel=1&amp;fs=1&amp;autohide=2&amp;showsearch=0&amp;showinfo=1&amp;iv_load_policy=1&amp;wmode=transparent" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -861,7 +861,7 @@ func TestReplaceYoutubeURLWithCustomURL(t *testing.T) {
 func TestVimeoIframeRewriteWithQueryString(t *testing.T) {
 	input := `<iframe src="https://player.vimeo.com/video/123456?title=0&amp;byline=0"></iframe>`
 	expected := `<iframe src="https://player.vimeo.com/video/123456?title=0&amp;byline=0&amp;dnt=1" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: %q != %q`, expected, output)
@@ -871,7 +871,7 @@ func TestVimeoIframeRewriteWithQueryString(t *testing.T) {
 func TestVimeoIframeRewriteWithoutQueryString(t *testing.T) {
 	input := `<iframe src="https://player.vimeo.com/video/123456"></iframe>`
 	expected := `<iframe src="https://player.vimeo.com/video/123456?dnt=1" sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox" loading="lazy"></iframe>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: %q != %q`, expected, output)
@@ -881,7 +881,7 @@ func TestVimeoIframeRewriteWithoutQueryString(t *testing.T) {
 func TestReplaceNoScript(t *testing.T) {
 	input := `<p>Before paragraph.</p><noscript>Inside <code>noscript</code> tag with an image: <img src="http://example.org/" alt="Test" loading="lazy"></noscript><p>After paragraph.</p>`
 	expected := `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -891,7 +891,7 @@ func TestReplaceNoScript(t *testing.T) {
 func TestReplaceScript(t *testing.T) {
 	input := `<p>Before paragraph.</p><script type="text/javascript">alert("1");</script><p>After paragraph.</p>`
 	expected := `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -901,7 +901,7 @@ func TestReplaceScript(t *testing.T) {
 func TestReplaceStyle(t *testing.T) {
 	input := `<p>Before paragraph.</p><style>body { background-color: #ff0000; }</style><p>After paragraph.</p>`
 	expected := `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -911,7 +911,7 @@ func TestReplaceStyle(t *testing.T) {
 func TestHiddenParagraph(t *testing.T) {
 	input := `<p>Before paragraph.</p><p hidden>This should <em>not</em> appear in the <strong>output</strong></p><p>After paragraph.</p>`
 	expected := `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -922,7 +922,7 @@ func TestAttributesAreStripped(t *testing.T) {
 	input := `<p style="color: red;">Some text.<hr style="color: blue"/>Test.</p>`
 	expected := `<p>Some text.<hr/>Test.</p>`
 
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
 	}
@@ -931,7 +931,7 @@ func TestAttributesAreStripped(t *testing.T) {
 func TestMathML(t *testing.T) {
 	input := `<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>x</mi><mn>2</mn></msup></math>`
 	expected := `<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>x</mi><mn>2</mn></msup></math>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -941,7 +941,7 @@ func TestMathML(t *testing.T) {
 func TestInvalidMathMLXMLNamespace(t *testing.T) {
 	input := `<math xmlns="http://example.org"><msup><mi>x</mi><mn>2</mn></msup></math>`
 	expected := `<math xmlns="http://www.w3.org/1998/Math/MathML"><msup><mi>x</mi><mn>2</mn></msup></math>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -951,7 +951,7 @@ func TestInvalidMathMLXMLNamespace(t *testing.T) {
 func TestBlockedResourcesSubstrings(t *testing.T) {
 	input := `<p>Before paragraph.</p><img src="http://stats.wordpress.com/something.php" alt="Blocked Resource"><p>After paragraph.</p>`
 	expected := `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output := SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output := sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -959,7 +959,7 @@ func TestBlockedResourcesSubstrings(t *testing.T) {
 
 	input = `<p>Before paragraph.</p><img src="http://twitter.com/share?text=This+is+google+a+search+engine&url=https%3A%2F%2Fwww.google.com" alt="Blocked Resource"><p>After paragraph.</p>`
 	expected = `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)
@@ -967,7 +967,7 @@ func TestBlockedResourcesSubstrings(t *testing.T) {
 
 	input = `<p>Before paragraph.</p><img src="http://www.facebook.com/sharer.php?u=https%3A%2F%2Fwww.google.com%[title]=This+Is%2C+Google+a+search+engine" alt="Blocked Resource"><p>After paragraph.</p>`
 	expected = `<p>Before paragraph.</p><p>After paragraph.</p>`
-	output = SanitizeHTMLWithDefaultOptions("http://example.org/", input)
+	output = sanitizeHTMLWithDefaultOptions("http://example.org/", input)
 
 	if expected != output {
 		t.Errorf(`Wrong output: "%s" != "%s"`, expected, output)

+ 7 - 7
internal/reader/sanitizer/srcset.go

@@ -9,14 +9,14 @@ import (
 	"strings"
 )
 
-type ImageCandidate struct {
+type imageCandidate struct {
 	ImageURL   string
 	Descriptor string
 }
 
-type ImageCandidates []*ImageCandidate
+type imageCandidates []*imageCandidate
 
-func (c ImageCandidates) String() string {
+func (c imageCandidates) String() string {
 	htmlCandidates := make([]string, 0, len(c))
 
 	for _, imageCandidate := range c {
@@ -35,7 +35,7 @@ func (c ImageCandidates) String() string {
 
 // ParseSrcSetAttribute returns the list of image candidates from the set.
 // https://html.spec.whatwg.org/#parse-a-srcset-attribute
-func ParseSrcSetAttribute(attributeValue string) (imageCandidates ImageCandidates) {
+func ParseSrcSetAttribute(attributeValue string) (imageCandidates imageCandidates) {
 	for _, unparsedCandidate := range strings.Split(attributeValue, ", ") {
 		if candidate, err := parseImageCandidate(unparsedCandidate); err == nil {
 			imageCandidates = append(imageCandidates, candidate)
@@ -45,18 +45,18 @@ func ParseSrcSetAttribute(attributeValue string) (imageCandidates ImageCandidate
 	return imageCandidates
 }
 
-func parseImageCandidate(input string) (*ImageCandidate, error) {
+func parseImageCandidate(input string) (*imageCandidate, error) {
 	parts := strings.Split(strings.TrimSpace(input), " ")
 	nbParts := len(parts)
 
 	switch nbParts {
 	case 1:
-		return &ImageCandidate{ImageURL: parts[0]}, nil
+		return &imageCandidate{ImageURL: parts[0]}, nil
 	case 2:
 		if !isValidWidthOrDensityDescriptor(parts[1]) {
 			return nil, fmt.Errorf(`srcset: invalid descriptor`)
 		}
-		return &ImageCandidate{ImageURL: parts[0], Descriptor: parts[1]}, nil
+		return &imageCandidate{ImageURL: parts[0], Descriptor: parts[1]}, nil
 	default:
 		return nil, fmt.Errorf(`srcset: invalid number of descriptors`)
 	}

+ 19 - 19
internal/reader/subscription/finder.go

@@ -22,27 +22,27 @@ import (
 	"github.com/PuerkitoBio/goquery"
 )
 
-type SubscriptionFinder struct {
+type subscriptionFinder struct {
 	requestBuilder   *fetcher.RequestBuilder
 	feedDownloaded   bool
 	feedResponseInfo *model.FeedCreationRequestFromSubscriptionDiscovery
 }
 
-func NewSubscriptionFinder(requestBuilder *fetcher.RequestBuilder) *SubscriptionFinder {
-	return &SubscriptionFinder{
+func NewSubscriptionFinder(requestBuilder *fetcher.RequestBuilder) *subscriptionFinder {
+	return &subscriptionFinder{
 		requestBuilder: requestBuilder,
 	}
 }
 
-func (f *SubscriptionFinder) IsFeedAlreadyDownloaded() bool {
+func (f *subscriptionFinder) IsFeedAlreadyDownloaded() bool {
 	return f.feedDownloaded
 }
 
-func (f *SubscriptionFinder) FeedResponseInfo() *model.FeedCreationRequestFromSubscriptionDiscovery {
+func (f *subscriptionFinder) FeedResponseInfo() *model.FeedCreationRequestFromSubscriptionDiscovery {
 	return f.feedResponseInfo
 }
 
-func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string, rssBridgeToken string) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string, rssBridgeToken string) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	responseHandler := fetcher.NewResponseHandler(f.requestBuilder.ExecuteRequest(websiteURL))
 	defer responseHandler.Close()
 
@@ -71,7 +71,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 
 	// Step 2) Check if the website URL is a YouTube channel.
 	slog.Debug("Try to detect feeds from YouTube channel page", slog.String("website_url", websiteURL))
-	if subscriptions, localizedError := f.FindSubscriptionsFromYouTubeChannelPage(websiteURL); localizedError != nil {
+	if subscriptions, localizedError := f.findSubscriptionsFromYouTubeChannelPage(websiteURL); localizedError != nil {
 		return nil, localizedError
 	} else if len(subscriptions) > 0 {
 		slog.Debug("Subscriptions found from YouTube channel page", slog.String("website_url", websiteURL), slog.Any("subscriptions", subscriptions))
@@ -80,7 +80,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 
 	// Step 3) Check if the website URL is a YouTube playlist.
 	slog.Debug("Try to detect feeds from YouTube playlist page", slog.String("website_url", websiteURL))
-	if subscriptions, localizedError := f.FindSubscriptionsFromYouTubePlaylistPage(websiteURL); localizedError != nil {
+	if subscriptions, localizedError := f.findSubscriptionsFromYouTubePlaylistPage(websiteURL); localizedError != nil {
 		return nil, localizedError
 	} else if len(subscriptions) > 0 {
 		slog.Debug("Subscriptions found from YouTube playlist page", slog.String("website_url", websiteURL), slog.Any("subscriptions", subscriptions))
@@ -92,7 +92,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 		slog.String("website_url", websiteURL),
 		slog.String("content_type", responseHandler.ContentType()),
 	)
-	if subscriptions, localizedError := f.FindSubscriptionsFromWebPage(websiteURL, responseHandler.ContentType(), bytes.NewReader(responseBody)); localizedError != nil {
+	if subscriptions, localizedError := f.findSubscriptionsFromWebPage(websiteURL, responseHandler.ContentType(), bytes.NewReader(responseBody)); localizedError != nil {
 		return nil, localizedError
 	} else if len(subscriptions) > 0 {
 		slog.Debug("Subscriptions found from web page", slog.String("website_url", websiteURL), slog.Any("subscriptions", subscriptions))
@@ -102,7 +102,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 	// Step 5) Check if the website URL can use RSS-Bridge.
 	if rssBridgeURL != "" {
 		slog.Debug("Try to detect feeds with RSS-Bridge", slog.String("website_url", websiteURL))
-		if subscriptions, localizedError := f.FindSubscriptionsFromRSSBridge(websiteURL, rssBridgeURL, rssBridgeToken); localizedError != nil {
+		if subscriptions, localizedError := f.findSubscriptionsFromRSSBridge(websiteURL, rssBridgeURL, rssBridgeToken); localizedError != nil {
 			return nil, localizedError
 		} else if len(subscriptions) > 0 {
 			slog.Debug("Subscriptions found from RSS-Bridge", slog.String("website_url", websiteURL), slog.Any("subscriptions", subscriptions))
@@ -112,7 +112,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 
 	// Step 6) Check if the website has a known feed URL.
 	slog.Debug("Try to detect feeds from well-known URLs", slog.String("website_url", websiteURL))
-	if subscriptions, localizedError := f.FindSubscriptionsFromWellKnownURLs(websiteURL); localizedError != nil {
+	if subscriptions, localizedError := f.findSubscriptionsFromWellKnownURLs(websiteURL); localizedError != nil {
 		return nil, localizedError
 	} else if len(subscriptions) > 0 {
 		slog.Debug("Subscriptions found with well-known URLs", slog.String("website_url", websiteURL), slog.Any("subscriptions", subscriptions))
@@ -122,7 +122,7 @@ func (f *SubscriptionFinder) FindSubscriptions(websiteURL, rssBridgeURL string,
 	return nil, nil
 }
 
-func (f *SubscriptionFinder) FindSubscriptionsFromWebPage(websiteURL, contentType string, body io.Reader) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) findSubscriptionsFromWebPage(websiteURL, contentType string, body io.Reader) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	queries := map[string]string{
 		"link[type='application/rss+xml']":   parser.FormatRSS,
 		"link[type='application/atom+xml']":  parser.FormatAtom,
@@ -151,7 +151,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromWebPage(websiteURL, contentTyp
 	subscriptionURLs := make(map[string]bool)
 	for query, kind := range queries {
 		doc.Find(query).Each(func(i int, s *goquery.Selection) {
-			subscription := new(Subscription)
+			subscription := new(subscription)
 			subscription.Type = kind
 
 			if title, exists := s.Attr("title"); exists {
@@ -181,7 +181,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromWebPage(websiteURL, contentTyp
 	return subscriptions, nil
 }
 
-func (f *SubscriptionFinder) FindSubscriptionsFromWellKnownURLs(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) findSubscriptionsFromWellKnownURLs(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	knownURLs := map[string]string{
 		"atom.xml":     parser.FormatAtom,
 		"feed.atom":    parser.FormatAtom,
@@ -237,7 +237,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromWellKnownURLs(websiteURL strin
 				continue
 			}
 
-			subscriptions = append(subscriptions, &Subscription{
+			subscriptions = append(subscriptions, &subscription{
 				Type:  kind,
 				Title: fullURL,
 				URL:   fullURL,
@@ -248,7 +248,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromWellKnownURLs(websiteURL strin
 	return subscriptions, nil
 }
 
-func (f *SubscriptionFinder) FindSubscriptionsFromRSSBridge(websiteURL, rssBridgeURL string, rssBridgeToken string) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) findSubscriptionsFromRSSBridge(websiteURL, rssBridgeURL string, rssBridgeToken string) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	slog.Debug("Trying to detect feeds using RSS-Bridge",
 		slog.String("website_url", websiteURL),
 		slog.String("rssbridge_url", rssBridgeURL),
@@ -273,7 +273,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromRSSBridge(websiteURL, rssBridg
 
 	subscriptions := make(Subscriptions, 0, len(bridges))
 	for _, bridge := range bridges {
-		subscriptions = append(subscriptions, &Subscription{
+		subscriptions = append(subscriptions, &subscription{
 			Title: bridge.BridgeMeta.Name,
 			URL:   bridge.URL,
 			Type:  parser.FormatAtom,
@@ -283,7 +283,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromRSSBridge(websiteURL, rssBridg
 	return subscriptions, nil
 }
 
-func (f *SubscriptionFinder) FindSubscriptionsFromYouTubeChannelPage(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) findSubscriptionsFromYouTubeChannelPage(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	decodedUrl, err := url.Parse(websiteURL)
 	if err != nil {
 		return nil, locale.NewLocalizedErrorWrapper(err, "error.invalid_site_url", err)
@@ -302,7 +302,7 @@ func (f *SubscriptionFinder) FindSubscriptionsFromYouTubeChannelPage(websiteURL
 	return nil, nil
 }
 
-func (f *SubscriptionFinder) FindSubscriptionsFromYouTubePlaylistPage(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
+func (f *subscriptionFinder) findSubscriptionsFromYouTubePlaylistPage(websiteURL string) (Subscriptions, *locale.LocalizedErrorWrapper) {
 	decodedUrl, err := url.Parse(websiteURL)
 	if err != nil {
 		return nil, locale.NewLocalizedErrorWrapper(err, "error.invalid_site_url", err)

+ 12 - 12
internal/reader/subscription/finder_test.go

@@ -70,7 +70,7 @@ func TestFindYoutubePlaylistFeed(t *testing.T) {
 	}
 
 	for _, scenario := range scenarios {
-		subscriptions, localizedError := NewSubscriptionFinder(nil).FindSubscriptionsFromYouTubePlaylistPage(scenario.websiteURL)
+		subscriptions, localizedError := NewSubscriptionFinder(nil).findSubscriptionsFromYouTubePlaylistPage(scenario.websiteURL)
 		if scenario.discoveryError {
 			if localizedError == nil {
 				t.Fatalf(`Parsing an invalid URL should return an error`)
@@ -159,7 +159,7 @@ func TestFindYoutubeChannelFeed(t *testing.T) {
 	}
 
 	for _, scenario := range scenarios {
-		subscriptions, localizedError := NewSubscriptionFinder(nil).FindSubscriptionsFromYouTubeChannelPage(scenario.websiteURL)
+		subscriptions, localizedError := NewSubscriptionFinder(nil).findSubscriptionsFromYouTubeChannelPage(scenario.websiteURL)
 		if scenario.discoveryError {
 			if localizedError == nil {
 				t.Fatalf(`Parsing an invalid URL should return an error`)
@@ -197,7 +197,7 @@ func TestParseWebPageWithRssFeed(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -230,7 +230,7 @@ func TestParseWebPageWithAtomFeed(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -263,7 +263,7 @@ func TestParseWebPageWithJSONFeed(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -296,7 +296,7 @@ func TestParseWebPageWithOldJSONFeedMimeType(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -329,7 +329,7 @@ func TestParseWebPageWithRelativeFeedURL(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -362,7 +362,7 @@ func TestParseWebPageWithEmptyTitle(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -396,7 +396,7 @@ func TestParseWebPageWithMultipleFeeds(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -418,7 +418,7 @@ func TestParseWebPageWithDuplicatedFeeds(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -451,7 +451,7 @@ func TestParseWebPageWithEmptyFeedURL(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}
@@ -472,7 +472,7 @@ func TestParseWebPageWithNoHref(t *testing.T) {
 		</body>
 	</html>`
 
-	subscriptions, err := NewSubscriptionFinder(nil).FindSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
+	subscriptions, err := NewSubscriptionFinder(nil).findSubscriptionsFromWebPage("http://example.org/", "text/html", strings.NewReader(htmlPage))
 	if err != nil {
 		t.Fatalf(`Parsing a correctly formatted HTML page should not return any error: %v`, err)
 	}

+ 6 - 6
internal/reader/subscription/subscription.go

@@ -5,20 +5,20 @@ package subscription // import "miniflux.app/v2/internal/reader/subscription"
 
 import "fmt"
 
-// Subscription represents a feed subscription.
-type Subscription struct {
+// subscription represents a feed subscription.
+type subscription struct {
 	Title string `json:"title"`
 	URL   string `json:"url"`
 	Type  string `json:"type"`
 }
 
-func NewSubscription(title, url, kind string) *Subscription {
-	return &Subscription{Title: title, URL: url, Type: kind}
+func NewSubscription(title, url, kind string) *subscription {
+	return &subscription{Title: title, URL: url, Type: kind}
 }
 
-func (s Subscription) String() string {
+func (s subscription) String() string {
 	return fmt.Sprintf(`Title=%q, URL=%q, Type=%q`, s.Title, s.URL, s.Type)
 }
 
 // Subscriptions represents a list of subscription.
-type Subscriptions []*Subscription
+type Subscriptions []*subscription

+ 5 - 5
internal/ui/form/auth.go

@@ -10,14 +10,14 @@ import (
 	"miniflux.app/v2/internal/locale"
 )
 
-// AuthForm represents the authentication form.
-type AuthForm struct {
+// authForm represents the authentication form.
+type authForm struct {
 	Username string
 	Password string
 }
 
 // Validate makes sure the form values are valid.
-func (a AuthForm) Validate() *locale.LocalizedError {
+func (a authForm) Validate() *locale.LocalizedError {
 	if a.Username == "" || a.Password == "" {
 		return locale.NewLocalizedError("error.fields_mandatory")
 	}
@@ -26,8 +26,8 @@ func (a AuthForm) Validate() *locale.LocalizedError {
 }
 
 // NewAuthForm returns a new AuthForm.
-func NewAuthForm(r *http.Request) *AuthForm {
-	return &AuthForm{
+func NewAuthForm(r *http.Request) *authForm {
+	return &authForm{
 		Username: strings.TrimSpace(r.FormValue("username")),
 		Password: strings.TrimSpace(r.FormValue("password")),
 	}

+ 12 - 12
internal/ui/form/settings.go

@@ -13,14 +13,14 @@ import (
 	"miniflux.app/v2/internal/validator"
 )
 
-// MarkReadBehavior list all possible behaviors for automatically marking an entry as read
-type MarkReadBehavior string
+// markReadBehavior list all possible behaviors for automatically marking an entry as read
+type markReadBehavior string
 
 const (
-	NoAutoMarkAsRead                           MarkReadBehavior = "no-auto"
-	MarkAsReadOnView                           MarkReadBehavior = "on-view"
-	MarkAsReadOnViewButWaitForPlayerCompletion MarkReadBehavior = "on-view-but-wait-for-player-completion"
-	MarkAsReadOnlyOnPlayerCompletion           MarkReadBehavior = "on-player-completion"
+	NoAutoMarkAsRead                           markReadBehavior = "no-auto"
+	MarkAsReadOnView                           markReadBehavior = "on-view"
+	MarkAsReadOnViewButWaitForPlayerCompletion markReadBehavior = "on-view-but-wait-for-player-completion"
+	MarkAsReadOnlyOnPlayerCompletion           markReadBehavior = "on-player-completion"
 )
 
 // SettingsForm represents the settings form.
@@ -48,7 +48,7 @@ type SettingsForm struct {
 	CategoriesSortingOrder string
 	MarkReadOnView         bool
 	// MarkReadBehavior is a string representation of the MarkReadOnView and MarkReadOnMediaPlayerCompletion fields together
-	MarkReadBehavior          MarkReadBehavior
+	MarkReadBehavior          markReadBehavior
 	MediaPlaybackRate         float64
 	BlockFilterEntryRules     string
 	KeepFilterEntryRules      string
@@ -58,7 +58,7 @@ type SettingsForm struct {
 
 // MarkAsReadBehavior returns the MarkReadBehavior from the given MarkReadOnView and MarkReadOnMediaPlayerCompletion values.
 // Useful to convert the values from the User model to the form
-func MarkAsReadBehavior(markReadOnView, markReadOnMediaPlayerCompletion bool) MarkReadBehavior {
+func MarkAsReadBehavior(markReadOnView, markReadOnMediaPlayerCompletion bool) markReadBehavior {
 	switch {
 	case markReadOnView && !markReadOnMediaPlayerCompletion:
 		return MarkAsReadOnView
@@ -73,9 +73,9 @@ func MarkAsReadBehavior(markReadOnView, markReadOnMediaPlayerCompletion bool) Ma
 	}
 }
 
-// ExtractMarkAsReadBehavior returns the MarkReadOnView and MarkReadOnMediaPlayerCompletion values from the given MarkReadBehavior.
+// extractMarkAsReadBehavior returns the MarkReadOnView and MarkReadOnMediaPlayerCompletion values from the given MarkReadBehavior.
 // Useful to extract the values from the form to the User model
-func ExtractMarkAsReadBehavior(behavior MarkReadBehavior) (markReadOnView, markReadOnMediaPlayerCompletion bool) {
+func extractMarkAsReadBehavior(behavior markReadBehavior) (markReadOnView, markReadOnMediaPlayerCompletion bool) {
 	switch behavior {
 	case MarkAsReadOnView:
 		return true, false
@@ -119,7 +119,7 @@ func (s *SettingsForm) Merge(user *model.User) *model.User {
 	user.AlwaysOpenExternalLinks = s.AlwaysOpenExternalLinks
 	user.OpenExternalLinksInNewTab = s.OpenExternalLinksInNewTab
 
-	MarkReadOnView, MarkReadOnMediaPlayerCompletion := ExtractMarkAsReadBehavior(s.MarkReadBehavior)
+	MarkReadOnView, MarkReadOnMediaPlayerCompletion := extractMarkAsReadBehavior(s.MarkReadBehavior)
 	user.MarkReadOnView = MarkReadOnView
 	user.MarkReadOnMediaPlayerCompletion = MarkReadOnMediaPlayerCompletion
 
@@ -205,7 +205,7 @@ func NewSettingsForm(r *http.Request) *SettingsForm {
 		DefaultHomePage:           r.FormValue("default_home_page"),
 		CategoriesSortingOrder:    r.FormValue("categories_sorting_order"),
 		MarkReadOnView:            r.FormValue("mark_read_on_view") == "1",
-		MarkReadBehavior:          MarkReadBehavior(r.FormValue("mark_read_behavior")),
+		MarkReadBehavior:          markReadBehavior(r.FormValue("mark_read_behavior")),
 		MediaPlaybackRate:         mediaPlaybackRate,
 		BlockFilterEntryRules:     r.FormValue("block_filter_entry_rules"),
 		KeepFilterEntryRules:      r.FormValue("keep_filter_entry_rules"),

+ 6 - 6
internal/ui/view/view.go

@@ -13,28 +13,28 @@ import (
 	"miniflux.app/v2/internal/ui/static"
 )
 
-// View wraps template argument building.
-type View struct {
+// view wraps template argument building.
+type view struct {
 	tpl    *template.Engine
 	r      *http.Request
 	params map[string]any
 }
 
 // Set adds a new template argument.
-func (v *View) Set(param string, value any) *View {
+func (v *view) Set(param string, value any) *view {
 	v.params[param] = value
 	return v
 }
 
 // Render executes the template with arguments.
-func (v *View) Render(template string) []byte {
+func (v *view) Render(template string) []byte {
 	return v.tpl.Render(template+".html", v.params)
 }
 
 // New returns a new view with default parameters.
-func New(tpl *template.Engine, r *http.Request, sess *session.Session) *View {
+func New(tpl *template.Engine, r *http.Request, sess *session.Session) *view {
 	theme := request.UserTheme(r)
-	return &View{tpl, r, map[string]any{
+	return &view{tpl, r, map[string]any{
 		"menu":              "",
 		"csrf":              request.CSRF(r),
 		"flashMessage":      sess.FlashMessage(request.FlashMessage(r)),

+ 1 - 1
internal/worker/pool.go

@@ -27,7 +27,7 @@ func NewPool(store *storage.Storage, nbWorkers int) *Pool {
 	}
 
 	for i := range nbWorkers {
-		worker := &Worker{id: i, store: store}
+		worker := &worker{id: i, store: store}
 		go worker.Run(workerPool.queue)
 	}
 

+ 3 - 3
internal/worker/worker.go

@@ -14,14 +14,14 @@ import (
 	"miniflux.app/v2/internal/storage"
 )
 
-// Worker refreshes a feed in the background.
-type Worker struct {
+// worker refreshes a feed in the background.
+type worker struct {
 	id    int
 	store *storage.Storage
 }
 
 // Run wait for a job and refresh the given feed.
-func (w *Worker) Run(c <-chan model.Job) {
+func (w *worker) Run(c <-chan model.Job) {
 	slog.Debug("Worker started",
 		slog.Int("worker_id", w.id),
 	)