From 642d09d5ec64e654c1a3b026c218409f1ef93f9a Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 12:16:36 +0800 Subject: [PATCH 01/16] feat: TriggerFavicon 1.support in headless mode to trigger favicon request. 2.when call it in no-headless mode will raise an error with message:browser is no-headless --- browser.go | 11 ++++++++++ lib/js/helper.go | 37 +++++++++++++++++++-------------- lib/js/helper.js | 42 ++++++++++++++++++++++++++++++++++++++ must.go | 6 ++++++ page.go | 20 ++++++++++++++++++ page_test.go | 53 ++++++++++++++++++++++++++++++++++++++++++++---- 6 files changed, 150 insertions(+), 19 deletions(-) diff --git a/browser.go b/browser.go index 11ce2861..0b149af7 100644 --- a/browser.go +++ b/browser.go @@ -10,6 +10,7 @@ package rod import ( "context" "reflect" + "strings" "sync" "time" @@ -457,6 +458,16 @@ func (b *Browser) pageInfo(id proto.TargetTargetID) (*proto.TargetTargetInfo, er return res.TargetInfo, nil } +func (b *Browser) isHeadless() (enabled bool) { + res, _ := proto.BrowserGetBrowserCommandLine{}.Call(b) + for _, v := range res.Arguments { + if strings.Contains(v, "headless") { + return true + } + } + return false +} + // IgnoreCertErrors switch. If enabled, all certificate errors will be ignored. func (b *Browser) IgnoreCertErrors(enable bool) error { return proto.SecuritySetIgnoreCertificateErrors{Ignore: enable}.Call(b) diff --git a/lib/js/helper.go b/lib/js/helper.go index 54cc568c..be689433 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -25,14 +25,14 @@ var ElementX = &Function{ // ElementsX ... var ElementsX = &Function{ Name: "elementsX", - Definition: `function(e){var t,n=functions.selectable(this);const i=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),r=[];for(;t=i.iterateNext();)r.push(t);return r}`, + Definition: `function(e){var t,n=functions.selectable(this);const r=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),i=[];for(;t=r.iterateNext();)i.push(t);return i}`, Dependencies: []*Function{Selectable}, } // ElementR ... var ElementR = &Function{ Name: "elementR", - Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),i=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const r=functions.selectable(this);e=Array.from(r.querySelectorAll(e)).find(e=>i.test(functions.text.call(e)));return e||null}`, + Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),r=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const i=functions.selectable(this);e=Array.from(i.querySelectorAll(e)).find(e=>r.test(functions.text.call(e)));return e||null}`, Dependencies: []*Function{Selectable, Text}, } @@ -53,14 +53,14 @@ var ContainsElement = &Function{ // InitMouseTracer ... var InitMouseTracer = &Function{ Name: "initMouseTracer", - Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const i=n.lastChild;i.id=e,i.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",i.removeAttribute("width"),i.removeAttribute("height"),document.body.parentElement.appendChild(i)}}`, + Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const r=n.lastChild;r.id=e,r.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",r.removeAttribute("width"),r.removeAttribute("height"),document.body.parentElement.appendChild(r)}}`, Dependencies: []*Function{WaitLoad}, } // UpdateMouseTracer ... var UpdateMouseTracer = &Function{ Name: "updateMouseTracer", - Definition: `function(e,t,n){const i=document.getElementById(e);return!!i&&(i.style.left=t-2+"px",i.style.top=n-3+"px",!0)}`, + Definition: `function(e,t,n){const r=document.getElementById(e);return!!r&&(r.style.left=t-2+"px",r.style.top=n-3+"px",!0)}`, Dependencies: []*Function{}, } @@ -74,22 +74,22 @@ var Rect = &Function{ // Overlay ... var Overlay = &Function{ Name: "overlay", - Definition: `async function(e,t,n,i,r,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; + Definition: `async function(e,t,n,r,i,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; border-radius: 3px; box-shadow: #5f3232 0 0 3px; pointer-events: none; box-sizing: border-box; left: ${t}px; top: ${n}px; - height: ${r}px; - width: ${i}px;` + "`" + `,i*r==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; + height: ${i}px; + width: ${r}px;` + "`" + `,r*i==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; box-shadow: #333 0 0 3px; padding: 2px 5px; border-radius: 3px; white-space: nowrap; - top: ${r}px;` + "`" + `,a.innerHTML=o,s.appendChild(a),document.body.parentElement.appendChild(s),window.innerHeight{const e=document.getElementById(n);var t;null!==e&&(t=r.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,i))};setTimeout(s,i)}`, + Definition: `async function(n,e){const r=100,i=functions.tag(this);let o=i.getBoundingClientRect();await functions.overlay(n,o.left,o.top,o.width,o.height,e);const s=()=>{const e=document.getElementById(n);var t;null!==e&&(t=i.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,r))};setTimeout(s,r)}`, Dependencies: []*Function{Tag, Overlay}, } @@ -124,7 +124,7 @@ var InputEvent = &Function{ // InputTime ... var InputTime = &Function{ Name: "inputTime", - Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),i=e(t.getMonth()+1),r=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${i}-` + "`" + `+r;break;case"datetime-local":this.value=n+` + "`" + `-${i}-${r}T${o}:` + "`" + `+s;break;case"month":this.value=i;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, + Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),r=e(t.getMonth()+1),i=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${r}-` + "`" + `+i;break;case"datetime-local":this.value=n+` + "`" + `-${r}-${i}T${o}:` + "`" + `+s;break;case"month":this.value=r;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, Dependencies: []*Function{InputEvent}, } @@ -135,6 +135,13 @@ var SelectText = &Function{ Dependencies: []*Function{}, } +// TriggerFavicon ... +var TriggerFavicon = &Function{ + Name: "triggerFavicon", + Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString();const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText})},r.send()})}`, + Dependencies: []*Function{}, +} + // SelectAllText ... var SelectAllText = &Function{ Name: "selectAllText", @@ -145,7 +152,7 @@ var SelectAllText = &Function{ // Select ... var Select = &Function{ Name: "select", - Definition: `function(e,n,t){let i;switch(t){case"regex":i=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":i=e.map(t=>e=>e.matches(t));break;default:i=e.map(t=>e=>e.innerText.includes(t))}const r=Array.from(this.options);let o=!1;return i.forEach(e=>{const t=r.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, + Definition: `function(e,n,t){let r;switch(t){case"regex":r=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":r=e.map(t=>e=>e.matches(t));break;default:r=e.map(t=>e=>e.innerText.includes(t))}const i=Array.from(this.options);let o=!1;return r.forEach(e=>{const t=i.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, Dependencies: []*Function{}, } @@ -180,14 +187,14 @@ var Resource = &Function{ // AddScriptTag ... var AddScriptTag = &Function{ Name: "addScriptTag", - Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n=document.createElement("script");r?(n.src=r,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=i,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n=document.createElement("script");i?(n.src=i,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=r,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } // AddStyleTag ... var AddStyleTag = &Function{ Name: "addStyleTag", - Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n;r?((n=document.createElement("link")).rel="stylesheet",n.href=r):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=i,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n;i?((n=document.createElement("link")).rel="stylesheet",n.href=i):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=r,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } @@ -208,13 +215,13 @@ var Tag = &Function{ // ExposeFunc ... var ExposeFunc = &Function{ Name: "exposeFunc", - Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,i)=>{const r=t+"_cb"+o++;window[r]=(e,t)=>{delete window[r],t?i(t):n(e)},window[t](JSON.stringify({req:e,cb:r}))})}`, + Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,r)=>{const i=t+"_cb"+o++;window[i]=(e,t)=>{delete window[i],t?r(t):n(e)},window[t](JSON.stringify({req:e,cb:i}))})}`, Dependencies: []*Function{}, } // GetXPath ... var GetXPath = &Function{ Name: "getXPath", - Definition: `function(e){class r{constructor(e,t){this.value=e,this.optimized=t||!1}toString(){return this.value}}function o(t){function n(e,t){return e===t||(e.nodeType===Node.ELEMENT_NODE&&t.nodeType===Node.ELEMENT_NODE?e.localName===t.localName:e.nodeType===t.nodeType||(e.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:e.nodeType)===(t.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:t.nodeType))}var e=t.parentNode,i=e?e.children:null;if(!i)return 0;let r;for(let e=0;e { + const faviconElement = document.querySelector('link[rel~=icon]') + const href = (faviconElement && faviconElement.href) || '/favicon.ico' + const faviconUrl = new URL(href, window.location).toString() + const xhr = new XMLHttpRequest() + xhr.open('GET', faviconUrl) + + xhr.ontimeout = function () { + reject({ + errorType: 'timeout_error', + xhr: xhr + }) + } + + xhr.onreadystatechange = function () { + if (xhr.readyState === 4) { + if ((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) { + resolve(xhr.responseText) + } else { + reject({ + errorType: 'status_error', + xhr: xhr, + status: xhr.status, + statusText: xhr.statusText + }) + } + } + } + + xhr.onerror = function () { + reject({ + errorType: 'onerror', + xhr: xhr, + status: xhr.status, + statusText: xhr.statusText + }) + } + xhr.send() + }) + }, + selectAllText() { this.select() }, diff --git a/must.go b/must.go index 7bd11e0d..be9e6907 100644 --- a/must.go +++ b/must.go @@ -372,6 +372,12 @@ func (p *Page) MustCaptureDOMSnapshot() (domSnapshot *proto.DOMSnapshotCaptureSn return domSnapshot } +// MustTriggerFavicon is similar to TriggerFavicon. +func (p *Page) MustTriggerFavicon() *Page { + p.e(p.TriggerFavicon()) + return p +} + // MustScreenshotFullPage is similar to ScreenshotFullPage. // If the toFile is "", it Page.will save output to "tmp/screenshots" folder, time as the file name. func (p *Page) MustScreenshotFullPage(toFile ...string) []byte { diff --git a/page.go b/page.go index fece64fd..fb883e09 100644 --- a/page.go +++ b/page.go @@ -348,6 +348,26 @@ func (p *Page) Close() error { return nil } +// TriggerFavicon supports when browser in headless mode +// to trigger favicon's request. Pay attention to this +// function only supported when browser in headless mode, +// if you call it in no-headless mode, it will raise an error +// with the message "browser is no-headless". +func (p *Page) TriggerFavicon() error { + + // check if browser whether in headless mode + // if not in headless mode then raise error + if !p.browser.isHeadless() { + return errors.New("browser is no-headless") + } + + _, err := p.Evaluate(evalHelper(js.TriggerFavicon).ByPromise()) + if err != nil { + return err + } + return nil +} + // HandleDialog accepts or dismisses next JavaScript initiated dialog (alert, confirm, prompt, or onbeforeunload). // Because modal dialog will block js, usually you have to trigger the dialog in another goroutine. // For example: diff --git a/page_test.go b/page_test.go index 5628c61c..cb472a01 100644 --- a/page_test.go +++ b/page_test.go @@ -3,6 +3,7 @@ package rod_test import ( "bytes" "context" + "github.com/go-rod/rod/lib/launcher" "image/png" "math" "net/http" @@ -80,14 +81,14 @@ func TestSetBlockedURLs(t *testing.T) { var urlsPattern = []string{} page.EnableDomain(proto.NetworkEnable{}) page.MustSetBlockedURLs(urlsPattern...) - urlsPattern = append(urlsPattern, "*.js") + urlsPattern = append(urlsPattern, "*.com") page.MustSetBlockedURLs(urlsPattern...) - go page.EachEvent( + go page.Context(g.Context()).EachEvent( func(e *proto.NetworkLoadingFailed) { g.Eq(e.BlockedReason, proto.NetworkBlockedReasonInspector) }, - ) - page.MustNavigate("https://github.com") + )() + page.MustNavigate("https://example.com") } func TestSetExtraHeaders(t *testing.T) { @@ -894,6 +895,50 @@ func TestPageElementFromObjectErr(t *testing.T) { g.Err(p.ElementFromObject(obj.Object)) } +func TestPageTriggerFavicon(t *testing.T) { + g := setup(t) + + // test browser in no-headless mode with an error + { + path, _ := launcher.LookPath() + u := launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).Headless(false).MustLaunch() + + browser := rod.New().ControlURL(u).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) + page := browser.MustPage("https://example.com") + err := page.TriggerFavicon() + g.Eq(err.Error(), "browser is no-headless") + browser.Close() + } + + // test browser in headless mode to trigger favicon request + { + page := g.page + page.EnableDomain(proto.NetworkEnable{}) + page.MustNavigate("https://github.com") + page.MustWaitIdle() + go page.Context(g.Context()).EachEvent( + func(e *proto.NetworkRequestWillBeSent) { + if e.Request.URL == "https://github.githubassets.com/favicons/favicon.png" { + g.Eq(e.Request.URL, "https://github.githubassets.com/favicons/favicon.png") + return + } + return + }, + )() + page.MustTriggerFavicon() + } + + // test browser in headless mode to trigger favicon request with an error + { + g.Panic(func() { + p := g.page.MustNavigate("https://example.com") + g.mc.stubErr(1, proto.RuntimeCallFunctionOn{}) + p.MustTriggerFavicon() + }) + } + +} + func TestPageActionAfterClose(t *testing.T) { g := setup(t) From 21c085d2c575a5df7f7b22c9d69e9d00e3bf357d Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 12:26:00 +0800 Subject: [PATCH 02/16] fix cli error --- page_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/page_test.go b/page_test.go index cb472a01..d2ccac5c 100644 --- a/page_test.go +++ b/page_test.go @@ -907,7 +907,7 @@ func TestPageTriggerFavicon(t *testing.T) { page := browser.MustPage("https://example.com") err := page.TriggerFavicon() g.Eq(err.Error(), "browser is no-headless") - browser.Close() + g.Eq(browser.Close(), nil) } // test browser in headless mode to trigger favicon request From 01b5699fd115b1d95c18847baed4e6208a0eca9b Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 12:32:36 +0800 Subject: [PATCH 03/16] fix cli error --- page_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/page_test.go b/page_test.go index d2ccac5c..a9511e93 100644 --- a/page_test.go +++ b/page_test.go @@ -920,9 +920,7 @@ func TestPageTriggerFavicon(t *testing.T) { func(e *proto.NetworkRequestWillBeSent) { if e.Request.URL == "https://github.githubassets.com/favicons/favicon.png" { g.Eq(e.Request.URL, "https://github.githubassets.com/favicons/favicon.png") - return } - return }, )() page.MustTriggerFavicon() From b956d384448fb61eb5c985fcc8d0413200f31e7d Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 12:43:33 +0800 Subject: [PATCH 04/16] fix cli error --- page_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/page_test.go b/page_test.go index a9511e93..33e2fd79 100644 --- a/page_test.go +++ b/page_test.go @@ -901,7 +901,7 @@ func TestPageTriggerFavicon(t *testing.T) { // test browser in no-headless mode with an error { path, _ := launcher.LookPath() - u := launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).Headless(false).MustLaunch() + u := launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16").Headless(false).MustLaunch() browser := rod.New().ControlURL(u).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) page := browser.MustPage("https://example.com") From 5592988069073bf5ba285c1cb185d37eb1be568b Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 12:56:54 +0800 Subject: [PATCH 05/16] fix cli error --- page_test.go | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/page_test.go b/page_test.go index 33e2fd79..2f9e226e 100644 --- a/page_test.go +++ b/page_test.go @@ -9,6 +9,7 @@ import ( "net/http" "os" "path/filepath" + "runtime" "sort" "sync" "testing" @@ -901,9 +902,14 @@ func TestPageTriggerFavicon(t *testing.T) { // test browser in no-headless mode with an error { path, _ := launcher.LookPath() - u := launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16").Headless(false).MustLaunch() + var u *launcher.Launcher + if runtime.GOOS == "darwin" { + u = launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).Headless(false) + } else { + u = launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16").Headless(false) + } - browser := rod.New().ControlURL(u).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) + browser := rod.New().ControlURL(u.MustLaunch()).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) page := browser.MustPage("https://example.com") err := page.TriggerFavicon() g.Eq(err.Error(), "browser is no-headless") From 24d05afaa60790e052ac3850e6932bd0a51629d5 Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 23:21:22 +0800 Subject: [PATCH 06/16] fix cli error --- page_test.go | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/page_test.go b/page_test.go index 2f9e226e..3b9dda57 100644 --- a/page_test.go +++ b/page_test.go @@ -901,19 +901,19 @@ func TestPageTriggerFavicon(t *testing.T) { // test browser in no-headless mode with an error { - path, _ := launcher.LookPath() - var u *launcher.Launcher + var l *launcher.Launcher if runtime.GOOS == "darwin" { - u = launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).Headless(false) + l = launcher.New().Set("proxy-bypass-list", "<-loopback>").Headless(false) } else { - u = launcher.New().Set("proxy-bypass-list", "<-loopback>").Bin(path).XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16").Headless(false) + l = launcher.New().Set("proxy-bypass-list", "<-loopback>").XVFB("--server-num=5", "--server-args=-screen 0 1600x900x16").Headless(false) } - browser := rod.New().ControlURL(u.MustLaunch()).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) + browser := rod.New().ControlURL(l.MustLaunch()).MustConnect().MustIgnoreCertErrors(false).Context(g.Context()) + defer browser.MustClose() + page := browser.MustPage("https://example.com") err := page.TriggerFavicon() g.Eq(err.Error(), "browser is no-headless") - g.Eq(browser.Close(), nil) } // test browser in headless mode to trigger favicon request From bae8d24a987e88af81d555578d054cb3150636aa Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sat, 27 May 2023 23:49:38 +0800 Subject: [PATCH 07/16] fix cli error --- page_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/page_test.go b/page_test.go index 3b9dda57..729e9c9f 100644 --- a/page_test.go +++ b/page_test.go @@ -920,6 +920,8 @@ func TestPageTriggerFavicon(t *testing.T) { { page := g.page page.EnableDomain(proto.NetworkEnable{}) + defer page.DisableDomain(proto.NetworkDisable{})() + page.MustNavigate("https://github.com") page.MustWaitIdle() go page.Context(g.Context()).EachEvent( From 407903480fb3ccbadd711028f337aaef45ea43fa Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Sun, 28 May 2023 20:20:32 +0800 Subject: [PATCH 08/16] Rollback SetBlockedURLs's test --- page_test.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/page_test.go b/page_test.go index 729e9c9f..f8921258 100644 --- a/page_test.go +++ b/page_test.go @@ -82,14 +82,14 @@ func TestSetBlockedURLs(t *testing.T) { var urlsPattern = []string{} page.EnableDomain(proto.NetworkEnable{}) page.MustSetBlockedURLs(urlsPattern...) - urlsPattern = append(urlsPattern, "*.com") + urlsPattern = append(urlsPattern, "*.js") page.MustSetBlockedURLs(urlsPattern...) - go page.Context(g.Context()).EachEvent( + go page.EachEvent( func(e *proto.NetworkLoadingFailed) { g.Eq(e.BlockedReason, proto.NetworkBlockedReasonInspector) }, - )() - page.MustNavigate("https://example.com") + ) + page.MustNavigate("https://github.com") } func TestSetExtraHeaders(t *testing.T) { From 3de81cb190be031fce958d969a4c08a28395a52a Mon Sep 17 00:00:00 2001 From: Yad Smood Date: Thu, 1 Jun 2023 01:23:37 +0800 Subject: [PATCH 09/16] reduce noise --- lib/docker/dev.Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/docker/dev.Dockerfile b/lib/docker/dev.Dockerfile index b1754eb0..1496544e 100644 --- a/lib/docker/dev.Dockerfile +++ b/lib/docker/dev.Dockerfile @@ -9,7 +9,7 @@ ARG golang ARG apt_sources="http://archive.ubuntu.com" RUN sed -i "s|http://archive.ubuntu.com|$apt_sources|g" /etc/apt/sources.list && \ - apt-get update && apt-get install --no-install-recommends -y git curl xz-utils build-essential && \ + apt-get -qq update && apt-get -qq install --no-install-recommends -y git curl xz-utils build-essential && \ rm -rf /var/lib/apt/lists/* # install nodejs From 0efc6d0e657c44786fb917e3d742837fe51f4a7c Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Thu, 1 Jun 2023 14:17:38 +0800 Subject: [PATCH 10/16] Rollback other change 1.suggest in `go run ./lib/js/generate` add step "npx -ys -- eslint@8.7.0 --config=lib/utils/lint/eslint.yml --ext=.js,.html --fix --ignore-path=.gitignore ." --- lib/js/helper.go | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/lib/js/helper.go b/lib/js/helper.go index be689433..9aa2aeaf 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -25,14 +25,14 @@ var ElementX = &Function{ // ElementsX ... var ElementsX = &Function{ Name: "elementsX", - Definition: `function(e){var t,n=functions.selectable(this);const r=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),i=[];for(;t=r.iterateNext();)i.push(t);return i}`, + Definition: `function(e){var t,n=functions.selectable(this);const i=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),r=[];for(;t=i.iterateNext();)r.push(t);return r}`, Dependencies: []*Function{Selectable}, } // ElementR ... var ElementR = &Function{ Name: "elementR", - Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),r=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const i=functions.selectable(this);e=Array.from(i.querySelectorAll(e)).find(e=>r.test(functions.text.call(e)));return e||null}`, + Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),i=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const r=functions.selectable(this);e=Array.from(r.querySelectorAll(e)).find(e=>i.test(functions.text.call(e)));return e||null}`, Dependencies: []*Function{Selectable, Text}, } @@ -53,14 +53,14 @@ var ContainsElement = &Function{ // InitMouseTracer ... var InitMouseTracer = &Function{ Name: "initMouseTracer", - Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const r=n.lastChild;r.id=e,r.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",r.removeAttribute("width"),r.removeAttribute("height"),document.body.parentElement.appendChild(r)}}`, + Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const i=n.lastChild;i.id=e,i.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",i.removeAttribute("width"),i.removeAttribute("height"),document.body.parentElement.appendChild(i)}}`, Dependencies: []*Function{WaitLoad}, } // UpdateMouseTracer ... var UpdateMouseTracer = &Function{ Name: "updateMouseTracer", - Definition: `function(e,t,n){const r=document.getElementById(e);return!!r&&(r.style.left=t-2+"px",r.style.top=n-3+"px",!0)}`, + Definition: `function(e,t,n){const i=document.getElementById(e);return!!i&&(i.style.left=t-2+"px",i.style.top=n-3+"px",!0)}`, Dependencies: []*Function{}, } @@ -74,22 +74,22 @@ var Rect = &Function{ // Overlay ... var Overlay = &Function{ Name: "overlay", - Definition: `async function(e,t,n,r,i,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; + Definition: `async function(e,t,n,i,r,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; border-radius: 3px; box-shadow: #5f3232 0 0 3px; pointer-events: none; box-sizing: border-box; left: ${t}px; top: ${n}px; - height: ${i}px; - width: ${r}px;` + "`" + `,r*i==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; + height: ${r}px; + width: ${i}px;` + "`" + `,i*r==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; box-shadow: #333 0 0 3px; padding: 2px 5px; border-radius: 3px; white-space: nowrap; - top: ${i}px;` + "`" + `,a.innerHTML=o,s.appendChild(a),document.body.parentElement.appendChild(s),window.innerHeight{const e=document.getElementById(n);var t;null!==e&&(t=i.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,r))};setTimeout(s,r)}`, + Definition: `async function(n,e){const i=100,r=functions.tag(this);let o=r.getBoundingClientRect();await functions.overlay(n,o.left,o.top,o.width,o.height,e);const s=()=>{const e=document.getElementById(n);var t;null!==e&&(t=r.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,i))};setTimeout(s,i)}`, Dependencies: []*Function{Tag, Overlay}, } @@ -124,7 +124,7 @@ var InputEvent = &Function{ // InputTime ... var InputTime = &Function{ Name: "inputTime", - Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),r=e(t.getMonth()+1),i=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${r}-` + "`" + `+i;break;case"datetime-local":this.value=n+` + "`" + `-${r}-${i}T${o}:` + "`" + `+s;break;case"month":this.value=r;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, + Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),i=e(t.getMonth()+1),r=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${i}-` + "`" + `+r;break;case"datetime-local":this.value=n+` + "`" + `-${i}-${r}T${o}:` + "`" + `+s;break;case"month":this.value=i;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, Dependencies: []*Function{InputEvent}, } @@ -152,7 +152,7 @@ var SelectAllText = &Function{ // Select ... var Select = &Function{ Name: "select", - Definition: `function(e,n,t){let r;switch(t){case"regex":r=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":r=e.map(t=>e=>e.matches(t));break;default:r=e.map(t=>e=>e.innerText.includes(t))}const i=Array.from(this.options);let o=!1;return r.forEach(e=>{const t=i.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, + Definition: `function(e,n,t){let i;switch(t){case"regex":i=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":i=e.map(t=>e=>e.matches(t));break;default:i=e.map(t=>e=>e.innerText.includes(t))}const r=Array.from(this.options);let o=!1;return i.forEach(e=>{const t=r.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, Dependencies: []*Function{}, } @@ -187,14 +187,14 @@ var Resource = &Function{ // AddScriptTag ... var AddScriptTag = &Function{ Name: "addScriptTag", - Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n=document.createElement("script");i?(n.src=i,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=r,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n=document.createElement("script");r?(n.src=r,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=i,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } // AddStyleTag ... var AddStyleTag = &Function{ Name: "addStyleTag", - Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n;i?((n=document.createElement("link")).rel="stylesheet",n.href=i):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=r,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n;r?((n=document.createElement("link")).rel="stylesheet",n.href=r):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=i,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } @@ -215,13 +215,13 @@ var Tag = &Function{ // ExposeFunc ... var ExposeFunc = &Function{ Name: "exposeFunc", - Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,r)=>{const i=t+"_cb"+o++;window[i]=(e,t)=>{delete window[i],t?r(t):n(e)},window[t](JSON.stringify({req:e,cb:i}))})}`, + Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,i)=>{const r=t+"_cb"+o++;window[r]=(e,t)=>{delete window[r],t?i(t):n(e)},window[t](JSON.stringify({req:e,cb:r}))})}`, Dependencies: []*Function{}, } // GetXPath ... var GetXPath = &Function{ Name: "getXPath", - Definition: `function(e){class i{constructor(e,t){this.value=e,this.optimized=t||!1}toString(){return this.value}}function o(t){function n(e,t){return e===t||(e.nodeType===Node.ELEMENT_NODE&&t.nodeType===Node.ELEMENT_NODE?e.localName===t.localName:e.nodeType===t.nodeType||(e.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:e.nodeType)===(t.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:t.nodeType))}var e=t.parentNode,r=e?e.children:null;if(!r)return 0;let i;for(let e=0;e Date: Thu, 1 Jun 2023 14:34:10 +0800 Subject: [PATCH 11/16] fix cli error and mod message --- lib/js/helper.go | 2 +- lib/js/helper.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/js/helper.go b/lib/js/helper.go index 9aa2aeaf..9aee8bdb 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -138,7 +138,7 @@ var SelectText = &Function{ // TriggerFavicon ... var TriggerFavicon = &Function{ Name: "triggerFavicon", - Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString();const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText})},r.send()})}`, + Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString();const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText})},r.send()})}`, Dependencies: []*Function{}, } diff --git a/lib/js/helper.js b/lib/js/helper.js index 7e2d8965..73e9d6ef 100644 --- a/lib/js/helper.js +++ b/lib/js/helper.js @@ -277,7 +277,8 @@ const functions = { errorType: 'status_error', xhr: xhr, status: xhr.status, - statusText: xhr.statusText + statusText: xhr.statusText, + responseText: xhr.responseText }) } } @@ -288,7 +289,8 @@ const functions = { errorType: 'onerror', xhr: xhr, status: xhr.status, - statusText: xhr.statusText + statusText: xhr.statusText, + responseText: xhr.responseText }) } xhr.send() From 9b8fa61d261bd8cb91e9f12fb326bbe1491eed76 Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Thu, 1 Jun 2023 17:45:43 +0800 Subject: [PATCH 12/16] fix cli error --- lib/js/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/helper.go b/lib/js/helper.go index 9aee8bdb..f081df6b 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -138,7 +138,7 @@ var SelectText = &Function{ // TriggerFavicon ... var TriggerFavicon = &Function{ Name: "triggerFavicon", - Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString();const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText})},r.send()})}`, + Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString(); const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText})},r.send()})}`, Dependencies: []*Function{}, } From c80f42b73b6efab83b4e50cd35aac83d2861af56 Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Thu, 1 Jun 2023 21:00:08 +0800 Subject: [PATCH 13/16] fix cli err --- lib/js/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/helper.go b/lib/js/helper.go index f081df6b..9aee8bdb 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -138,7 +138,7 @@ var SelectText = &Function{ // TriggerFavicon ... var TriggerFavicon = &Function{ Name: "triggerFavicon", - Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString(); const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText})},r.send()})}`, + Definition: `function(){return new Promise((e,t)=>{var n=document.querySelector("link[rel~=icon]"),n=n&&n.href||"/favicon.ico",n=new URL(n,window.location).toString();const r=new XMLHttpRequest;r.open("GET",n),r.ontimeout=function(){t({errorType:"timeout_error",xhr:r})},r.onreadystatechange=function(){4===r.readyState&&(200<=r.status&&r.status<300||304===r.status?e(r.responseText):t({errorType:"status_error",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText}))},r.onerror=function(){t({errorType:"onerror",xhr:r,status:r.status,statusText:r.statusText,responseText:r.responseText})},r.send()})}`, Dependencies: []*Function{}, } From ae7175239de7709ac6b49b033fa877679330f780 Mon Sep 17 00:00:00 2001 From: BUG-Fly <1252811289@qq.com> Date: Thu, 1 Jun 2023 21:06:10 +0800 Subject: [PATCH 14/16] fix cli err --- lib/js/helper.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/js/helper.go b/lib/js/helper.go index 9aee8bdb..47bcf39e 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -224,4 +224,4 @@ var GetXPath = &Function{ Name: "getXPath", Definition: `function(e){class r{constructor(e,t){this.value=e,this.optimized=t||!1}toString(){return this.value}}function o(t){function n(e,t){return e===t||(e.nodeType===Node.ELEMENT_NODE&&t.nodeType===Node.ELEMENT_NODE?e.localName===t.localName:e.nodeType===t.nodeType||(e.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:e.nodeType)===(t.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:t.nodeType))}var e=t.parentNode,i=e?e.children:null;if(!i)return 0;let r;for(let e=0;e Date: Thu, 1 Jun 2023 21:16:41 +0800 Subject: [PATCH 15/16] fix cli err and lint js step --- lib/js/generate/main.go | 2 ++ lib/js/helper.go | 32 ++++++++++++++++---------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/lib/js/generate/main.go b/lib/js/generate/main.go index 92a60f77..981c1019 100644 --- a/lib/js/generate/main.go +++ b/lib/js/generate/main.go @@ -56,6 +56,8 @@ func fnName(name string) string { } func getList() gson.JSON { + utils.Exec("npx -ys -- eslint@8.7.0 --config=lib/utils/lint/eslint.yml --ext=.js,.html --fix --ignore-path=.gitignore .") + code := utils.ExecLine(false, "npx -ys -- uglify-js@3.14.5 -c -m -- lib/js/helper.js") script := fmt.Sprintf(` diff --git a/lib/js/helper.go b/lib/js/helper.go index 47bcf39e..50c7995d 100644 --- a/lib/js/helper.go +++ b/lib/js/helper.go @@ -25,14 +25,14 @@ var ElementX = &Function{ // ElementsX ... var ElementsX = &Function{ Name: "elementsX", - Definition: `function(e){var t,n=functions.selectable(this);const i=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),r=[];for(;t=i.iterateNext();)r.push(t);return r}`, + Definition: `function(e){var t,n=functions.selectable(this);const r=document.evaluate(e,n,null,XPathResult.ORDERED_NODE_ITERATOR_TYPE),i=[];for(;t=r.iterateNext();)i.push(t);return i}`, Dependencies: []*Function{Selectable}, } // ElementR ... var ElementR = &Function{ Name: "elementR", - Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),i=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const r=functions.selectable(this);e=Array.from(r.querySelectorAll(e)).find(e=>i.test(functions.text.call(e)));return e||null}`, + Definition: `function(e,t){var n=t.match(/(\/?)(.+)\1([a-z]*)/i),r=n[3]&&!/^(?!.*?(.).*?\1)[gmixXsuUAJ]+$/.test(n[3])?new RegExp(t):new RegExp(n[2],n[3]);const i=functions.selectable(this);e=Array.from(i.querySelectorAll(e)).find(e=>r.test(functions.text.call(e)));return e||null}`, Dependencies: []*Function{Selectable, Text}, } @@ -53,14 +53,14 @@ var ContainsElement = &Function{ // InitMouseTracer ... var InitMouseTracer = &Function{ Name: "initMouseTracer", - Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const i=n.lastChild;i.id=e,i.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",i.removeAttribute("width"),i.removeAttribute("height"),document.body.parentElement.appendChild(i)}}`, + Definition: `async function(e,t){if(await functions.waitLoad(),!document.getElementById(e)){const n=document.createElement("div");n.innerHTML=t;const r=n.lastChild;r.id=e,r.style="position: absolute; z-index: 2147483647; width: 17px; pointer-events: none;",r.removeAttribute("width"),r.removeAttribute("height"),document.body.parentElement.appendChild(r)}}`, Dependencies: []*Function{WaitLoad}, } // UpdateMouseTracer ... var UpdateMouseTracer = &Function{ Name: "updateMouseTracer", - Definition: `function(e,t,n){const i=document.getElementById(e);return!!i&&(i.style.left=t-2+"px",i.style.top=n-3+"px",!0)}`, + Definition: `function(e,t,n){const r=document.getElementById(e);return!!r&&(r.style.left=t-2+"px",r.style.top=n-3+"px",!0)}`, Dependencies: []*Function{}, } @@ -74,22 +74,22 @@ var Rect = &Function{ // Overlay ... var Overlay = &Function{ Name: "overlay", - Definition: `async function(e,t,n,i,r,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; + Definition: `async function(e,t,n,r,i,o){await functions.waitLoad();const s=document.createElement("div");if(s.id=e,s.style=` + "`" + `position: fixed; z-index:2147483647; border: 2px dashed red; border-radius: 3px; box-shadow: #5f3232 0 0 3px; pointer-events: none; box-sizing: border-box; left: ${t}px; top: ${n}px; - height: ${r}px; - width: ${i}px;` + "`" + `,i*r==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; + height: ${i}px; + width: ${r}px;` + "`" + `,r*i==0&&(s.style.border="none"),o){const a=document.createElement("div");a.style=` + "`" + `position: absolute; color: #cc26d6; font-size: 12px; background: #ffffffeb; box-shadow: #333 0 0 3px; padding: 2px 5px; border-radius: 3px; white-space: nowrap; - top: ${r}px;` + "`" + `,a.innerHTML=o,s.appendChild(a),document.body.parentElement.appendChild(s),window.innerHeight{const e=document.getElementById(n);var t;null!==e&&(t=r.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,i))};setTimeout(s,i)}`, + Definition: `async function(n,e){const r=100,i=functions.tag(this);let o=i.getBoundingClientRect();await functions.overlay(n,o.left,o.top,o.width,o.height,e);const s=()=>{const e=document.getElementById(n);var t;null!==e&&(t=i.getBoundingClientRect(),o.left===t.left&&o.top===t.top&&o.width===t.width&&o.height===t.height||(e.style.left=t.left+"px",e.style.top=t.top+"px",e.style.width=t.width+"px",e.style.height=t.height+"px",o=t),setTimeout(s,r))};setTimeout(s,r)}`, Dependencies: []*Function{Tag, Overlay}, } @@ -124,7 +124,7 @@ var InputEvent = &Function{ // InputTime ... var InputTime = &Function{ Name: "inputTime", - Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),i=e(t.getMonth()+1),r=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${i}-` + "`" + `+r;break;case"datetime-local":this.value=n+` + "`" + `-${i}-${r}T${o}:` + "`" + `+s;break;case"month":this.value=i;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, + Definition: `function(e){const t=new Date(e);var e=e=>e.toString().padStart(2,"0"),n=t.getFullYear(),r=e(t.getMonth()+1),i=e(t.getDate()),o=e(t.getHours()),s=e(t.getMinutes());switch(this.type){case"date":this.value=n+` + "`" + `-${r}-` + "`" + `+i;break;case"datetime-local":this.value=n+` + "`" + `-${r}-${i}T${o}:` + "`" + `+s;break;case"month":this.value=r;break;case"time":this.value=o+":"+s}functions.inputEvent.call(this)}`, Dependencies: []*Function{InputEvent}, } @@ -152,7 +152,7 @@ var SelectAllText = &Function{ // Select ... var Select = &Function{ Name: "select", - Definition: `function(e,n,t){let i;switch(t){case"regex":i=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":i=e.map(t=>e=>e.matches(t));break;default:i=e.map(t=>e=>e.innerText.includes(t))}const r=Array.from(this.options);let o=!1;return i.forEach(e=>{const t=r.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, + Definition: `function(e,n,t){let r;switch(t){case"regex":r=e.map(e=>{const t=new RegExp(e);return e=>t.test(e.innerText)});break;case"css-selector":r=e.map(t=>e=>e.matches(t));break;default:r=e.map(t=>e=>e.innerText.includes(t))}const i=Array.from(this.options);let o=!1;return r.forEach(e=>{const t=i.find(e);t&&(t.selected=n,o=!0)}),this.dispatchEvent(new Event("input",{bubbles:!0})),this.dispatchEvent(new Event("change",{bubbles:!0})),o}`, Dependencies: []*Function{}, } @@ -187,14 +187,14 @@ var Resource = &Function{ // AddScriptTag ... var AddScriptTag = &Function{ Name: "addScriptTag", - Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n=document.createElement("script");r?(n.src=r,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=i,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n=document.createElement("script");i?(n.src=i,n.onload=e):(n.type="text/javascript",n.text=o,e()),n.id=r,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } // AddStyleTag ... var AddStyleTag = &Function{ Name: "addStyleTag", - Definition: `function(i,r,o){if(!document.getElementById(i))return new Promise((e,t)=>{var n;r?((n=document.createElement("link")).rel="stylesheet",n.href=r):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=i,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, + Definition: `function(r,i,o){if(!document.getElementById(r))return new Promise((e,t)=>{var n;i?((n=document.createElement("link")).rel="stylesheet",n.href=i):((n=document.createElement("style")).type="text/css",n.appendChild(document.createTextNode(o)),e()),n.id=r,n.onload=e,n.onerror=t,document.head.appendChild(n)})}`, Dependencies: []*Function{}, } @@ -215,13 +215,13 @@ var Tag = &Function{ // ExposeFunc ... var ExposeFunc = &Function{ Name: "exposeFunc", - Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,i)=>{const r=t+"_cb"+o++;window[r]=(e,t)=>{delete window[r],t?i(t):n(e)},window[t](JSON.stringify({req:e,cb:r}))})}`, + Definition: `function(e,t){let o=0;window[e]=e=>new Promise((n,r)=>{const i=t+"_cb"+o++;window[i]=(e,t)=>{delete window[i],t?r(t):n(e)},window[t](JSON.stringify({req:e,cb:i}))})}`, Dependencies: []*Function{}, } // GetXPath ... var GetXPath = &Function{ Name: "getXPath", - Definition: `function(e){class r{constructor(e,t){this.value=e,this.optimized=t||!1}toString(){return this.value}}function o(t){function n(e,t){return e===t||(e.nodeType===Node.ELEMENT_NODE&&t.nodeType===Node.ELEMENT_NODE?e.localName===t.localName:e.nodeType===t.nodeType||(e.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:e.nodeType)===(t.nodeType===Node.CDATA_SECTION_NODE?Node.TEXT_NODE:t.nodeType))}var e=t.parentNode,i=e?e.children:null;if(!i)return 0;let r;for(let e=0;e Date: Thu, 1 Jun 2023 22:27:22 +0800 Subject: [PATCH 16/16] remove lint js step --- lib/js/generate/main.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/js/generate/main.go b/lib/js/generate/main.go index 981c1019..92a60f77 100644 --- a/lib/js/generate/main.go +++ b/lib/js/generate/main.go @@ -56,8 +56,6 @@ func fnName(name string) string { } func getList() gson.JSON { - utils.Exec("npx -ys -- eslint@8.7.0 --config=lib/utils/lint/eslint.yml --ext=.js,.html --fix --ignore-path=.gitignore .") - code := utils.ExecLine(false, "npx -ys -- uglify-js@3.14.5 -c -m -- lib/js/helper.js") script := fmt.Sprintf(`