CKEDITOR.dialog.add( 'googlemapsIcons', function( editor ) { 'use strict'; var MarkerColors = editor.config.googleMaps_markerColors || [ 'green', 'purple', 'yellow', 'blue', 'orange', 'red' ], columns = MarkerColors.length, images = [], dialog; for (var i = 0; i < columns; i++ ) { var name = MarkerColors[i]; images.push({ name:name, src:'https://maps.gstatic.com/mapfiles/ms/micons/' + name + '-dot.png' } ); } var icons = editor.config.googleMaps_Icons; if (icons) { for (name in icons) { var icon = icons[ name ]; images.push( { name:name, src:icon.marker.image } ); } columns = Math.min( 10, images.length ); } /** * Simulate "this" of a dialog for non-dialog events. * @type {CKEDITOR.dialog} */ var onClick = function( evt ) { var target = evt.data.getTarget(), targetName = target.getName(); if ( targetName == 'a' ) target = target.getChild( 0 ); else if ( targetName != 'img' ) return; var name = target.getAttribute( 'data-name' ); dialog.onSelect( name ); dialog.hide(); evt.data.preventDefault(); }; var onKeydown = CKEDITOR.tools.addFunction( function( ev, element ) { ev = new CKEDITOR.dom.event( ev ); element = new CKEDITOR.dom.element( element ); var relative, nodeToMove; var keystroke = ev.getKeystroke(); var rtl = editor.lang.dir == 'rtl'; switch ( keystroke ) { // UP-ARROW case 38 : // relative is TR if ( ( relative = element.getParent().getParent().getPrevious() ) ) { nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); nodeToMove.focus(); } ev.preventDefault(); break; // DOWN-ARROW case 40 : // relative is TR if ( ( relative = element.getParent().getParent().getNext() ) ) { nodeToMove = relative.getChild( [ element.getParent().getIndex(), 0 ] ); if ( nodeToMove ) nodeToMove.focus(); } ev.preventDefault(); break; // ENTER // SPACE case 32 : onClick( { data: ev } ); ev.preventDefault(); break; // RIGHT-ARROW case rtl ? 37 : 39 : // TAB case 9 : // relative is TD if ( ( relative = element.getParent().getNext() ) ) { nodeToMove = relative.getChild( 0 ); nodeToMove.focus(); ev.preventDefault(true); } else { // relative is TR if ( ( relative = element.getParent().getParent().getNext() ) ) { nodeToMove = relative.getChild( [ 0, 0 ] ); if ( nodeToMove ) nodeToMove.focus(); ev.preventDefault(true); } } break; // LEFT-ARROW case rtl ? 39 : 37 : // SHIFT + TAB case CKEDITOR.SHIFT + 9 : // relative is TD if ( ( relative = element.getParent().getPrevious() ) ) { nodeToMove = relative.getChild( 0 ); nodeToMove.focus(); ev.preventDefault(true); } else { // relative is TR if ( ( relative = element.getParent().getParent().getPrevious() ) ) { nodeToMove = relative.getLast().getChild( 0 ); nodeToMove.focus(); ev.preventDefault(true); } } break; default : // Do not stop not handled events. return; } }); var buildHtml = function() { // Build the HTML for the images table. var html = [ '' ]; for ( i = 0 ; i < images.length ; i++ ) { if ( i % columns === 0 ) html.push( '' ); var image = images[ i ]; html.push( '' ); if ( i % columns == columns - 1 ) html.push( '' ); } if ( i < columns - 1 ) { for ( ; i < columns - 1 ; i++ ) html.push( '' ); html.push( '' ); } html.push( '
' + '', '' + '', '
' ); return html.join( '' ); }; var imagesSelector = { type : 'html', html : '
' + buildHtml() + '
', id : 'imagesSelector', onLoad : function( event ) { dialog = event.sender; }, focus : function() { var size = images.length, i; for ( i = 0 ; i < size ; i++ ) { if (images[i].name == dialog.initialName) break; } var initialImage = this.getElement().getElementsByTag( 'a' ).getItem( i ); initialImage.focus(); }, onClick : onClick, style : 'width: 100%; border-collapse: separate;' }; function resolveUrl(url) { // Resolve the url so it becomes a full URL including the host var img = document.createElement('IMG'); img.src = url; url = img.src; img = null; return url; } return { title : editor.lang.googlemaps.selectIcon, minWidth : 270, minHeight : 80, contents : [ { id : 'Info', label : '', title : '', padding : 0, elements : [ imagesSelector, { type:'hbox', children: [ { type : 'button', id : 'browse', style : 'margin-top:4px;margin-bottom:2px; display:inline-block;', label : editor.lang.common.browseServer, filebrowser : { action : 'Browse', target: 'Info:txtUrl', url: editor.config.filebrowserIconBrowseUrl || editor.config.filebrowserImageBrowseUrl || editor.config.filebrowserBrowseUrl } }, { type:'text', hidden:true, id:'txtUrl', onChange: function() { // Add new icon and select it: var value = resolveUrl(this.getValue()), nameParts = value.match(/([^\/]+)\.[^\/]*$/) || value.match(/([^\/]+)[^\/]*$/), name = nameParts && nameParts[1] || value, dialog = this.getDialog(), resized = false; // clean up name = name.replace(/[^\w]/g, ''); // Initialize the object if it doesn't exist if (!editor.config.googleMaps_Icons) editor.config.googleMaps_Icons = {}; // Add the image if it isn't available in the set if (!editor.config.googleMaps_Icons[ name ]) { // Push the new marker var marker = { marker : { image: value } }, shadow = editor.config.googleMaps_shadowMarker; if (shadow) { if (typeof shadow != 'string') shadow = shadow( value ); marker.shadow = { image: shadow }; } editor.config.googleMaps_Icons[ name ] = marker; images.push( { name:name, src:value } ); var contents = dialog.parts.contents, contentTable = contents.getFirst().getFirst().$, initial = { width:contentTable.offsetWidth, height: contentTable.offsetHeight }; // rebuild the table so it shows correctly when the dialog opens again dialog.getContentElement('Info', 'imagesSelector').getElement().setHtml( buildHtml() ); // Check if we need to resize the dialog if (contentTable.offsetWidth > initial.width || contentTable.offsetHeight > initial.height) { resized = true; dialog.resize( contentTable.offsetWidth, contentTable.offsetHeight); } } // select it dialog.onSelect( name ); if ( !resized || !CKEDITOR.env.ie || CKEDITOR.env.ie9Compat ) dialog.hide(); else { // In some skins there's a function executed on a timeout after a dialog resize, // so we must delay the hide until it's performed. setTimeout( function() { dialog.hide(); }, ( editor.lang.dir == 'rtl' ? 1001 : 101) ); } } } ] } ] } ], buttons : [ CKEDITOR.dialog.cancelButton ] }; } );