| 1 | /* global tinymce */ |
| 2 | tinymce.PluginManager.add( 'wpaudiovideo', function( editor ) { |
| 3 | |
| 4 | function parseMediaShortcode( content ) { |
| 5 | return content.replace( /\[(audio|video)[^\]]*\][\s\S]*?\[\/\1\]/g, function( match, type ) { |
| 6 | var data = tinymce.DOM.encode( match.substr(1) ), |
| 7 | cls = 'wp-media-shortcode dashicons dashicons-format-' + type; |
| 8 | |
| 9 | return '<div class="' + cls + '" title="' + data + '" contenteditable="false">\u00a0</div>'; |
| 10 | }); |
| 11 | } |
| 12 | |
| 13 | function getMediaShortcode( content ) { |
| 14 | function getAttr( str, name ) { |
| 15 | name = new RegExp( name + '=\"([^\"]+)\"', 'g' ).exec( str ); |
| 16 | return name ? window.decodeURIComponent( name[1] ) : ''; |
| 17 | } |
| 18 | |
| 19 | return content.replace( /<div ([^>]+)>(?:\u00a0| | )*<\/div>/g, function( match, attr ) { |
| 20 | var cls = getAttr( attr, 'class' ); |
| 21 | |
| 22 | if ( cls.indexOf('wp-media-shortcode') !== -1 ) { |
| 23 | return tinymce.trim( '[' + getAttr( attr, 'title' ) ); |
| 24 | } |
| 25 | |
| 26 | return match; |
| 27 | }); |
| 28 | } |
| 29 | |
| 30 | editor.on( 'BeforeSetContent', function( e ) { |
| 31 | e.content = parseMediaShortcode( e.content ); |
| 32 | }); |
| 33 | |
| 34 | editor.on( 'PostProcess', function( e ) { |
| 35 | if ( e.get ) { |
| 36 | e.content = getMediaShortcode( e.content ); |
| 37 | } |
| 38 | }); |
| 39 | |
| 40 | editor.on( 'init', function() { |
| 41 | var dom = editor.dom, |
| 42 | selection = editor.selection; |
| 43 | |
| 44 | function moveCaret( node ) { |
| 45 | selection.select( node.nextSibling || node.previousSibling || node.parentNode ); |
| 46 | selection.collapse( true ); |
| 47 | editor.nodeChanged(); |
| 48 | } |
| 49 | |
| 50 | function getWrapper( event ) { |
| 51 | if ( dom.hasClass( event.target, 'wp-control' ) ) { |
| 52 | return event.target; |
| 53 | } else { |
| 54 | return dom.getParent( event.target, 'div.wp-control' ) || dom.getParent( selection.getNode(), 'div.wp-control' ); |
| 55 | } |
| 56 | } |
| 57 | |
| 58 | editor.on( 'click contextmenu', function( event ) { |
| 59 | var wrapper = getWrapper( event ); |
| 60 | |
| 61 | if ( wrapper ) { |
| 62 | // Don't follow links in the non-editable wrapper |
| 63 | if ( dom.is( event.target, 'a' ) || dom.getParent( event.target, 'a' ) ) { |
| 64 | event.preventDefault(); |
| 65 | } |
| 66 | |
| 67 | if ( tinymce.Env.ie ) { |
| 68 | // Move the caret out of the wrapper |
| 69 | moveCaret( wrapper ); |
| 70 | } |
| 71 | } |
| 72 | }); |
| 73 | |
| 74 | editor.on( 'mousedown', function( event ) { |
| 75 | var wrapper = getWrapper( event ); |
| 76 | |
| 77 | if ( wrapper ) { |
| 78 | dom.addClass( wrapper, 'wp-selected' ) |
| 79 | event.preventDefault(); |
| 80 | |
| 81 | if ( tinymce.Env.ie && tinymce.Env.ie < 9 ) { |
| 82 | // Move the caret out of the wrapper |
| 83 | setTimeout( function() { |
| 84 | moveCaret( wrapper ); |
| 85 | }, 0 ); |
| 86 | |
| 87 | |
| 88 | // Prevent IE < 9 from making the div resizable. |
| 89 | // Without this the tick border and resize handles show for a moment. |
| 90 | // oncontrolselect and unselectable="on" don't seem to work here :( |
| 91 | // throw new Error('(ignore me)'); |
| 92 | } |
| 93 | } else { |
| 94 | dom.removeClass( dom.select( 'div.wp-selected' ), 'wp-selected' ); |
| 95 | } |
| 96 | }); |
| 97 | |
| 98 | editor.on( 'keydown', function( event ) { |
| 99 | var element, p, |
| 100 | key = event.keyCode; |
| 101 | |
| 102 | if ( key === tinymce.util.VK.DELETE || key === tinymce.util.VK.BACKSPACE ) { |
| 103 | element = dom.select( 'div.wp-selected' ); |
| 104 | |
| 105 | if ( element.length ) { |
| 106 | dom.events.cancel( event ); |
| 107 | dom.remove( element[0] ); |
| 108 | editor.nodeChanged(); |
| 109 | } |
| 110 | } |
| 111 | }); |
| 112 | }); |
| 113 | |
| 114 | return { |
| 115 | parseMediaShortcode: parseMediaShortcode, |
| 116 | getMediaShortcode: getMediaShortcode |
| 117 | }; |
| 118 | }); |