代码拉取完成,页面将自动刷新
package phantomjs
import (
"bytes"
"encoding/json"
"errors"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"os/exec"
"path/filepath"
"time"
)
var (
// ErrInjectionFailed is returned by InjectJS when injection fails.
ErrInjectionFailed = errors.New("injection failed")
)
// Keyboard modifiers.
const (
ShiftKey = 0x02000000
CtrlKey = 0x04000000
AltKey = 0x08000000
MetaKey = 0x10000000
Keypad = 0x20000000
)
// Default settings.
const (
DefaultPort = 20202
DefaultBinPath = "phantomjs"
)
// Process represents a PhantomJS process.
type Process struct {
path string
cmd *exec.Cmd
// Path to the 'phantomjs' binary.
BinPath string
// HTTP port used to communicate with phantomjs.
Port int
// Output from the process.
Stdout io.Writer
Stderr io.Writer
}
// NewProcess returns a new instance of Process.
func NewProcess() *Process {
return &Process{
BinPath: DefaultBinPath,
Port: DefaultPort,
Stdout: os.Stdout,
Stderr: os.Stderr,
}
}
// Path returns a temporary path that the process is run from.
func (p *Process) Path() string {
return p.path
}
// Open start the phantomjs process with the shim script.
func (p *Process) Open() error {
if err := func() error {
// Generate temporary path to run script from.
path, err := ioutil.TempDir("", "phantomjs-")
if err != nil {
return err
}
p.path = path
// Write shim script.
scriptPath := filepath.Join(path, "shim.js")
if err := ioutil.WriteFile(scriptPath, []byte(shim), 0600); err != nil {
return err
}
// Start external process.
cmd := exec.Command(p.BinPath, scriptPath)
cmd.Env = []string{fmt.Sprintf("PORT=%d", p.Port)}
cmd.Stdout = p.Stdout
cmd.Stderr = p.Stderr
if err := cmd.Start(); err != nil {
return err
}
p.cmd = cmd
// Wait until process is available.
if err := p.wait(); err != nil {
return err
}
return nil
}(); err != nil {
p.Close()
return err
}
return nil
}
// Close stops the process.
func (p *Process) Close() (err error) {
// Kill process.
if p.cmd != nil {
if e := p.cmd.Process.Kill(); e != nil && err == nil {
err = e
}
p.cmd.Wait()
}
// Remove shim file.
if p.path != "" {
if e := os.RemoveAll(p.path); e != nil && err == nil {
err = e
}
}
return err
}
// URL returns the process' API URL.
func (p *Process) URL() string {
return fmt.Sprintf("http://localhost:%d", p.Port)
}
// wait continually checks the process until it gets a response or times out.
func (p *Process) wait() error {
ticker := time.NewTicker(1000 * time.Millisecond)
defer ticker.Stop()
timer := time.NewTimer(30 * time.Second)
defer ticker.Stop()
for {
select {
case <-timer.C:
return errors.New("timeout")
case <-ticker.C:
if err := p.ping(); err == nil {
return nil
}
}
}
}
// ping checks the process to see if it is up.
func (p *Process) ping() error {
// Send request.
resp, err := http.Get(p.URL() + "/ping")
if err != nil {
return err
}
resp.Body.Close()
// Verify successful status code.
if resp.StatusCode != http.StatusOK {
return fmt.Errorf("unexpected status: %d", resp.StatusCode)
}
return nil
}
// CreateWebPage returns a new instance of a "webpage".
func (p *Process) CreateWebPage() (*WebPage, error) {
var resp struct {
Ref refJSON `json:"ref"`
}
if err := p.doJSON("POST", "/webpage/Create", nil, &resp); err != nil {
return nil, err
}
return &WebPage{ref: newRef(p, resp.Ref.ID)}, nil
}
// doJSON sends an HTTP request to url and encodes and decodes the req/resp as JSON.
func (p *Process) doJSON(method, path string, req, resp interface{}) error {
// Encode request.
var r io.Reader
if req != nil {
buf, err := json.Marshal(req)
if err != nil {
return err
}
r = bytes.NewReader(buf)
}
// Create request.
httpRequest, err := http.NewRequest(method, p.URL()+path, r)
if err != nil {
return err
}
// Send request.
httpResponse, err := http.DefaultClient.Do(httpRequest)
if err != nil {
return err
}
defer httpResponse.Body.Close()
// Read response body.
body, err := ioutil.ReadAll(httpResponse.Body)
if err != nil {
return err
}
// Check response code.
if httpResponse.StatusCode == http.StatusNotFound {
return fmt.Errorf("not found: %s", path)
}
// If an error was returned then return it.
var errResp errorResponse
if err := json.Unmarshal(body, &errResp); err != nil {
return errors.New("phantomjs.Process: " + string(body))
} else if errResp.Error != "" {
return errors.New(errResp.Error)
}
// Decode response if reference passed in.
if resp != nil {
if err := json.Unmarshal(body, resp); err != nil {
return fmt.Errorf("unmarshal error: err=%s, body=%s", err, body)
}
}
return nil
}
type errorResponse struct {
Error string `json:"error"`
}
// DefaultProcess is a global, shared process.
// It must be opened before use.
var DefaultProcess = NewProcess()
// CreateWebPage returns a new instance of a "webpage" using the default process.
func CreateWebPage() (*WebPage, error) {
return DefaultProcess.CreateWebPage()
}
// WebPage represents an object returned from "webpage.create()".
type WebPage struct {
ref *Ref
}
// Open opens a URL.
func (p *WebPage) Open(url string) error {
req := map[string]interface{}{
"ref": p.ref.id,
"url": url,
}
var resp struct {
Status string `json:"status"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Open", req, &resp); err != nil {
return err
}
if resp.Status != "success" {
return errors.New("failed")
}
return nil
}
// CanGoBack returns true if the page can be navigated back.
func (p *WebPage) CanGoBack() (bool, error) {
var resp struct {
Value bool `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/CanGoBack", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return false, err
}
return resp.Value, nil
}
// CanGoForward returns true if the page can be navigated forward.
func (p *WebPage) CanGoForward() (bool, error) {
var resp struct {
Value bool `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/CanGoForward", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return false, err
}
return resp.Value, nil
}
// ClipRect returns the clipping rectangle used when rendering.
// Returns nil if no clipping rectangle is set.
func (p *WebPage) ClipRect() (Rect, error) {
var resp struct {
Value rectJSON `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/ClipRect", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return Rect{}, err
}
return Rect{
Top: resp.Value.Top,
Left: resp.Value.Left,
Width: resp.Value.Width,
Height: resp.Value.Height,
}, nil
}
// SetClipRect sets the clipping rectangle used when rendering.
// Set to nil to render the entire webpage.
func (p *WebPage) SetClipRect(rect Rect) error {
req := map[string]interface{}{
"ref": p.ref.id,
"rect": rectJSON{
Top: rect.Top,
Left: rect.Left,
Width: rect.Width,
Height: rect.Height,
},
}
return p.ref.process.doJSON("POST", "/webpage/SetClipRect", req, nil)
}
// Content returns content of the webpage enclosed in an HTML/XML element.
func (p *WebPage) Content() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Content", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// SetContent sets the content of the webpage.
func (p *WebPage) SetContent(content string) error {
return p.ref.process.doJSON("POST", "/webpage/SetContent", map[string]interface{}{"ref": p.ref.id, "content": content}, nil)
}
// Cookies returns a list of cookies visible to the current URL.
func (p *WebPage) Cookies() ([]*http.Cookie, error) {
var resp struct {
Value []cookieJSON `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Cookies", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return nil, err
}
a := make([]*http.Cookie, len(resp.Value))
for i := range resp.Value {
a[i] = decodeCookieJSON(resp.Value[i])
}
return a, nil
}
// SetCookies sets a list of cookies visible to the current URL.
func (p *WebPage) SetCookies(cookies []*http.Cookie) error {
a := make([]cookieJSON, len(cookies))
for i := range cookies {
a[i] = encodeCookieJSON(cookies[i])
}
req := map[string]interface{}{"ref": p.ref.id, "cookies": a}
return p.ref.process.doJSON("POST", "/webpage/SetCookies", req, nil)
}
// CustomHeaders returns a list of additional headers sent with the web page.
func (p *WebPage) CustomHeaders() (http.Header, error) {
var resp struct {
Value map[string]string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/CustomHeaders", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return nil, err
}
// Convert to a header object.
hdr := make(http.Header)
for key, value := range resp.Value {
hdr.Set(key, value)
}
return hdr, nil
}
// SetCustomHeaders sets a list of additional headers sent with the web page.
//
// This function does not support multiple headers with the same name. Only
// the first value for a header key will be used.
func (p *WebPage) SetCustomHeaders(header http.Header) error {
m := make(map[string]string)
for key := range header {
m[key] = header.Get(key)
}
req := map[string]interface{}{"ref": p.ref.id, "headers": m}
return p.ref.process.doJSON("POST", "/webpage/SetCustomHeaders", req, nil)
}
// FocusedFrameName returns the name of the currently focused frame.
func (p *WebPage) FocusedFrameName() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FocusedFrameName", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// FrameContent returns the content of the current frame.
func (p *WebPage) FrameContent() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameContent", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// SetFrameContent sets the content of the current frame.
func (p *WebPage) SetFrameContent(content string) error {
return p.ref.process.doJSON("POST", "/webpage/SetFrameContent", map[string]interface{}{"ref": p.ref.id, "content": content}, nil)
}
// FrameName returns the name of the current frame.
func (p *WebPage) FrameName() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameName", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// FramePlainText returns the plain text representation of the current frame content.
func (p *WebPage) FramePlainText() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FramePlainText", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// FrameTitle returns the title of the current frame.
func (p *WebPage) FrameTitle() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameTitle", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// FrameURL returns the URL of the current frame.
func (p *WebPage) FrameURL() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameURL", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// FrameCount returns the total number of frames.
func (p *WebPage) FrameCount() (int, error) {
var resp struct {
Value int `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameCount", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return 0, err
}
return resp.Value, nil
}
// FrameNames returns an list of frame names.
func (p *WebPage) FrameNames() ([]string, error) {
var resp struct {
Value []string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/FrameNames", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return nil, err
}
return resp.Value, nil
}
// LibraryPath returns the path used by InjectJS() to resolve scripts.
// Initially it is set to Process.Path().
func (p *WebPage) LibraryPath() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/LibraryPath", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// SetLibraryPath sets the library path used by InjectJS().
func (p *WebPage) SetLibraryPath(path string) error {
return p.ref.process.doJSON("POST", "/webpage/SetLibraryPath", map[string]interface{}{"ref": p.ref.id, "path": path}, nil)
}
// NavigationLocked returns true if the navigation away from the page is disabled.
func (p *WebPage) NavigationLocked() (bool, error) {
var resp struct {
Value bool `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/NavigationLocked", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return false, err
}
return resp.Value, nil
}
// SetNavigationLocked sets whether navigation away from the page should be disabled.
func (p *WebPage) SetNavigationLocked(value bool) error {
return p.ref.process.doJSON("POST", "/webpage/SetNavigationLocked", map[string]interface{}{"ref": p.ref.id, "value": value}, nil)
}
// OfflineStoragePath returns the path used by offline storage.
func (p *WebPage) OfflineStoragePath() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/OfflineStoragePath", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// OfflineStorageQuota returns the number of bytes that can be used for offline storage.
func (p *WebPage) OfflineStorageQuota() (int, error) {
var resp struct {
Value int `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/OfflineStorageQuota", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return 0, err
}
return resp.Value, nil
}
// OwnsPages returns true if this page owns pages opened in other windows.
func (p *WebPage) OwnsPages() (bool, error) {
var resp struct {
Value bool `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/OwnsPages", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return false, err
}
return resp.Value, nil
}
// SetOwnsPages sets whether this page owns pages opened in other windows.
func (p *WebPage) SetOwnsPages(v bool) error {
return p.ref.process.doJSON("POST", "/webpage/SetOwnsPages", map[string]interface{}{"ref": p.ref.id, "value": v}, nil)
}
// PageWindowNames returns an list of owned window names.
func (p *WebPage) PageWindowNames() ([]string, error) {
var resp struct {
Value []string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/PageWindowNames", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return nil, err
}
return resp.Value, nil
}
// Pages returns a list of owned pages.
func (p *WebPage) Pages() ([]*WebPage, error) {
var resp struct {
Refs []refJSON `json:"refs"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Pages", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return nil, err
}
// Convert reference IDs to web pages.
a := make([]*WebPage, len(resp.Refs))
for i, ref := range resp.Refs {
a[i] = &WebPage{ref: newRef(p.ref.process, ref.ID)}
}
return a, nil
}
// PaperSize returns the size of the web page when rendered as a PDF.
func (p *WebPage) PaperSize() (PaperSize, error) {
var resp struct {
Value paperSizeJSON `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/PaperSize", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return PaperSize{}, err
}
return decodePaperSizeJSON(resp.Value), nil
}
// SetPaperSize sets the size of the web page when rendered as a PDF.
func (p *WebPage) SetPaperSize(size PaperSize) error {
req := map[string]interface{}{"ref": p.ref.id, "size": encodePaperSizeJSON(size)}
return p.ref.process.doJSON("POST", "/webpage/SetPaperSize", req, nil)
}
// PlainText returns the plain text representation of the page.
func (p *WebPage) PlainText() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/PlainText", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// ScrollPosition returns the current scroll position of the page.
func (p *WebPage) ScrollPosition() (Position, error) {
var resp struct {
Top int `json:"top"`
Left int `json:"left"`
}
if err := p.ref.process.doJSON("POST", "/webpage/ScrollPosition", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return Position{}, err
}
return Position{Top: resp.Top, Left: resp.Left}, nil
}
// SetScrollPosition sets the current scroll position of the page.
func (p *WebPage) SetScrollPosition(pos Position) error {
return p.ref.process.doJSON("POST", "/webpage/SetScrollPosition", map[string]interface{}{"ref": p.ref.id, "top": pos.Top, "left": pos.Left}, nil)
}
// Settings returns the settings used on the web page.
func (p *WebPage) Settings() (WebPageSettings, error) {
var resp struct {
Settings webPageSettingsJSON `json:"settings"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Settings", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return WebPageSettings{}, err
}
return WebPageSettings{
JavascriptEnabled: resp.Settings.JavascriptEnabled,
LoadImages: resp.Settings.LoadImages,
LocalToRemoteURLAccessEnabled: resp.Settings.LocalToRemoteURLAccessEnabled,
UserAgent: resp.Settings.UserAgent,
Username: resp.Settings.Username,
Password: resp.Settings.Password,
XSSAuditingEnabled: resp.Settings.XSSAuditingEnabled,
WebSecurityEnabled: resp.Settings.WebSecurityEnabled,
ResourceTimeout: time.Duration(resp.Settings.ResourceTimeout) * time.Millisecond,
}, nil
}
// SetSettings sets various settings on the web page.
//
// The settings apply only during the initial call to the page.open function.
// Subsequent modification of the settings object will not have any impact.
func (p *WebPage) SetSettings(settings WebPageSettings) error {
req := map[string]interface{}{
"ref": p.ref.id,
"settings": webPageSettingsJSON{
JavascriptEnabled: settings.JavascriptEnabled,
LoadImages: settings.LoadImages,
LocalToRemoteURLAccessEnabled: settings.LocalToRemoteURLAccessEnabled,
UserAgent: settings.UserAgent,
Username: settings.Username,
Password: settings.Password,
XSSAuditingEnabled: settings.XSSAuditingEnabled,
WebSecurityEnabled: settings.WebSecurityEnabled,
ResourceTimeout: int(settings.ResourceTimeout / time.Millisecond),
},
}
return p.ref.process.doJSON("POST", "/webpage/SetSettings", req, nil)
}
// Title returns the title of the web page.
func (p *WebPage) Title() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Title", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// URL returns the current URL of the web page.
func (p *WebPage) URL() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/URL", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// ViewportSize returns the size of the viewport on the browser.
func (p *WebPage) ViewportSize() (width, height int, err error) {
var resp struct {
Width int `json:"width"`
Height int `json:"height"`
}
if err := p.ref.process.doJSON("POST", "/webpage/ViewportSize", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return 0, 0, err
}
return resp.Width, resp.Height, nil
}
// SetViewportSize sets the size of the viewport.
func (p *WebPage) SetViewportSize(width, height int) error {
return p.ref.process.doJSON("POST", "/webpage/SetViewportSize", map[string]interface{}{"ref": p.ref.id, "width": width, "height": height}, nil)
}
// WindowName returns the window name of the web page.
func (p *WebPage) WindowName() (string, error) {
var resp struct {
Value string `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/WindowName", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return "", err
}
return resp.Value, nil
}
// ZoomFactor returns zoom factor when rendering the page.
func (p *WebPage) ZoomFactor() (float64, error) {
var resp struct {
Value float64 `json:"value"`
}
if err := p.ref.process.doJSON("POST", "/webpage/ZoomFactor", map[string]interface{}{"ref": p.ref.id}, &resp); err != nil {
return 0, err
}
return resp.Value, nil
}
// SetZoomFactor sets the zoom factor when rendering the page.
func (p *WebPage) SetZoomFactor(factor float64) error {
return p.ref.process.doJSON("POST", "/webpage/SetZoomFactor", map[string]interface{}{"ref": p.ref.id, "value": factor}, nil)
}
// AddCookie adds a cookie to the page.
// Returns true if the cookie was successfully added.
func (p *WebPage) AddCookie(cookie *http.Cookie) (bool, error) {
var resp struct {
ReturnValue bool `json:"returnValue"`
}
req := map[string]interface{}{"ref": p.ref.id, "cookie": encodeCookieJSON(cookie)}
if err := p.ref.process.doJSON("POST", "/webpage/AddCookie", req, &resp); err != nil {
return false, err
}
return resp.ReturnValue, nil
}
// ClearCookies deletes all cookies visible to the current URL.
func (p *WebPage) ClearCookies() error {
return p.ref.process.doJSON("POST", "/webpage/ClearCookies", map[string]interface{}{"ref": p.ref.id}, nil)
}
// Close releases the web page and its resources.
func (p *WebPage) Close() error {
return p.ref.process.doJSON("POST", "/webpage/Close", map[string]interface{}{"ref": p.ref.id}, nil)
}
// DeleteCookie removes a cookie with a matching name.
// Returns true if the cookie was successfully deleted.
func (p *WebPage) DeleteCookie(name string) (bool, error) {
var resp struct {
ReturnValue bool `json:"returnValue"`
}
req := map[string]interface{}{"ref": p.ref.id, "name": name}
if err := p.ref.process.doJSON("POST", "/webpage/DeleteCookie", req, &resp); err != nil {
return false, err
}
return resp.ReturnValue, nil
}
// EvaluateAsync executes a JavaScript function and returns immediately.
// Execution is delayed by delay. No value is returned.
func (p *WebPage) EvaluateAsync(script string, delay time.Duration) error {
return p.ref.process.doJSON("POST", "/webpage/EvaluateAsync", map[string]interface{}{"ref": p.ref.id, "script": script, "delay": int(delay / time.Millisecond)}, nil)
}
// EvaluateJavaScript executes a JavaScript function.
// Returns the value returned by the function.
func (p *WebPage) EvaluateJavaScript(script string) (interface{}, error) {
var resp struct {
ReturnValue interface{} `json:"returnValue"`
}
if err := p.ref.process.doJSON("POST", "/webpage/EvaluateJavaScript", map[string]interface{}{"ref": p.ref.id, "script": script}, &resp); err != nil {
return nil, err
}
return resp.ReturnValue, nil
}
// Evaluate executes a JavaScript function in the context of the web page.
// Returns the value returned by the function.
func (p *WebPage) Evaluate(script string) (interface{}, error) {
var resp struct {
ReturnValue interface{} `json:"returnValue"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Evaluate", map[string]interface{}{"ref": p.ref.id, "script": script}, &resp); err != nil {
return nil, err
}
return resp.ReturnValue, nil
}
// Page returns an owned page by window name.
// Returns nil if the page cannot be found.
func (p *WebPage) Page(name string) (*WebPage, error) {
var resp struct {
Ref refJSON `json:"ref"`
}
if err := p.ref.process.doJSON("POST", "/webpage/Page", map[string]interface{}{"ref": p.ref.id, "name": name}, &resp); err != nil {
return nil, err
}
if resp.Ref.ID == "" {
return nil, nil
}
return &WebPage{ref: newRef(p.ref.process, resp.Ref.ID)}, nil
}
// GoBack navigates back to the previous page.
func (p *WebPage) GoBack() error {
return p.ref.process.doJSON("POST", "/webpage/GoBack", map[string]interface{}{"ref": p.ref.id}, nil)
}
// GoForward navigates to the next page.
func (p *WebPage) GoForward() error {
return p.ref.process.doJSON("POST", "/webpage/GoForward", map[string]interface{}{"ref": p.ref.id}, nil)
}
// Go navigates to the page in history by relative offset.
// A positive index moves forward, a negative index moves backwards.
func (p *WebPage) Go(index int) error {
return p.ref.process.doJSON("POST", "/webpage/Go", map[string]interface{}{"ref": p.ref.id, "index": index}, nil)
}
// IncludeJS includes an external script from url.
// Returns after the script has been loaded.
func (p *WebPage) IncludeJS(url string) error {
return p.ref.process.doJSON("POST", "/webpage/IncludeJS", map[string]interface{}{"ref": p.ref.id, "url": url}, nil)
}
// InjectJS injects an external script from the local filesystem.
//
// The script will be loaded from the Process.Path() directory. If it cannot be
// found then it is loaded from the library path.
func (p *WebPage) InjectJS(filename string) error {
var resp struct {
ReturnValue bool `json:"returnValue"`
}
if err := p.ref.process.doJSON("POST", "/webpage/InjectJS", map[string]interface{}{"ref": p.ref.id, "filename": filename}, &resp); err != nil {
return err
}
if !resp.ReturnValue {
return ErrInjectionFailed
}
return nil
}
// Reload reloads the current web page.
func (p *WebPage) Reload() error {
return p.ref.process.doJSON("POST", "/webpage/Reload", map[string]interface{}{"ref": p.ref.id}, nil)
}
// RenderBase64 renders the web page to a base64 encoded string.
func (p *WebPage) RenderBase64(format string) (string, error) {
var resp struct {
ReturnValue string `json:"returnValue"`
}
if err := p.ref.process.doJSON("POST", "/webpage/RenderBase64", map[string]interface{}{"ref": p.ref.id, "format": format}, &resp); err != nil {
return "", err
}
return resp.ReturnValue, nil
}
// Render renders the web page to a file with the given format and quality settings.
// This supports the "PDF", "PNG", "JPEG", "BMP", "PPM", and "GIF" formats.
func (p *WebPage) Render(filename, format string, quality int) error {
req := map[string]interface{}{"ref": p.ref.id, "filename": filename, "format": format, "quality": quality}
return p.ref.process.doJSON("POST", "/webpage/Render", req, nil)
}
// SendMouseEvent sends a mouse event as if it came from the user.
// It is not a synthetic event.
//
// The eventType can be "mouseup", "mousedown", "mousemove", "doubleclick",
// or "click". The mouseX and mouseY specify the position of the mouse on the
// screen. The button argument specifies the mouse button clicked (e.g. "left").
func (p *WebPage) SendMouseEvent(eventType string, mouseX, mouseY int, button string) error {
return p.ref.process.doJSON("POST", "/webpage/SendMouseEvent", map[string]interface{}{"ref": p.ref.id, "eventType": eventType, "mouseX": mouseX, "mouseY": mouseY, "button": button}, nil)
}
// SendKeyboardEvent sends a keyboard event as if it came from the user.
// It is not a synthetic event.
//
// The eventType can be "keyup", "keypress", or "keydown".
//
// The key argument is a string or a key listed here:
// https://github.com/ariya/phantomjs/commit/cab2635e66d74b7e665c44400b8b20a8f225153a
//
// Keyboard modifiers can be joined together using the bitwise OR operator.
func (p *WebPage) SendKeyboardEvent(eventType string, key string, modifier int) error {
return p.ref.process.doJSON("POST", "/webpage/SendKeyboardEvent", map[string]interface{}{"ref": p.ref.id, "eventType": eventType, "key": key, "modifier": modifier}, nil)
}
// SetContentAndURL sets the content and URL of the page.
func (p *WebPage) SetContentAndURL(content, url string) error {
return p.ref.process.doJSON("POST", "/webpage/SetContentAndURL", map[string]interface{}{"ref": p.ref.id, "content": content, "url": url}, nil)
}
// Stop stops the web page.
func (p *WebPage) Stop() error {
return p.ref.process.doJSON("POST", "/webpage/Stop", map[string]interface{}{"ref": p.ref.id}, nil)
}
// SwitchToFocusedFrame changes the current frame to the frame that is in focus.
func (p *WebPage) SwitchToFocusedFrame() error {
return p.ref.process.doJSON("POST", "/webpage/SwitchToFocusedFrame", map[string]interface{}{"ref": p.ref.id}, nil)
}
// SwitchToFrameName changes the current frame to a frame with a given name.
func (p *WebPage) SwitchToFrameName(name string) error {
return p.ref.process.doJSON("POST", "/webpage/SwitchToFrameName", map[string]interface{}{"ref": p.ref.id, "name": name}, nil)
}
// SwitchToFramePosition changes the current frame to the frame at the given position.
func (p *WebPage) SwitchToFramePosition(pos int) error {
return p.ref.process.doJSON("POST", "/webpage/SwitchToFramePosition", map[string]interface{}{"ref": p.ref.id, "position": pos}, nil)
}
// SwitchToMainFrame switches the current frame to the main frame.
func (p *WebPage) SwitchToMainFrame() error {
return p.ref.process.doJSON("POST", "/webpage/SwitchToMainFrame", map[string]interface{}{"ref": p.ref.id}, nil)
}
// SwitchToParentFrame switches the current frame to the parent of the current frame.
func (p *WebPage) SwitchToParentFrame() error {
return p.ref.process.doJSON("POST", "/webpage/SwitchToParentFrame", map[string]interface{}{"ref": p.ref.id}, nil)
}
// UploadFile uploads a file to a form element specified by selector.
func (p *WebPage) UploadFile(selector, filename string) error {
return p.ref.process.doJSON("POST", "/webpage/UploadFile", map[string]interface{}{"ref": p.ref.id, "selector": selector, "filename": filename}, nil)
}
// OpenWebPageSettings represents the settings object passed to WebPage.Open().
type OpenWebPageSettings struct {
Method string `json:"method"`
}
// Ref represents a reference to an object in phantomjs.
type Ref struct {
process *Process
id string
}
// newRef returns a new instance of a referenced object within the process.
func newRef(p *Process, id string) *Ref {
return &Ref{process: p, id: id}
}
// ID returns the reference identifier.
func (r *Ref) ID() string {
return r.id
}
// refJSON is a struct for encoding refs as JSON.
type refJSON struct {
ID string `json:"id"`
}
// Rect represents a rectangle used by WebPage.ClipRect().
type Rect struct {
Top int
Left int
Width int
Height int
}
// rectJSON is a struct for encoding rects as JSON.
type rectJSON struct {
Top int `json:"top"`
Left int `json:"left"`
Width int `json:"width"`
Height int `json:"height"`
}
// cookieJSON is a struct for encoding http.Cookie objects as JSON.
type cookieJSON struct {
Domain string `json:"domain"`
Expires string `json:"expires"`
Expiry int `json:"expiry"`
HTTPOnly bool `json:"httponly"`
Name string `json:"name"`
Path string `json:"path"`
Secure bool `json:"secure"`
Value string `json:"value"`
}
func encodeCookieJSON(v *http.Cookie) cookieJSON {
out := cookieJSON{
Domain: v.Domain,
HTTPOnly: v.HttpOnly,
Name: v.Name,
Path: v.Path,
Secure: v.Secure,
Value: v.Value,
}
if !v.Expires.IsZero() {
out.Expires = v.Expires.UTC().Format(http.TimeFormat)
}
return out
}
func decodeCookieJSON(v cookieJSON) *http.Cookie {
out := &http.Cookie{
Domain: v.Domain,
RawExpires: v.Expires,
HttpOnly: v.HTTPOnly,
Name: v.Name,
Path: v.Path,
Secure: v.Secure,
Value: v.Value,
}
if v.Expires != "" {
expires, _ := time.Parse(http.TimeFormat, v.Expires)
out.Expires = expires
out.RawExpires = v.Expires
}
return out
}
// PaperSize represents the size of a webpage when rendered as a PDF.
//
// Units can be specified in "mm", "cm", "in", or "px".
// If no unit is specified then "px" is used.
type PaperSize struct {
// Dimensions of the paper.
// This can also be specified via Format.
Width string
Height string
// Supported formats: "A3", "A4", "A5", "Legal", "Letter", "Tabloid".
Format string
// Margins around the paper.
Margin *PaperSizeMargin
// Supported orientations: "portrait", "landscape".
Orientation string
}
// PaperSizeMargin represents the margins around the paper.
type PaperSizeMargin struct {
Top string
Bottom string
Left string
Right string
}
type paperSizeJSON struct {
Width string `json:"width,omitempty"`
Height string `json:"height,omitempty"`
Format string `json:"format,omitempty"`
Margin *paperSizeMarginJSON `json:"margin,omitempty"`
Orientation string `json:"orientation,omitempty"`
}
type paperSizeMarginJSON struct {
Top string `json:"top,omitempty"`
Bottom string `json:"bottom,omitempty"`
Left string `json:"left,omitempty"`
Right string `json:"right,omitempty"`
}
func encodePaperSizeJSON(v PaperSize) paperSizeJSON {
out := paperSizeJSON{
Width: v.Width,
Height: v.Height,
Format: v.Format,
Orientation: v.Orientation,
}
if v.Margin != nil {
out.Margin = &paperSizeMarginJSON{
Top: v.Margin.Top,
Bottom: v.Margin.Bottom,
Left: v.Margin.Left,
Right: v.Margin.Right,
}
}
return out
}
func decodePaperSizeJSON(v paperSizeJSON) PaperSize {
out := PaperSize{
Width: v.Width,
Height: v.Height,
Format: v.Format,
Orientation: v.Orientation,
}
if v.Margin != nil {
out.Margin = &PaperSizeMargin{
Top: v.Margin.Top,
Bottom: v.Margin.Bottom,
Left: v.Margin.Left,
Right: v.Margin.Right,
}
}
return out
}
// Position represents a coordinate on the page, in pixels.
type Position struct {
Top int
Left int
}
// WebPageSettings represents various settings on a web page.
type WebPageSettings struct {
JavascriptEnabled bool
LoadImages bool
LocalToRemoteURLAccessEnabled bool
UserAgent string
Username string
Password string
XSSAuditingEnabled bool
WebSecurityEnabled bool
ResourceTimeout time.Duration
}
type webPageSettingsJSON struct {
JavascriptEnabled bool `json:"javascriptEnabled"`
LoadImages bool `json:"loadImages"`
LocalToRemoteURLAccessEnabled bool `json:"localToRemoteUrlAccessEnabled"`
UserAgent string `json:"userAgent"`
Username string `json:"username"`
Password string `json:"password"`
XSSAuditingEnabled bool `json:"XSSAuditingEnabled"`
WebSecurityEnabled bool `json:"webSecurityEnabled"`
ResourceTimeout int `json:"resourceTimeout"`
}
// shim is the included javascript used to communicate with PhantomJS.
const shim = `
var system = require("system")
var webpage = require('webpage');
var webserver = require('webserver');
/*
* HTTP API
*/
// Serves RPC API.
var server = webserver.create();
server.listen(system.env["PORT"], function(request, response) {
try {
switch (request.url) {
case '/ping': return handlePing(request, response);
case '/webpage/CanGoBack': return handleWebpageCanGoBack(request, response);
case '/webpage/CanGoForward': return handleWebpageCanGoForward(request, response);
case '/webpage/ClipRect': return handleWebpageClipRect(request, response);
case '/webpage/SetClipRect': return handleWebpageSetClipRect(request, response);
case '/webpage/Cookies': return handleWebpageCookies(request, response);
case '/webpage/SetCookies': return handleWebpageSetCookies(request, response);
case '/webpage/CustomHeaders': return handleWebpageCustomHeaders(request, response);
case '/webpage/SetCustomHeaders': return handleWebpageSetCustomHeaders(request, response);
case '/webpage/Create': return handleWebpageCreate(request, response);
case '/webpage/Content': return handleWebpageContent(request, response);
case '/webpage/SetContent': return handleWebpageSetContent(request, response);
case '/webpage/FocusedFrameName': return handleWebpageFocusedFrameName(request, response);
case '/webpage/FrameContent': return handleWebpageFrameContent(request, response);
case '/webpage/SetFrameContent': return handleWebpageSetFrameContent(request, response);
case '/webpage/FrameName': return handleWebpageFrameName(request, response);
case '/webpage/FramePlainText': return handleWebpageFramePlainText(request, response);
case '/webpage/FrameTitle': return handleWebpageFrameTitle(request, response);
case '/webpage/FrameURL': return handleWebpageFrameURL(request, response);
case '/webpage/FrameCount': return handleWebpageFrameCount(request, response);
case '/webpage/FrameNames': return handleWebpageFrameNames(request, response);
case '/webpage/LibraryPath': return handleWebpageLibraryPath(request, response);
case '/webpage/SetLibraryPath': return handleWebpageSetLibraryPath(request, response);
case '/webpage/NavigationLocked': return handleWebpageNavigationLocked(request, response);
case '/webpage/SetNavigationLocked': return handleWebpageSetNavigationLocked(request, response);
case '/webpage/OfflineStoragePath': return handleWebpageOfflineStoragePath(request, response);
case '/webpage/OfflineStorageQuota': return handleWebpageOfflineStorageQuota(request, response);
case '/webpage/OwnsPages': return handleWebpageOwnsPages(request, response);
case '/webpage/SetOwnsPages': return handleWebpageSetOwnsPages(request, response);
case '/webpage/PageWindowNames': return handleWebpagePageWindowNames(request, response);
case '/webpage/Pages': return handleWebpagePages(request, response);
case '/webpage/PaperSize': return handleWebpagePaperSize(request, response);
case '/webpage/SetPaperSize': return handleWebpageSetPaperSize(request, response);
case '/webpage/PlainText': return handleWebpagePlainText(request, response);
case '/webpage/ScrollPosition': return handleWebpageScrollPosition(request, response);
case '/webpage/SetScrollPosition': return handleWebpageSetScrollPosition(request, response);
case '/webpage/Settings': return handleWebpageSettings(request, response);
case '/webpage/SetSettings': return handleWebpageSetSettings(request, response);
case '/webpage/Title': return handleWebpageTitle(request, response);
case '/webpage/URL': return handleWebpageURL(request, response);
case '/webpage/ViewportSize': return handleWebpageViewportSize(request, response);
case '/webpage/SetViewportSize': return handleWebpageSetViewportSize(request, response);
case '/webpage/WindowName': return handleWebpageWindowName(request, response);
case '/webpage/ZoomFactor': return handleWebpageZoomFactor(request, response);
case '/webpage/SetZoomFactor': return handleWebpageSetZoomFactor(request, response);
case '/webpage/AddCookie': return handleWebpageAddCookie(request, response);
case '/webpage/ClearCookies': return handleWebpageClearCookies(request, response);
case '/webpage/DeleteCookie': return handleWebpageDeleteCookie(request, response);
case '/webpage/Open': return handleWebpageOpen(request, response);
case '/webpage/Close': return handleWebpageClose(request, response);
case '/webpage/EvaluateAsync': return handleWebpageEvaluateAsync(request, response);
case '/webpage/EvaluateJavaScript': return handleWebpageEvaluateJavaScript(request, response);
case '/webpage/Evaluate': return handleWebpageEvaluate(request, response);
case '/webpage/Page': return handleWebpagePage(request, response);
case '/webpage/GoBack': return handleWebpageGoBack(request, response);
case '/webpage/GoForward': return handleWebpageGoForward(request, response);
case '/webpage/Go': return handleWebpageGo(request, response);
case '/webpage/IncludeJS': return handleWebpageIncludeJS(request, response);
case '/webpage/InjectJS': return handleWebpageInjectJS(request, response);
case '/webpage/Reload': return handleWebpageReload(request, response);
case '/webpage/RenderBase64': return handleWebpageRenderBase64(request, response);
case '/webpage/Render': return handleWebpageRender(request, response);
case '/webpage/SendMouseEvent': return handleWebpageSendMouseEvent(request, response);
case '/webpage/SendKeyboardEvent': return handleWebpageSendKeyboardEvent(request, response);
case '/webpage/SetContentAndURL': return handleWebpageSetContentAndURL(request, response);
case '/webpage/Stop': return handleWebpageStop(request, response);
case '/webpage/SwitchToFocusedFrame': return handleWebpageSwitchToFocusedFrame(request, response);
case '/webpage/SwitchToFrameName': return handleWebpageSwitchToFrameName(request, response);
case '/webpage/SwitchToFramePosition': return handleWebpageSwitchToFramePosition(request, response);
case '/webpage/SwitchToMainFrame': return handleWebpageSwitchToMainFrame(request, response);
case '/webpage/SwitchToParentFrame': return handleWebpageSwitchToParentFrame(request, response);
case '/webpage/UploadFile': return handleWebpageUploadFile(request, response);
default: return handleNotFound(request, response);
}
} catch(e) {
response.statusCode = 500;
response.write(JSON.stringify({url: request.url, error: e.message}));
response.closeGracefully();
}
});
function handlePing(request, response) {
response.statusCode = 200;
response.write('ok');
response.closeGracefully();
}
function handleWebpageCanGoBack(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.canGoBack}));
response.closeGracefully();
}
function handleWebpageCanGoForward(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.canGoForward}));
response.closeGracefully();
}
function handleWebpageClipRect(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.clipRect}));
response.closeGracefully();
}
function handleWebpageSetClipRect(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.clipRect = msg.rect;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageCookies(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.cookies}));
response.closeGracefully();
}
function handleWebpageSetCookies(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.cookies = msg.cookies;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageCustomHeaders(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.customHeaders}));
response.closeGracefully();
}
function handleWebpageSetCustomHeaders(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.customHeaders = msg.headers;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageCreate(request, response) {
var ref = createRef(webpage.create());
response.statusCode = 200;
response.write(JSON.stringify({ref: ref}));
response.closeGracefully();
}
function handleWebpageOpen(request, response) {
var msg = JSON.parse(request.post)
var page = ref(msg.ref)
page.open(msg.url, function(status) {
response.write(JSON.stringify({status: status}));
response.closeGracefully();
})
}
function handleWebpageContent(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.content}));
response.closeGracefully();
}
function handleWebpageSetContent(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.content = msg.content;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageFocusedFrameName(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.focusedFrameName}));
response.closeGracefully();
}
function handleWebpageFrameContent(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.frameContent}));
response.closeGracefully();
}
function handleWebpageSetFrameContent(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.frameContent = msg.content;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageFrameName(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.frameName}));
response.closeGracefully();
}
function handleWebpageFramePlainText(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.framePlainText}));
response.closeGracefully();
}
function handleWebpageFrameTitle(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.frameTitle}));
response.closeGracefully();
}
function handleWebpageFrameURL(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.frameUrl}));
response.closeGracefully();
}
function handleWebpageFrameCount(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.framesCount}));
response.closeGracefully();
}
function handleWebpageFrameNames(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.framesName}));
response.closeGracefully();
}
function handleWebpageLibraryPath(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.libraryPath}));
response.closeGracefully();
}
function handleWebpageSetLibraryPath(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.libraryPath = msg.path;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageNavigationLocked(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.navigationLocked}));
response.closeGracefully();
}
function handleWebpageSetNavigationLocked(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.navigationLocked = msg.value;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageOfflineStoragePath(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.offlineStoragePath}));
response.closeGracefully();
}
function handleWebpageOfflineStorageQuota(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.offlineStorageQuota}));
response.closeGracefully();
}
function handleWebpageOwnsPages(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.ownsPages}));
response.closeGracefully();
}
function handleWebpageSetOwnsPages(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.ownsPages = msg.value;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpagePageWindowNames(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.pagesWindowName}));
response.closeGracefully();
}
function handleWebpagePages(request, response) {
var page = ref(JSON.parse(request.post).ref);
var refs = page.pages.map(function(p) { return createRef(p); })
response.write(JSON.stringify({refs: refs}));
response.closeGracefully();
}
function handleWebpagePaperSize(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.paperSize}));
response.closeGracefully();
}
function handleWebpageSetPaperSize(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.paperSize = msg.size;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpagePlainText(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.plainText}));
response.closeGracefully();
}
function handleWebpageScrollPosition(request, response) {
var page = ref(JSON.parse(request.post).ref);
var pos = page.scrollPosition;
response.write(JSON.stringify({top: pos.top, left: pos.left}));
response.closeGracefully();
}
function handleWebpageSetScrollPosition(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.scrollPosition = {top: msg.top, left: msg.left};
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSettings(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({settings: page.settings}));
response.closeGracefully();
}
function handleWebpageSetSettings(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.settings = msg.settings;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageTitle(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.title}));
response.closeGracefully();
}
function handleWebpageURL(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.url}));
response.closeGracefully();
}
function handleWebpageViewportSize(request, response) {
var page = ref(JSON.parse(request.post).ref);
var viewport = page.viewportSize;
response.write(JSON.stringify({width: viewport.width, height: viewport.height}));
response.closeGracefully();
}
function handleWebpageSetViewportSize(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.viewportSize = {width: msg.width, height: msg.height};
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageWindowName(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.windowName}));
response.closeGracefully();
}
function handleWebpageZoomFactor(request, response) {
var page = ref(JSON.parse(request.post).ref);
response.write(JSON.stringify({value: page.zoomFactor}));
response.closeGracefully();
}
function handleWebpageSetZoomFactor(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.zoomFactor = msg.value;
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageAddCookie(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.addCookie(msg.cookie);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpageClearCookies(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.clearCookies();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageDeleteCookie(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.deleteCookie(msg.name);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpageClose(request, response) {
var msg = JSON.parse(request.post);
// Close page.
var page = ref(msg.ref);
page.close();
delete(refs, msg.ref);
// Close and dereference owned pages.
for (var i = 0; i < page.pages.length; i++) {
page.pages[i].close();
deleteRef(page.pages[i]);
}
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageEvaluateAsync(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.evaluateAsync(msg.script, msg.delay);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageEvaluateJavaScript(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.evaluateJavaScript(msg.script);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpageEvaluate(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.evaluate(msg.script);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpagePage(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var p = page.getPage(msg.name);
if (p === null) {
response.write(JSON.stringify({}));
} else {
response.write(JSON.stringify({ref: createRef(p)}));
}
response.closeGracefully();
}
function handleWebpageGoBack(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.goBack();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageGoForward(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.goForward();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageGo(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.go(msg.index);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageIncludeJS(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.includeJs(msg.url, function() {
response.write(JSON.stringify({}));
response.closeGracefully();
});
}
function handleWebpageInjectJS(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.injectJs(msg.filename);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpageReload(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.reload();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageRenderBase64(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
var returnValue = page.renderBase64(msg.format);
response.write(JSON.stringify({returnValue: returnValue}));
response.closeGracefully();
}
function handleWebpageRender(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.render(msg.filename, {format: msg.format, quality: msg.quality});
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSendMouseEvent(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.sendEvent(msg.eventType, msg.mouseX, msg.mouseY, msg.button);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSendKeyboardEvent(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.sendEvent(msg.eventType, msg.key, null, null, msg.modifier);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSetContentAndURL(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.setContent(msg.content, msg.url);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageStop(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.stop();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSwitchToFocusedFrame(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.switchToFocusedFrame();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSwitchToFrameName(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.switchToFrame(msg.name);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSwitchToFramePosition(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.switchToFrame(msg.position);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSwitchToMainFrame(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.switchToMainFrame();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageSwitchToParentFrame(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.switchToParentFrame();
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleWebpageUploadFile(request, response) {
var msg = JSON.parse(request.post);
var page = ref(msg.ref);
page.uploadFile(msg.selector, msg.filename);
response.write(JSON.stringify({}));
response.closeGracefully();
}
function handleNotFound(request, response) {
response.statusCode = 404;
response.write(JSON.stringify({error:"not found"}));
response.closeGracefully();
}
/*
* REFS
*/
// Holds references to remote objects.
var refID = 0;
var refs = {};
// Adds an object to the reference map and a ref object.
function createRef(value) {
// Return existing reference, if one exists.
for (var key in refs) {
if (refs.hasOwnProperty(key)) {
if (refs[key] === value) {
return key
}
}
}
// Generate a new id for new references.
refID++;
refs[refID.toString()] = value;
return {id: refID.toString()};
}
// Removes a reference to a value, if any.
function deleteRef(value) {
for (var key in refs) {
if (refs.hasOwnProperty(key)) {
if (refs[key] === value) {
delete(refs, key);
}
}
}
}
// Returns a reference object by ID.
function ref(id) {
return refs[id];
}
`
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。