{"action":"created","comment":{"url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/comments/227994560","pull_request_review_id":168145445,"id":227994560,"node_id":"MDI0OlB1bGxSZXF1ZXN0UmV2aWV3Q29tbWVudDIyNzk5NDU2MA==","diff_hunk":"@@ -79,26 +152,466 @@\n \t\t\t\t}\n \n \t\t\t\tfunction dataCallback( matchInfo, callback ) {\n-\t\t\t\t\tvar emojiName =  matchInfo.query.substr( 1 ).toLowerCase(),\n+\t\t\t\t\tvar emojiName = matchInfo.query.substr( 1 ).toLowerCase(),\n \t\t\t\t\t\tdata = CKEDITOR.tools.array.filter( emojiList, function( item ) {\n \t\t\t\t\t\t\t// Comparing lowercased strings, because emoji should be case insensitive (#2167).\n \t\t\t\t\t\t\treturn item.id.toLowerCase().indexOf( emojiName ) !== -1;\n-\t\t\t\t\t\t} ).sort( function( a, b ) {\n-\t\t\t\t\t\t\t// Sort at the beginning emoji starts with given query.\n-\t\t\t\t\t\t\tvar isAStartWithEmojiName = a.id.substr( 1, emojiName.length ) === emojiName,\n-\t\t\t\t\t\t\t\tisBStartWithEmojiName = b.id.substr( 1, emojiName.length ) === emojiName;\n-\n-\t\t\t\t\t\t\tif ( isAStartWithEmojiName && isBStartWithEmojiName || !isAStartWithEmojiName && !isBStartWithEmojiName ) {\n-\t\t\t\t\t\t\t\treturn a.id === b.id ? 0 : ( a.id > b.id ? 1 : -1 );\n-\t\t\t\t\t\t\t} else if ( isAStartWithEmojiName ) {\n-\t\t\t\t\t\t\t\treturn -1;\n-\t\t\t\t\t\t\t} else {\n-\t\t\t\t\t\t\t\treturn 1;\n-\t\t\t\t\t\t\t}\n \t\t\t\t\t\t} );\n \t\t\t\t\tcallback( data );\n \t\t\t\t}\n \t\t\t} );\n+\n+\t\t\teditor.addCommand( 'insertEmoji', {\n+\t\t\t\texec: function( editor, data ) {\n+\t\t\t\t\teditor.insertHtml( data.emojiText );\n+\t\t\t\t}\n+\t\t\t} );\n+\n+\t\t\tif ( !editor.plugins.toolbar ) {\n+\t\t\t\treturn;\n+\t\t\t}\n+\n+\t\t\teditor.ui.addToolbarGroup( 'emoji', 'insert' );\n+\t\t\t// Name is responsible for icon name also.\n+\t\t\teditor.ui.add( 'emojiPanel', CKEDITOR.UI_PANELBUTTON, {\n+\t\t\t\tlabel: 'emoji',\n+\t\t\t\ttitle: 'Emoji List',\n+\t\t\t\tmodes: { wysiwyg: 1 },\n+\t\t\t\teditorFocus: 0,\n+\t\t\t\ttoolbar: 'insert',\n+\t\t\t\tpanel: {\n+\t\t\t\t\tcss: [ CKEDITOR.skin.getPath( 'editor' ), this.path + 'skins/default.css' ],\n+\t\t\t\t\tattributes: { role: 'listbox', 'aria-label': 'Emoji List' },\n+\t\t\t\t\tmarkFirst: false\n+\t\t\t\t},\n+\n+\t\t\t\tonBlock: function( panel, block ) {\n+\t\t\t\t\tvar keys = block.keys,\n+\t\t\t\t\t\trtl = editor.lang.dir === 'rtl';\n+\n+\t\t\t\t\tkeys[ rtl ? 37 : 39 ] = 'next'; // ARROW-RIGHT\n+\t\t\t\t\tkeys[ 40 ] = 'next'; // ARROW-DOWN\n+\t\t\t\t\tkeys[ 9 ] = 'next'; // TAB\n+\t\t\t\t\tkeys[ rtl ? 39 : 37 ] = 'prev'; // ARROW-LEFT\n+\t\t\t\t\tkeys[ 38 ] = 'prev'; // ARROW-UP\n+\t\t\t\t\tkeys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB\n+\t\t\t\t\tkeys[ 32 ] = 'click'; // SPACE\n+\n+\t\t\t\t\tblockElement = block.element;\n+\t\t\t\t\tblock.element.getAscendant( 'html' ).addClass( 'cke_emoji' );\n+\t\t\t\t\tblock.element.getDocument().appendStyleSheet( CKEDITOR.getUrl( CKEDITOR.basePath + 'contents.css' ) );\n+\t\t\t\t\tblock.element.addClass( 'cke_emoji-panel_block' );\n+\t\t\t\t\tblock.element.setHtml( createEmojiBlock() );\n+\t\t\t\t\tpanel.element.addClass( 'cke_emoji_panel' );\n+\n+\t\t\t\t\tblockObject = block;\n+\n+\t\t\t\t\tregisterListeners( listeners );\n+\t\t\t\t},\n+\n+\t\t\t\tonOpen: openReset()\n+\t\t\t} );\n+\n+\t\t\tfunction createEmojiBlock() {\n+\t\t\t\tvar output = [];\n+\n+\t\t\t\toutput.push( createGroupsNavigation() );\n+\t\t\t\toutput.push( createSeparator() );\n+\t\t\t\toutput.push( createSearchSection() );\n+\t\t\t\toutput.push( createEmojiListBlock() );\n+\t\t\t\toutput.push( createSeparator() );\n+\t\t\t\toutput.push( createStatusBar() );\n+\n+\t\t\t\treturn '<div class=\"cke_emoji_inner_panel\">' + output.join( '' ) + '</div>';\n+\t\t\t}\n+\n+\t\t\tfunction createSeparator() {\n+\t\t\t\treturn '<hr>';\n+\t\t\t}\n+\n+\t\t\tfunction createGroupsNavigation() {\n+\t\t\t\tvar itemTemplate,\n+\t\t\t\t\titems,\n+\t\t\t\t\tsvgUrl,\n+\t\t\t\t\timgUrl;\n+\n+\t\t\t\tif ( !CKEDITOR.env.ie ) {\n+\t\t\t\t\tsvgUrl = CKEDITOR.getUrl( that.path + 'assets/icons-all.svg' );\n+\n+\t\t\t\t\titemTemplate = new CKEDITOR.template(\n+\t\t\t\t\t\t'<li class=\"cke_emoji-navigation_item\" data-cke-emoji-group=\"{group}\"><a href=\"{href}\" draggable=\"false\" _cke_focus=\"1\"><svg viewBox=\"0 0 34 34\"> <use href=\"' +\n+\t\t\t\t\t\tsvgUrl +\n+\t\t\t\t\t\t'{href}\"></use></svg></a></li>'\n+\t\t\t\t\t);\n+\n+\t\t\t\t\titems = CKEDITOR.tools.array.reduce( GROUPS, function( acc, item ) {\n+\t\t\t\t\t\treturn acc + itemTemplate.output( {\n+\t\t\t\t\t\t\tgroup: escapeString( item.name ),\n+\t\t\t\t\t\t\thref: escapeString( '#' + item.name.toLowerCase() )\n+\t\t\t\t\t\t} );\n+\t\t\t\t\t}, '' );\n+\t\t\t\t} else {\n+\t\t\t\t\timgUrl = CKEDITOR.getUrl( that.path + 'assets/icons-all.png' );\n+\n+\t\t\t\t\titemTemplate = new CKEDITOR.template(\n+\t\t\t\t\t\t'<li class=\"cke_emoji-navigation_item\" data-cke-emoji-group=\"{group}\"><a href=\"{href}\" draggable=\"false\" _cke_focus=\"1\">' +\n+\t\t\t\t\t\t'<span style=\"background-image:url(' + imgUrl + ');display:inline-block;width:21px;height:21px;background-size:105px 42px;' +\n+\t\t\t\t\t\t'background-repeat:no-repeat;background-position:{positionX}px {positionY}px;\"></span>' +\n+\t\t\t\t\t\t'</a></li>'\n+\t\t\t\t\t);\n+\n+\t\t\t\t\titems = CKEDITOR.tools.array.reduce( GROUPS, function( acc, item ) {\n+\t\t\t\t\t\treturn acc + itemTemplate.output( {\n+\t\t\t\t\t\t\tgroup: escapeString( item.name ),\n+\t\t\t\t\t\t\thref: escapeString( '#' + item.name.toLowerCase() ),\n+\t\t\t\t\t\t\tpositionX: item.position.x,\n+\t\t\t\t\t\t\tpositionY: item.position.y\n+\t\t\t\t\t\t} );\n+\t\t\t\t\t}, '' );\n+\t\t\t\t}\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: 'nav li',\n+\t\t\t\t\tevent: 'click',\n+\t\t\t\t\tlistener: function( event ) {\n+\t\t\t\t\t\tvar nodeArr = blockElement.find( 'nav li' ).toArray();\n+\t\t\t\t\t\tvar activeElement = event.sender;\n+\t\t\t\t\t\tCKEDITOR.tools.array.forEach( nodeArr, function( node ) {\n+\t\t\t\t\t\t\tif ( node.equals( activeElement ) ) {\n+\t\t\t\t\t\t\t\tnode.addClass( 'active' );\n+\t\t\t\t\t\t\t} else {\n+\t\t\t\t\t\t\t\tnode.removeClass( 'active' );\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t} );\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: 'nav li',\n+\t\t\t\t\tevent: 'click',\n+\t\t\t\t\tlistener: clearSearchAndMoveFocus\n+\t\t\t\t} );\n+\n+\t\t\t\treturn '<nav><ul>' + items + '</ul></nav>';\n+\t\t\t}\n+\n+\t\t\tfunction createSearchSection() {\n+\t\t\t\tvar loupeUrl = CKEDITOR.getUrl( that.path + 'assets/loupe.svg' );\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: 'input',\n+\t\t\t\t\tevent: 'input',\n+\t\t\t\t\tlistener: ( function() {\n+\t\t\t\t\t\tvar buffer = CKEDITOR.tools.throttle( 200, filter );\n+\t\t\t\t\t\treturn buffer.input;\n+\t\t\t\t\t} )()\n+\t\t\t\t} );\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: 'input',\n+\t\t\t\t\tevent: 'click',\n+\t\t\t\t\tlistener: ( function() {\n+\t\t\t\t\t\tvar inputNumber;\n+\t\t\t\t\t\treturn function() {\n+\t\t\t\t\t\t\tif ( inputNumber === undefined ) {\n+\t\t\t\t\t\t\t\tinputNumber = getItemIndex( blockObject._.getItems().toArray(), blockElement.findOne( 'input' ) );\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t\tblockObject._.markItem( inputNumber );\n+\t\t\t\t\t\t};\n+\t\t\t\t\t} )()\n+\t\t\t\t} );\n+\t\t\t\treturn '<label class=\"cke_emoji-search\"><img src=\"' + escapeString( loupeUrl ) +\n+\t\t\t\t\t'\" /><input placeholder=\"' + escapeString( lang.searchPlaceholder ) +\n+\t\t\t\t\t'\" type=\"search\" _cke_focus=\"1\"></label>';\n+\t\t\t}\n+\n+\t\t\tfunction createEmojiListBlock() {\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: '.cke_emoji-outer_emoji_block',\n+\t\t\t\t\tevent: 'scroll',\n+\t\t\t\t\tlistener: ( function() {\n+\t\t\t\t\t\tvar buffer = CKEDITOR.tools.throttle( 150, refreshNavigationStatus );\n+\t\t\t\t\t\treturn buffer.input;\n+\t\t\t\t\t} )()\n+\t\t\t\t} );\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: '.cke_emoji-outer_emoji_block',\n+\t\t\t\t\tevent: 'click',\n+\t\t\t\t\tlistener: function( event ) {\n+\t\t\t\t\t\tif ( event.data.getTarget().data( 'cke-emoji-name' ) ) {\n+\t\t\t\t\t\t\teditor.execCommand( 'insertEmoji', { emojiText: event.data.getTarget().data( 'cke-emoji-symbol' ) } );\n+\t\t\t\t\t\t}\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: '.cke_emoji-outer_emoji_block',\n+\t\t\t\t\tevent: 'mouseover',\n+\t\t\t\t\tlistener: function( event ) {\n+\t\t\t\t\t\tupdateStatusbar( event.data.getTarget() );\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\tlisteners.push( {\n+\t\t\t\t\tselector: '.cke_emoji-outer_emoji_block',\n+\t\t\t\t\tevent: 'keyup',\n+\t\t\t\t\tlistener: function() {\n+\t\t\t\t\t\tupdateStatusbar( blockObject._.getItems().getItem( blockObject._.focusIndex ) );\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\treturn '<div class=\"cke_emoji-outer_emoji_block\">' + getEmojiSections() + '</div>';\n+\t\t\t}\n+\n+\t\t\tfunction createStatusBar() {\n+\t\t\t\treturn '<div class=\"cke_emoji-status_bar\">' +\n+\t\t\t\t\t'<div class=\"cke_emoji-status_icon\"></div>' +\n+\t\t\t\t\t'<div class=\"cke_emoji-status_description\"><p class=\"cke_emoji-status_description\"></p><p class=\"cke_emoji-status_full_name\"></p></div>' +\n+\t\t\t\t\t'</div>';\n+\t\t\t}\n+\n+\t\t\tfunction getEmojiSections() {\n+\t\t\t\treturn CKEDITOR.tools.array.reduce( GROUPS, function( acc, item ) {\n+\t\t\t\t\treturn acc + getEmojiSection( item );\n+\t\t\t\t}, '' );\n+\t\t\t}\n+\n+\t\t\tfunction getEmojiSection( item ) {\n+\t\t\t\tvar groupName = escapeString( item.name ),\n+\t\t\t\t\tsectionName = escapeString( item.sectionName ),\n+\t\t\t\t\tgroup = getEmojiListGroup( groupName );\n+\n+\t\t\t\treturn '<section data-cke-emoji-group=\"' + groupName + '\" ><h2 id=\"' + groupName + '\">' + sectionName + '</h2><ul>' + group + '</ul></section>';\n+\t\t\t}\n+\n+\t\t\tfunction getEmojiListGroup( groupName ) {\n+\t\t\t\tvar emojiList = editor._.emoji.list,\n+\t\t\t\t\temojiTpl = new CKEDITOR.template( '<li class=\"cke_emoji_item\">' +\n+\t\t\t\t\t'<a draggable=\"false\" data-cke-emoji-full-name=\"{id}\" data-cke-emoji-name=\"{name}\" data-cke-emoji-symbol=\"{symbol}\" data-cke-emoji-group=\"{group}\" ' +\n+\t\t\t\t\t'data-cke-emoji-keywords=\"{keywords}\" title=\"{id}\" href=\"#\" _cke_focus=\"1\">{symbol}</a>' +\n+\t\t\t\t\t'</li>' );\n+\n+\t\t\t\treturn CKEDITOR.tools.array.reduce(\n+\t\t\t\t\tCKEDITOR.tools.array.filter(\n+\t\t\t\t\t\temojiList,\n+\t\t\t\t\t\tfunction( item ) {\n+\t\t\t\t\t\t\treturn item.group === groupName;\n+\t\t\t\t\t\t}\n+\t\t\t\t\t),\n+\t\t\t\t\tfunction( acc, item ) {\n+\t\t\t\t\t\treturn acc + emojiTpl.output( {\n+\t\t\t\t\t\t\t\tsymbol: escapeString( item.symbol ),\n+\t\t\t\t\t\t\t\tid: escapeString( item.id ),\n+\t\t\t\t\t\t\t\tname: escapeString( item.id.replace( /::.*$/, ':' ).replace( /^:|:$/g, '' ).replace( /_/g, ' ' ) ),\n+\t\t\t\t\t\t\t\tgroup: escapeString( item.group ),\n+\t\t\t\t\t\t\t\tkeywords: escapeString( ( item.keywords || [] ).join( ',' ) )\n+\t\t\t\t\t\t\t} );\n+\t\t\t\t\t},\n+\t\t\t\t\t''\n+\t\t\t\t);\n+\t\t\t}\n+\n+\t\t\t// Apply filters to emoji items in dropdown.\n+\t\t\t// Hidding not searched one.\n+\t\t\t// Can accpet input event or string\n+\t\t\tfunction filter( evt ) {\n+\t\t\t\tvar emojiItems = blockElement.findOne( '.cke_emoji-outer_emoji_block' ).find( 'li > a' ).toArray(),\n+\t\t\t\t\tsections = blockElement.findOne( '.cke_emoji-outer_emoji_block' ).find( 'h2' ).toArray(),\n+\t\t\t\t\tgroups = {},\n+\t\t\t\t\tquery = typeof evt === 'string' ? evt : evt.sender.getValue();\n+\n+\t\t\t\tCKEDITOR.tools.array.forEach( emojiItems, function( element ) {\n+\t\t\t\t\tif ( isNameOrKeywords( query, element.data( 'cke-emoji-name' ), element.data( 'cke-emoji-keywords' ) ) || query === '' ) {\n+\t\t\t\t\t\telement.removeClass( 'hidden' );\n+\t\t\t\t\t\telement.getParent().removeClass( 'hidden' );\n+\t\t\t\t\t\tgroups[ element.data( 'cke-emoji-group' ) ] = true;\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\telement.addClass( 'hidden' );\n+\t\t\t\t\t\telement.getParent().addClass( 'hidden' );\n+\t\t\t\t\t}\n+\n+\t\t\t\t\tfunction isNameOrKeywords( query, name, keywordsString ) {\n+\t\t\t\t\t\tvar keywords,\n+\t\t\t\t\t\t\ti;\n+\t\t\t\t\t\tif ( name.indexOf( query ) !== -1 ) {\n+\t\t\t\t\t\t\treturn true;\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\tif ( keywordsString ) {\n+\t\t\t\t\t\t\tkeywords = keywordsString.split( ',' );\n+\t\t\t\t\t\t\tfor ( i = 0; i < keywords.length; i++ ) {\n+\t\t\t\t\t\t\t\tif ( keywords[ i ].indexOf( query ) !== -1 ) {\n+\t\t\t\t\t\t\t\t\treturn true;\n+\t\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t\t}\n+\t\t\t\t\t\t}\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\tCKEDITOR.tools.array.forEach( sections, function( element ) {\n+\t\t\t\t\tif ( groups[ element.getId() ] ) {\n+\t\t\t\t\t\telement.getParent().removeClass( 'hidden' );\n+\t\t\t\t\t\telement.removeClass( 'hidden' );\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\telement.addClass( 'hidden' );\n+\t\t\t\t\t\telement.getParent().addClass( 'hidden' );\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\n+\t\t\t\trefreshNavigationStatus();\n+\t\t\t}\n+\n+\t\t\tfunction clearSearchInput() {\n+\t\t\t\tblockElement.findOne( 'input' ).setValue( '' );\n+\t\t\t\tfilter( '' );\n+\t\t\t}\n+\n+\t\t\t// Resets state of emoji dropdown.\n+\t\t\t// Clear filters, reset focus, etc.\n+\t\t\tfunction openReset() {\n+\t\t\t\tvar firstCall,\n+\t\t\t\t\tinputIndex,\n+\t\t\t\t\tinput;\n+\n+\t\t\t\treturn function() {\n+\n+\t\t\t\t\tif ( !firstCall ) {\n+\t\t\t\t\t\tfilter( '' );\n+\n+\t\t\t\t\t\tinput = blockElement.findOne( 'input' );\n+\t\t\t\t\t\tinputIndex = getItemIndex( blockObject._.getItems().toArray(), input );\n+\n+\t\t\t\t\t\tfirstCall = true;\n+\t\t\t\t\t}\n+\n+\t\t\t\t\tblockElement.findOne( '.cke_emoji-outer_emoji_block' ).$.scrollTop = 0;\n+\t\t\t\t\trefreshNavigationStatus();\n+\n+\t\t\t\t\t// Clear search results:\n+\t\t\t\t\tclearSearchInput();\n+\n+\t\t\t\t\t// Reset focus:\n+\t\t\t\t\tCKEDITOR.tools.setTimeout( function() {\n+\t\t\t\t\t\tinput.focus( true );\n+\t\t\t\t\t\tblockObject._.markItem( inputIndex );\n+\t\t\t\t\t} );\n+\n+\t\t\t\t\t// Remove statusbar icons:\n+\t\t\t\t\tclearStatusbar();\n+\t\t\t\t};\n+\t\t\t}\n+\n+\t\t\tfunction refreshNavigationStatus() {\n+\t\t\t\tvar sections = blockElement.find( 'section' ).toArray(),\n+\t\t\t\t\tcontainerOffset = blockElement.findOne( '.cke_emoji-outer_emoji_block' ).getClientRect().top,\n+\t\t\t\t\tsection,\n+\t\t\t\t\tgroupName,\n+\t\t\t\t\tnavigationElements;\n+\n+\t\t\t\tsection = CKEDITOR.tools.array.filter( sections, function( element ) {\n+\t\t\t\t\tvar rect = element.getClientRect();\n+\t\t\t\t\tif ( !rect.height || element.findOne( 'h2' ).hasClass( 'hidden' ) ) {\n+\t\t\t\t\t\treturn false;\n+\t\t\t\t\t}\n+\t\t\t\t\treturn rect.height + rect.top > containerOffset;\n+\t\t\t\t} );\n+\t\t\t\tgroupName = section.length ? section[ 0 ].data( 'cke-emoji-group' ) : false;\n+\t\t\t\tnavigationElements = blockElement.find( 'nav li' ).toArray();\n+\n+\t\t\t\tCKEDITOR.tools.array.forEach( navigationElements, function( node ) {\n+\t\t\t\t\tif ( node.data( 'cke-emoji-group' ) === groupName ) {\n+\t\t\t\t\t\tnode.addClass( 'active' );\n+\t\t\t\t\t} else {\n+\t\t\t\t\t\tnode.removeClass( 'active' );\n+\t\t\t\t\t}\n+\t\t\t\t} );\n+\t\t\t}\n+\n+\t\t\tfunction updateStatusbar( element ) {\n+\t\t\t\tif ( element.getName() !== 'a' ) {\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\n+\t\t\t\tblockElement.findOne( '.cke_emoji-status_icon' ).setText( escapeString( element.getText() ) );\n+\t\t\t\tblockElement.findOne( 'p.cke_emoji-status_description' ).setText( escapeString( element.data( 'cke-emoji-name' ) ) );\n+\t\t\t\tblockElement.findOne( 'p.cke_emoji-status_full_name' ).setText( escapeString( element.data( 'cke-emoji-full-name' ) ) );\n+\t\t\t}\n+\n+\t\t\tfunction clearStatusbar() {\n+\t\t\t\tblockElement.findOne( '.cke_emoji-status_icon' ).setText( '' );\n+\t\t\t\tblockElement.findOne( 'p.cke_emoji-status_description' ).setText( '' );\n+\t\t\t\tblockElement.findOne( 'p.cke_emoji-status_full_name' ).setText( '' );\n+\t\t\t}\n+\n+\t\t\tfunction clearSearchAndMoveFocus( event ) {\n+\t\t\t\tclearSearchInput();\n+\t\t\t\tmoveFocus( event );\n+\t\t\t}\n+\n+\t\t\tfunction moveFocus( event ) {\n+\t\t\t\tvar groupName = event.data.getTarget().getAscendant( 'li', true ).data( 'cke-emoji-group' ),\n+\t\t\t\t\tfirstSectionItem = blockElement.findOne( 'a[data-cke-emoji-group=\"' + escapeString( groupName ) + '\"]' ),\n+\t\t\t\t\titemIndex;\n+\n+\t\t\t\tif ( !firstSectionItem ) {\n+\t\t\t\t\treturn;\n+\t\t\t\t}\n+\n+\t\t\t\titemIndex = getItemIndex( blockObject._.getItems().toArray(), firstSectionItem );\n+\t\t\t\tfirstSectionItem.focus( true );\n+\t\t\t\tblockObject._.markItem( itemIndex );\n+\t\t\t}\n+\n+\t\t\tfunction getItemIndex( list, item ) {\n+\t\t\t\treturn CKEDITOR.tools.array.indexOf( list, function( element ) {\n+\t\t\t\t\treturn element.equals( item );\n+\t\t\t\t} );\n+\t\t\t}\n+\n+\t\t\tfunction registerListeners( list ) {\n+\t\t\t\tCKEDITOR.tools.array.forEach( list, function( item ) {\n+\t\t\t\t\tvar root = blockElement,\n+\t\t\t\t\t\tselector = item.selector,\n+\t\t\t\t\t\tlistener = item.listener,\n+\t\t\t\t\t\tevent = item.event;\n+\n+\t\t\t\t\tCKEDITOR.tools.array.forEach( root.find( selector ).toArray(), function( node ) {\n+\t\t\t\t\t\tnode.on( event, listener );\n+\t\t\t\t\t} );\n+\t\t\t\t} );\n+\t\t\t}\n+\n+\t\t\tfunction escapeString( str ) {","path":"plugins/emoji/plugin.js","position":544,"original_position":544,"commit_id":"d04c4bb3a032006ad1bbd4be39e1a4df327a8d88","original_commit_id":"d04c4bb3a032006ad1bbd4be39e1a4df327a8d88","user":{"login":"mlewand","id":5353898,"node_id":"MDQ6VXNlcjUzNTM4OTg=","avatar_url":"https://avatars0.githubusercontent.com/u/5353898?v=4","gravatar_id":"","url":"https://api.github.com/users/mlewand","html_url":"https://github.com/mlewand","followers_url":"https://api.github.com/users/mlewand/followers","following_url":"https://api.github.com/users/mlewand/following{/other_user}","gists_url":"https://api.github.com/users/mlewand/gists{/gist_id}","starred_url":"https://api.github.com/users/mlewand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlewand/subscriptions","organizations_url":"https://api.github.com/users/mlewand/orgs","repos_url":"https://api.github.com/users/mlewand/repos","events_url":"https://api.github.com/users/mlewand/events{/privacy}","received_events_url":"https://api.github.com/users/mlewand/received_events","type":"User","site_admin":false},"body":"There is already a function for HTML encoding. Look in `CKEDITOR.tools` to reuse it.","created_at":"2018-10-24T23:36:22Z","updated_at":"2018-10-24T23:51:54Z","html_url":"https://github.com/ckeditor/ckeditor-dev/pull/2461#discussion_r227994560","pull_request_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461","author_association":"MEMBER","_links":{"self":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/comments/227994560"},"html":{"href":"https://github.com/ckeditor/ckeditor-dev/pull/2461#discussion_r227994560"},"pull_request":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461"}}},"pull_request":{"url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461","id":220684862,"node_id":"MDExOlB1bGxSZXF1ZXN0MjIwNjg0ODYy","html_url":"https://github.com/ckeditor/ckeditor-dev/pull/2461","diff_url":"https://github.com/ckeditor/ckeditor-dev/pull/2461.diff","patch_url":"https://github.com/ckeditor/ckeditor-dev/pull/2461.patch","issue_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/2461","number":2461,"state":"open","locked":false,"title":"Introduce emoji dropdown","user":{"login":"msamsel","id":9017322,"node_id":"MDQ6VXNlcjkwMTczMjI=","avatar_url":"https://avatars2.githubusercontent.com/u/9017322?v=4","gravatar_id":"","url":"https://api.github.com/users/msamsel","html_url":"https://github.com/msamsel","followers_url":"https://api.github.com/users/msamsel/followers","following_url":"https://api.github.com/users/msamsel/following{/other_user}","gists_url":"https://api.github.com/users/msamsel/gists{/gist_id}","starred_url":"https://api.github.com/users/msamsel/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/msamsel/subscriptions","organizations_url":"https://api.github.com/users/msamsel/orgs","repos_url":"https://api.github.com/users/msamsel/repos","events_url":"https://api.github.com/users/msamsel/events{/privacy}","received_events_url":"https://api.github.com/users/msamsel/received_events","type":"User","site_admin":false},"body":"## What is the purpose of this pull request?\r\n\r\nNew feature\r\n\r\n## Does your PR contain necessary tests?\r\n\r\nAll patches which change the editor code must include tests. You can always read more\r\non [PR testing](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_contributing_code.html#tests),\r\n[how to set the testing environment](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_tests.html) and\r\n[how to create tests](https://ckeditor.com/docs/ckeditor4/latest/guide/dev_tests.html#creating-your-own-test)\r\nin the official CKEditor documentation.\r\n\r\n### This PR contains\r\n\r\n- [x] Unit tests\r\n- [x] Manual tests\r\n\r\n## What changes did you make?\r\n\r\n* Plugin require fix from #2453 to have possibility to focus on input element. **Branch is rebased on this change.**\r\n* Add new float panel which displays list of emoji, with basic functionality\r\n* Emoji dropdown also search using keywords not only names of given emoji\r\n\r\nClose #2062.","created_at":"2018-10-05T12:28:25Z","updated_at":"2018-10-24T23:51:54Z","closed_at":null,"merged_at":null,"merge_commit_sha":"66b45eb353a5c61f0b52f1f3fe17e4bc175cc123","assignee":{"login":"mlewand","id":5353898,"node_id":"MDQ6VXNlcjUzNTM4OTg=","avatar_url":"https://avatars0.githubusercontent.com/u/5353898?v=4","gravatar_id":"","url":"https://api.github.com/users/mlewand","html_url":"https://github.com/mlewand","followers_url":"https://api.github.com/users/mlewand/followers","following_url":"https://api.github.com/users/mlewand/following{/other_user}","gists_url":"https://api.github.com/users/mlewand/gists{/gist_id}","starred_url":"https://api.github.com/users/mlewand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlewand/subscriptions","organizations_url":"https://api.github.com/users/mlewand/orgs","repos_url":"https://api.github.com/users/mlewand/repos","events_url":"https://api.github.com/users/mlewand/events{/privacy}","received_events_url":"https://api.github.com/users/mlewand/received_events","type":"User","site_admin":false},"assignees":[{"login":"mlewand","id":5353898,"node_id":"MDQ6VXNlcjUzNTM4OTg=","avatar_url":"https://avatars0.githubusercontent.com/u/5353898?v=4","gravatar_id":"","url":"https://api.github.com/users/mlewand","html_url":"https://github.com/mlewand","followers_url":"https://api.github.com/users/mlewand/followers","following_url":"https://api.github.com/users/mlewand/following{/other_user}","gists_url":"https://api.github.com/users/mlewand/gists{/gist_id}","starred_url":"https://api.github.com/users/mlewand/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/mlewand/subscriptions","organizations_url":"https://api.github.com/users/mlewand/orgs","repos_url":"https://api.github.com/users/mlewand/repos","events_url":"https://api.github.com/users/mlewand/events{/privacy}","received_events_url":"https://api.github.com/users/mlewand/received_events","type":"User","site_admin":false}],"requested_reviewers":[],"requested_teams":[],"labels":[],"milestone":null,"commits_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461/commits","review_comments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461/comments","review_comment_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/comments{/number}","comments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/2461/comments","statuses_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/statuses/d04c4bb3a032006ad1bbd4be39e1a4df327a8d88","head":{"label":"ckeditor:t/2062","ref":"t/2062","sha":"d04c4bb3a032006ad1bbd4be39e1a4df327a8d88","user":{"login":"ckeditor","id":825710,"node_id":"MDEyOk9yZ2FuaXphdGlvbjgyNTcxMA==","avatar_url":"https://avatars2.githubusercontent.com/u/825710?v=4","gravatar_id":"","url":"https://api.github.com/users/ckeditor","html_url":"https://github.com/ckeditor","followers_url":"https://api.github.com/users/ckeditor/followers","following_url":"https://api.github.com/users/ckeditor/following{/other_user}","gists_url":"https://api.github.com/users/ckeditor/gists{/gist_id}","starred_url":"https://api.github.com/users/ckeditor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ckeditor/subscriptions","organizations_url":"https://api.github.com/users/ckeditor/orgs","repos_url":"https://api.github.com/users/ckeditor/repos","events_url":"https://api.github.com/users/ckeditor/events{/privacy}","received_events_url":"https://api.github.com/users/ckeditor/received_events","type":"Organization","site_admin":false},"repo":{"id":5482172,"node_id":"MDEwOlJlcG9zaXRvcnk1NDgyMTcy","name":"ckeditor-dev","full_name":"ckeditor/ckeditor-dev","private":false,"owner":{"login":"ckeditor","id":825710,"node_id":"MDEyOk9yZ2FuaXphdGlvbjgyNTcxMA==","avatar_url":"https://avatars2.githubusercontent.com/u/825710?v=4","gravatar_id":"","url":"https://api.github.com/users/ckeditor","html_url":"https://github.com/ckeditor","followers_url":"https://api.github.com/users/ckeditor/followers","following_url":"https://api.github.com/users/ckeditor/following{/other_user}","gists_url":"https://api.github.com/users/ckeditor/gists{/gist_id}","starred_url":"https://api.github.com/users/ckeditor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ckeditor/subscriptions","organizations_url":"https://api.github.com/users/ckeditor/orgs","repos_url":"https://api.github.com/users/ckeditor/repos","events_url":"https://api.github.com/users/ckeditor/events{/privacy}","received_events_url":"https://api.github.com/users/ckeditor/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/ckeditor/ckeditor-dev","description":"The development repository of CKEditor 4.","fork":false,"url":"https://api.github.com/repos/ckeditor/ckeditor-dev","forks_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/forks","keys_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/teams","hooks_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/hooks","issue_events_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/events{/number}","events_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/events","assignees_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/assignees{/user}","branches_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/branches{/branch}","tags_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/tags","blobs_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/statuses/{sha}","languages_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/languages","stargazers_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/stargazers","contributors_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/contributors","subscribers_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/subscribers","subscription_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/subscription","commits_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/contents/{+path}","compare_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/merges","archive_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/downloads","issues_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues{/number}","pulls_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls{/number}","milestones_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/milestones{/number}","notifications_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/labels{/name}","releases_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/releases{/id}","deployments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/deployments","created_at":"2012-08-20T14:21:13Z","updated_at":"2018-10-24T17:17:35Z","pushed_at":"2018-10-24T18:44:13Z","git_url":"git://github.com/ckeditor/ckeditor-dev.git","ssh_url":"git@github.com:ckeditor/ckeditor-dev.git","clone_url":"https://github.com/ckeditor/ckeditor-dev.git","svn_url":"https://github.com/ckeditor/ckeditor-dev","homepage":"https://ckeditor.com/ckeditor-4","size":64275,"stargazers_count":4242,"watchers_count":4242,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1909,"mirror_url":null,"archived":false,"open_issues_count":670,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":1909,"open_issues":670,"watchers":4242,"default_branch":"major"}},"base":{"label":"ckeditor:major","ref":"major","sha":"f4c14b67f49e2e03c4009745d086e3e6989f6f56","user":{"login":"ckeditor","id":825710,"node_id":"MDEyOk9yZ2FuaXphdGlvbjgyNTcxMA==","avatar_url":"https://avatars2.githubusercontent.com/u/825710?v=4","gravatar_id":"","url":"https://api.github.com/users/ckeditor","html_url":"https://github.com/ckeditor","followers_url":"https://api.github.com/users/ckeditor/followers","following_url":"https://api.github.com/users/ckeditor/following{/other_user}","gists_url":"https://api.github.com/users/ckeditor/gists{/gist_id}","starred_url":"https://api.github.com/users/ckeditor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ckeditor/subscriptions","organizations_url":"https://api.github.com/users/ckeditor/orgs","repos_url":"https://api.github.com/users/ckeditor/repos","events_url":"https://api.github.com/users/ckeditor/events{/privacy}","received_events_url":"https://api.github.com/users/ckeditor/received_events","type":"Organization","site_admin":false},"repo":{"id":5482172,"node_id":"MDEwOlJlcG9zaXRvcnk1NDgyMTcy","name":"ckeditor-dev","full_name":"ckeditor/ckeditor-dev","private":false,"owner":{"login":"ckeditor","id":825710,"node_id":"MDEyOk9yZ2FuaXphdGlvbjgyNTcxMA==","avatar_url":"https://avatars2.githubusercontent.com/u/825710?v=4","gravatar_id":"","url":"https://api.github.com/users/ckeditor","html_url":"https://github.com/ckeditor","followers_url":"https://api.github.com/users/ckeditor/followers","following_url":"https://api.github.com/users/ckeditor/following{/other_user}","gists_url":"https://api.github.com/users/ckeditor/gists{/gist_id}","starred_url":"https://api.github.com/users/ckeditor/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ckeditor/subscriptions","organizations_url":"https://api.github.com/users/ckeditor/orgs","repos_url":"https://api.github.com/users/ckeditor/repos","events_url":"https://api.github.com/users/ckeditor/events{/privacy}","received_events_url":"https://api.github.com/users/ckeditor/received_events","type":"Organization","site_admin":false},"html_url":"https://github.com/ckeditor/ckeditor-dev","description":"The development repository of CKEditor 4.","fork":false,"url":"https://api.github.com/repos/ckeditor/ckeditor-dev","forks_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/forks","keys_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/keys{/key_id}","collaborators_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/teams","hooks_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/hooks","issue_events_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/events{/number}","events_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/events","assignees_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/assignees{/user}","branches_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/branches{/branch}","tags_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/tags","blobs_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/refs{/sha}","trees_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/trees{/sha}","statuses_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/statuses/{sha}","languages_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/languages","stargazers_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/stargazers","contributors_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/contributors","subscribers_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/subscribers","subscription_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/subscription","commits_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/commits{/sha}","git_commits_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/git/commits{/sha}","comments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/comments{/number}","issue_comment_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/comments{/number}","contents_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/contents/{+path}","compare_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/compare/{base}...{head}","merges_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/merges","archive_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/downloads","issues_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues{/number}","pulls_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls{/number}","milestones_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/milestones{/number}","notifications_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/labels{/name}","releases_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/releases{/id}","deployments_url":"https://api.github.com/repos/ckeditor/ckeditor-dev/deployments","created_at":"2012-08-20T14:21:13Z","updated_at":"2018-10-24T17:17:35Z","pushed_at":"2018-10-24T18:44:13Z","git_url":"git://github.com/ckeditor/ckeditor-dev.git","ssh_url":"git@github.com:ckeditor/ckeditor-dev.git","clone_url":"https://github.com/ckeditor/ckeditor-dev.git","svn_url":"https://github.com/ckeditor/ckeditor-dev","homepage":"https://ckeditor.com/ckeditor-4","size":64275,"stargazers_count":4242,"watchers_count":4242,"language":"HTML","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1909,"mirror_url":null,"archived":false,"open_issues_count":670,"license":{"key":"other","name":"Other","spdx_id":"NOASSERTION","url":null,"node_id":"MDc6TGljZW5zZTA="},"forks":1909,"open_issues":670,"watchers":4242,"default_branch":"major"}},"_links":{"self":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461"},"html":{"href":"https://github.com/ckeditor/ckeditor-dev/pull/2461"},"issue":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/2461"},"comments":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/issues/2461/comments"},"review_comments":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461/comments"},"review_comment":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/pulls/2461/commits"},"statuses":{"href":"https://api.github.com/repos/ckeditor/ckeditor-dev/statuses/d04c4bb3a032006ad1bbd4be39e1a4df327a8d88"}},"author_association":"CONTRIBUTOR"}}
{"actor":{"display_login":"mlewand"}}