11import { createState } from "dreamland/core" ;
22import { StatefulClass } from "./StatefulClass" ;
3- import { scramjet } from "./main" ;
3+ import { browser , scramjet } from "./main" ;
44import {
55 addHistoryListeners ,
66 History ,
@@ -107,9 +107,44 @@ export class Tab extends StatefulClass {
107107 }
108108}
109109
110- function pageContextItems ( client : ScramjetClient , tab : Tab ) {
111- let frame = tab . frame ;
110+ function copyImageToClipboard ( img : HTMLImageElement ) {
111+ if ( ! img . complete || ! img . naturalWidth ) {
112+ console . error ( "Image not loaded yet" ) ;
113+ return ;
114+ }
115+
116+ const canvas = document . createElement ( "canvas" ) ;
117+ canvas . width = img . naturalWidth ;
118+ canvas . height = img . naturalHeight ;
119+
120+ const ctx = canvas . getContext ( "2d" ) ;
121+ if ( ! ctx ) {
122+ console . error ( "Failed to get canvas context" ) ;
123+ return ;
124+ }
125+
126+ ctx . drawImage ( img , 0 , 0 ) ;
112127
128+ canvas . toBlob ( ( blob ) => {
129+ if ( blob ) {
130+ navigator . clipboard
131+ . write ( [
132+ new ClipboardItem ( {
133+ "image/png" : blob ,
134+ } ) ,
135+ ] )
136+ . then ( ( ) => {
137+ console . log ( "Image copied to clipboard" ) ;
138+ } )
139+ . catch ( ( err ) => {
140+ console . error ( "Failed to copy image to clipboard" , err ) ;
141+ } ) ;
142+ }
143+ } , "image/png" ) ;
144+ }
145+
146+ function pageContextItems ( client : ScramjetClient , tab : Tab , e : MouseEvent ) {
147+ console . log ( e . target ) ;
113148 const selection = client . global . getSelection ( ) ;
114149 if ( selection && selection . toString ( ) . length > 0 ) {
115150 return [
@@ -135,6 +170,43 @@ function pageContextItems(client: ScramjetClient, tab: Tab) {
135170 ] ;
136171 }
137172
173+ let target = e . target ;
174+ let view = e . view ! . window ;
175+ // need to use e.view here they're different objects
176+ if ( target && target instanceof view . HTMLImageElement ) {
177+ return [
178+ {
179+ label : "Open Image in New Tab" ,
180+ action : ( ) => {
181+ // TODO: this is broken lol
182+ const imgUrl = scramjet . decodeUrl ( target . src ) ;
183+ if ( imgUrl ) {
184+ let newTab = browser . newTab ( ) ;
185+ newTab . pushNavigate ( new URL ( imgUrl ) ) ;
186+ }
187+ } ,
188+ } ,
189+ {
190+ label : "Copy Image URL" ,
191+ action : ( ) => {
192+ navigator . clipboard . writeText ( scramjet . decodeUrl ( target . src ) ) ;
193+ } ,
194+ } ,
195+ {
196+ label : "Copy Image" ,
197+ action : ( ) => {
198+ copyImageToClipboard ( target ) ;
199+ } ,
200+ } ,
201+ {
202+ label : "Save Image As..." ,
203+ action : ( ) => {
204+ // TODO
205+ } ,
206+ } ,
207+ ] ;
208+ }
209+
138210 return [
139211 {
140212 label : "Back" ,
@@ -183,7 +255,11 @@ function injectContextMenu(client: ScramjetClient, tab: Tab) {
183255 xoff += x ;
184256 yoff += y ;
185257
186- createMenu ( xoff + e . pageX , yoff + e . pageY , pageContextItems ( client , tab ) ) ;
258+ createMenu (
259+ xoff + e . pageX ,
260+ yoff + e . pageY ,
261+ pageContextItems ( client , tab , e )
262+ ) ;
187263 e . preventDefault ( ) ;
188264 } ) ;
189265}
0 commit comments