@@ -358,6 +358,70 @@ function RemoteFunctions(config = {}) {
358358 }
359359 }
360360
361+ /**
362+ * this is for cut button, when user clicks on cut button we copy the element's source code
363+ * into the clipboard and remove it from the src code. read `_cutElementToClipboard` in `LivePreviewEdit.js`
364+ * @param {Event } event
365+ * @param {DOMElement } element - the element we need to cut
366+ */
367+ function _handleCutOptionClick ( event , element ) {
368+ if ( isElementEditable ( element ) ) {
369+ const tagId = element . getAttribute ( "data-brackets-id" ) ;
370+
371+ window . _Brackets_MessageBroker . send ( {
372+ livePreviewEditEnabled : true ,
373+ element : element ,
374+ event : event ,
375+ tagId : Number ( tagId ) ,
376+ cut : true
377+ } ) ;
378+ } else {
379+ console . error ( "The TagID might be unavailable or the element tag is directly body or html" ) ;
380+ }
381+ }
382+
383+ /**
384+ * this is for copy button, similar to cut just we don't remove the elements source code
385+ * @param {Event } event
386+ * @param {DOMElement } element
387+ */
388+ function _handleCopyOptionClick ( event , element ) {
389+ if ( isElementEditable ( element ) ) {
390+ const tagId = element . getAttribute ( "data-brackets-id" ) ;
391+
392+ window . _Brackets_MessageBroker . send ( {
393+ livePreviewEditEnabled : true ,
394+ element : element ,
395+ event : event ,
396+ tagId : Number ( tagId ) ,
397+ copy : true
398+ } ) ;
399+ } else {
400+ console . error ( "The TagID might be unavailable or the element tag is directly body or html" ) ;
401+ }
402+ }
403+
404+ /**
405+ * this is for paste button, this inserts the saved content from clipboard just above this element
406+ * @param {Event } event
407+ * @param {DOMElement } targetElement
408+ */
409+ function _handlePasteOptionClick ( event , targetElement ) {
410+ if ( isElementEditable ( targetElement ) ) {
411+ const targetTagId = targetElement . getAttribute ( "data-brackets-id" ) ;
412+
413+ window . _Brackets_MessageBroker . send ( {
414+ livePreviewEditEnabled : true ,
415+ element : targetElement ,
416+ event : event ,
417+ tagId : Number ( targetTagId ) ,
418+ paste : true
419+ } ) ;
420+ } else {
421+ console . error ( "The TagID might be unavailable or the element tag is directly body or html" ) ;
422+ }
423+ }
424+
361425 /**
362426 * this is for select-parent button
363427 * When user clicks on this option for a particular element, we get its parent element and trigger a click on it
@@ -400,6 +464,12 @@ function RemoteFunctions(config = {}) {
400464 _handleDuplicateOptionClick ( e , element ) ;
401465 } else if ( action === "delete" ) {
402466 _handleDeleteOptionClick ( e , element ) ;
467+ } else if ( action === "cut" ) {
468+ _handleCutOptionClick ( e , element ) ;
469+ } else if ( action === "copy" ) {
470+ _handleCopyOptionClick ( e , element ) ;
471+ } else if ( action === "paste" ) {
472+ _handlePasteOptionClick ( e , element ) ;
403473 } else if ( action === "ai" ) {
404474 _handleAIOptionClick ( e , element ) ;
405475 } else if ( action === "image-gallery" ) {
@@ -1360,6 +1430,30 @@ function RemoteFunctions(config = {}) {
13601430 </svg>
13611431 ` ,
13621432
1433+ cut : `
1434+ <svg viewBox="0 0 24 24" fill="currentColor">
1435+ <circle cx="6" cy="6" r="3"/>
1436+ <circle cx="6" cy="18" r="3"/>
1437+ <line x1="20" y1="4" x2="8.12" y2="15.88" stroke="currentColor" stroke-width="2"/>
1438+ <line x1="14.47" y1="14.48" x2="20" y2="20" stroke="currentColor" stroke-width="2"/>
1439+ <line x1="8.12" y1="8.12" x2="12" y2="12" stroke="currentColor" stroke-width="2"/>
1440+ </svg>
1441+ ` ,
1442+
1443+ copy : `
1444+ <svg viewBox="0 0 24 24" fill="currentColor">
1445+ <rect x="9" y="9" width="13" height="13" rx="2" ry="2" fill="none" stroke="currentColor" stroke-width="2"/>
1446+ <path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" stroke="currentColor" stroke-width="2"/>
1447+ </svg>
1448+ ` ,
1449+
1450+ paste : `
1451+ <svg viewBox="0 0 24 24" fill="currentColor">
1452+ <path d="M16 4h2a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2V6a2 2 0 0 1 2-2h2"/>
1453+ <rect x="8" y="2" width="8" height="4" rx="1" ry="1"/>
1454+ </svg>
1455+ ` ,
1456+
13631457 imageGallery : `
13641458 <svg viewBox="0 0 24 24" fill="currentColor">
13651459 <path d="M21 19V5c0-1.1-.9-2-2-2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2zM8.5 13.5l2.5 3.01L14.5 12l4.5 6H5l3.5-4.5z"/>
@@ -1512,6 +1606,15 @@ function RemoteFunctions(config = {}) {
15121606 <span data-action="delete" title="${ config . strings . delete } ">
15131607 ${ ICONS . trash }
15141608 </span>
1609+ <span data-action="cut" title='Cut'>
1610+ ${ ICONS . cut }
1611+ </span>
1612+ <span data-action="copy" title='Copy'>
1613+ ${ ICONS . copy }
1614+ </span>
1615+ <span data-action="paste" title='Paste'>
1616+ ${ ICONS . paste }
1617+ </span>
15151618 </div>` ;
15161619
15171620 let styles = `
@@ -1614,7 +1717,7 @@ function RemoteFunctions(config = {}) {
16141717 span . addEventListener ( 'click' , ( event ) => {
16151718 event . stopPropagation ( ) ;
16161719 event . preventDefault ( ) ;
1617- // data-action is to differentiate between the buttons (duplicate, delete or select-parent)
1720+ // data-action is to differentiate between the buttons (duplicate, delete, select-parent etc )
16181721 const action = event . currentTarget . getAttribute ( 'data-action' ) ;
16191722 handleOptionClick ( event , action , this . element ) ;
16201723 if ( action !== 'duplicate' ) {
0 commit comments