aboutsummaryrefslogtreecommitdiffstats
path: root/src/webview
diff options
context:
space:
mode:
Diffstat (limited to 'src/webview')
-rw-r--r--src/webview/contextMenuBuilder.ts117
-rw-r--r--src/webview/notifications.ts75
-rw-r--r--src/webview/recipe.ts2
3 files changed, 95 insertions, 99 deletions
diff --git a/src/webview/contextMenuBuilder.ts b/src/webview/contextMenuBuilder.ts
index 0a8b9c57b..d68605963 100644
--- a/src/webview/contextMenuBuilder.ts
+++ b/src/webview/contextMenuBuilder.ts
@@ -130,8 +130,8 @@ interface ContextMenuStringTable {
130 translatorLanguage: string; 130 translatorLanguage: string;
131 }) => string; 131 }) => string;
132 openLinkUrl: () => string; 132 openLinkUrl: () => string;
133 openLinkInFerdiumUrl: () => string;
134 openInBrowser: () => string; 133 openInBrowser: () => string;
134 openInFerdium: () => string;
135 copyLinkUrl: () => string; 135 copyLinkUrl: () => string;
136 copyImageUrl: () => string; 136 copyImageUrl: () => string;
137 copyImage: () => string; 137 copyImage: () => string;
@@ -158,8 +158,8 @@ const contextMenuStringTable: ContextMenuStringTable = {
158 `Translate to ${translatorLanguage}`, 158 `Translate to ${translatorLanguage}`,
159 translateLanguage: ({ translatorLanguage }) => `${translatorLanguage}`, 159 translateLanguage: ({ translatorLanguage }) => `${translatorLanguage}`,
160 openLinkUrl: () => 'Open Link', 160 openLinkUrl: () => 'Open Link',
161 openLinkInFerdiumUrl: () => 'Open Link in Ferdium',
162 openInBrowser: () => 'Open in Browser', 161 openInBrowser: () => 'Open in Browser',
162 openInFerdium: () => 'Open in Ferdium',
163 copyLinkUrl: () => 'Copy Link', 163 copyLinkUrl: () => 'Copy Link',
164 copyImageUrl: () => 'Copy Image Address', 164 copyImageUrl: () => 'Copy Image Address',
165 copyImage: () => 'Copy Image', 165 copyImage: () => 'Copy Image',
@@ -299,10 +299,13 @@ export class ContextMenuBuilder {
299 this.addPastePlain(menu, menuInfo); 299 this.addPastePlain(menu, menuInfo);
300 this.addInspectElement(menu, menuInfo); 300 this.addInspectElement(menu, menuInfo);
301 this.processMenu(menu); 301 this.processMenu(menu);
302 302 this.addSeparator(menu);
303 this.copyPageUrl(menu, menuInfo); 303 this.copyPageUrl(menu, menuInfo);
304 this.goToHomePage(menu, menuInfo); 304 this.addSeparator(menu);
305 this.openInBrowser(menu, menuInfo); 305 this.openInBrowser(menu, menuInfo);
306 this.openInFerdium(menu, menuInfo);
307 this.addSeparator(menu);
308 this.goToHomePage(menu, menuInfo);
306 309
307 return menu; 310 return menu;
308 } 311 }
@@ -340,16 +343,8 @@ export class ContextMenuBuilder {
340 }, 343 },
341 }); 344 });
342 345
343 const openInFerdiumLink = new MenuItem({
344 label: this.stringTable.openLinkInFerdiumUrl(),
345 click: () => {
346 window.location.href = menuInfo.linkURL;
347 },
348 });
349
350 menu.append(copyLink); 346 menu.append(copyLink);
351 menu.append(openLink); 347 menu.append(openLink);
352 menu.append(openInFerdiumLink);
353 348
354 if (this.isSrcUrlValid(menuInfo)) { 349 if (this.isSrcUrlValid(menuInfo)) {
355 this.addSeparator(menu); 350 this.addSeparator(menu);
@@ -358,13 +353,15 @@ export class ContextMenuBuilder {
358 353
359 this.addInspectElement(menu, menuInfo); 354 this.addInspectElement(menu, menuInfo);
360 this.processMenu(menu); 355 this.processMenu(menu);
361
362 this.addSeparator(menu); 356 this.addSeparator(menu);
363 this.goBack(menu); 357 this.goBack(menu);
364 this.goForward(menu); 358 this.goForward(menu);
365 this.copyPageUrl(menu, menuInfo); 359 this.copyPageUrl(menu, menuInfo);
366 this.goToHomePage(menu, menuInfo); 360 this.addSeparator(menu);
367 this.openInBrowser(menu, menuInfo); 361 this.openInBrowser(menu, menuInfo);
362 this.openInFerdium(menu, menuInfo);
363 this.addSeparator(menu);
364 this.goToHomePage(menu, menuInfo);
368 365
369 return menu; 366 return menu;
370 } 367 }
@@ -384,16 +381,19 @@ export class ContextMenuBuilder {
384 this.addTranslateItems(menu, menuInfo); 381 this.addTranslateItems(menu, menuInfo);
385 } 382 }
386 this.addCopy(menu, menuInfo); 383 this.addCopy(menu, menuInfo);
387 this.addInspectElement(menu, menuInfo);
388 // @ts-expect-error Expected 1 arguments, but got 2.
389 this.processMenu(menu, menuInfo);
390 384
385 this.addInspectElement(menu, menuInfo);
386 this.processMenu(menu);
391 this.addSeparator(menu); 387 this.addSeparator(menu);
392 this.goBack(menu); 388 this.goBack(menu);
393 this.goForward(menu); 389 this.goForward(menu);
390 this.addSeparator(menu);
394 this.copyPageUrl(menu, menuInfo); 391 this.copyPageUrl(menu, menuInfo);
395 this.goToHomePage(menu, menuInfo); 392 this.addSeparator(menu);
396 this.openInBrowser(menu, menuInfo); 393 this.openInBrowser(menu, menuInfo);
394 this.openInFerdium(menu, menuInfo);
395 this.addSeparator(menu);
396 this.goToHomePage(menu, menuInfo);
397 397
398 return menu; 398 return menu;
399 } 399 }
@@ -412,8 +412,7 @@ export class ContextMenuBuilder {
412 this.addImageItems(menu, menuInfo); 412 this.addImageItems(menu, menuInfo);
413 } 413 }
414 this.addInspectElement(menu, menuInfo); 414 this.addInspectElement(menu, menuInfo);
415 // @ts-expect-error Expected 1 arguments, but got 2. 415 this.processMenu(menu);
416 this.processMenu(menu, menuInfo);
417 416
418 return menu; 417 return menu;
419 } 418 }
@@ -644,7 +643,7 @@ export class ContextMenuBuilder {
644 addImageItems( 643 addImageItems(
645 menu: Electron.CrossProcessExports.Menu, 644 menu: Electron.CrossProcessExports.Menu,
646 menuInfo: IContextMenuParams, 645 menuInfo: IContextMenuParams,
647 ) { 646 ): void {
648 const copyImage = new MenuItem({ 647 const copyImage = new MenuItem({
649 label: this.stringTable.copyImage(), 648 label: this.stringTable.copyImage(),
650 click: () => { 649 click: () => {
@@ -719,8 +718,6 @@ export class ContextMenuBuilder {
719 718
720 menu.append(downloadImage); 719 menu.append(downloadImage);
721 } 720 }
722
723 return menu;
724 } 721 }
725 722
726 /** 723 /**
@@ -729,7 +726,7 @@ export class ContextMenuBuilder {
729 addCut( 726 addCut(
730 menu: Electron.CrossProcessExports.Menu, 727 menu: Electron.CrossProcessExports.Menu,
731 menuInfo: IContextMenuParams, 728 menuInfo: IContextMenuParams,
732 ) { 729 ): void {
733 const webContents = this.getWebContents(); 730 const webContents = this.getWebContents();
734 menu.append( 731 menu.append(
735 new MenuItem({ 732 new MenuItem({
@@ -739,8 +736,6 @@ export class ContextMenuBuilder {
739 click: () => webContents.cut(), 736 click: () => webContents.cut(),
740 }), 737 }),
741 ); 738 );
742
743 return menu;
744 } 739 }
745 740
746 /** 741 /**
@@ -749,7 +744,7 @@ export class ContextMenuBuilder {
749 addCopy( 744 addCopy(
750 menu: Electron.CrossProcessExports.Menu, 745 menu: Electron.CrossProcessExports.Menu,
751 menuInfo: IContextMenuParams, 746 menuInfo: IContextMenuParams,
752 ) { 747 ): void {
753 const webContents = this.getWebContents(); 748 const webContents = this.getWebContents();
754 menu.append( 749 menu.append(
755 new MenuItem({ 750 new MenuItem({
@@ -759,8 +754,6 @@ export class ContextMenuBuilder {
759 click: () => webContents.copy(), 754 click: () => webContents.copy(),
760 }), 755 }),
761 ); 756 );
762
763 return menu;
764 } 757 }
765 758
766 /** 759 /**
@@ -769,7 +762,7 @@ export class ContextMenuBuilder {
769 addPaste( 762 addPaste(
770 menu: Electron.CrossProcessExports.Menu, 763 menu: Electron.CrossProcessExports.Menu,
771 menuInfo: IContextMenuParams, 764 menuInfo: IContextMenuParams,
772 ) { 765 ): void {
773 const webContents = this.getWebContents(); 766 const webContents = this.getWebContents();
774 menu.append( 767 menu.append(
775 new MenuItem({ 768 new MenuItem({
@@ -779,14 +772,12 @@ export class ContextMenuBuilder {
779 click: () => webContents.paste(), 772 click: () => webContents.paste(),
780 }), 773 }),
781 ); 774 );
782
783 return menu;
784 } 775 }
785 776
786 addPastePlain( 777 addPastePlain(
787 menu: Electron.CrossProcessExports.Menu, 778 menu: Electron.CrossProcessExports.Menu,
788 menuInfo: IContextMenuParams, 779 menuInfo: IContextMenuParams,
789 ) { 780 ): void {
790 if ( 781 if (
791 menuInfo.editFlags.canPaste && 782 menuInfo.editFlags.canPaste &&
792 !menuInfo.linkText && 783 !menuInfo.linkText &&
@@ -806,9 +797,8 @@ export class ContextMenuBuilder {
806 /** 797 /**
807 * Adds a separator item. 798 * Adds a separator item.
808 */ 799 */
809 addSeparator(menu: Electron.CrossProcessExports.Menu) { 800 addSeparator(menu: Electron.CrossProcessExports.Menu): void {
810 menu.append(new MenuItem({ type: 'separator' })); 801 menu.append(new MenuItem({ type: 'separator' }));
811 return menu;
812 } 802 }
813 803
814 /** 804 /**
@@ -818,18 +808,17 @@ export class ContextMenuBuilder {
818 menu: Electron.CrossProcessExports.Menu, 808 menu: Electron.CrossProcessExports.Menu,
819 menuInfo: IContextMenuParams, 809 menuInfo: IContextMenuParams,
820 needsSeparator = true, 810 needsSeparator = true,
821 ) { 811 ): void {
822 const webContents = this.getWebContents(); 812 const webContents = this.getWebContents();
823 if (!this.debugMode) return menu; 813 if (!this.debugMode) return;
824 if (needsSeparator) this.addSeparator(menu); 814 if (needsSeparator) this.addSeparator(menu);
825 815
826 const inspect = new MenuItem({ 816 menu.append(
827 label: this.stringTable.inspectElement(), 817 new MenuItem({
828 click: () => webContents.inspectElement(menuInfo.x, menuInfo.y), 818 label: this.stringTable.inspectElement(),
829 }); 819 click: () => webContents.inspectElement(menuInfo.x, menuInfo.y),
830 820 }),
831 menu.append(inspect); 821 );
832 return menu;
833 } 822 }
834 823
835 /** 824 /**
@@ -847,7 +836,7 @@ export class ContextMenuBuilder {
847 (arg0: string): void; 836 (arg0: string): void;
848 }, 837 },
849 outputFormat: string = 'image/png', 838 outputFormat: string = 'image/png',
850 ) { 839 ): void {
851 let canvas: HTMLCanvasElement | null = document.createElement('canvas'); 840 let canvas: HTMLCanvasElement | null = document.createElement('canvas');
852 const ctx = canvas.getContext('2d'); 841 const ctx = canvas.getContext('2d');
853 const img = new Image(); 842 const img = new Image();
@@ -871,7 +860,7 @@ export class ContextMenuBuilder {
871 /** 860 /**
872 * Adds the 'go back' menu item 861 * Adds the 'go back' menu item
873 */ 862 */
874 goBack(menu: Electron.CrossProcessExports.Menu) { 863 goBack(menu: Electron.CrossProcessExports.Menu): void {
875 const webContents = this.getWebContents(); 864 const webContents = this.getWebContents();
876 865
877 menu.append( 866 menu.append(
@@ -882,14 +871,12 @@ export class ContextMenuBuilder {
882 click: () => webContents.goBack(), 871 click: () => webContents.goBack(),
883 }), 872 }),
884 ); 873 );
885
886 return menu;
887 } 874 }
888 875
889 /** 876 /**
890 * Adds the 'go forward' menu item 877 * Adds the 'go forward' menu item
891 */ 878 */
892 goForward(menu: Electron.CrossProcessExports.Menu) { 879 goForward(menu: Electron.CrossProcessExports.Menu): void {
893 const webContents = this.getWebContents(); 880 const webContents = this.getWebContents();
894 menu.append( 881 menu.append(
895 new MenuItem({ 882 new MenuItem({
@@ -899,8 +886,6 @@ export class ContextMenuBuilder {
899 click: () => webContents.goForward(), 886 click: () => webContents.goForward(),
900 }), 887 }),
901 ); 888 );
902
903 return menu;
904 } 889 }
905 890
906 /** 891 /**
@@ -909,7 +894,7 @@ export class ContextMenuBuilder {
909 copyPageUrl( 894 copyPageUrl(
910 menu: Electron.CrossProcessExports.Menu, 895 menu: Electron.CrossProcessExports.Menu,
911 menuInfo: IContextMenuParams, 896 menuInfo: IContextMenuParams,
912 ) { 897 ): void {
913 menu.append( 898 menu.append(
914 new MenuItem({ 899 new MenuItem({
915 label: this.stringTable.copyPageUrl(), 900 label: this.stringTable.copyPageUrl(),
@@ -923,8 +908,6 @@ export class ContextMenuBuilder {
923 }, 908 },
924 }), 909 }),
925 ); 910 );
926
927 return menu;
928 } 911 }
929 912
930 /** 913 /**
@@ -933,7 +916,7 @@ export class ContextMenuBuilder {
933 goToHomePage( 916 goToHomePage(
934 menu: Electron.CrossProcessExports.Menu, 917 menu: Electron.CrossProcessExports.Menu,
935 menuInfo: IContextMenuParams, 918 menuInfo: IContextMenuParams,
936 ) { 919 ): void {
937 const baseURL = new window.URL(menuInfo.pageURL); 920 const baseURL = new window.URL(menuInfo.pageURL);
938 menu.append( 921 menu.append(
939 new MenuItem({ 922 new MenuItem({
@@ -946,8 +929,6 @@ export class ContextMenuBuilder {
946 }, 929 },
947 }), 930 }),
948 ); 931 );
949
950 return menu;
951 } 932 }
952 933
953 /** 934 /**
@@ -956,7 +937,7 @@ export class ContextMenuBuilder {
956 openInBrowser( 937 openInBrowser(
957 menu: Electron.CrossProcessExports.Menu, 938 menu: Electron.CrossProcessExports.Menu,
958 menuInfo: IContextMenuParams, 939 menuInfo: IContextMenuParams,
959 ) { 940 ): void {
960 menu.append( 941 menu.append(
961 new MenuItem({ 942 new MenuItem({
962 label: this.stringTable.openInBrowser(), 943 label: this.stringTable.openInBrowser(),
@@ -966,14 +947,30 @@ export class ContextMenuBuilder {
966 }, 947 },
967 }), 948 }),
968 ); 949 );
950 }
969 951
970 return menu; 952 /**
953 * Adds the 'open in ferdium' menu item.
954 */
955 openInFerdium(
956 menu: Electron.CrossProcessExports.Menu,
957 menuInfo: IContextMenuParams,
958 ): void {
959 menu.append(
960 new MenuItem({
961 label: this.stringTable.openInFerdium(),
962 enabled: true,
963 click: () => {
964 window.location.href = menuInfo.linkURL;
965 },
966 }),
967 );
971 } 968 }
972 969
973 _sendNotificationOnClipboardEvent( 970 _sendNotificationOnClipboardEvent(
974 isDisabled: boolean, 971 isDisabled: boolean,
975 notificationText: () => string, 972 notificationText: () => string,
976 ) { 973 ): void {
977 if (isDisabled) { 974 if (isDisabled) {
978 return; 975 return;
979 } 976 }
diff --git a/src/webview/notifications.ts b/src/webview/notifications.ts
index e4401ab6e..0da86fbba 100644
--- a/src/webview/notifications.ts
+++ b/src/webview/notifications.ts
@@ -31,52 +31,51 @@ export class NotificationsHandler {
31} 31}
32 32
33export const notificationsClassDefinition = `(() => { 33export const notificationsClassDefinition = `(() => {
34 class Notification { 34class Notification {
35 static permission = 'granted'; 35 static permission = 'granted';
36
37 constructor(title = '', options = {}) {
38 this.title = title;
39 this.options = options;
40 try {
41 window.ferdium.displayNotification(title, options)
42 .then(() => {
43 if (typeof (this.onClick) === 'function') {
44 this.onClick();
45 }
46 });
47 } catch(error) {
48 this.options.onClick = null;
49 window.ferdium.displayNotification(title, options)
50 .then(() => {
51 if (typeof (this.onClick) === 'function') {
52 this.onClick();
53 }
54 });
55 }
56 }
57 36
58 static requestPermission(cb = null) { 37 static _notification;
59 if (!cb) {
60 return new Promise((resolve) => {
61 resolve(Notification.permission);
62 });
63 }
64 38
65 if (typeof (cb) === 'function') { 39 constructor(title = '', options = {}) {
66 return cb(Notification.permission); 40 Notification._displayNotification(title, options);
67 } 41 }
68 42
69 return Notification.permission; 43 static _displayNotification(title, options) {
70 } 44 Notification._notification = window.ferdium
45 .displayNotification(title, options)
46 .then(() => {
47 // TODO: After several tries, we couldn't find a way to trigger the native notification onclick event.
48 // This was needed so that user could go to the specific context when clicking on the notification (it only goes to the service now).
49 // For now, we don't do anything here
50 });
51 }
71 52
72 onNotify(data) { 53 static requestPermission(cb) {
73 return data; 54 if (typeof cb === 'function') {
55 cb(Notification.permission);
74 } 56 }
75 57
76 onClick() {} 58 return Promise.resolve(Notification.permission);
59 }
60
61 onNotify(data) {
62 return data;
63 }
77 64
78 close() {} 65 close() {
66 if (Notification._notification) {
67 Notification._notification = null;
68 }
79 } 69 }
80 70
71 onclick() {}
72
73 onclose() {}
74
75 onerror() {}
76
77 onshow() {}
78}
79
81 window.Notification = Notification; 80 window.Notification = Notification;
82})();`; 81})();`;
diff --git a/src/webview/recipe.ts b/src/webview/recipe.ts
index a35a99699..ad2215ffd 100644
--- a/src/webview/recipe.ts
+++ b/src/webview/recipe.ts
@@ -121,7 +121,7 @@ contextBridge.exposeInMainWorld('ferdium', {
121 setDialogTitle: (title: string | null | undefined) => 121 setDialogTitle: (title: string | null | undefined) =>
122 dialogTitleHandler.setDialogTitle(title), 122 dialogTitleHandler.setDialogTitle(title),
123 displayNotification: (title: string, options: any) => { 123 displayNotification: (title: string, options: any) => {
124 notificationsHandler.displayNotification( 124 return notificationsHandler.displayNotification(
125 title, 125 title,
126 // The following line is needed so that a proper clone of the "options" object is made. 126 // The following line is needed so that a proper clone of the "options" object is made.
127 // This line was causing issues with some services. 127 // This line was causing issues with some services.