@@ -21,6 +21,13 @@ const statusDiv = document.getElementById('status');
2121const saveBtn = document . getElementById ( 'save' ) ;
2222const testBtn = document . getElementById ( 'test' ) ;
2323const clearBtn = document . getElementById ( 'clearConfig' ) ;
24+ const newMenuItemInput = document . getElementById ( 'newMenuItemName' ) ;
25+ const addMenuItemBtn = document . getElementById ( 'addMenuItem' ) ;
26+ const contextMenuItemsDiv = document . getElementById ( 'contextMenuItems' ) ;
27+
28+ // --- Context Menu Items Management ---
29+
30+ let contextMenuItems = [ { id : 'default' , name : 'Default' } ] ; // Default item always present
2431
2532// --- Initialization ---
2633
@@ -33,6 +40,7 @@ document.addEventListener('DOMContentLoaded', function() {
3340 loadSavedConfiguration ( ) ;
3441 setupEventListeners ( ) ;
3542 updateSslWarning ( ) ;
43+ loadContextMenuItems ( ) ;
3644} ) ;
3745
3846/**
@@ -143,6 +151,116 @@ function loadSavedConfiguration() {
143151 } ) ;
144152}
145153
154+ /**
155+ * Load context menu items from storage
156+ */
157+ function loadContextMenuItems ( ) {
158+ chrome . storage . sync . get ( [ 'contextMenuItems' ] , ( result ) => {
159+ if ( result . contextMenuItems && Array . isArray ( result . contextMenuItems ) ) {
160+ contextMenuItems = result . contextMenuItems ;
161+ }
162+ renderContextMenuItems ( ) ;
163+ } ) ;
164+ }
165+
166+ /**
167+ * Render context menu items in the UI
168+ */
169+ function renderContextMenuItems ( ) {
170+ contextMenuItemsDiv . innerHTML = '' ;
171+
172+ contextMenuItems . forEach ( ( item , index ) => {
173+ const itemDiv = document . createElement ( 'div' ) ;
174+ itemDiv . className = 'menu-item' ;
175+
176+ const nameSpan = document . createElement ( 'span' ) ;
177+ nameSpan . className = 'menu-item-name' ;
178+ nameSpan . textContent = item . name ;
179+
180+ // Add "Default" indicator for the default item
181+ if ( item . id === 'default' ) {
182+ const defaultSpan = document . createElement ( 'span' ) ;
183+ defaultSpan . className = 'menu-item-default' ;
184+ defaultSpan . textContent = '(Default)' ;
185+ nameSpan . appendChild ( defaultSpan ) ;
186+ }
187+
188+ itemDiv . appendChild ( nameSpan ) ;
189+
190+ // Only allow removing non-default items
191+ if ( item . id !== 'default' ) {
192+ const removeBtn = document . createElement ( 'button' ) ;
193+ removeBtn . className = 'menu-item-remove' ;
194+ removeBtn . textContent = 'Remove' ;
195+ removeBtn . addEventListener ( 'click' , ( ) => removeContextMenuItem ( index ) ) ;
196+ itemDiv . appendChild ( removeBtn ) ;
197+ }
198+
199+ contextMenuItemsDiv . appendChild ( itemDiv ) ;
200+ } ) ;
201+ }
202+
203+ /**
204+ * Add a new context menu item
205+ */
206+ function addContextMenuItem ( ) {
207+ const name = newMenuItemInput . value . trim ( ) ;
208+
209+ if ( ! name ) {
210+ showStatus ( 'Please enter a menu item name.' , 'error' ) ;
211+ return ;
212+ }
213+
214+ if ( name . length > 32 ) {
215+ showStatus ( 'Menu item name cannot exceed 32 characters.' , 'error' ) ;
216+ return ;
217+ }
218+
219+ // Check for duplicate names
220+ if ( contextMenuItems . some ( item => item . name . toLowerCase ( ) === name . toLowerCase ( ) ) ) {
221+ showStatus ( 'A menu item with this name already exists.' , 'error' ) ;
222+ return ;
223+ }
224+
225+ // Generate unique ID
226+ const id = name . toLowerCase ( ) . replace ( / \s + / g, '-' ) . replace ( / [ ^ a - z 0 - 9 - ] / g, '' ) ;
227+
228+ contextMenuItems . push ( { id, name } ) ;
229+
230+ // Save to storage
231+ chrome . storage . sync . set ( { contextMenuItems } , ( ) => {
232+ renderContextMenuItems ( ) ;
233+ newMenuItemInput . value = '' ;
234+ showStatus ( 'Menu item added! Click "Save" to apply changes.' , 'success' ) ;
235+ setTimeout ( clearStatus , 2000 ) ;
236+ } ) ;
237+ }
238+
239+ /**
240+ * Remove a context menu item
241+ * @param {number } index - Index of the item to remove
242+ */
243+ function removeContextMenuItem ( index ) {
244+ if ( index < 0 || index >= contextMenuItems . length ) {
245+ return ;
246+ }
247+
248+ // Don't allow removing the default item
249+ if ( contextMenuItems [ index ] . id === 'default' ) {
250+ showStatus ( 'Cannot remove the default menu item.' , 'error' ) ;
251+ return ;
252+ }
253+
254+ contextMenuItems . splice ( index , 1 ) ;
255+
256+ // Save to storage
257+ chrome . storage . sync . set ( { contextMenuItems } , ( ) => {
258+ renderContextMenuItems ( ) ;
259+ showStatus ( 'Menu item removed! Click "Save" to apply changes.' , 'success' ) ;
260+ setTimeout ( clearStatus , 2000 ) ;
261+ } ) ;
262+ }
263+
146264/**
147265 * Setup event listeners for various UI elements
148266 */
@@ -160,6 +278,20 @@ function setupEventListeners() {
160278 if ( clearBtn ) {
161279 clearBtn . addEventListener ( 'click' , handleClearConfig ) ;
162280 }
281+
282+ // Add menu item button handler
283+ if ( addMenuItemBtn ) {
284+ addMenuItemBtn . addEventListener ( 'click' , addContextMenuItem ) ;
285+ }
286+
287+ // Allow adding menu item by pressing Enter
288+ if ( newMenuItemInput ) {
289+ newMenuItemInput . addEventListener ( 'keypress' , ( e ) => {
290+ if ( e . key === 'Enter' ) {
291+ addContextMenuItem ( ) ;
292+ }
293+ } ) ;
294+ }
163295}
164296
165297// --- Configuration Management ---
@@ -226,7 +358,7 @@ function handleTest() {
226358 * Handle clear config button click
227359 */
228360function handleClearConfig ( ) {
229- chrome . storage . sync . remove ( [ 'haHost' , 'ssl' , 'webhookId' , 'userName' , 'deviceName' ] , ( ) => {
361+ chrome . storage . sync . remove ( [ 'haHost' , 'ssl' , 'webhookId' , 'userName' , 'deviceName' , 'contextMenuItems' ] , ( ) => {
230362 // Clear form fields
231363 hostInput . value = '' ;
232364 sslToggle . checked = true ;
@@ -236,6 +368,10 @@ function handleClearConfig() {
236368 deviceInput . value = '' ;
237369 }
238370
371+ // Reset context menu items to default
372+ contextMenuItems = [ { id : 'default' , name : 'Default' } ] ;
373+ renderContextMenuItems ( ) ;
374+
239375 showStatus ( 'Config cleared!' , 'success' ) ;
240376 setTimeout ( clearStatus , 2000 ) ;
241377 } ) ;
0 commit comments