@tindalabs/shield 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (118) hide show
  1. package/LICENSE +9 -0
  2. package/README.md +357 -0
  3. package/dist/assess.d.ts +16 -0
  4. package/dist/assess.js +220 -0
  5. package/dist/config/default-extensions-config.json +103 -0
  6. package/dist/core/ContentProtector.d.ts +63 -0
  7. package/dist/core/ContentProtector.js +281 -0
  8. package/dist/core/index.d.ts +1 -0
  9. package/dist/core/index.js +2 -0
  10. package/dist/core/mediator/ContentProtectionMediator.d.ts +86 -0
  11. package/dist/core/mediator/ContentProtectionMediator.js +238 -0
  12. package/dist/core/mediator/eventDataTypes.d.ts +112 -0
  13. package/dist/core/mediator/eventDataTypes.js +23 -0
  14. package/dist/core/mediator/handlers/abstractEventHandler.d.ts +41 -0
  15. package/dist/core/mediator/handlers/abstractEventHandler.js +59 -0
  16. package/dist/core/mediator/handlers/devToolsEventHandler.d.ts +9 -0
  17. package/dist/core/mediator/handlers/devToolsEventHandler.js +95 -0
  18. package/dist/core/mediator/handlers/eventHandlerRegistry.d.ts +9 -0
  19. package/dist/core/mediator/handlers/eventHandlerRegistry.js +34 -0
  20. package/dist/core/mediator/handlers/extensionEventHandlers.d.ts +40 -0
  21. package/dist/core/mediator/handlers/extensionEventHandlers.js +140 -0
  22. package/dist/core/mediator/handlers/iFrameEventHandlers.d.ts +27 -0
  23. package/dist/core/mediator/handlers/iFrameEventHandlers.js +93 -0
  24. package/dist/core/mediator/handlers/screenShotEventHandlers.d.ts +34 -0
  25. package/dist/core/mediator/handlers/screenShotEventHandlers.js +111 -0
  26. package/dist/core/mediator/protection-event.d.ts +77 -0
  27. package/dist/core/mediator/protection-event.js +32 -0
  28. package/dist/core/mediator/types.d.ts +105 -0
  29. package/dist/core/mediator/types.js +1 -0
  30. package/dist/index.d.ts +10 -0
  31. package/dist/index.js +7 -0
  32. package/dist/otel.d.ts +24 -0
  33. package/dist/otel.js +83 -0
  34. package/dist/policy.d.ts +98 -0
  35. package/dist/policy.js +97 -0
  36. package/dist/strategies/AbstractStrategy.d.ts +124 -0
  37. package/dist/strategies/AbstractStrategy.js +256 -0
  38. package/dist/strategies/ClipboardStrategy.d.ts +67 -0
  39. package/dist/strategies/ClipboardStrategy.js +291 -0
  40. package/dist/strategies/ContextMenuStrategy.d.ts +60 -0
  41. package/dist/strategies/ContextMenuStrategy.js +454 -0
  42. package/dist/strategies/DevToolsStrategy.d.ts +55 -0
  43. package/dist/strategies/DevToolsStrategy.js +314 -0
  44. package/dist/strategies/ExtensionStrategy.d.ts +66 -0
  45. package/dist/strategies/ExtensionStrategy.js +486 -0
  46. package/dist/strategies/IFrameStrategy.d.ts +49 -0
  47. package/dist/strategies/IFrameStrategy.js +255 -0
  48. package/dist/strategies/KeyboardStrategy.d.ts +35 -0
  49. package/dist/strategies/KeyboardStrategy.js +130 -0
  50. package/dist/strategies/PrintStrategy.d.ts +47 -0
  51. package/dist/strategies/PrintStrategy.js +201 -0
  52. package/dist/strategies/ScreenshotStrategy.d.ts +90 -0
  53. package/dist/strategies/ScreenshotStrategy.js +502 -0
  54. package/dist/strategies/SelectionStrategy.d.ts +49 -0
  55. package/dist/strategies/SelectionStrategy.js +216 -0
  56. package/dist/strategies/WatermarkStrategy.d.ts +56 -0
  57. package/dist/strategies/WatermarkStrategy.js +287 -0
  58. package/dist/strategies/index.d.ts +10 -0
  59. package/dist/strategies/index.js +11 -0
  60. package/dist/types/assessment.d.ts +62 -0
  61. package/dist/types/assessment.js +1 -0
  62. package/dist/types/index.d.ts +278 -0
  63. package/dist/types/index.js +17 -0
  64. package/dist/utils/DOMObserver.d.ts +68 -0
  65. package/dist/utils/DOMObserver.js +134 -0
  66. package/dist/utils/base/LoggableComponent.d.ts +44 -0
  67. package/dist/utils/base/LoggableComponent.js +56 -0
  68. package/dist/utils/detectors/AbstractDevToolsDetector.d.ts +98 -0
  69. package/dist/utils/detectors/AbstractDevToolsDetector.js +127 -0
  70. package/dist/utils/detectors/dateToStringDetector.d.ts +43 -0
  71. package/dist/utils/detectors/dateToStringDetector.js +96 -0
  72. package/dist/utils/detectors/debugLibDetector.d.ts +64 -0
  73. package/dist/utils/detectors/debugLibDetector.js +195 -0
  74. package/dist/utils/detectors/debuggerDetector.d.ts +51 -0
  75. package/dist/utils/detectors/debuggerDetector.js +211 -0
  76. package/dist/utils/detectors/defineGetterDetector.d.ts +48 -0
  77. package/dist/utils/detectors/defineGetterDetector.js +150 -0
  78. package/dist/utils/detectors/detectorInterface.d.ts +36 -0
  79. package/dist/utils/detectors/detectorInterface.js +1 -0
  80. package/dist/utils/detectors/devToolsDetectorManager.d.ts +88 -0
  81. package/dist/utils/detectors/devToolsDetectorManager.js +243 -0
  82. package/dist/utils/detectors/funcToStringDetector.d.ts +43 -0
  83. package/dist/utils/detectors/funcToStringDetector.js +90 -0
  84. package/dist/utils/detectors/regToStringDetector.d.ts +43 -0
  85. package/dist/utils/detectors/regToStringDetector.js +129 -0
  86. package/dist/utils/detectors/sizeDetector.d.ts +54 -0
  87. package/dist/utils/detectors/sizeDetector.js +134 -0
  88. package/dist/utils/detectors/timingDetector.d.ts +55 -0
  89. package/dist/utils/detectors/timingDetector.js +143 -0
  90. package/dist/utils/dom.d.ts +20 -0
  91. package/dist/utils/dom.js +83 -0
  92. package/dist/utils/environment.d.ts +29 -0
  93. package/dist/utils/environment.js +267 -0
  94. package/dist/utils/eventManager.d.ts +162 -0
  95. package/dist/utils/eventManager.js +548 -0
  96. package/dist/utils/index.d.ts +2 -0
  97. package/dist/utils/index.js +3 -0
  98. package/dist/utils/intervalManager.d.ts +91 -0
  99. package/dist/utils/intervalManager.js +221 -0
  100. package/dist/utils/keyboardShortcutManager/keyboardShortcutManager.d.ts +41 -0
  101. package/dist/utils/keyboardShortcutManager/keyboardShortcutManager.js +135 -0
  102. package/dist/utils/keyboardShortcutManager/keyboardShortcuts.d.ts +18 -0
  103. package/dist/utils/keyboardShortcutManager/keyboardShortcuts.js +195 -0
  104. package/dist/utils/logging/simple/Loggable.d.ts +33 -0
  105. package/dist/utils/logging/simple/Loggable.js +1 -0
  106. package/dist/utils/logging/simple/LoggingDelegate.d.ts +42 -0
  107. package/dist/utils/logging/simple/LoggingDelegate.js +53 -0
  108. package/dist/utils/logging/simple/SimpleLoggingService.d.ts +39 -0
  109. package/dist/utils/logging/simple/SimpleLoggingService.js +58 -0
  110. package/dist/utils/orientation.d.ts +15 -0
  111. package/dist/utils/orientation.js +32 -0
  112. package/dist/utils/protectedContentManager.d.ts +155 -0
  113. package/dist/utils/protectedContentManager.js +424 -0
  114. package/dist/utils/securityOverlayManager.d.ts +253 -0
  115. package/dist/utils/securityOverlayManager.js +786 -0
  116. package/dist/utils/timeoutManager.d.ts +50 -0
  117. package/dist/utils/timeoutManager.js +113 -0
  118. package/package.json +61 -0
@@ -0,0 +1,221 @@
1
+ import { isBrowser } from "./environment";
2
+ import { LoggableComponent } from "./base/LoggableComponent";
3
+ /**
4
+ * Manages periodic tasks for the content protection toolkit
5
+ * Consolidates multiple interval timers into a single efficient timer
6
+ */
7
+ export class IntervalManager extends LoggableComponent {
8
+ /**
9
+ * Create a new IntervalManager
10
+ * @param debugMode Enable debug mode for troubleshooting
11
+ */
12
+ constructor(debugMode = false) {
13
+ super("IntervalManager", debugMode);
14
+ this.tasks = new Map();
15
+ this.intervalId = null;
16
+ this.intervalFrequency = 500; // Base interval in ms (2 checks per second)
17
+ this.isRunning = false;
18
+ this.logger.log("Initialized");
19
+ }
20
+ /**
21
+ * Register a new task to be executed periodically
22
+ * @param id Unique identifier for the task
23
+ * @param callback Function to execute
24
+ * @param frequency How often to run the task in milliseconds
25
+ * @returns The task ID for later reference
26
+ */
27
+ registerTask(id, callback, frequency) {
28
+ if (!isBrowser())
29
+ return id;
30
+ // Ensure we have a unique ID by appending a timestamp if needed
31
+ let taskId = id;
32
+ if (this.tasks.has(taskId)) {
33
+ taskId = `${id}-${Date.now()}`;
34
+ }
35
+ this.tasks.set(taskId, {
36
+ id: taskId,
37
+ callback,
38
+ frequency,
39
+ lastRun: 0,
40
+ isActive: true,
41
+ });
42
+ this.logger.log(`Registered task "${taskId}" with frequency ${frequency}ms`);
43
+ // Start the interval if it's not already running
44
+ this.startInterval();
45
+ return taskId;
46
+ }
47
+ /**
48
+ * Unregister a task by ID
49
+ * @param id Task ID to remove
50
+ * @returns True if the task was found and removed
51
+ */
52
+ unregisterTask(id) {
53
+ if (!isBrowser())
54
+ return false;
55
+ const result = this.tasks.delete(id);
56
+ if (result) {
57
+ this.logger.log(`Unregistered task "${id}"`);
58
+ }
59
+ // If no tasks remain, stop the interval
60
+ if (this.tasks.size === 0) {
61
+ this.stopInterval();
62
+ }
63
+ return result;
64
+ }
65
+ /**
66
+ * Pause a specific task without removing it
67
+ * @param id Task ID to pause
68
+ * @returns True if the task was found and paused
69
+ */
70
+ pauseTask(id) {
71
+ if (!isBrowser())
72
+ return false;
73
+ const task = this.tasks.get(id);
74
+ if (task) {
75
+ task.isActive = false;
76
+ this.tasks.set(id, task);
77
+ this.logger.log(`Paused task "${id}"`);
78
+ return true;
79
+ }
80
+ return false;
81
+ }
82
+ /**
83
+ * Resume a paused task
84
+ * @param id Task ID to resume
85
+ * @returns True if the task was found and resumed
86
+ */
87
+ resumeTask(id) {
88
+ if (!isBrowser())
89
+ return false;
90
+ const task = this.tasks.get(id);
91
+ if (task) {
92
+ task.isActive = true;
93
+ this.tasks.set(id, task);
94
+ this.logger.log(`Resumed task "${id}"`);
95
+ return true;
96
+ }
97
+ return false;
98
+ }
99
+ /**
100
+ * Start the interval timer
101
+ */
102
+ startInterval() {
103
+ if (this.isRunning || !isBrowser())
104
+ return;
105
+ this.intervalId = window.setInterval(() => {
106
+ this.executeEligibleTasks();
107
+ }, this.intervalFrequency);
108
+ this.isRunning = true;
109
+ this.logger.log(`Started interval timer with frequency ${this.intervalFrequency}ms`);
110
+ }
111
+ /**
112
+ * Stop the interval timer
113
+ */
114
+ stopInterval() {
115
+ if (!this.isRunning || !isBrowser())
116
+ return;
117
+ if (this.intervalId !== null) {
118
+ window.clearInterval(this.intervalId);
119
+ this.intervalId = null;
120
+ }
121
+ this.isRunning = false;
122
+ this.logger.log("Stopped interval timer");
123
+ }
124
+ /**
125
+ * Execute all tasks that are due to run
126
+ */
127
+ executeEligibleTasks() {
128
+ const now = Date.now();
129
+ this.tasks.forEach((task) => {
130
+ // Skip inactive tasks
131
+ if (!task.isActive)
132
+ return;
133
+ // Check if the task is due to run
134
+ const timeSinceLastRun = now - (task.lastRun || 0);
135
+ if (timeSinceLastRun >= task.frequency) {
136
+ try {
137
+ this.logger.log(`Executing task "${task.id}"`);
138
+ // Execute the task
139
+ task.callback();
140
+ // Update the last run time
141
+ task.lastRun = now;
142
+ this.tasks.set(task.id, task);
143
+ }
144
+ catch (error) {
145
+ this.logger.error(`Error executing task "${task.id}":`, error);
146
+ }
147
+ }
148
+ });
149
+ }
150
+ /**
151
+ * Force execution of a specific task immediately
152
+ * @param id Task ID to execute
153
+ * @returns True if the task was found and executed
154
+ */
155
+ executeTaskNow(id) {
156
+ if (!isBrowser())
157
+ return false;
158
+ const task = this.tasks.get(id);
159
+ if (task && task.isActive) {
160
+ try {
161
+ this.logger.log(`Executing task "${id}" immediately`);
162
+ task.callback();
163
+ task.lastRun = Date.now();
164
+ this.tasks.set(id, task);
165
+ return true;
166
+ }
167
+ catch (error) {
168
+ this.logger.error(`Error executing task "${id}" immediately:`, error);
169
+ }
170
+ }
171
+ return false;
172
+ }
173
+ /**
174
+ * Get the current status of all registered tasks
175
+ * @returns Array of task status objects
176
+ */
177
+ getTasksStatus() {
178
+ const now = Date.now();
179
+ const result = [];
180
+ this.tasks.forEach((task) => {
181
+ result.push({
182
+ id: task.id,
183
+ isActive: task.isActive,
184
+ frequency: task.frequency,
185
+ lastRun: task.lastRun,
186
+ timeSinceLastRun: task.lastRun ? now - task.lastRun : null,
187
+ });
188
+ });
189
+ return result;
190
+ }
191
+ /**
192
+ * Clean up and stop all intervals
193
+ */
194
+ dispose() {
195
+ if (!isBrowser())
196
+ return;
197
+ this.stopInterval();
198
+ this.tasks.clear();
199
+ this.logger.log("Disposed");
200
+ }
201
+ /**
202
+ * Update the base interval frequency
203
+ * @param frequency New frequency in milliseconds
204
+ */
205
+ setIntervalFrequency(frequency) {
206
+ if (frequency < 100) {
207
+ this.logger.warn("Frequency below 100ms may cause performance issues");
208
+ }
209
+ this.intervalFrequency = frequency;
210
+ // Restart the interval with the new frequency if it's running
211
+ if (this.isRunning) {
212
+ this.stopInterval();
213
+ this.startInterval();
214
+ }
215
+ this.logger.log(`Updated interval frequency to ${frequency}ms`);
216
+ }
217
+ }
218
+ /**
219
+ * Create a singleton instance for use throughout the application
220
+ */
221
+ export const intervalManager = new IntervalManager(false);
@@ -0,0 +1,41 @@
1
+ import { ShortcutCategory, KeyboardShortcut } from "./keyboardShortcuts";
2
+ export type OSType = "windows" | "mac" | "linux" | "unknown";
3
+ export declare class KeyboardShortcutManager {
4
+ private static instance;
5
+ private shortcuts;
6
+ private osType;
7
+ private constructor();
8
+ static getInstance(): KeyboardShortcutManager;
9
+ /**
10
+ * Get all registered shortcuts
11
+ */
12
+ getAllShortcuts(): KeyboardShortcut[];
13
+ /**
14
+ * Get shortcuts by category
15
+ */
16
+ getShortcutsByCategory(category: ShortcutCategory): KeyboardShortcut[];
17
+ /**
18
+ * Get shortcuts for multiple categories
19
+ */
20
+ getShortcutsByCategories(categories: ShortcutCategory[]): KeyboardShortcut[];
21
+ /**
22
+ * Check if a keyboard event matches any shortcut in the given categories
23
+ */
24
+ matchesShortcut(event: KeyboardEvent, categories?: ShortcutCategory[]): KeyboardShortcut | null;
25
+ /**
26
+ * Check if a keyboard event matches a specific shortcut
27
+ */
28
+ private eventMatchesShortcut;
29
+ /**
30
+ * Check if modifiers in the event match the required modifiers
31
+ */
32
+ private checkModifiers;
33
+ /**
34
+ * Get a description of a keyboard shortcut for the current OS
35
+ */
36
+ getShortcutDescription(shortcut: KeyboardShortcut): string;
37
+ /**
38
+ * Format keys for display (e.g., "Ctrl+C")
39
+ */
40
+ private formatKeysForDisplay;
41
+ }
@@ -0,0 +1,135 @@
1
+ import { ShortcutCategory, ALL_SHORTCUTS } from "./keyboardShortcuts";
2
+ import { getOS } from "../environment";
3
+ export class KeyboardShortcutManager {
4
+ constructor() {
5
+ this.shortcuts = ALL_SHORTCUTS;
6
+ const os = getOS();
7
+ this.osType = os.name;
8
+ }
9
+ static getInstance() {
10
+ if (!KeyboardShortcutManager.instance) {
11
+ KeyboardShortcutManager.instance = new KeyboardShortcutManager();
12
+ }
13
+ return KeyboardShortcutManager.instance;
14
+ }
15
+ /**
16
+ * Get all registered shortcuts
17
+ */
18
+ getAllShortcuts() {
19
+ return this.shortcuts;
20
+ }
21
+ /**
22
+ * Get shortcuts by category
23
+ */
24
+ getShortcutsByCategory(category) {
25
+ return this.shortcuts.filter(shortcut => shortcut.category === category);
26
+ }
27
+ /**
28
+ * Get shortcuts for multiple categories
29
+ */
30
+ getShortcutsByCategories(categories) {
31
+ return this.shortcuts.filter(shortcut => categories.includes(shortcut.category));
32
+ }
33
+ /**
34
+ * Check if a keyboard event matches any shortcut in the given categories
35
+ */
36
+ matchesShortcut(event, categories = Object.values(ShortcutCategory)) {
37
+ const relevantShortcuts = this.getShortcutsByCategories(categories);
38
+ for (const shortcut of relevantShortcuts) {
39
+ if (this.eventMatchesShortcut(event, shortcut)) {
40
+ return shortcut;
41
+ }
42
+ }
43
+ return null;
44
+ }
45
+ /**
46
+ * Check if a keyboard event matches a specific shortcut
47
+ */
48
+ eventMatchesShortcut(event, shortcut) {
49
+ // Get the appropriate keys based on platform
50
+ let keysToCheck = shortcut.keys;
51
+ if (this.osType === "mac" && shortcut.macKeys) {
52
+ keysToCheck = shortcut.macKeys;
53
+ }
54
+ else if (this.osType === "linux" && shortcut.linuxKeys) {
55
+ keysToCheck = shortcut.linuxKeys;
56
+ }
57
+ // If there are no keys for this platform, this shortcut doesn't apply
58
+ if (!keysToCheck || keysToCheck.length === 0) {
59
+ return false;
60
+ }
61
+ // Special case for modifier keys
62
+ const modifiersMatch = this.checkModifiers(event, keysToCheck);
63
+ // Check if the main key matches (non-modifier key)
64
+ const mainKeys = keysToCheck.filter(key => !["Control", "Alt", "Shift", "Meta", "Win", "Option"].includes(key));
65
+ // If there's no main key, just check modifiers
66
+ if (mainKeys.length === 0) {
67
+ return modifiersMatch;
68
+ }
69
+ // Check if any of the main keys match the event key
70
+ const keyMatches = mainKeys.some(key => {
71
+ // Handle special cases like PrintScreen which might be reported differently
72
+ if (key === "PrintScreen" &&
73
+ (event.key === "PrintScreen" ||
74
+ event.key === "PrtScn" ||
75
+ event.key === "Print" ||
76
+ event.code === "PrintScreen" ||
77
+ event.keyCode === 44)) {
78
+ return true;
79
+ }
80
+ // Handle function keys
81
+ if (key.startsWith("F") && !isNaN(parseInt(key.substring(1)))) {
82
+ return event.key === key;
83
+ }
84
+ // Normal key matching
85
+ return event.key.toLowerCase() === key.toLowerCase() ||
86
+ event.code.toLowerCase() === key.toLowerCase();
87
+ });
88
+ return modifiersMatch && keyMatches;
89
+ }
90
+ /**
91
+ * Check if modifiers in the event match the required modifiers
92
+ */
93
+ checkModifiers(event, keys) {
94
+ // Handle different naming conventions
95
+ const hasCtrl = keys.includes("Control") || keys.includes("Ctrl");
96
+ const hasAlt = keys.includes("Alt") || keys.includes("Option");
97
+ const hasShift = keys.includes("Shift");
98
+ const hasMeta = keys.includes("Meta") || keys.includes("Win") || keys.includes("Command");
99
+ return ((hasCtrl === event.ctrlKey) &&
100
+ (hasAlt === event.altKey) &&
101
+ (hasShift === event.shiftKey) &&
102
+ (hasMeta === event.metaKey));
103
+ }
104
+ /**
105
+ * Get a description of a keyboard shortcut for the current OS
106
+ */
107
+ getShortcutDescription(shortcut) {
108
+ let keysToUse = shortcut.keys;
109
+ if (this.osType === "mac" && shortcut.macKeys) {
110
+ keysToUse = shortcut.macKeys;
111
+ }
112
+ else if (this.osType === "linux" && shortcut.linuxKeys) {
113
+ keysToUse = shortcut.linuxKeys;
114
+ }
115
+ // Format the keys for display
116
+ return this.formatKeysForDisplay(keysToUse);
117
+ }
118
+ /**
119
+ * Format keys for display (e.g., "Ctrl+C")
120
+ */
121
+ formatKeysForDisplay(keys) {
122
+ return keys.map(key => {
123
+ // Replace with more readable versions
124
+ switch (key) {
125
+ case "Control": return this.osType === "mac" ? "Ctrl" : "Ctrl";
126
+ case "Meta": return this.osType === "mac" ? "⌘" : "Win";
127
+ case "Alt": return this.osType === "mac" ? "Option" : "Alt";
128
+ case "Shift": return this.osType === "mac" ? "⇧" : "Shift";
129
+ case "Option": return "Option";
130
+ case "Win": return "Win";
131
+ default: return key;
132
+ }
133
+ }).join(this.osType === "mac" ? " + " : "+");
134
+ }
135
+ }
@@ -0,0 +1,18 @@
1
+ export declare enum ShortcutCategory {
2
+ COPY = "copy",
3
+ SAVE = "save",
4
+ PRINT = "print",
5
+ VIEW_SOURCE = "viewSource",
6
+ DEVTOOLS = "devTools",
7
+ SCREENSHOT = "screenshot",
8
+ FULLSCREEN = "fullscreen"
9
+ }
10
+ export interface KeyboardShortcut {
11
+ id: string;
12
+ category: ShortcutCategory;
13
+ description: string;
14
+ keys: string[];
15
+ macKeys?: string[];
16
+ linuxKeys?: string[];
17
+ }
18
+ export declare const ALL_SHORTCUTS: KeyboardShortcut[];
@@ -0,0 +1,195 @@
1
+ export var ShortcutCategory;
2
+ (function (ShortcutCategory) {
3
+ ShortcutCategory["COPY"] = "copy";
4
+ ShortcutCategory["SAVE"] = "save";
5
+ ShortcutCategory["PRINT"] = "print";
6
+ ShortcutCategory["VIEW_SOURCE"] = "viewSource";
7
+ ShortcutCategory["DEVTOOLS"] = "devTools";
8
+ ShortcutCategory["SCREENSHOT"] = "screenshot";
9
+ ShortcutCategory["FULLSCREEN"] = "fullscreen";
10
+ })(ShortcutCategory || (ShortcutCategory = {}));
11
+ // Define all shortcuts
12
+ export const ALL_SHORTCUTS = [
13
+ {
14
+ id: "save",
15
+ category: ShortcutCategory.SAVE,
16
+ description: "Save page",
17
+ keys: ["Control", "s"],
18
+ macKeys: ["Meta", "s"],
19
+ // Linux typically uses the same as Windows for this
20
+ },
21
+ {
22
+ id: "print",
23
+ category: ShortcutCategory.PRINT,
24
+ description: "Print page",
25
+ keys: ["Control", "p"],
26
+ macKeys: ["Meta", "p"],
27
+ },
28
+ {
29
+ id: "view-source",
30
+ category: ShortcutCategory.VIEW_SOURCE,
31
+ description: "View page source",
32
+ keys: ["Control", "u"],
33
+ macKeys: ["Meta", "u"],
34
+ },
35
+ {
36
+ id: "copy",
37
+ category: ShortcutCategory.COPY,
38
+ description: "Copy selected content",
39
+ keys: ["Control", "c"],
40
+ macKeys: ["Meta", "c"],
41
+ },
42
+ {
43
+ id: "cut",
44
+ category: ShortcutCategory.COPY,
45
+ description: "Cut selected content",
46
+ keys: ["Control", "x"],
47
+ macKeys: ["Meta", "x"],
48
+ },
49
+ {
50
+ id: "devtools-open",
51
+ category: ShortcutCategory.DEVTOOLS,
52
+ description: "Open developer tools",
53
+ keys: ["F12"],
54
+ macKeys: ["F12"],
55
+ linuxKeys: ["F12"],
56
+ },
57
+ {
58
+ id: "devtools-inspect",
59
+ category: ShortcutCategory.DEVTOOLS,
60
+ description: "Open developer tools inspector",
61
+ keys: ["Control", "Shift", "i"],
62
+ macKeys: ["Meta", "Option", "i"],
63
+ linuxKeys: ["Control", "Shift", "i"],
64
+ },
65
+ {
66
+ id: "devtools-console",
67
+ category: ShortcutCategory.DEVTOOLS,
68
+ description: "Open developer tools console",
69
+ keys: ["Control", "Shift", "j"],
70
+ macKeys: ["Meta", "Option", "j"],
71
+ linuxKeys: ["Control", "Shift", "j"],
72
+ },
73
+ {
74
+ id: "screenshot-printscreen",
75
+ category: ShortcutCategory.SCREENSHOT,
76
+ description: "Take screenshot (Windows/Linux)",
77
+ keys: ["PrintScreen"],
78
+ linuxKeys: ["PrintScreen"],
79
+ },
80
+ {
81
+ id: "screenshot-area-linux",
82
+ category: ShortcutCategory.SCREENSHOT,
83
+ description: "Take area screenshot (Linux)",
84
+ keys: ["Shift", "PrintScreen"],
85
+ linuxKeys: ["Shift", "PrintScreen"],
86
+ },
87
+ {
88
+ id: "screenshot-window-linux",
89
+ category: ShortcutCategory.SCREENSHOT,
90
+ description: "Take window screenshot (Linux)",
91
+ keys: ["Alt", "PrintScreen"],
92
+ linuxKeys: ["Alt", "PrintScreen"],
93
+ },
94
+ {
95
+ id: "screenshot-clipboard-linux",
96
+ category: ShortcutCategory.SCREENSHOT,
97
+ description: "Copy screenshot to clipboard (Linux)",
98
+ keys: ["Control", "PrintScreen"],
99
+ linuxKeys: ["Control", "PrintScreen"],
100
+ },
101
+ {
102
+ id: "screenshot-gnome-special",
103
+ category: ShortcutCategory.SCREENSHOT,
104
+ description: "GNOME special screenshot shortcut",
105
+ keys: ["Control", "Shift", "p"],
106
+ linuxKeys: ["Control", "Shift", "p"],
107
+ },
108
+ {
109
+ id: "screenshot-flameshot",
110
+ category: ShortcutCategory.SCREENSHOT,
111
+ description: "Flameshot screenshot tool (Linux)",
112
+ keys: ["F10"],
113
+ linuxKeys: ["F10"],
114
+ },
115
+ {
116
+ id: "screenshot-mac-full",
117
+ category: ShortcutCategory.SCREENSHOT,
118
+ description: "Take full screenshot (Mac)",
119
+ keys: [], // Empty for Windows/Linux
120
+ macKeys: ["Shift", "Meta", "3"],
121
+ },
122
+ {
123
+ id: "screenshot-mac-area",
124
+ category: ShortcutCategory.SCREENSHOT,
125
+ description: "Take area screenshot (Mac)",
126
+ keys: [], // Empty for Windows/Linux
127
+ macKeys: ["Shift", "Meta", "4"],
128
+ },
129
+ {
130
+ id: "screenshot-mac-tools",
131
+ category: ShortcutCategory.SCREENSHOT,
132
+ description: "Open screenshot tools (Mac)",
133
+ keys: [], // Empty for Windows/Linux
134
+ macKeys: ["Shift", "Meta", "5"],
135
+ },
136
+ {
137
+ id: "screenshot-win-snipping",
138
+ category: ShortcutCategory.SCREENSHOT,
139
+ description: "Open Snipping Tool (Windows)",
140
+ keys: ["Win", "Shift", "s"],
141
+ },
142
+ {
143
+ id: "screenshot-win-snapshot",
144
+ category: ShortcutCategory.SCREENSHOT,
145
+ description: "Windows SnapshotKey",
146
+ keys: ["SnapshotKey"],
147
+ },
148
+ {
149
+ id: "screenshot-firefox-save",
150
+ category: ShortcutCategory.SCREENSHOT,
151
+ description: "Firefox Save Page As (can be used for screenshots)",
152
+ keys: ["Alt", "s"],
153
+ },
154
+ {
155
+ id: "fullscreen",
156
+ category: ShortcutCategory.FULLSCREEN,
157
+ description: "Toggle fullscreen mode",
158
+ keys: ["F11"],
159
+ macKeys: ["F11"],
160
+ linuxKeys: ["F11"],
161
+ },
162
+ {
163
+ id: "fullscreen-alt-enter",
164
+ category: ShortcutCategory.FULLSCREEN,
165
+ description: "Toggle fullscreen mode (Alt+Enter)",
166
+ keys: ["Alt", "Enter"],
167
+ linuxKeys: ["Alt", "Enter"],
168
+ },
169
+ {
170
+ id: "fullscreen-ctrl-f",
171
+ category: ShortcutCategory.FULLSCREEN,
172
+ description: "Toggle fullscreen in some browsers",
173
+ keys: ["Control", "f"],
174
+ macKeys: ["Meta", "f"],
175
+ },
176
+ {
177
+ id: "fullscreen-alt-f",
178
+ category: ShortcutCategory.FULLSCREEN,
179
+ description: "Toggle fullscreen in some applications",
180
+ keys: ["Alt", "f"],
181
+ },
182
+ {
183
+ id: "fullscreen-alt-k",
184
+ category: ShortcutCategory.FULLSCREEN,
185
+ description: "Toggle fullscreen in some media players",
186
+ keys: ["Alt", "k"],
187
+ },
188
+ {
189
+ id: "fullscreen-mac",
190
+ category: ShortcutCategory.FULLSCREEN,
191
+ description: "Toggle fullscreen on Mac",
192
+ keys: [],
193
+ macKeys: ["Control", "Meta", "f"],
194
+ },
195
+ ];
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Interface for components that support logging
3
+ */
4
+ export interface Loggable {
5
+ /**
6
+ * Log a debug message if debug mode is enabled
7
+ * @param message Message to log
8
+ * @param args Additional arguments to log
9
+ */
10
+ log(message: string, ...args: unknown[]): void;
11
+ /**
12
+ * Log a warning message
13
+ * @param message Warning message
14
+ * @param args Additional arguments to log
15
+ */
16
+ warn(message: string, ...args: unknown[]): void;
17
+ /**
18
+ * Log an error message
19
+ * @param message Error message
20
+ * @param args Additional arguments to log
21
+ */
22
+ error(message: string, ...args: unknown[]): void;
23
+ /**
24
+ * Set debug mode
25
+ * @param enabled Whether debug mode should be enabled
26
+ */
27
+ setDebugMode(enabled: boolean): void;
28
+ /**
29
+ * Check if debug mode is enabled
30
+ * @returns Whether debug mode is enabled
31
+ */
32
+ isDebugEnabled(): boolean;
33
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,42 @@
1
+ import { Loggable } from "./Loggable";
2
+ /**
3
+ * Delegate class that implements logging functionality
4
+ * Can be composed into any class that needs logging
5
+ */
6
+ export declare class LoggingDelegate implements Loggable {
7
+ private logger;
8
+ /**
9
+ * Create a new LoggingDelegate
10
+ * @param componentName Name of the component for log prefixing
11
+ * @param debugMode Whether debug mode is enabled
12
+ */
13
+ constructor(componentName: string, debugMode?: boolean);
14
+ /**
15
+ * Log a debug message if debug mode is enabled
16
+ * @param message Message to log
17
+ * @param args Additional arguments to log
18
+ */
19
+ log(message: string, ...args: unknown[]): void;
20
+ /**
21
+ * Log a warning message
22
+ * @param message Warning message
23
+ * @param args Additional arguments to log
24
+ */
25
+ warn(message: string, ...args: unknown[]): void;
26
+ /**
27
+ * Log an error message
28
+ * @param message Error message
29
+ * @param args Additional arguments to log
30
+ */
31
+ error(message: string, ...args: unknown[]): void;
32
+ /**
33
+ * Set debug mode
34
+ * @param enabled Whether debug mode should be enabled
35
+ */
36
+ setDebugMode(enabled: boolean): void;
37
+ /**
38
+ * Check if debug mode is enabled
39
+ * @returns Whether debug mode is enabled
40
+ */
41
+ isDebugEnabled(): boolean;
42
+ }