github.com/MontFerret/ferret@v0.18.0/pkg/stdlib/html/screenshot.go (about)

     1  package html
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/MontFerret/ferret/pkg/drivers"
     8  	"github.com/MontFerret/ferret/pkg/runtime/core"
     9  	"github.com/MontFerret/ferret/pkg/runtime/values"
    10  	"github.com/MontFerret/ferret/pkg/runtime/values/types"
    11  )
    12  
    13  // SCREENSHOT takes a screenshot of a given page.
    14  // @param {HTMLPage|String} target - Target page or url.
    15  // @param {Object} [params] - An object containing the following properties :
    16  // @param {Float | Int} [params.x=0] - X position of the viewport.
    17  // @param {Float | Int} [params.y=0] - Y position of the viewport.
    18  // @param {Float | Int} [params.width] - Width of the viewport.
    19  // @param {Float | Int} [params.height] - Height of the viewport.
    20  // @param {String} [params.format="jpeg"] - Either "jpeg" or "png".
    21  // @param {Int} [params.quality=100] - Quality, in [0, 100], only for jpeg format.
    22  // @return {Binary} - Screenshot in binary format.
    23  func Screenshot(ctx context.Context, args ...core.Value) (core.Value, error) {
    24  	err := core.ValidateArgs(args, 1, 2)
    25  
    26  	if err != nil {
    27  		return values.None, err
    28  	}
    29  
    30  	arg1 := args[0]
    31  
    32  	err = core.ValidateType(arg1, drivers.HTMLPageType, types.String)
    33  
    34  	if err != nil {
    35  		return values.None, err
    36  	}
    37  
    38  	page, closeAfter, err := OpenOrCastPage(ctx, arg1)
    39  
    40  	if err != nil {
    41  		return values.None, err
    42  	}
    43  
    44  	defer func() {
    45  		if closeAfter {
    46  			page.Close()
    47  		}
    48  	}()
    49  
    50  	screenshotParams := drivers.ScreenshotParams{
    51  		X:       0,
    52  		Y:       0,
    53  		Width:   -1,
    54  		Height:  -1,
    55  		Format:  drivers.ScreenshotFormatJPEG,
    56  		Quality: 100,
    57  	}
    58  
    59  	if len(args) == 2 {
    60  		arg2 := args[1]
    61  		err = core.ValidateType(arg2, types.Object)
    62  
    63  		if err != nil {
    64  			return values.None, err
    65  		}
    66  
    67  		params, ok := arg2.(*values.Object)
    68  
    69  		if !ok {
    70  			return values.None, core.Error(core.ErrInvalidType, "expected object")
    71  		}
    72  
    73  		format, found := params.Get("format")
    74  
    75  		if found {
    76  			err = core.ValidateType(format, types.String)
    77  
    78  			if err != nil {
    79  				return values.None, err
    80  			}
    81  
    82  			if !drivers.IsScreenshotFormatValid(format.String()) {
    83  				return values.None, core.Error(
    84  					core.ErrInvalidArgument,
    85  					fmt.Sprintf("format is not valid, expected jpeg or png, but got %s", format.String()))
    86  			}
    87  
    88  			screenshotParams.Format = drivers.ScreenshotFormat(format.String())
    89  		}
    90  
    91  		x, found := params.Get("x")
    92  
    93  		if found {
    94  			err = core.ValidateType(x, types.Float, types.Int)
    95  
    96  			if err != nil {
    97  				return values.None, err
    98  			}
    99  
   100  			if x.Type() == types.Int {
   101  				screenshotParams.X = values.Float(x.(values.Int))
   102  			}
   103  		}
   104  
   105  		y, found := params.Get("y")
   106  
   107  		if found {
   108  			err = core.ValidateType(y, types.Float, types.Int)
   109  
   110  			if err != nil {
   111  				return values.None, err
   112  			}
   113  
   114  			if y.Type() == types.Int {
   115  				screenshotParams.Y = values.Float(y.(values.Int))
   116  			}
   117  		}
   118  
   119  		width, found := params.Get("width")
   120  
   121  		if found {
   122  			err = core.ValidateType(width, types.Float, types.Int)
   123  
   124  			if err != nil {
   125  				return values.None, err
   126  			}
   127  
   128  			if width.Type() == types.Int {
   129  				screenshotParams.Width = values.Float(width.(values.Int))
   130  			}
   131  		}
   132  
   133  		height, found := params.Get("height")
   134  
   135  		if found {
   136  			err = core.ValidateType(height, types.Float, types.Int)
   137  
   138  			if err != nil {
   139  				return values.None, err
   140  			}
   141  
   142  			if height.Type() == types.Int {
   143  				screenshotParams.Height = values.Float(height.(values.Int))
   144  			}
   145  		}
   146  
   147  		quality, found := params.Get("quality")
   148  
   149  		if found {
   150  			err = core.ValidateType(quality, types.Int)
   151  
   152  			if err != nil {
   153  				return values.None, err
   154  			}
   155  
   156  			screenshotParams.Quality = quality.(values.Int)
   157  		}
   158  	}
   159  
   160  	scr, err := page.CaptureScreenshot(ctx, screenshotParams)
   161  
   162  	if err != nil {
   163  		return values.None, err
   164  	}
   165  
   166  	return scr, nil
   167  }