shithub: opossum

Download patch

ref: 2e8eb15b7f930db7469914a1ce70bdec608a9349
parent: ac32db32e14093022a4e363f808659191ce43cca
author: Philip Silva <philip.silva@protonmail.com>
date: Sat Jan 30 22:57:44 EST 2021

More gracefully continue when single scripts fail

--- a/browser/experimental.go
+++ b/browser/experimental.go
@@ -4,10 +4,9 @@
 	"fmt"
 	"image"
 	"github.com/psilva261/opossum/domino"
-	"github.com/psilva261/opossum/nodes"
-
 	"9fans.net/go/draw"
 	"github.com/mjl-/duit"
+	"strings"
 )
 
 type AtomBox struct {
@@ -121,14 +120,16 @@
 	})
 }
 
-func processJS2(d *domino.Domino, doc *nodes.Node, scripts []string) (resHtm string, err error) {
+func processJS2(d *domino.Domino, scripts []string) (resHtm string, err error) {
 	initialized := false
 	for _, script := range scripts {
-		if _, err := d.Exec/*6*/(script, !initialized); err == nil {
-			initialized = true
-		} else {
+		if _, err := d.Exec/*6*/(script, !initialized); err != nil {
+			if strings.Contains(err.Error(), "halt at") {
+				return "", fmt.Errorf("execution halted: %w", err)
+			}
 			log.Errorf("exec <script>: %v", err)
 		}
+		initialized = true
 	}
 
 	resHtm, changed, err := d.TrackChanges()
--- a/browser/experimental_test.go
+++ b/browser/experimental_test.go
@@ -1,11 +1,63 @@
 package browser
 
 import (
+	"golang.org/x/net/html"
 	//"github.com/mjl-/duit"
+	"github.com/psilva261/opossum/domino"
+	"github.com/psilva261/opossum/logger"
+	"github.com/psilva261/opossum/nodes"
+	"github.com/psilva261/opossum/style"
+	"io/ioutil"
+	"strings"
 	"testing"
 )
 
+func init() {
+	quiet := false
+	logger.Quiet = &quiet
+	f := false
+	domino.DebugDumpJS = &f
+	domino.SetLogger(&logger.Logger{})
+	logger.Init()
+	SetLogger(&logger.Logger{})
+	style.Init(nil, &logger.Logger{})
+}
+
 func TestAtom(t *testing.T) {
 	//var ui duit.UI
 	//ui = &Atom{}
+}
+
+func TestProcessJS2SkipFailure(t *testing.T) {
+	h := `
+	<html>
+	<body>
+	<h1 id="title">Hello</h1>
+	</body>
+	</html>
+	`
+	buf := strings.NewReader(h)
+	doc, err := html.Parse(buf)
+	if err != nil { t.Fatalf(err.Error()) }
+	nt := nodes.NewNodeTree(doc, style.Map{}, make(map[*html.Node]style.Map), nil)
+	d := domino.NewDomino(h, nt)
+	d.Start()
+	jq, err := ioutil.ReadFile("../domino/jquery-3.5.1.js")
+	if err != nil {
+		t.Fatalf("%v", err)
+	}
+	scripts := []string{
+		string(jq),
+		`throw 'fail';`,
+		`throw 'fail';`,
+		`$('body').hide()`,
+		`throw 'fail';`,
+	}
+	h, err = processJS2(d, scripts)
+	if err != nil { t.Errorf(err.Error()) }
+	t.Logf("h = %+v", h)
+	if !strings.Contains(h, `<body style="display: none;">`) {
+		t.Fail()
+	}
+	d.Stop()
 }
--- a/browser/website.go
+++ b/browser/website.go
@@ -90,7 +90,7 @@
 			log.Printf("css: unexpected %v", contentType)
 		}
 	}
-	csss = append([]string{ /*string(revertCSS), */ style.AddOnCSS}, csss...)
+	csss = append([]string{style.AddOnCSS}, csss...)
 	doc, nodeMap := pass(w.html, csss...)
 
 	// 3rd pass is only needed initially to load the scripts and set the goja VM
@@ -122,7 +122,7 @@
 		}
 		w.d = domino.NewDomino(w.html, nt)
 		w.d.Start()
-		jsProcessed, err := processJS2(w.d, nt, codes)
+		jsProcessed, err := processJS2(w.d, codes)
 		if err == nil {
 			if w.html != jsProcessed {
 				log.Infof("html changed")
--- a/domino/domino.go
+++ b/domino/domino.go
@@ -19,7 +19,7 @@
 
 var DebugDumpJS *bool
 var log *logger.Logger
-var timeout = 10*time.Second
+var timeout = 20*time.Second
 
 func SetLogger(l *logger.Logger) {
 	log = l
@@ -26,7 +26,6 @@
 }
 
 type Domino struct {
-	initialized bool
 	loop       *eventloop.EventLoop
 	html       string
 	nt           *nodes.Node
@@ -102,9 +101,6 @@
 }
 
 func (d *Domino) Exec(script string, initial bool) (res string, err error) {
-	if !initial && !d.initialized {
-		initial = true
-	}
 	script = strings.Replace(script, "const ", "var ", -1)
 	script = strings.Replace(script, "let ", "var ", -1)
 	script = strings.Replace(script, "<!--", "", -1)
@@ -237,10 +233,10 @@
 				if v != nil {
 					res = v.String()
 				}
-				if err == nil { d.initialized=true }
 				goto cleanup
 			case er := <- errCh:
 				log.Infof("err")
+				<-time.After(10 * time.Millisecond)
 				err = fmt.Errorf("event loop: %w", er)
 				goto cleanup
 			case <-time.After(timeout):