예제 #1
0
// UpdateGoPackage updates Go packages specified by importPathPattern.
func UpdateGoPackage(importPathPattern string) {
	var goPackage = document.GetElementByID(importPathPattern)
	var goPackageButton = goPackage.GetElementsByClassName("update-button")[0].(*dom.HTMLAnchorElement)

	goPackageButton.SetTextContent("Updating...")
	goPackageButton.AddEventListener("click", false, func(event dom.Event) { event.PreventDefault() })
	goPackageButton.SetTabIndex(-1)
	goPackageButton.Class().Add("disabled")

	go func() {
		req := xhr.NewRequest("POST", "/-/update")
		req.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
		err := req.Send(url.Values{"import_path_pattern": {importPathPattern}}.Encode())
		if err != nil {
			println(err.Error())
			return
		}

		// Hide the "Updating..." label.
		goPackageButton.Style().SetProperty("display", "none", "")

		// Show "No Updates Available" if there are no remaining updates.
		if !hasUpdatesAvailable() {
			document.GetElementByID("no_updates").(dom.HTMLElement).Style().SetProperty("display", "none", "")
		}

		// Move this Go package to "Installed Updates" list.
		installedUpdates := document.GetElementByID("installed_updates").(dom.HTMLElement)
		installedUpdates.Style().SetProperty("display", "", "")
		installedUpdates.ParentNode().InsertBefore(goPackage, installedUpdates.NextSibling()) // Insert after.
	}()
}
예제 #2
0
func loadJSON(r Resource) (string, error) {
	req := xhr.NewRequest("GET", r.url)
	err := req.Send("")
	if err != nil {
		return "", err
	}
	return req.Response.String(), nil
	// ch := make(chan error, 1)

	// req := js.Global.Get("XMLHttpRequest").New()
	// req.Call("open", "GET", r.url, true)
	// req.Call("addEventListener", "load", func(*js.Object) {
	// 	go func() { ch <- nil }()
	// }, false)
	// req.Call("addEventListener", "error", func(o *js.Object) {
	// 	go func() { ch <- &js.Error{Object: o} }()
	// }, false)
	// req.Call("send", nil)

	// err := <-ch
	// if err != nil {
	// 	return "", err
	// }

	// return req.Get("responseText").Str(), nil
}
예제 #3
0
func main() {
	req := xhr.NewRequest("GET", "/")
	err := req.Send(nil)
	if err != nil {
		println(err)
	}
	headers := req.ResponseHeaders()
	println(headers)
}
예제 #4
0
func loadFont(r Resource) (*truetype.Font, error) {
	req := xhr.NewRequest("GET", r.url+"_js")
	err := req.Send("")
	if err != nil {
		return &truetype.Font{}, err
	}
	fontDataEncoded := bytes.NewBuffer([]byte(req.Response.String()))
	fontDataCompressed := base64.NewDecoder(base64.StdEncoding, fontDataEncoded)
	fontDataTtf, err := gzip.NewReader(fontDataCompressed)
	if err != nil {
		return nil, err
	}
	var ttfBytes []byte
	ttfBytes, err = ioutil.ReadAll(fontDataTtf)
	if err != nil {
		return nil, err
	}
	return freetype.ParseFont(ttfBytes)
}
예제 #5
0
파일: uploader.go 프로젝트: theclapp/js
func (u *uploader) upload() {
	fd := dom.NewFormData()
	// println("fd.set", fd.Set)
	files := u.target.Files()
	for _, file := range files {
		fd.Append(file.Name, file)
	}
	req := xhr.NewRequest("POST", u.url.Get().String())
	println("xhr url:", u.url.Get().String())
	err := req.Send(fd)
	// when network error or response error
	if err != nil || req.Status != 200 {
		if errCallback != nil {
			errCallback(u.url.Get().String(), files, req.Status)
		}
		return
	}
	// upload ok
	if callback != nil {
		callback(u.url.Get().String(), files)
	}
}
예제 #6
0
// UpdateRepository updates specified repository.
// repoRoot is the import path corresponding to the root of the repository.
func UpdateRepository(event dom.Event, repoRoot string) {
	event.PreventDefault()
	if event.(*dom.MouseEvent).Button != 0 {
		return
	}

	repoUpdate := document.GetElementByID(repoRoot)
	updateButton := repoUpdate.GetElementsByClassName("update-button")[0].(*dom.HTMLAnchorElement)

	updateButton.SetTextContent("Updating...")
	updateButton.AddEventListener("click", false, func(event dom.Event) { event.PreventDefault() })
	updateButton.SetTabIndex(-1)
	updateButton.Class().Add("disabled")

	go func() {
		req := xhr.NewRequest("POST", "/-/update")
		req.SetRequestHeader("Content-Type", "application/x-www-form-urlencoded")
		err := req.Send(url.Values{"repo_root": {repoRoot}}.Encode())
		if err != nil {
			println(err.Error())
			return
		}

		// Hide the "Updating..." label.
		updateButton.Style().SetProperty("display", "none", "")

		// Show "No Updates Available" if there are no remaining updates.
		if !anyUpdatesRemaining() {
			document.GetElementByID("no_updates").(dom.HTMLElement).Style().SetProperty("display", "", "")
		}

		// Move this Go package to "Installed Updates" list.
		installedUpdates := document.GetElementByID("installed_updates").(dom.HTMLElement)
		installedUpdates.Style().SetProperty("display", "", "")
		installedUpdates.ParentNode().InsertBefore(repoUpdate, installedUpdates.NextSibling()) // Insert after.
	}()
}
예제 #7
0
/**
 * @param {string} searchTerm - Search term for Google Image search.
 * @param {func(string,int,int)} callback - Called when an image has
 *   been found. The callback gets the URL, width and height of the image.
 * @param {func(string)} errorCallback - Called when the image is not found.
 *   The callback gets a string that describes the failure reason.
 */
func getImageUrl(searchTerm string, callback func(imageUrl, width, height string), errorCallback func(errorMessage string)) {
	// Google image search - 100 searches per day.
	// https://developers.google.com/image-search/
	searchUrl := "https://ajax.googleapis.com/ajax/services/search/images" + "?v=1.0&q=" + url.QueryEscape(searchTerm)

	req := xhr.NewRequest("GET", searchUrl)
	req.Timeout = 2000 // two second, in milliseconds
	req.ResponseType = "text"
	err := req.Send(nil)
	if err != nil {
		errorCallback("Something went wrong with GET request to " + searchUrl + "." + err.Error())
		return
	}
	returnFormat := struct {
		ResponseData struct {
			Results []struct {
				Url      string `json:"Url"`
				TbWidth  string `json:"tbWidth"`
				TbHeight string `json:"tbHeight"`
			} `json:"results"`
		} `json:"responseData"`
	}{}
	err = json.Unmarshal([]byte(req.Response.String()), &returnFormat)
	if err != nil {
		errorCallback("Failed to unmarshal response into object, with Error: " + err.Error() + ". Response was: " + req.Response.String())
		return
	}
	fmt.Println("Got from API: ", returnFormat)

	firstResult := returnFormat.ResponseData.Results[0]
	imageUrl := firstResult.Url
	width := firstResult.TbWidth
	height := firstResult.TbHeight

	callback(imageUrl, width, height)
}
예제 #8
0
func main() {
	var location = dom.GetWindow().Top().Location() // We might be inside an iframe, but want to use the location of topmost window.

	codeReady := make(chan struct{}) // Used to synchronize when "code" value is ready.

	app := angularjs.NewModule("playground", nil, nil)

	app.NewController("PlaygroundCtrl", func(scope *angularjs.Scope) {
		if strings.HasPrefix(location.Hash, "#/") {
			id := location.Hash[2:]

			req := xhr.NewRequest("GET", "http://"+snippetStoreHost+"/p/"+id)
			req.ResponseType = xhr.ArrayBuffer
			go func() {
				err := req.Send(nil)
				if err != nil || req.Status != 200 {
					scope.Apply(func() {
						scope.Set("output", []Line{Line{"type": "err", "content": `failed to load snippet "` + id + `"`}})
					})
					return
				}

				data := js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte)
				scope.Apply(func() {
					scope.Set("code", string(data))
					close(codeReady)
				})
			}()
		} else {
			scope.Set("code", "package main\n\nimport (\n\t\"fmt\"\n\t\"github.com/gopherjs/gopherjs/js\"\n)\n\nfunc main() {\n\tfmt.Println(\"Hello, playground\")\n\tjs.Global.Call(\"alert\", \"Hello, JavaScript\")\n\tprintln(\"Hello, JS console\")\n}\n")
			close(codeReady)
		}
		scope.Set("shareUrl", "")
		scope.Set("showShareUrl", false)

		packages := make(map[string]*compiler.Archive)
		var pkgsToLoad map[string]struct{}
		importContext := compiler.NewImportContext(func(path string) (*compiler.Archive, error) {
			if pkg, found := packages[path]; found {
				return pkg, nil
			}
			pkgsToLoad[path] = struct{}{}
			return &compiler.Archive{}, nil
		})
		fileSet := token.NewFileSet()
		pkgsReceived := 0

		setupEnvironment(scope)

		codeArea := angularjs.ElementById("code")
		codeArea.On("input", func(e *angularjs.Event) {
			scope.Set("showShareUrl", false)
			location.Hash = ""
		})
		codeArea.On("keydown", func(e *angularjs.Event) {
			toInsert := ""
			switch e.KeyCode {
			case '\t':
				toInsert = "\t"
			case '\r':
				toInsert = "\n"
				start := codeArea.Prop("selectionStart").Int()
				code := scope.Get("code").String()
				i := strings.LastIndex(code[:start], "\n") + 1
				for i < start {
					c := code[i]
					if c != ' ' && c != '\t' {
						break
					}
					toInsert += string(c)
					i++
				}
			}
			if toInsert != "" {
				scope.Set("showShareUrl", false)
				location.Hash = ""

				start := codeArea.Prop("selectionStart").Int()
				end := codeArea.Prop("selectionEnd").Int()
				code := scope.Get("code").String()
				scope.Apply(func() {
					scope.Set("code", code[:start]+toInsert+code[end:])
				})
				codeArea.SetProp("selectionStart", start+len(toInsert))
				codeArea.SetProp("selectionEnd", start+len(toInsert))
				e.PreventDefault()
			}
		})

		var run func(bool)
		run = func(loadOnly bool) {
			output = nil
			scope.Set("output", output)
			pkgsToLoad = make(map[string]struct{})

			file, err := parser.ParseFile(fileSet, "prog.go", []byte(scope.Get("code").String()), parser.ParseComments)
			if err != nil {
				if list, ok := err.(scanner.ErrorList); ok {
					for _, entry := range list {
						output = append(output, Line{"type": "err", "content": entry.Error()})
					}
					scope.Set("output", output)
					return
				}
				scope.Set("output", []Line{Line{"type": "err", "content": err.Error()}})
				return
			}

			mainPkg, err := compiler.Compile("main", []*ast.File{file}, fileSet, importContext, false)
			packages["main"] = mainPkg
			if err != nil && len(pkgsToLoad) == 0 {
				if list, ok := err.(compiler.ErrorList); ok {
					var output []Line
					for _, entry := range list {
						output = append(output, Line{"type": "err", "content": entry.Error()})
					}
					scope.Set("output", output)
					return
				}
				scope.Set("output", []Line{Line{"type": "err", "content": err.Error()}})
				return
			}

			var allPkgs []*compiler.Archive
			if len(pkgsToLoad) == 0 {
				allPkgs, _ = compiler.ImportDependencies(mainPkg, importContext.Import)
			}

			if len(pkgsToLoad) != 0 {
				pkgsReceived = 0
				for path := range pkgsToLoad {
					req := xhr.NewRequest("GET", "pkg/"+path+".a.js")
					req.ResponseType = xhr.ArrayBuffer
					go func(path string) {
						err := req.Send(nil)
						if err != nil || req.Status != 200 {
							scope.Apply(func() {
								scope.Set("output", []Line{Line{"type": "err", "content": `failed to load package "` + path + `"`}})
							})
							return
						}

						data := js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte)
						packages[path], err = compiler.ReadArchive(path+".a", path, bytes.NewReader(data), importContext.Packages)
						if err != nil {
							scope.Apply(func() {
								scope.Set("output", []Line{Line{"type": "err", "content": err.Error()}})
							})
							return
						}
						pkgsReceived++
						if pkgsReceived == len(pkgsToLoad) {
							run(loadOnly)
						}
					}(path)
				}
				return
			}

			if loadOnly {
				return
			}

			jsCode := bytes.NewBuffer(nil)
			jsCode.WriteString("try{\n")
			compiler.WriteProgramCode(allPkgs, &compiler.SourceMapFilter{Writer: jsCode})
			jsCode.WriteString("} catch (err) {\ngoPanicHandler(err.message);\n}\n")
			js.Global.Set("$checkForDeadlock", true)
			js.Global.Call("eval", js.InternalObject(jsCode.String()))
		}
		scope.Set("run", run)
		go func() {
			<-codeReady // Wait for "code" value to be ready.
			run(true)
		}()

		scope.Set("format", func() {
			out, err := format.Source([]byte(scope.Get("code").String()))
			if err != nil {
				scope.Set("output", []Line{Line{"type": "err", "content": err.Error()}})
				return
			}
			scope.Set("code", string(out))
			scope.Set("output", []Line{})
		})

		scope.Set("share", func() {
			req := xhr.NewRequest("POST", "http://"+snippetStoreHost+"/share")
			req.ResponseType = xhr.ArrayBuffer
			go func() {
				err := req.Send([]byte(scope.Get("code").String())) // Send as binary.
				if err != nil || req.Status != 200 {
					scope.Apply(func() {
						scope.Set("output", []Line{Line{"type": "err", "content": `failed to share snippet`}})
					})
					return
				}

				data := js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte)
				scope.Apply(func() {
					id := string(data)

					location.Hash = "#/" + id

					scope.Set("shareUrl", location.String())
					scope.Set("showShareUrl", true)
					// TODO: Do this better using AngularJS.
					//       Perhaps using http://stackoverflow.com/questions/14833326/how-to-set-focus-on-input-field/18295416.
					go func() {
						time.Sleep(time.Millisecond)
						dom.GetWindow().Document().GetElementByID("share-url").(*dom.HTMLInputElement).Select()
					}()
				})
			}()
		})

		// Start watching for hashchange events, and reload snippet if it happens.
		dom.GetWindow().Top().AddEventListener("hashchange", false, func(event dom.Event) {
			event.PreventDefault()

			if strings.HasPrefix(location.Hash, "#/") {
				id := location.Hash[2:]

				req := xhr.NewRequest("GET", "http://"+snippetStoreHost+"/p/"+id)
				req.ResponseType = xhr.ArrayBuffer
				go func() {
					err := req.Send(nil)
					if err != nil || req.Status != 200 {
						scope.Apply(func() {
							scope.Set("output", []Line{Line{"type": "err", "content": `failed to load snippet "` + id + `"`}})
						})
						return
					}

					data := js.Global.Get("Uint8Array").New(req.Response).Interface().([]byte)
					scope.Apply(func() {
						scope.Set("code", string(data))
					})
				}()
			}
		})
	})
}