github.com/cockroachdb/tools@v0.0.0-20230222021103-a6d27438930d/cmd/present/play.go (about)

     1  // Copyright 2012 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io/fs"
    11  	"net/http"
    12  	"net/url"
    13  	"time"
    14  
    15  	"golang.org/x/tools/godoc/static"
    16  	"golang.org/x/tools/playground/socket"
    17  	"golang.org/x/tools/present"
    18  
    19  	// This will register a handler at /compile that will proxy to the
    20  	// respective endpoints at play.golang.org. This allows the frontend to call
    21  	// these endpoints without needing cross-origin request sharing (CORS).
    22  	// Note that this is imported regardless of whether the endpoints are used or
    23  	// not (in the case of a local socket connection, they are not called).
    24  	_ "golang.org/x/tools/playground"
    25  )
    26  
    27  var scripts = []string{"jquery.js", "jquery-ui.js", "playground.js", "play.js"}
    28  
    29  // playScript registers an HTTP handler at /play.js that serves all the
    30  // scripts specified by the variable above, and appends a line that
    31  // initializes the playground with the specified transport.
    32  func playScript(fsys fs.FS, transport string) {
    33  	modTime := time.Now()
    34  	var buf bytes.Buffer
    35  	for _, p := range scripts {
    36  		if s, ok := static.Files[p]; ok {
    37  			buf.WriteString(s)
    38  			continue
    39  		}
    40  		b, err := fs.ReadFile(fsys, "static/"+p)
    41  		if err != nil {
    42  			panic(err)
    43  		}
    44  		buf.Write(b)
    45  	}
    46  	fmt.Fprintf(&buf, "\ninitPlayground(new %v());\n", transport)
    47  	b := buf.Bytes()
    48  	http.HandleFunc("/play.js", func(w http.ResponseWriter, r *http.Request) {
    49  		w.Header().Set("Content-type", "application/javascript")
    50  		http.ServeContent(w, r, "", modTime, bytes.NewReader(b))
    51  	})
    52  }
    53  
    54  func initPlayground(fsys fs.FS, origin *url.URL) {
    55  	if !present.PlayEnabled {
    56  		return
    57  	}
    58  	if *usePlayground {
    59  		playScript(fsys, "HTTPTransport")
    60  		return
    61  	}
    62  
    63  	playScript(fsys, "SocketTransport")
    64  	http.Handle("/socket", socket.NewHandler(origin))
    65  }
    66  
    67  func playable(c present.Code) bool {
    68  	play := present.PlayEnabled && c.Play
    69  
    70  	// Restrict playable files to only Go source files when using play.golang.org,
    71  	// since there is no method to execute shell scripts there.
    72  	if *usePlayground {
    73  		return play && c.Ext == ".go"
    74  	}
    75  	return play
    76  }