a temporary webpage for video thumbnail(s)

Post your working scripts, libraries and tools for AHK v1.1 and older
SundayProgrammer
Posts: 143
Joined: 25 Dec 2020, 12:26

a temporary webpage for video thumbnail(s)

Post by SundayProgrammer » 21 Jul 2022, 10:58

Code: Select all

;samples
Clipboard=
(
Why Does Scrum Make Programmers HATE Coding?	https://i.ytimg.com/an_webp/HURvJDldVGA/mqdefault_6s.webp?du=3000&sqp=CICH5ZYG&rs=AOn4CLAR4oRIegMsvGdr_dYwwCw8s2vR-w
Simple AutoHotkey to Chrome Part 1 - No Selenium, no debug mode, AutoControl.	https://i.ytimg.com/vi/gr4z0Xw8W2g/hq720.jpg?sqp=-oaymwEcCOgCEMoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCHR_8s9erIADZiJKlDm4X1_-bL6g
JavaScript Tutorial for Beginners - 01 - Introduction	https://www.dailymotion.com/video/x3vgtnf	https://s2.dmcdn.net/v/DzcKR1MrtYKSNdxXv/x240
Javascript & JQuery - Chapter 8 - JQuery Events and Effects	https://www.dailymotion.com/video/x27kfyz	https://s2.dmcdn.net/v/7zppR1KcevK9bh_M4/x240
HTML, CSS, JavaScript Explained [in 4 minutes for beginners]	https://i.ytimg.com/an_webp/gT0Lh1eYk78/mqdefault_6s.webp?du=3000&sqp=CJXK5JYG&rs=AOn4CLCBhqPS3f0_nhkzbgBcs1_rB9ZXKQ
a fresh new web framework is out	https://i.ytimg.com/an_webp/4boXExbbGCk/mqdefault_6s.webp?du=3000&sqp=CNz65JYG&rs=AOn4CLCyoJsF2MdmMRJm-uDRz8opzNsFvw
)

browserexe = msedge.exe

IfWinExist, ahk_exe %browserexe%
	WinActivate
Else Run, %browserexe%
WinWaitActive, ahk_exe %browserexe%

ClipSave(True), Clipboard := genWebpageCode(Clipboard)
IfWinActive, ahk_exe %browserexe%
{	Send, ^l
	If AddressBarWaitFocused(9)
	{	Send, j^v{Enter}
		Sleep, 1000
		ClipSave(False)
	}Else MsgBox, Oops...
}ExitApp

genWebpageCode(theList) {	; generate the code for opening up a temporary webpage which hosts the video thumbnail(s) that interested you
	theList := StrReplace(theList, "'", "'")
	Loop, Parse, theList, `n
		If pos := InStr(A_LoopField, "`t")
		{	If SubStr(A_LoopField, 1, 1) = ";"
				Continue
			If StrReplace(A_LoopField, "`t",, c) and c = 1
			{	RegExMatch(A_LoopField, "/(an_webp|vi)/([^/]+)/", m), url := "https://www.youtube.com/watch?v=" m2, imgurl := "https://img.youtube.com/vi/" m2 "/mqdefault.jpg", img2url := StrReplace(SubStr(A_LoopField, pos + 1), "`r")
				If InStr(img2url, "/vi/") or SubStr(WebRead(img2url), 1, 5) == "RIFF "
					img2url := imgurl
			}Else url := SubStr(A_LoopField, pos + 1, InStr(SubStr(A_LoopField, pos + 1), "`t") - 1), imgurl := StrReplace(SubStr(A_LoopField, InStr(A_LoopField, "`t",, pos + 1) + 1), "`r"), img2url := imgurl
			t := SubStr(A_LoopField, 1, pos - 1)
			theCode .= "<div id=""dismissible"" class=""thumb-block""><div><div class=""thumbnail""><a href=""" url """><img src=""" imgurl """><img src=""" img2url """></a></div><div class=""thumbtext""><a href=""" url """>" t "</a></div></div></div>`n"
		}
	theCode := "avascript: {var newWin = window.open(); newWin.document.write('<title>YouTube and/or other videos</title>`n<base target=""_blank"">`n<style>`nbody{background-color:black}`n.thumb-block{display:inline-flex;flex-flow:column;padding:0px 0px 5px 0px}`n.thumb-block div{background-color:ffebc3}`n.thumbnail{width:100%;height:100%;padding:5px -5px 0px 5px;display:inline-block;position:relative}`na img:last-child{display:none}a:hover img:last-child{display:block}a:hover img:first-child{display:none}`n.delete{position:absolute;top:0px;right:0px;width:50px;height:50px}`na #bttn{display:none}a:hover #bttn{display:block}`n.thumbtext{display:flex;font-size:18pt;color:white;padding:0px 5px 5px 5px}`n.thumbtext a{flex-grow:1;width:0}`n</style>`n<body>`n" theCode "<script>var t=Array.from(document.getElementsByClassName(""thumbnail""));`nfor (var i=0;i<t.length;i++){`nvar x=document.createElement(""img"");`nx.setAttribute(""class"",""delete"");`nx.setAttribute(""onclick"",""document.querySelector(\'a:hover\').closest(\'#dismissible\').remove();return false"");`nx.setAttribute(""src"",""https://cdn.iconscout.com/icon/free/png-128/delete-4393995-3644065.png"");`nx.setAttribute(""id"",""bttn"");`nt[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`n}`n</script>`n</body>')}"
	Return theCode
}

AddressBarWaitFocused(maxTolsec) {
	beg := A_TickCount
	While, not AddressBarFocused() and A_TickCount - beg < maxTolsec * 1000
		Continue
	Return AddressBarFocused()
}
AddressBarFocused() {
	Return GetFocusedElement().Name = "Address and search bar"
}
GetFocusedElement() {	; based on the script written by Descolada (https://www.autohotkey.com/boards/viewtopic.php?p=459451&sid=dde6b407875aadff59bc35e0864f63e4#p459451)
	IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
	DllCall(NumGet(NumGet(IUIAutomation+0)+8*A_PtrSize), "ptr",IUIAutomation, "ptr*",element)	;IUIAutomation::GetFocusedElement
	DllCall(NumGet(NumGet(element+0)+23*A_PtrSize), "ptr", element, "ptr*", name)	;IUIAutomationElement::CurrentName
	DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "uint",30045, "ptr", (VarSetCapacity(val,8+2*A_PtrSize)+NumPut(0,val,0,"short")+NumPut(0,val,8,"ptr"))*0+&val)	;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(element)
	ObjRelease(IUIAutomation)
	Return {"Name":StrGet(name,"utf-16"), "Value":StrGet(NumGet(val,8,"ptr"),"utf-16")}
}
ClipSave(Yes) {
	static ClipSave
	If Yes
		ClipSave := ClipboardAll
	Else Clipboard := ClipSave
}
WebRead(theUrl) {	; from autohotkey documentation example
	; Example: Download text to a variable:
	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", theUrl, true)
	whr.Send()
	; Using 'true' above and the call below allows the script to remain responsive.
	whr.WaitForResponse()
	return whr.ResponseText
}
edited on 2022-July-21: i noticed that youtube video preview-on-hover url will be outdated (and i don't want to bother updating it), so i added a fix to avoid the unwanted pitfall which happened when the preview link is no longer fresh.
edited on 2022-July-22: minor adjustment
2022-8-13 edited: added <base target="_blank">
2022-8-14 edited: added a delete feature
2022-8-17 edited: made an adjustment to have the delete button shown only on hover.

related post
Last edited by SundayProgrammer on 17 Aug 2022, 05:24, edited 4 times in total.

AHKStudent
Posts: 1472
Joined: 05 May 2018, 12:23

Re: a temporary webpage for video thumbnail(s)

Post by AHKStudent » 22 Jul 2022, 00:46

what does this script do?

SundayProgrammer
Posts: 143
Joined: 25 Dec 2020, 12:26

Re: a temporary webpage for video thumbnail(s)

Post by SundayProgrammer » 22 Jul 2022, 02:17

AHKStudent wrote:
22 Jul 2022, 00:46
what does this script do?
the essential part is the function "genWebpageCode" per se (which generates the code for opening up a temporary webpage which could host the video thumbnail(s) that interested you), everything else is just a quick roundup for demonstration.

two types of line on the list are allowed, one for youtube, and one for non-youtube. (did not make it one universal, because youtube has its own distinct "structure" in links which enables lesser information yet with additional feature.) for non-youtube line, it should have three fields: the 1st field is the "video title", the 2nd field is the "video url", and the 3rd field is the "image url"; whereas, for youtube line, it should have two fields: the 1st field is the "video title", and the 2nd field is the "image url" (it could be a preview-on-hover url if at all available). field-delimiter is tab, ie chr(9); whereas record-delimiter is apparently new-line, chr(10) alone, or both chr(13) and chr(10). line(s) without tab character will be ignored; and, a semi-colon on the first position of the line, even though it has tab character(s), will also be ignored.

that's pretty much it. don't know what else need to tell.

AHKStudent
Posts: 1472
Joined: 05 May 2018, 12:23

Re: a temporary webpage for video thumbnail(s)

Post by AHKStudent » 22 Jul 2022, 06:24

SundayProgrammer wrote:
22 Jul 2022, 02:17
AHKStudent wrote:
22 Jul 2022, 00:46
what does this script do?
the essential part is the function "genWebpageCode" per se (which generates the code for opening up a temporary webpage which could host the video thumbnail(s) that interested you), everything else is just a quick roundup for demonstration.

two types of line on the list are allowed, one for youtube, and one for non-youtube. (did not make it one universal, because youtube has its own distinct "structure" in links which enables lesser information yet with additional feature.) for non-youtube line, it should have three fields: the 1st field is the "video title", the 2nd field is the "video url", and the 3rd field is the "image url"; whereas, for youtube line, it should have two fields: the 1st field is the "video title", and the 2nd field is the "image url" (it could be a preview-on-hover url if at all available). field-delimiter is tab, ie chr(9); whereas record-delimiter is apparently new-line, chr(10) alone, or both chr(13) and chr(10). line(s) without tab character will be ignored; and, a semi-colon on the first position of the line, even though it has tab character(s), will also be ignored.

that's pretty much it. don't know what else need to tell.
thanks I'll check it out :thumbup:

SundayProgrammer
Posts: 143
Joined: 25 Dec 2020, 12:26

Re: a temporary webpage for video thumbnail(s)

Post by SundayProgrammer » 01 Aug 2022, 05:28

added a feature in this version, enabled user to rearrange the sequential order of the thumbnails by drag&drop.

how to use: drag a thumbnail to a position occupied by another. upon drop, the dragged one will take that position, and the rest will shift.

Code: Select all

;samples
Clipboard=
(
Why Does Scrum Make Programmers HATE Coding?	https://i.ytimg.com/an_webp/HURvJDldVGA/mqdefault_6s.webp?du=3000&sqp=CICH5ZYG&rs=AOn4CLAR4oRIegMsvGdr_dYwwCw8s2vR-w
Simple AutoHotkey to Chrome Part 1 - No Selenium, no debug mode, AutoControl.	https://i.ytimg.com/vi/gr4z0Xw8W2g/hq720.jpg?sqp=-oaymwEcCOgCEMoBSFXyq4qpAw4IARUAAIhCGAFwAcABBg==&rs=AOn4CLCHR_8s9erIADZiJKlDm4X1_-bL6g
JavaScript Tutorial for Beginners - 01 - Introduction	https://www.dailymotion.com/video/x3vgtnf	https://s2.dmcdn.net/v/DzcKR1MrtYKSNdxXv/x240
Javascript & JQuery - Chapter 8 - JQuery Events and Effects	https://www.dailymotion.com/video/x27kfyz	https://s2.dmcdn.net/v/7zppR1KcevK9bh_M4/x240
HTML, CSS, JavaScript Explained [in 4 minutes for beginners]	https://i.ytimg.com/an_webp/gT0Lh1eYk78/mqdefault_6s.webp?du=3000&sqp=CJXK5JYG&rs=AOn4CLCBhqPS3f0_nhkzbgBcs1_rB9ZXKQ
a fresh new web framework is out	https://i.ytimg.com/an_webp/4boXExbbGCk/mqdefault_6s.webp?du=3000&sqp=CNz65JYG&rs=AOn4CLCyoJsF2MdmMRJm-uDRz8opzNsFvw
)

browserexe = msedge.exe

IfWinExist, ahk_exe %browserexe%
	WinActivate
Else Run, %browserexe%
WinWaitActive, ahk_exe %browserexe%

ClipSave(True), Clipboard := genWebpageCode(Clipboard)
IfWinActive, ahk_exe %browserexe%
{	Send, ^l
	If AddressBarWaitFocused(9)
	{	Send, j^v{Enter}
		Sleep, 1000
		ClipSave(False)
	}Else MsgBox, Oops...
}ExitApp

genWebpageCode(theList) {	; generate the code for opening up a temporary webpage which hosts the video thumbnail(s) that interested you
	theList := StrReplace(theList, "'", "&apos;")
	Loop, Parse, theList, `n
		If pos := InStr(A_LoopField, "`t")
		{	If SubStr(A_LoopField, 1, 1) = ";"
				Continue
			If StrReplace(A_LoopField, "`t",, c) and c = 1
			{	RegExMatch(A_LoopField, "/(an_webp|vi)/([^/]+)/", m), url := "https://www.youtube.com/watch?v=" m2, imgurl := "https://img.youtube.com/vi/" m2 "/mqdefault.jpg", img2url := StrReplace(SubStr(A_LoopField, pos + 1), "`r")
				If InStr(img2url, "/vi/") or SubStr(WebRead(img2url), 1, 5) == "RIFF "
					img2url := imgurl
			}Else url := SubStr(A_LoopField, pos + 1, InStr(SubStr(A_LoopField, pos + 1), "`t") - 1), imgurl := StrReplace(SubStr(A_LoopField, InStr(A_LoopField, "`t",, pos + 1) + 1), "`r"), img2url := imgurl
			t := SubStr(A_LoopField, 1, pos - 1)
			theCode .= "<div id=""dismissible"" class=""thumb-block"" ondrop=""drop(event)"" ondragover=""allowDrop(event)""><div class=""thumb-DnD"" ondragstart=""dragStart(event)"" draggable=""true""><div class=""thumbnail""><a href=""" url """><img src=""" imgurl """><img src=""" img2url """></a></div><div class=""thumbtext""><a href=""" url """>" t "</a></div></div></div>`n"
		}
	theCode := "avascript: {var newWin = window.open(); newWin.document.write('<title>YouTube and/or other videos</title>`n<base target=""_blank"">`n<style>`nbody{background-color:black}`n.showSource{position:fixed;top:2px;right:5px;width:50px;height:50px}`n.thumb-block{display:inline-flex;flex-flow:column;padding:0px 0px 5px 0px}`n.thumb-DnD{background-color:ffebc3;padding:5px}`n.thumbnail{width:100%;height:100%;padding:5px -5px 0px 5px;display:inline-block;position:relative}`na img:last-child{display:none}a:hover img:last-child{display:block}a:hover img:first-child{display:none}`n.delete{position:absolute;top:0px;right:0px;width:50px;height:50px}`n.movetoTop{position:absolute;top:0px;left:0px;width:50px;height:50px}`n.movetoBottom{position:absolute;bottom:0px;right:0px;width:50px;height:50px}`na #bttn{display:none}a:hover #bttn{display:block}`n.thumbtext{display:flex;font-size:18pt;color:white;padding:0px 5px 5px 5px}`n.thumbtext a{flex-grow:1;width:0}`n</style>`n<body>`n<div id=""bodyMain"">`n" theCode "</div>`n<img class=""showSource"" onclick=""showSource()"" title=""Show Source"" src=""https://img.icons8.com/external-flaticons-flat-flat-icons/2x/external-sources-history-flaticons-flat-flat-icons.png"">`n<script>`nsessionStorage.sessionID=Math.random();`nvar t=Array.from(document.getElementsByClassName(""thumbnail""));`nfor (var i=0;i<t.length;i++){`nvar x=document.createElement(""img"");`nx.setAttribute(""class"",""delete"");`nx.setAttribute(""onclick"",""removeThumb();return false"");`nx.setAttribute(""src"",""https://cdn.iconscout.com/icon/free/png-128/delete-4393995-3644065.png"");`nx.setAttribute(""id"",""bttn"");`nt[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`nvar x=document.createElement(""img"");`nx.setAttribute(""class"",""movetoTop"");`nx.setAttribute(""onclick"",""movetoTop();return false"");`nx.setAttribute(""src"",""https://img.icons8.com/emoji/2x/top-arrow-emoj.png"");`nx.setAttribute(""id"",""bttn"");`nt[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`nvar x=document.createElement(""img"");`nx.setAttribute(""class"",""movetoBottom"");`nx.setAttribute(""onclick"",""movetoBottom();return false"");`nx.setAttribute(""src"",""https://img.icons8.com/external-others-inmotus-design/2x/external-Down-round-icons-others-inmotus-design-2.png"");`nx.setAttribute(""title"",""Move this thumbnail to the bottom"");`nx.setAttribute(""id"",""bttn"");`nt[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`n}`nfunction removeThumb(){`n	document.querySelector(""a:hover"").closest(""#dismissible"").remove()`n}`nfunction movetoTop(){`n	var thisBlock=document.querySelector(""a:hover"").closest(""#dismissible"");`n	document.getElementById(""bodyMain"").insertBefore(thisBlock,document.getElementById(""bodyMain"").querySelector(""div:first-child""));`n	thisBlock.style.setProperty(""padding-right"",""5px"")`n}`nfunction movetoBottom(){`n	var thisBlock=document.querySelector(""a:hover"").closest(""#dismissible"");`n	document.getElementById(""bodyMain"").insertBefore(thisBlock,document.getElementById(""bodyMain"").querySelector(""div:last-child"").nextSibling);`n	thisBlock.style.setProperty(""padding-left"",""5px"")`n}`nfunction showSource(){`n	var result="""";`n	var tt=Array.from(document.getElementsByClassName(""thumbtext""));`n	var tn=Array.from(document.getElementsByClassName(""thumbnail""));`n	for (var i=0;i<tt.length;i++){`n		var vtit=tt[i].querySelector(""a:first-child"").innerText;`n		var ytvid=tt[i].querySelector(""a:first-child"").href.match(/(?<=\\.youtube\\.com\\/watch\\?v=)[^&\\/]+/i);`n		if (ytvid!==null){`n			var result=result+vtit+""<< tab >>""+tn[i].querySelector(""img:last-child"").src+""<br>""}`n		else{var result=result+vtit+""<< tab >>""+tn[i].querySelector(""a:first-child"").href+""<< tab >>""+tn[i].querySelector(""img:first-child"").src+""<br>""}}`n	window.open().document.write(result)`n}`nfunction dragStart(event){`n	if (event.target.getAttribute(""class"")!==""thumb-block""){`n		var finaltarget=event.target.closest("".thumb-block"")}`n	else{var finaltarget=event.target}`n	if (document.getElementById(""673795646789056767945676"")!==null){`n			document.getElementById(""673795646789056767945676"").id=""""}`n	finaltarget.id=""673795646789056767945676"";`n	event.dataTransfer.setData(""data/id"",finaltarget.id);`n	event.dataTransfer.setData(""data/html"",finaltarget.innerHTML);`n	event.dataTransfer.setData(""data/session"",sessionStorage.sessionID);`n}`nfunction allowDrop(event){`nevent.preventDefault();`n}`nfunction drop(event){`n	event.preventDefault();`n	if (event.target.getAttribute(""class"")!==""thumb-block""){`n		var finaltarget=event.target.closest("".thumb-block"")}`n	else{var finaltarget=event.target}`n	if (event.dataTransfer.getData(""data/session"")===sessionStorage.sessionID){`n		var data=event.dataTransfer.getData(""data/id"");`n		var element=document.getElementById(data);`n		element.id=""dismissible"";`n		if (finaltarget.querySelector(""a"")!==null){`n			element.style.setProperty(""padding-right"",""5px"");`n			document.getElementById(""bodyMain"").insertBefore(element,finaltarget)}`n		else{finaltarget.appendChild(element.querySelector("".thumb-DnD""))}`n	}else{`n		if (event.dataTransfer.getData(""data/html"").length===0){`n			var freedata=event.dataTransfer.getData(""text/html"");`n			if (freedata.length>0){`n				if (freedata.match("" id=\\""mouseover-overlay\\"""")){`n					var imgurl=freedata.match(/(?<=mouseover.+?src="")[^""]+/i);`n					if (imgurl!==null){`n						finaltarget.querySelector(""img:last-child"").src=imgurl.toString().replace(/&amp;/ig,""&"")}`n					return}`n				let ytvid=freedata.match(/(?<=\\.youtube\\.com\\/(?:watch\\?v=|shorts\\/))[^""&\\/]+/i);`n				if (ytvid!==null){`n					var vurl=""https://www.youtube.com/watch?v=""+ytvid;`n					var imgurl=""https://img.youtube.com/vi/""+ytvid+""/mqdefault.jpg"";`n					var vtit=freedata.match(/(?<=aria-label="")[^""]+/i);`n					if (vtit===null){`n						var vtit=freedata.match(/(?<=title="")[^""]+/i);`n						if (vtit===null){var vtit=freedata.match(/(?<=>)[^<]+(?=<\\/a>)/i)}}}`n				else{`n					var vurl=freedata.match(/(?<=href="")[^""]+/i);`n					if (freedata.toString().match(/vimeo\\.com\\//i)!==null){`n						var imgurl=freedata.match(/(?<=<img .*?src="")[^""]+/i);`n						var vtit=freedata.match(/(?<=span title="")[^""]+/ig)}`n					else{`n						if (vurl!==null){`n							var imgurl=""https://img.icons8.com/cotton/2x/grinning-face-with-sweat-icon--v2.png"";`n							var vtit=freedata.match(/(?<=>).+?(?=<\\/a>)/i)}`n						else{`n							var imgurl=freedata.match(/(?<=<img .*?src="")[^""]+/i);`n							finaltarget.querySelector(""img:first-child"").src=imgurl;`n							finaltarget.querySelector(""img:last-child"").src=imgurl;`n							return}}}`n				var data = ""<div class=\\""thumb-DnD\\"" ondragstart=\\""dragStart(event)\\"" draggable=\\""true\\""><div class=\\""thumbnail\\""><a href=\\""""+vurl+""\\""><img src=\\""""+imgurl+""\\""><img class=\\""delete\\"" onclick=\\""removeThumb();return false\\"" src=\\""https://cdn.iconscout.com/icon/free/png-128/delete-4393995-3644065.png\\"" id=\\""bttn\\""><img class=\\""movetoTop\\"" onclick=\\""movetoTop();return false\\"" src=\\""https://img.icons8.com/emoji/2x/top-arrow-emoj.png\\"" id=\\""bttn\\""><img class=\\""movetoBottom\\"" onclick=\\""movetoBottom();return false\\"" src=\\""https://img.icons8.com/external-others-inmotus-design/2x/external-Down-round-icons-others-inmotus-design-2.png\\"" title=\\""Move this thumbnail to the bottom\\"" id=\\""bttn\\""><img src=\\""""+imgurl+""\\""></a></div><div class=\\""thumbtext\\""><a href=\\""""+vurl+""\\"">""+vtit+""</a></div></div>""}}`n		else{var data=event.dataTransfer.getData(""data/html"")}`n		if (finaltarget.querySelector(""a"")!==null){`n			var newBlock=document.createElement(""div"");`n			newBlock.setAttribute(""id"",""dismissible"");`n			newBlock.setAttribute(""class"",""thumb-block"");`n			newBlock.setAttribute(""ondrop"",""drop(event)"");`n			newBlock.setAttribute(""ondragover"",""allowDrop(event)"");`n			newBlock.style.setProperty(""padding-right"",""5px"");`n			document.getElementById(""bodyMain"").insertBefore(newBlock,finaltarget);`n			newBlock.innerHTML=data}`n		else{finaltarget.innerHTML=data}`n	}`n}`n</script>`n</body>')}"
	Return theCode
}

AddressBarWaitFocused(maxTolsec) {
	beg := A_TickCount
	While, not AddressBarFocused() and A_TickCount - beg < maxTolsec * 1000
		Continue
	Return AddressBarFocused()
}
AddressBarFocused() {
	Return GetFocusedElement().Name = "Address and search bar"
}
GetFocusedElement() {	; based on the script written by Descolada (https://www.autohotkey.com/boards/viewtopic.php?p=459451&sid=dde6b407875aadff59bc35e0864f63e4#p459451)
	IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
	DllCall(NumGet(NumGet(IUIAutomation+0)+8*A_PtrSize), "ptr",IUIAutomation, "ptr*",element)	;IUIAutomation::GetFocusedElement
	DllCall(NumGet(NumGet(element+0)+23*A_PtrSize), "ptr", element, "ptr*", name)	;IUIAutomationElement::CurrentName
	DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "uint",30045, "ptr", (VarSetCapacity(val,8+2*A_PtrSize)+NumPut(0,val,0,"short")+NumPut(0,val,8,"ptr"))*0+&val)	;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(element)
	ObjRelease(IUIAutomation)
	Return {"Name":StrGet(name,"utf-16"), "Value":StrGet(NumGet(val,8,"ptr"),"utf-16")}
}
ClipSave(Yes) {
	static ClipSave
	If Yes
		ClipSave := ClipboardAll
	Else Clipboard := ClipSave
}
WebRead(theUrl) {	; from autohotkey documentation example
	; Example: Download text to a variable:
	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", theUrl, true)
	whr.Send()
	; Using 'true' above and the call below allows the script to remain responsive.
	whr.WaitForResponse()
	return whr.ResponseText
}
2022-8-13 edited: added <base target="_blank">
2022-8-14 edited: added a delete feature
2022-8-15 edited: added 2 more features, move thumbnail to the top, and move thumbnail to the bottom.
2022-8-16 added one more feature, enabled user to drag a thumbnail to another webpage (this will become "copy" instead of "move"), provided that both sides have the same drag&drop script working behind the scene that support such operation.
2022-8-17 edited: fixed a bug (produced since the cross webpage drag&drop was implemented), and made an adjustment to have the buttons shown only on hover.
2022-8-21 edited: see this post --> click me
2022-8-22 edited: fixed a bug (produced since the "show source" icon was implemented)
Last edited by SundayProgrammer on 22 Aug 2022, 04:14, edited 8 times in total.

SundayProgrammer
Posts: 143
Joined: 25 Dec 2020, 12:26

Re: a temporary webpage for video thumbnail(s)

Post by SundayProgrammer » 12 Aug 2022, 12:45

added a feature in this version, enabled user to randomly draw some (range from 1 to 50) videos to play in a batch.

how to: use the slider to set the number of videos you want your batch to hold, and hit the red button (at upper-left corner) to play.

note: this feature is all for youtube videos (i hope a red button could more or less remind users), non-youtube videos will all be skipped. if you slide to a number bigger than the total number of videos available, the latter will be applied.

Code: Select all

;samples
Clipboard=
(
Make You Feel My Love - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/GMMSYOXmulA/mqdefault.jpg
All By Myself - Celine Dion - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/4Y1ThLEezys/mqdefault.jpg
The Prayer - Celine Dion & Andrea Bocelli - Lucy & Martha Thomas Cover by Lucy Thomas Music	https://img.youtube.com/vi/kzyi0W2gymA/mqdefault.jpg
Footprints in the Sand - Leona Lewis - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/-kFoiYfrq0M/mqdefault.jpg
Wind Beneath My Wings - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/tYqh4xFSkOk/mqdefault.jpg
Run To You - Whitney Houston - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/FK4scBScMg0/mqdefault.jpg
O Holy Night - Lucy and Martha Thomas by Lucy Thomas Music	https://img.youtube.com/vi/Bbu6AII10Pk/mqdefault.jpg
I Don't Want To Miss A Thing - Aerosmith - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/z_di6262CDE/mqdefault.jpg
Someone You Loved - Lewis Capaldi - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/QjdqqBDhHjI/mqdefault.jpg
Always Remember Us This Way - ("A Star is Born") - Lady Gaga - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/vpgRjShpLCQ/mqdefault.jpg
Can't Help Falling in Love - Elvis Presley - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/0siyVtIxu4M/mqdefault.jpg
I Will Always Love You - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/ETrbRH4F7nE/mqdefault.jpg
At Last - Etta James - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/x1etaSAh0nE/mqdefault.jpg
When You Believe - ("The Prince of Egypt") - Lucy & Martha Thomas Cover by Lucy Thomas Music	https://img.youtube.com/vi/q4SPW9mk2ro/mqdefault.jpg
Over The Rainbow - Eva Cassidy - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/n1JvDqck4sM/mqdefault.jpg
There You'll Be - Faith Hill - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/QC1UABSrIoQ/mqdefault.jpg
Fix You - Coldplay - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/-COUAj4Lbuk/mqdefault.jpg
Hallelujah - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/4hjgkvuKES8/mqdefault.jpg
You Raise Me Up - Cover by Lucy and Martha Thomas by Lucy Thomas Music	https://img.youtube.com/vi/dU00EuczOiA/mqdefault.jpg
Somewhere - (There's A Place For Us) - West Side Story - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/sSlLNSWAXpo/mqdefault.jpg
La Vie En Rose - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/-yI3bOKIZKk/mqdefault.jpg
In The Arms Of An Angel - Sarah McLachlan - Lucy and Martha Thomas Cover by Lucy Thomas Music	https://img.youtube.com/vi/zWPhcG74j84/mqdefault.jpg
Reflection - From Disney's "Mulan" - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/UaJIPYaDlZE/mqdefault.jpg
My Heart Will Go On - Titanic - Celine Dion - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/H-15vIN62PQ/mqdefault.jpg
Hero - Mariah Carey - Cover by Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/i9NtZVt_16k/mqdefault.jpg
Say Something - A Great Big World - Cover by Sisters Lucy and Martha Thomas by Lucy Thomas Music	https://img.youtube.com/vi/rNvbGLhB91M/mqdefault.jpg
Memory - Cats Musical - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/4v-cJX17xy4/mqdefault.jpg
Beautiful Ghosts (From Cats) - Cover by Lucy Thomas, 15 by Lucy Thomas Music	https://img.youtube.com/vi/d54XJ9Rhaiw/mqdefault.jpg
10,000 Hours - Dan + Shay, Justin Bieber - Cover by Lucy Thomas,15 by Lucy Thomas Music	https://img.youtube.com/vi/ln9smh85fi8/mqdefault.jpg
Gentle Breeze - From The Musical "Rosie" - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/cQ21Nsj7Xqw/mqdefault.jpg
Writing's On The Wall - Sam Smith - Cover by Lucy Thomas, 15 by Lucy Thomas Music	https://img.youtube.com/vi/V9hs91W4nSo/mqdefault.jpg
Run - Snow Patrol - Cover by Lucy Thomas, 15 by Lucy Thomas Music	https://img.youtube.com/vi/HTnry6S4vgc/mqdefault.jpg
A Million Dreams - The Greatest Showman - Cover by Lucy Thomas, 15 by Lucy Thomas Music	https://img.youtube.com/vi/LA2KkFYPaIA/mqdefault.jpg
"Suddenly" - From the Musical "Rosie" - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/Rj44LxVEwkw/mqdefault.jpg
BEAUTIFUL New Musical Song - "STARLIGHT" - From the Musical "Rosie" - Lucy Thomas by Lucy Thomas Music	https://img.youtube.com/vi/RoqLoGoVFVk/mqdefault.jpg
I'll Never Love Again - (A Star is Born) - Lady Gaga - Cover by Lucy Thomas, 15 by Lucy Thomas Music	https://img.youtube.com/vi/4g1Qpu9XPL8/mqdefault.jpg
Listen - Beyonce - Dreamgirls - Cover by Lucy Thomas, 14 by Lucy Thomas Music	https://img.youtube.com/vi/-fGe8Z4uLWE/mqdefault.jpg
Can I Have This Dance from High School Musical - Cover by Lucy Thomas and Will Callan by Lucy Thomas Music	https://img.youtube.com/vi/5G27a65HfeU/mqdefault.jpg
Beauty and the Beast - Cover by Lucy Thomas, 14 by Lucy Thomas Music	https://img.youtube.com/vi/CUeHeFRqik0/mqdefault.jpg
She Used To Be Mine - Waitress Musical - Cover by Lucy Thomas, 14 by Lucy Thomas Music	https://img.youtube.com/vi/bgGUPA-ToKc/mqdefault.jpg
Emeli Sande - Clown - Cover by Lucy Thomas, 14 by Lucy Thomas Music	https://img.youtube.com/vi/j4WOvrJu3fY/mqdefault.jpg
Never Enough - The Greatest Showman - Cover by Lucy Thomas, 14 by Lucy Thomas Music	https://img.youtube.com/vi/wUAjg-y8910/mqdefault.jpg
)

browserexe = msedge.exe

IfWinExist, ahk_exe %browserexe%
	WinActivate
Else Run, %browserexe%
WinWaitActive, ahk_exe %browserexe%

ClipSave(True), Clipboard := genWebpageCode(Clipboard)
IfWinActive, ahk_exe %browserexe%
{	Send, ^l
	If AddressBarWaitFocused(9)
	{	Send, j^v{Enter}
		Sleep, 3000
		ClipSave(False)
	}Else MsgBox, Oops...
}ExitApp

genWebpageCode(theList) {	; generate the code for opening up a temporary webpage which hosts the video thumbnail(s) that interested you
	theList := StrReplace(theList, "'", "&apos;")
	Loop, Parse, theList, `n
		If pos := InStr(A_LoopField, "`t")
		{	If SubStr(A_LoopField, 1, 1) = ";"
				Continue
			If StrReplace(A_LoopField, "`t",, c) and c = 1
			{	RegExMatch(A_LoopField, "/(an_webp|vi)/([^/]+)/", m), url := "https://www.youtube.com/watch?v=" m2, imgurl := "https://img.youtube.com/vi/" m2 "/mqdefault.jpg", img2url := StrReplace(SubStr(A_LoopField, pos + 1), "`r")
				If InStr(img2url, "/vi/") or SubStr(WebRead(img2url), 1, 5) == "RIFF "
					img2url := imgurl
			}Else url := SubStr(A_LoopField, pos + 1, InStr(SubStr(A_LoopField, pos + 1), "`t") - 1), imgurl := StrReplace(SubStr(A_LoopField, InStr(A_LoopField, "`t",, pos + 1) + 1), "`r"), img2url := imgurl
			t := SubStr(A_LoopField, 1, pos - 1)
			theCode .= "<div id=""dismissible"" class=""thumb-block"" ondrop=""drop(event)"" ondragover=""allowDrop(event)""><div class=""thumb-DnD"" ondragstart=""dragStart(event)"" draggable=""true""><div class=""thumbnail""><a href=""" url """><img src=""" imgurl """><img src=""" img2url """></a></div><div class=""thumbtext""><a href=""" url """>" t "</a></div></div></div>`n"
		}
	theCode := "avascript: {var newWin = window.open(); newWin.document.write('<title>YouTube and/or other videos</title>`n<base target=""_blank"">`n<style>`nbody{font-size:18pt;background-color:black}`nheader{color:white;background-color:MediumSeaGreen;padding:5px;width:100%;margin-top:-60px;position:absolute}`nbutton{color:white;background-color:red;padding:10px 15px;border-radius:10px;cursor:pointer;font-size:13pt}`n.sCap+.sCap{margin-left:30px}`n.showSource{position:fixed;top:2px;right:5px;width:50px;height:50px}`n.bodyMain{margin-top:60px}`n.thumb-block{display:inline-flex;flex-flow:column;padding:0px 0px 5px 0px}`n.thumb-DnD{background-color:ffebc3;padding:5px}`n.thumbnail{width:100%;height:100%;padding:5px -5px 0px 5px;display:inline-block;position:relative}`na img:last-child{display:none}a:hover img:last-child{display:block}a:hover img:first-child{display:none}`n.delete{position:absolute;top:0px;right:0px;width:50px;height:50px}`n.movetoTop{position:absolute;top:0px;left:0px;width:50px;height:50px}`n.movetoBottom{position:absolute;bottom:0px;right:0px;width:50px;height:50px}`na #bttn{display:none}a:hover #bttn{display:block}`n.thumbtext{display:flex;padding:0px 5px 5px 5px}`n.thumbtext a{flex-grow:1;width:0}`n</style>`n<body>`n<header><button onclick=""rExtract()"">Random Draw</button><div style=""position:absolute;top:5px;left:160px""><div style=""display:inline-flex""><div class=""sCap"">How many: <span id=""howmany"">25</span></div><div class=""sCap"">(Thumbnail Count: <span id=""thumbCount"">to be updated</span> <a onclick=""updateThumbCount();return false"" href=""#"" ondragstart=""dragStart(event)"" draggable=""true"">(Refresh)</a>)</div></div><br><input type=""range"" min=""1"" max=""50"" value=""25"" style=""width:500px"" oninput=""updateHowmany(event)""></div></header>`n<img class=""showSource"" onclick=""showSource()"" title=""Show Source"" src=""https://img.icons8.com/external-flaticons-flat-flat-icons/2x/external-sources-history-flaticons-flat-flat-icons.png"">`n<div class=""bodyMain"">`n" theCode "</div>`n<script>`nsessionStorage.sessionID=Math.random();`nvar t=Array.from(document.getElementsByClassName(""thumbnail""));`nfor (var i=0;i<t.length;i++){`n	var x=document.createElement(""img"");`n	x.setAttribute(""class"",""delete"");`n	x.setAttribute(""onclick"",""removeThumb();return false"");`n	x.setAttribute(""src"",""https://cdn.iconscout.com/icon/free/png-128/delete-4393995-3644065.png"");`n	x.setAttribute(""id"",""bttn"");`n	t[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`n	var x=document.createElement(""img"");`n	x.setAttribute(""class"",""movetoTop"");`n	x.setAttribute(""onclick"",""movetoTop();return false"");`n	x.setAttribute(""src"",""https://img.icons8.com/emoji/2x/top-arrow-emoj.png"");`n	x.setAttribute(""id"",""bttn"");`n	t[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`n	var x=document.createElement(""img"");`n	x.setAttribute(""class"",""movetoBottom"");`n	x.setAttribute(""onclick"",""movetoBottom();return false"");`n	x.setAttribute(""src"",""https://img.icons8.com/external-others-inmotus-design/2x/external-Down-round-icons-others-inmotus-design-2.png"");`n	x.setAttribute(""title"",""Move this thumbnail to the bottom"");`n	x.setAttribute(""id"",""bttn"");`n	t[i].querySelector(""a:first-child"").insertBefore(x,t[i].querySelector(""img:last-child""));`n}`nupdateThumbCount();`nfunction updateThumbCount(){`n	document.getElementById(""thumbCount"").innerHTML=document.querySelector("".bodyMain"").childElementCount;`n}`nfunction updateHowmany(event){`n	document.getElementById(""howmany"").innerHTML=event.target.value;`n	updateThumbCount();`n}`nfunction rExtract(){`n	var t=Array.from(document.getElementsByClassName(""thumbnail""));`n	var t=t.sort(function(){return 0.5-Math.random()});var r=[];`n	let n=parseInt(document.getElementById(""howmany"").innerHTML,10);`n	for (var i=0;i<n;i++){`n		if (i<t.length){`n			r.push(t[i].querySelector(""a:first-child"").href.match(/(?<=\\.youtube\\.com\\/watch\\?v=)[^&\\/]+/i))}`n		else{break}`n	}window.open(""https://www.youtube.com/watch_videos?video_ids=""+r);`n}`nfunction removeThumb(){`n	document.querySelector(""a:hover"").closest(""#dismissible"").remove();`n	updateThumbCount()`n}`nfunction movetoTop(){`n	var thisBlock=document.querySelector(""a:hover"").closest(""#dismissible"");`n	document.querySelector("".bodyMain"").insertBefore(thisBlock,document.querySelector("".bodyMain"").querySelector(""div:first-child""));`n	thisBlock.style.setProperty(""padding-right"",""5px"")`n}`nfunction movetoBottom(){`n	var thisBlock=document.querySelector(""a:hover"").closest(""#dismissible"");`n	document.querySelector("".bodyMain"").insertBefore(thisBlock,document.querySelector("".bodyMain"").querySelector(""div:last-child"").nextSibling);`n	thisBlock.style.setProperty(""padding-left"",""5px"")`n}`nfunction showSource(){`n	var result="""";`n	var tt=Array.from(document.getElementsByClassName(""thumbtext""));`n	var tn=Array.from(document.getElementsByClassName(""thumbnail""));`n	for (var i=0;i<tt.length;i++){`n		var vtit=tt[i].querySelector(""a:first-child"").innerText;`n		var ytvid=tt[i].querySelector(""a:first-child"").href.match(/(?<=\\.youtube\\.com\\/watch\\?v=)[^&\\/]+/i);`n		if (ytvid!==null){`n			var result=result+vtit+""<< tab >>""+tn[i].querySelector(""img:last-child"").src+""<br>""}`n		else{var result=result+vtit+""<< tab >>""+tn[i].querySelector(""a:first-child"").href+""<< tab >>""+tn[i].querySelector(""img:first-child"").src+""<br>""}}`n	window.open().document.write(result)`n}`nfunction dragStart(event){`n	if (event.target.innerHTML===""(Refresh)""){`n		event.dataTransfer.setData(""data/id"",""Flag:CopyAll"");`n		event.dataTransfer.setData(""data/html"",document.querySelector("".bodyMain"").innerHTML);`n	}else{`n		if (event.target.getAttribute(""class"")!==""thumb-block""){`n			var finaltarget=event.target.closest("".thumb-block"")}`n		else{var finaltarget=event.target}`n		if (document.getElementById(""673795646789056767945676"")!==null){`n			document.getElementById(""673795646789056767945676"").id=""""}`n		finaltarget.id=""673795646789056767945676"";`n		event.dataTransfer.setData(""data/id"",finaltarget.id);`n		event.dataTransfer.setData(""data/html"",finaltarget.innerHTML);`n	}event.dataTransfer.setData(""data/session"",sessionStorage.sessionID);`n}`nfunction allowDrop(event){`n	event.preventDefault();`n}`nfunction drop(event){`n	event.preventDefault();`n	if (event.target.getAttribute(""class"")!==""thumb-block""){`n		var finaltarget=event.target.closest("".thumb-block"")}`n	else{var finaltarget=event.target}`n	if (event.dataTransfer.getData(""data/session"")===sessionStorage.sessionID){`n		var data=event.dataTransfer.getData(""data/id"");`n		if (data===""Flag:CopyAll""){return}`n		var element=document.getElementById(data);`n		element.id=""dismissible"";`n		if (finaltarget.querySelector(""a"")!==null){`n			element.style.setProperty(""padding-right"",""5px"");`n			document.querySelector("".bodyMain"").insertBefore(element,finaltarget)}`n		else{finaltarget.appendChild(element.querySelector("".thumb-DnD""))}`n	}else{`n		if (event.dataTransfer.getData(""data/html"").length===0){`n			var freedata=event.dataTransfer.getData(""text/html"");`n			if (freedata.length>0){`n				if (freedata.match("" id=\\""mouseover-overlay\\"""")){`n					var imgurl=freedata.match(/(?<=mouseover.+?src="")[^""]+/i);`n					if (imgurl!==null){`n						finaltarget.querySelector(""img:last-child"").src=imgurl.toString().replace(/&amp;/ig,""&"")}`n					return}`n				let ytvid=freedata.match(/(?<=\\.youtube\\.com\\/(?:watch\\?v=|shorts\\/))[^""&\\/]+/i);`n				if (ytvid!==null){`n					var vurl=""https://www.youtube.com/watch?v=""+ytvid;`n					var imgurl=""https://img.youtube.com/vi/""+ytvid+""/mqdefault.jpg"";`n					var vtit=freedata.match(/(?<=aria-label="")[^""]+/i);`n					if (vtit===null){`n						var vtit=freedata.match(/(?<=title="")[^""]+/i);`n						if (vtit===null){var vtit=freedata.match(/(?<=>)[^<]+(?=<\\/a>)/i)}}}`n				else{`n					var vurl=freedata.match(/(?<=href="")[^""]+/i);`n					if (freedata.toString().match(/vimeo\\.com\\//i)!==null){`n						var imgurl=freedata.match(/(?<=<img .*?src="")[^""]+/i);`n						var vtit=freedata.match(/(?<=span title="")[^""]+/ig)}`n					else{`n						if (vurl!==null){`n							var imgurl=""https://img.icons8.com/cotton/2x/grinning-face-with-sweat-icon--v2.png"";`n							var vtit=freedata.match(/(?<=>).+?(?=<\\/a>)/i)}`n						else{`n							var imgurl=freedata.match(/(?<=<img .*?src="")[^""]+/i);`n							finaltarget.querySelector(""img:first-child"").src=imgurl;`n							finaltarget.querySelector(""img:last-child"").src=imgurl;`n							return}}}`n				var data = ""<div class=\\""thumb-DnD\\"" ondragstart=\\""dragStart(event)\\"" draggable=\\""true\\""><div class=\\""thumbnail\\""><a href=\\""""+vurl+""\\""><img src=\\""""+imgurl+""\\""><img class=\\""delete\\"" onclick=\\""removeThumb();return false\\"" src=\\""https://cdn.iconscout.com/icon/free/png-128/delete-4393995-3644065.png\\"" id=\\""bttn\\""><img class=\\""movetoTop\\"" onclick=\\""movetoTop();return false\\"" src=\\""https://img.icons8.com/emoji/2x/top-arrow-emoj.png\\"" id=\\""bttn\\""><img class=\\""movetoBottom\\"" onclick=\\""movetoBottom();return false\\"" src=\\""https://img.icons8.com/external-others-inmotus-design/2x/external-Down-round-icons-others-inmotus-design-2.png\\"" title=\\""Move this thumbnail to the bottom\\"" id=\\""bttn\\""><img src=\\""""+imgurl+""\\""></a></div><div class=\\""thumbtext\\""><a href=\\""""+vurl+""\\"">""+vtit+""</a></div></div>""}}`n		else{var data=event.dataTransfer.getData(""data/html"")}`n		if (event.dataTransfer.getData(""data/id"")===""Flag:CopyAll""){`n			document.querySelector("".bodyMain"").innerHTML=data+document.querySelector("".bodyMain"").innerHTML;`n			updateThumbCount();`n			return}`n		if (finaltarget.querySelector(""a"")!==null){`n			var newBlock=document.createElement(""div"");`n			newBlock.setAttribute(""id"",""dismissible"");`n			newBlock.setAttribute(""class"",""thumb-block"");`n			newBlock.setAttribute(""ondrop"",""drop(event)"");`n			newBlock.setAttribute(""ondragover"",""allowDrop(event)"");`n			newBlock.style.setProperty(""padding-right"",""5px"");`n			document.querySelector("".bodyMain"").insertBefore(newBlock,finaltarget);`n			newBlock.innerHTML=data}`n		else{finaltarget.innerHTML=data}`n		updateThumbCount();`n	}`n}`n</script>`n</body>')}"
	Return theCode
}

AddressBarWaitFocused(maxTolsec) {
	beg := A_TickCount
	While, not AddressBarFocused() and A_TickCount - beg < maxTolsec * 1000
		Continue
	Return AddressBarFocused()
}
AddressBarFocused() {
	Return GetFocusedElement().Name = "Address and search bar"
}
GetFocusedElement() {	; based on the script written by Descolada (https://www.autohotkey.com/boards/viewtopic.php?p=459451&sid=dde6b407875aadff59bc35e0864f63e4#p459451)
	IUIAutomation := ComObjCreate(CLSID_CUIAutomation := "{ff48dba4-60ef-4201-aa87-54103eef594e}", IID_IUIAutomation := "{30cbe57d-d9d0-452a-ab13-7ac5ac4825ee}")
	DllCall(NumGet(NumGet(IUIAutomation+0)+8*A_PtrSize), "ptr",IUIAutomation, "ptr*",element)	;IUIAutomation::GetFocusedElement
	DllCall(NumGet(NumGet(element+0)+23*A_PtrSize), "ptr", element, "ptr*", name)	;IUIAutomationElement::CurrentName
	DllCall(NumGet(NumGet(element+0)+10*A_PtrSize), "ptr", element, "uint",30045, "ptr", (VarSetCapacity(val,8+2*A_PtrSize)+NumPut(0,val,0,"short")+NumPut(0,val,8,"ptr"))*0+&val)	;IUIAutomationElement::GetCurrentPropertyValue
	ObjRelease(element)
	ObjRelease(IUIAutomation)
	Return {"Name":StrGet(name,"utf-16"), "Value":StrGet(NumGet(val,8,"ptr"),"utf-16")}
}
ClipSave(Yes) {
	static ClipSave
	If Yes
		ClipSave := ClipboardAll
	Else Clipboard := ClipSave
}
WebRead(theUrl) {	; from autohotkey documentation example
	; Example: Download text to a variable:
	whr := ComObjCreate("WinHttp.WinHttpRequest.5.1")
	whr.Open("GET", theUrl, true)
	whr.Send()
	; Using 'true' above and the call below allows the script to remain responsive.
	whr.WaitForResponse()
	return whr.ResponseText
}
2022-8-13 edited: added <base target="_blank">
2022-8-14 edited: added a delete feature
2022-8-15 edited: added 2 more features, move thumbnail to the top, and move thumbnail to the bottom; fixed a careless mistake (produced since the "random draw") which bumped the drag&drop feature implemented previously.
2022-8-16 edited: added one more feature, enabled user to drag a thumbnail to another webpage (this will become "copy" instead of "move"), provided that both sides have the same drag&drop script working behind the scene that support such operation.
2022-8-17 edited: fixed a bug (produced since the cross webpage drag&drop was implemented), and made an adjustment to have the buttons shown only on hover.
2022-8-21 edited: see next post
Last edited by SundayProgrammer on 21 Aug 2022, 10:19, edited 1 time in total.

SundayProgrammer
Posts: 143
Joined: 25 Dec 2020, 12:26

Re: a temporary webpage for video thumbnail(s)

Post by SundayProgrammer » 21 Aug 2022, 06:56

this latest update enabled user to drag a video thumbnail from other webpages (such as youtube, vimeo, and the likes.)

video thumbnails mainly consist of two parts, an image and a text (video title). when a drag&drop operation started, from the image vs from the text, the payload are mostly different. for instance, drag from the text part of a video thumbnail from youtube, the payload only consists of an url (for accessing of the video) and the video titles. it does not have any url of the image nor any url for preview-on-hover. (fortunately though, for youtube, it's quite simple to derive an image url out of its video access url.) whereas, drag from the image part of a video thumbnail from youtube, the payload mainly consists of those information related to the image and the preview-on-hover if applicable. so, the drop handler needs different reactions for different payloads (ie which part of the thumbnail was it dragged from.)

that said, for vimeo, there is no difference in the payload, no matter it's dragged from the image part or the text part, both consists almost all the information needed. so, as you can see, it could be very different from website to website. hence, the drop handler needs different reactions for different payloads not only concerning which part of the thumbnail was it dragged from, but also from which website.

worst case, (for some websites) you may need to drag&drop twice for a complete operation. firstly, drag from the text part of the thumbnail (thus a thumbnail without the correct image resulted upon drop), and lastly, drag from the image part of the thumbnail, and drop it on the one that was just created by the previous step.

besides, in this update, one more icon (at upper-right corner) is added, which will generate back the list from all the thumbnails shown on the page. (note: i don't know how to produce a tab character, so i made it "<< tab >>" instead.)

that's pretty much it.

Post Reply

Return to “Scripts and Functions (v1)”