summaryrefslogtreecommitdiffstats
path: root/transform/absurl.go
diff options
context:
space:
mode:
authorNoah Campbell <noahcampbell@gmail.com>2013-10-01 12:59:29 -0700
committerNoah Campbell <noahcampbell@gmail.com>2013-10-08 18:37:49 +0200
commiteb117eb9043a4954079f1845f61cc0bfe2facb37 (patch)
tree17ae626e3bca147af3c7b2eb04d4cc9cf5e64c0e /transform/absurl.go
parentf0211b84a1967c4dae471c19e5bde69016345c95 (diff)
Move AbsURL into seperate file
Diffstat (limited to 'transform/absurl.go')
-rw-r--r--transform/absurl.go59
1 files changed, 59 insertions, 0 deletions
diff --git a/transform/absurl.go b/transform/absurl.go
new file mode 100644
index 000000000..6e7eb125b
--- /dev/null
+++ b/transform/absurl.go
@@ -0,0 +1,59 @@
+package transform
+
+import (
+ htmltran "code.google.com/p/go-html-transform/html/transform"
+ "io"
+ "net/url"
+)
+
+type AbsURL struct {
+ BaseURL string
+}
+
+func (t *AbsURL) Apply(r io.Reader, w io.Writer) (err error) {
+ var tr *htmltran.Transformer
+
+ if tr, err = htmltran.NewFromReader(r); err != nil {
+ return
+ }
+
+ if err = t.absUrlify(tr, elattr{"a", "href"}, elattr{"script", "src"}); err != nil {
+ return
+ }
+
+ return tr.Render(w)
+}
+
+type elattr struct {
+ tag, attr string
+}
+
+func (t *AbsURL) absUrlify(tr *htmltran.Transformer, selectors ...elattr) (err error) {
+ var baseURL, inURL *url.URL
+
+ if baseURL, err = url.Parse(t.BaseURL); err != nil {
+ return
+ }
+
+ replace := func(in string) string {
+ if inURL, err = url.Parse(in); err != nil {
+ return in + "?"
+ }
+ if fragmentOnly(inURL) {
+ return in
+ }
+ return baseURL.ResolveReference(inURL).String()
+ }
+
+ for _, el := range selectors {
+ if err = tr.Apply(htmltran.TransformAttrib(el.attr, replace), el.tag); err != nil {
+ return
+ }
+ }
+
+ return
+}
+
+func fragmentOnly(u *url.URL) bool {
+ return u.Fragment != "" && u.Scheme == "" && u.Opaque == "" && u.User == nil && u.Host == "" && u.Path == "" && u.Path == "" && u.RawQuery == ""
+}