Skip to content

Commit

Permalink
Add support for appending JS resource at end of HTML (#3)
Browse files Browse the repository at this point in the history
* snapshot: start wiring in JS at EOF hooks; doesn't work yet

* working through bugs

* update to use aaronland/go-http-static v0.0.3, aaronland/go-http-leaflet v0.3.0; add support for appending JS resource at end of HTML
  • Loading branch information
thisisaaronland committed Mar 10, 2023
1 parent 21ee885 commit 3c7dba3
Show file tree
Hide file tree
Showing 131 changed files with 7,306 additions and 3,320 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ cli:
go build -mod vendor -o bin/example cmd/example/main.go

debug:
go run -mod vendor cmd/example/main.go
go run -mod vendor cmd/example/main.go -javascript-at-eof

protomaps-js:
curl -s -L -o static/javascript/protomaps.js https://unpkg.com/protomaps@latest/dist/protomaps.js
Expand Down
27 changes: 17 additions & 10 deletions cmd/example/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,25 @@
<body>
<div id="map"></div>
<script type="text/javascript">
window.addEventListener("load", function load(event){

var tile_url = document.body.getAttribute("data-protomaps-tile-url");

var tile_url = document.body.getAttribute("data-protomaps-tile-url");

const map = L.map('map');
map.setView([37.61799, -122.370943], 14);
if (! tile_url){
alert("Missing tile URL");
return false;
}

const map = L.map('map');
map.setView([37.61799, -122.370943], 14);

console.log(tile_url);

var layer = protomaps.leafletLayer({url:tile_url})
layer.addTo(map);

new L.Hash(map);
var layer = protomaps.leafletLayer({url:tile_url})

layer.addTo(map);
layer.addInspector(map);

new L.Hash(map);
});
</script>
</body>
</html>
3 changes: 3 additions & 0 deletions cmd/example/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ func main() {

append_leaflet := flag.Bool("append-leaflet", true, "Append Leaflet.js assets and resources bundled with the go-http-protomaps package.")

js_eof := flag.Bool("javascript-at-eof", false, "Append JavaScript resources to end of HTML file.")

flag.Parse()

ctx := context.Background()
Expand Down Expand Up @@ -90,6 +92,7 @@ func main() {
pm_opts.TileURL = *tile_url

pm_opts.LeafletOptions.EnableHash()
pm_opts.AppendJavaScriptAtEOF = *js_eof

index_handler = protomaps.AppendResourcesHandler(index_handler, pm_opts)
mux.Handle("/", index_handler)
Expand Down
13 changes: 7 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@ module github.com/sfomuseum/go-http-protomaps
go 1.18

require (
github.com/aaronland/go-http-leaflet v0.1.3
github.com/aaronland/go-http-rewrite v1.0.1
github.com/aaronland/go-http-server v1.0.0
github.com/aaronland/go-http-leaflet v0.3.0
github.com/aaronland/go-http-server v1.0.1
github.com/aaronland/go-http-static v0.0.3
)

require (
github.com/aaronland/go-http-rewrite v1.1.0 // indirect
github.com/aaronland/go-roster v1.0.0 // indirect
github.com/akrylysov/algnhsa v0.12.1 // indirect
github.com/aws/aws-lambda-go v1.9.0 // indirect
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 // indirect
github.com/akrylysov/algnhsa v1.0.0 // indirect
github.com/aws/aws-lambda-go v1.37.0 // indirect
golang.org/x/net v0.8.0 // indirect
)
35 changes: 17 additions & 18 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,21 +1,20 @@
github.com/aaronland/go-http-leaflet v0.1.3 h1:HY3u9EHthS4ddTij4aoqSF2JgSru1IIUWZT+2I7Ica0=
github.com/aaronland/go-http-leaflet v0.1.3/go.mod h1:JuRh3NIHjOj4G5ITXOCXbxaLVTCgD5FRIePDqKSJYG0=
github.com/aaronland/go-http-rewrite v1.0.1 h1:BWUlr88wN+jQJUGFd5sSl5fysxHlLYN0FB330pRRP+Q=
github.com/aaronland/go-http-rewrite v1.0.1/go.mod h1:DVpymWnsPZI9P2cmgs6lz2cWiUltfDJ6UNOwuvSXyF0=
github.com/aaronland/go-http-server v1.0.0 h1:AF+4JLEyXNj7Mulpcx8yaek1RWGojWOQMg5vinEDDVs=
github.com/aaronland/go-http-server v1.0.0/go.mod h1:gJ2TDOB9EhK8IULIf3UqVYcv1TaEa5N2er9YaBvD2M0=
github.com/aaronland/go-http-leaflet v0.3.0 h1:d88rMERw+m+CiwGTPgWL9LoPDpJH9eBH8r+np9pOxLY=
github.com/aaronland/go-http-leaflet v0.3.0/go.mod h1:5tlCL3eWYRQBpzW7ZxRB7ocwWaW832qTRXkzw/3r+Jo=
github.com/aaronland/go-http-rewrite v1.1.0 h1:HhsltNyYRnIz2FR+qANZLx2ykiRuNuNK1JgPonKBLHQ=
github.com/aaronland/go-http-rewrite v1.1.0/go.mod h1:iA9jQBureJrzO6fTzmRLS+fkbAI1Fna71iTb1hP8n3k=
github.com/aaronland/go-http-server v1.0.1 h1:ULzPl1cinglgIDd1fRV02WFRUrG4Sv1LW06rGasLHqA=
github.com/aaronland/go-http-server v1.0.1/go.mod h1:sg3+O9NJREN2YTChO5e2sdjmuhFJKTH39u+HV5V8Bpo=
github.com/aaronland/go-http-static v0.0.3 h1:0MnYXNwGVDCzre5YwinfPSdAFHInbBbmBv5hJtb/FX8=
github.com/aaronland/go-http-static v0.0.3/go.mod h1:/s6lHGXq95ZR9nMJmE9slE4uMi92GP34CuG3f9xlfsY=
github.com/aaronland/go-roster v1.0.0 h1:FRDGrTqsYySKjWnAhbBGXyeGlI/o5/t9FZYCbUmyQtI=
github.com/aaronland/go-roster v1.0.0/go.mod h1:KIsYZgrJlAsyb9LsXSCvlqvbcCBVjCSqcQiZx42i9ro=
github.com/akrylysov/algnhsa v0.12.1 h1:A9Ojt4hZrL77mhBc3qGO3Sn9reyf+tvM3DmR0SfXguc=
github.com/akrylysov/algnhsa v0.12.1/go.mod h1:xAcJ/X8DV+81e+dUjIoB/r5CbISrSXV9//leoMDHcdk=
github.com/aws/aws-lambda-go v1.9.0 h1:r9TWtk8ozLYdMW+aelUeWny8z2mjghJCMx6/uUwOLNo=
github.com/aws/aws-lambda-go v1.9.0/go.mod h1:zUsUQhAUjYzR8AuduJPCfhBuKWUaDbQiPOG+ouzmE1A=
github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/akrylysov/algnhsa v1.0.0 h1:qlogYL9n7MfU/TJJJCKqpg6gLgCuR/IkdFGwIJClBnE=
github.com/akrylysov/algnhsa v1.0.0/go.mod h1:ConzNpk7uLAl7Hi5LqcImgl3Oq2flRe6W7zum5A1p/8=
github.com/aws/aws-lambda-go v1.37.0 h1:WXkQ/xhIcXZZ2P5ZBEw+bbAKeCEcb5NtiYpSwVVzIXg=
github.com/aws/aws-lambda-go v1.37.0/go.mod h1:jwFe2KmMsHmffA1X2R09hH6lFzJQxzI8qK17ewzbQMM=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.3.0 h1:TivCn/peBQ7UY8ooIcPgZFpTNSz0Q2U6UrFlUfqbe0Q=
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4 h1:HVyaeDAYux4pnY+D/SiwmLOR36ewZ4iGQIIrtnuCjFA=
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
github.com/stretchr/testify v1.7.2 h1:4jaiDzPyXQvSd7D0EjG45355tLlV3VOECpq10pLC+8s=
golang.org/x/net v0.8.0 h1:Zrh2ngAOFYneWTAIAPethzeaQLuHwhuBkuV6ZiRnUaQ=
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
129 changes: 17 additions & 112 deletions protomaps.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@ package protomaps

import (
"fmt"
"github.com/aaronland/go-http-leaflet"
"github.com/aaronland/go-http-rewrite"
"github.com/sfomuseum/go-http-protomaps/static"
"io/fs"
_ "log"
"net/http"
"path/filepath"
"strings"

"github.com/aaronland/go-http-leaflet"
aa_static "github.com/aaronland/go-http-static"
"github.com/sfomuseum/go-http-protomaps/static"
)

// By default the go-http-protomaps package will also include and reference Leaflet.js resources using the aaronland/go-http-leaflet package. If you want or need to disable this behaviour set this variable to false.
Expand All @@ -28,6 +26,9 @@ type ProtomapsOptions struct {
TileURL string
// A leaflet.LeafletOptions struct
LeafletOptions *leaflet.LeafletOptions
// AppendJavaScriptAtEOF is a boolean flag to append JavaScript markup at the end of an HTML document
// rather than in the <head> HTML element. Default is false
AppendJavaScriptAtEOF bool
}

// Return a *ProtomapsOptions struct with default paths and URIs.
Expand All @@ -49,83 +50,29 @@ func DefaultProtomapsOptions() *ProtomapsOptions {
// AppendResourcesHandler will rewrite any HTML produced by previous handler to include the necessary markup to load Protomaps JavaScript files and related assets.
func AppendResourcesHandler(next http.Handler, opts *ProtomapsOptions) http.Handler {

if APPEND_LEAFLET_RESOURCES {
next = leaflet.AppendResourcesHandler(next, opts.LeafletOptions)
}

return AppendResourcesHandlerWithPrefix(next, opts, "")
}

// AppendResourcesHandlerWithPrefix will rewrite any HTML produced by previous handler to include the necessary markup to load Protomaps JavaScript files and related assets ensuring that all URIs are prepended with a prefix.
func AppendResourcesHandlerWithPrefix(next http.Handler, opts *ProtomapsOptions, prefix string) http.Handler {

if APPEND_LEAFLET_RESOURCES {
opts.LeafletOptions.AppendJavaScriptAtEOF = opts.AppendJavaScriptAtEOF
next = leaflet.AppendResourcesHandlerWithPrefix(next, opts.LeafletOptions, prefix)
}

js := make([]string, len(opts.JS))
css := make([]string, len(opts.CSS))

attrs := map[string]string{
"protomaps-tile-url": opts.TileURL,
}

for i, path := range opts.JS {
js[i] = appendPrefix(prefix, path)
}

for i, path := range opts.CSS {
css[i] = appendPrefix(prefix, path)
}

for k, path := range attrs {

if strings.HasSuffix(k, "-url") && !strings.HasPrefix(path, "http") {
attrs[k] = appendPrefix(prefix, path)
}
}

ext_opts := &rewrite.AppendResourcesOptions{
JavaScript: js,
Stylesheets: css,
DataAttributes: attrs,
}

return rewrite.AppendResourcesHandler(next, ext_opts)
}

// AssetsHandler returns a net/http FS instance containing the embedded Protomaps assets that are included with this package.
func AssetsHandler() (http.Handler, error) {
http_fs := http.FS(static.FS)
return http.FileServer(http_fs), nil
}

// AssetsHandler returns a net/http FS instance containing the embedded Protomaps assets that are included with this package ensuring that all URLs are stripped of prefix.
func AssetsHandlerWithPrefix(prefix string) (http.Handler, error) {

fs_handler, err := AssetsHandler()

if err != nil {
return nil, err
}

prefix = strings.TrimRight(prefix, "/")

if prefix == "" {
return fs_handler, nil
}

rewrite_func := func(req *http.Request) (*http.Request, error) {
req.URL.Path = strings.Replace(req.URL.Path, prefix, "", 1)
return req, nil
}
static_opts := aa_static.DefaultResourcesOptions()
static_opts.CSS = opts.CSS
static_opts.JS = opts.JS
static_opts.DataAttributes["protomaps-tile-url"] = opts.TileURL
static_opts.AppendJavaScriptAtEOF = opts.AppendJavaScriptAtEOF

rewrite_handler := rewrite.RewriteRequestHandler(fs_handler, rewrite_func)
return rewrite_handler, nil
return aa_static.AppendResourcesHandlerWithPrefix(next, static_opts, prefix)
}

// Append all the files in the net/http FS instance containing the embedded Protomaps assets to an *http.ServeMux instance.
func AppendAssetHandlers(mux *http.ServeMux) error {

return AppendAssetHandlersWithPrefix(mux, "")
}

Expand All @@ -137,41 +84,11 @@ func AppendAssetHandlersWithPrefix(mux *http.ServeMux, prefix string) error {
err := leaflet.AppendAssetHandlersWithPrefix(mux, prefix)

if err != nil {
return err
return fmt.Errorf("Failed to append Leaflet assets, %w", err)
}
}

asset_handler, err := AssetsHandlerWithPrefix(prefix)

if err != nil {
return nil
}

walk_func := func(path string, info fs.DirEntry, err error) error {

if path == "." {
return nil
}

if info.IsDir() {
return nil
}

if prefix != "" {
path = appendPrefix(prefix, path)
}

if !strings.HasPrefix(path, "/") {
path = fmt.Sprintf("/%s", path)
}

// log.Println("APPEND", path)

mux.Handle(path, asset_handler)
return nil
}

return fs.WalkDir(static.FS, ".", walk_func)
return aa_static.AppendStaticAssetHandlersWithPrefix(mux, static.FS, prefix)
}

// FileHandlerFromPath will take a path and create a http.FileServer handler
Expand Down Expand Up @@ -201,15 +118,3 @@ func FileHandlerFromPath(path string, prefix string) (string, http.Handler, erro

return tile_url, tile_handler, nil
}

func appendPrefix(prefix string, path string) string {

prefix = strings.TrimRight(prefix, "/")

if prefix != "" {
path = strings.TrimLeft(path, "/")
path = filepath.Join(prefix, path)
}

return path
}
16 changes: 12 additions & 4 deletions static/javascript/protomaps.js
Original file line number Diff line number Diff line change
Expand Up @@ -2416,24 +2416,30 @@ var protomaps = (() => {
}
}
function zxyToTileId(z2, x2, y) {
if (z2 > 26) {
throw Error("Tile zoom level exceeds max safe number limit (26)");
}
if (x2 > Math.pow(2, z2) - 1 || y > Math.pow(2, z2) - 1) {
throw Error("tile x/y outside zoom level bounds");
}
let acc = 0;
let tz = 0;
while (tz < z2) {
acc += (1 << tz) * (1 << tz);
acc += Math.pow(2, tz) * Math.pow(2, tz);
tz++;
}
const n2 = 1 << z2;
const n2 = Math.pow(2, z2);
let rx = 0;
let ry = 0;
let d = 0;
const xy = [x2, y];
let s2 = n2 / 2 >> 0;
let s2 = n2 / 2;
while (s2 > 0) {
rx = (xy[0] & s2) > 0 ? 1 : 0;
ry = (xy[1] & s2) > 0 ? 1 : 0;
d += s2 * s2 * (3 * rx ^ ry);
rotate(s2, xy, rx, ry);
s2 = s2 / 2 >> 0;
s2 = s2 / 2;
}
return acc + d;
}
Expand Down Expand Up @@ -6144,6 +6150,8 @@ var protomaps = (() => {
var base = 1.4;
if (text_size.base)
base = text_size.base;
else
text_size.base = base;
let t2 = numberFn(text_size);
return (z2, f2) => {
return `${style}${weight}${t2(z2, f2)}px ${fontfaces.map((f3) => f3.face).join(", ")}`;
Expand Down
4 changes: 2 additions & 2 deletions static/javascript/protomaps.min.js

Large diffs are not rendered by default.

4 changes: 3 additions & 1 deletion vendor/github.com/aaronland/go-http-leaflet/Makefile

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 4 additions & 14 deletions vendor/github.com/aaronland/go-http-leaflet/README.md

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit 3c7dba3

Please sign in to comment.