Service to handle interaction with the self.editor (sublime, atom, etc.)
@param {String} self.editor - name of the self.editor
556895
function(editor, openWindowFn) {
  this.editor = editor;
  this.openWindowFn = openWindowFn;
  this.supportedEditors = this._getSupportedEditors();
  if (this.editor && !this._isSupportedEditor(this.editor)) {
    throw new Error(this.editor+' was not found in list of supported editors. Please check your global settings to ensure the self.editor path for '+this.editor+' is configured correctly.');
  }
}
681450
function( editor ) {
			var elementPath = editor.elementPath(),
				activePath = elementPath && elementPath.elements,
				pathMember, ret;

			// IE8: upon initialization if there is no path elementPath() returns null.
			if ( elementPath ) {
				for ( var i = 0; i < activePath.length; i++ ) {
					pathMember = activePath[ i ];

					if ( !ret && pathMember.getName() == 'span' && pathMember.hasAttribute( 'dir' ) && pathMember.hasAttribute( 'lang' ) )
						ret = pathMember;
				}
			}

			return ret;
		}
231580
def buffer_edit(editor, location, force=False):
    
    if location is None:
        # Edit/open without a location will reload the current file, if there are
        # no changes.
        eb = editor.window_arrangement.active_editor_buffer
        if eb.location is None:
            editor.show_message(_NO_FILE_NAME)
        elif not force and eb.has_unsaved_changes:
            editor.show_message(_NO_WRITE_SINCE_LAST_CHANGE_TEXT)
        else:
            eb.reload()
    else:
        editor.file_explorer = ''
        editor.window_arrangement.open_buffer(location, show_in_current_window=True)
1100462
function( editor ) {
		var config = editor.config,
			lang = editor.lang.colorbutton;

		var clickFn;

		if ( !CKEDITOR.env.hc ) {
			addButton( 'TextColor', 'fore', lang.textColorTitle, 10 );
			addButton( 'BGColor', 'back', lang.bgColorTitle, 20 );
		}

		function addButton( name, type, title, order ) {
			var style = new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ] ),
				colorBoxId = CKEDITOR.tools.getNextId() + '_colorBox';

			editor.ui.add( name, CKEDITOR.UI_PANELBUTTON, {
				label: title,
				title: title,
				modes: { wysiwyg: 1 },
				editorFocus: 0,
				toolbar: 'colors,' + order,
				allowedContent: style,
				requiredContent: style,

				panel: {
					css: CKEDITOR.skin.getPath( 'editor' ),
					attributes: { role: 'listbox', 'aria-label': lang.panelTitle }
				},

				onBlock: function( panel, block ) {
					block.autoSize = true;
					block.element.addClass( 'cke_colorblock' );
					block.element.setHtml( renderColors( panel, type, colorBoxId ) );
					// The block should not have scrollbars (#5933, #6056)
					block.element.getDocument().getBody().setStyle( 'overflow', 'hidden' );

					CKEDITOR.ui.fire( 'ready', this );

					var keys = block.keys;
					var rtl = editor.lang.dir == 'rtl';
					keys[ rtl ? 37 : 39 ] = 'next'; // ARROW-RIGHT
					keys[ 40 ] = 'next'; // ARROW-DOWN
					keys[ 9 ] = 'next'; // TAB
					keys[ rtl ? 39 : 37 ] = 'prev'; // ARROW-LEFT
					keys[ 38 ] = 'prev'; // ARROW-UP
					keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB
					keys[ 32 ] = 'click'; // SPACE
				},

				refresh: function() {
					if ( !editor.activeFilter.check( style ) )
						this.setState( CKEDITOR.TRISTATE_DISABLED );
				},

				// The automatic colorbox should represent the real color (#6010)
				onOpen: function() {

					var selection = editor.getSelection(),
						block = selection && selection.getStartElement(),
						path = editor.elementPath( block ),
						color;

					if ( !path )
						return;

					// Find the closest block element.
					block = path.block || path.blockLimit || editor.document.getBody();

					// The background color might be transparent. In that case, look up the color in the DOM tree.
					do {
						color = block && block.getComputedStyle( type == 'back' ? 'background-color' : 'color' ) || 'transparent';
					}
					while ( type == 'back' && color == 'transparent' && block && ( block = block.getParent() ) );

					// The box should never be transparent.
					if ( !color || color == 'transparent' )
						color = '#ffffff';

					this._.panel._.iframe.getFrameDocument().getById( colorBoxId ).setStyle( 'background-color', color );

					return color;
				}
			} );
		}


		function renderColors( panel, type, colorBoxId ) {
			var output = [],
				colors = config.colorButton_colors.split( ',' ),
				// Tells if we should include "More Colors..." button.
				moreColorsEnabled = editor.plugins.colordialog && config.colorButton_enableMore !== false,
				// aria-setsize and aria-posinset attributes are used to indicate size of options, because
				// screen readers doesn't play nice with table, based layouts (#12097).
				total = colors.length + ( moreColorsEnabled ? 2 : 1 );

			var clickFn = CKEDITOR.tools.addFunction( function( color, type ) {
				if ( color == '?' ) {
					var applyColorStyle = arguments.callee;

					function onColorDialogClose( evt ) {
						this.removeListener( 'ok', onColorDialogClose );
						this.removeListener( 'cancel', onColorDialogClose );

						evt.name == 'ok' && applyColorStyle( this.getContentElement( 'picker', 'selectedColor' ).getValue(), type );
					}

					editor.openDialog( 'colordialog', function() {
						this.on( 'ok', onColorDialogClose );
						this.on( 'cancel', onColorDialogClose );
					} );

					return;
				}

				editor.focus();

				panel.hide();

				editor.fire( 'saveSnapshot' );

				// Clean up any conflicting style within the range.
				editor.removeStyle( new CKEDITOR.style( config[ 'colorButton_' + type + 'Style' ], { color: 'inherit' } ) );

				if ( color ) {
					var colorStyle = config[ 'colorButton_' + type + 'Style' ];

					colorStyle.childRule = type == 'back' ?
					function( element ) {
						// It's better to apply background color as the innermost style. (#3599)
						// Except for "unstylable elements". (#6103)
						return isUnstylable( element );
					} : function( element ) {
						// Fore color style must be applied inside links instead of around it. (#4772,#6908)
						return !( element.is( 'a' ) || element.getElementsByTag( 'a' ).count() ) || isUnstylable( element );
					};

					editor.applyStyle( new CKEDITOR.style( colorStyle, { color: color } ) );
				}

				editor.fire( 'saveSnapshot' );
			} );

			// Render the "Automatic" button.
			output.push( '<a class="cke_colorauto" _cke_focus=1 hidefocus=true' +
				' title="', lang.auto, '"' +
				' onclick="CKEDITOR.tools.callFunction(', clickFn, ',null,\'', type, '\');return false;"' +
				' href="javascript:void(\'', lang.auto, '\')"' +
				' role="option" aria-posinset="1" aria-setsize="', total, '">' +
				'<table role="presentation" cellspacing=0 cellpadding=0 width="100%">' +
					'<tr>' +
						'<td>' +
							'<span class="cke_colorbox" id="', colorBoxId, '"></span>' +
						'</td>' +
						'<td colspan=7 align=center>', lang.auto, '</td>' +
					'</tr>' +
				'</table>' +
				'</a>' +
				'<table role="presentation" cellspacing=0 cellpadding=0 width="100%">' );

			// Render the color boxes.
			for ( var i = 0; i < colors.length; i++ ) {
				if ( ( i % 8 ) === 0 )
					output.push( '</tr><tr>' );

				var parts = colors[ i ].split( '/' ),
					colorName = parts[ 0 ],
					colorCode = parts[ 1 ] || colorName;

				// The data can be only a color code (without #) or colorName + color code
				// If only a color code is provided, then the colorName is the color with the hash
				// Convert the color from RGB to RRGGBB for better compatibility with IE and <font>. See #5676
				if ( !parts[ 1 ] )
					colorName = '#' + colorName.replace( /^(.)(.)(.)$/, '$1$1$2$2$3$3' );

				var colorLabel = editor.lang.colorbutton.colors[ colorCode ] || colorCode;
				output.push( '<td>' +
					'<a class="cke_colorbox" _cke_focus=1 hidefocus=true' +
						' title="', colorLabel, '"' +
						' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'', colorName, '\',\'', type, '\'); return false;"' +
						' href="javascript:void(\'', colorLabel, '\')"' +
						' role="option" aria-posinset="', ( i + 2 ), '" aria-setsize="', total, '">' +
						'<span class="cke_colorbox" style="background-color:#', colorCode, '"></span>' +
					'</a>' +
					'</td>' );
			}

			// Render the "More Colors" button.
			if ( moreColorsEnabled ) {
				output.push( '</tr>' +
					'<tr>' +
						'<td colspan=8 align=center>' +
							'<a class="cke_colormore" _cke_focus=1 hidefocus=true' +
								' title="', lang.more, '"' +
								' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'?\',\'', type, '\');return false;"' +
								' href="javascript:void(\'', lang.more, '\')"', ' role="option" aria-posinset="', total, '" aria-setsize="', total, '">', lang.more, '</a>' +
						'</td>' ); // tr is later in the code.
			}

			output.push( '</tr></table>' );

			return output.join( '' );
		}

		function isUnstylable( ele ) {
			return ( ele.getAttribute( 'contentEditable' ) == 'false' ) || ele.getAttribute( 'data-nostyle' );
		}
	}
1343293
function( editor ) {
			editor._.elementsPath = {
				idBase: 'cke_elementspath_' + CKEDITOR.tools.getNextNumber() + '_',
				filters: []
			};

			editor.on( 'uiSpace', function( event ) {
				if ( event.data.space == 'bottom' )
					initElementsPath( editor, event.data );
			} );
		}
501677
function _restoreEditorViewState(editor) {
        // We want to ignore the current state of the editor, so don't call __getViewState()
        var viewState = ViewStateManager.getViewState(editor.document.file);
        if (viewState) {
            editor.restoreViewState(viewState);
        }
    }
231174
function(self, options) {

    self.options = options;
    self.editorName = self.name + '-widgets-editor';

    // Opens the editor modal of a widget, unless the widget is contextualOnly,
    // in which case we simply save the widget and call the save method
    // Widget can opitonally be set to skipInitialModal which skips the first
    // edit modal but binds future editing interactions

    self.edit = function(data, options, save) {
      if (!data) {
        data = {};
      }
      if (!data._id) {
        _.assign(data, apos.schemas.newInstance(self.schema));
      }

      // Only create a modal editor if the schema is not contextual only
      if (self.options.contextualOnly) {

        return save(checkOrGenerateId(data), function() {});

      } else {

        if (self.options.skipInitialModal && (!data || !data._id)) {
          return save(checkOrGenerateId(data), function() {});

        }

        apos.create(self.editorName, {
          label: self.label,
          action: self.options.action,
          schema: self.options.schema,
          data: data,
          templateOptions: options,
          save: save,
          module: self
        });
      }

      // Checks for an id or assign a generated one
      function checkOrGenerateId (data) {
        data = data || {};
        if (!data._id) {
          data._id = apos.utils.generateId();
        }
        return data;
      }

    };

    // Area editor calls this to determine whether to apply an empty state
    // class for the widget
    self.isEmpty = function($widget) {
      return false;
    };

    var superGetData = self.getData;
    self.getData = function($widget) {
      var data = superGetData($widget);
      // If the field is contextual and its type has a `contextualConvert`
      // function, we need to run that when retrieving the widget's data.
      // Or, if the field has a `contextualIsPresent` method, we can use that
      // to check whether an editor is actually present for it, bypassing the
      // need to restrict this feature solely to fields marked contextual
      // in the schema.
      _.each(self.schema, function(field) {
        var type = apos.schemas.fieldTypes[field.type];
        if (
          (type.contextualIsPresent && type.contextualIsPresent($widget, field) && type.contextualConvert) ||
          (field.contextual && type.contextualConvert)
        ) {
          apos.schemas.fieldTypes[field.type].contextualConvert(data, field.name, $widget, field);
        }
      });
      return data;
    };

    // Start autosaving the area containing the given widget,
    // then invoke the given function. On failure fn is not invoked.
    // Invoked by widgets that are edited contextually on the page,
    // like apostrophe-rich-text, as opposed to widgets edited
    // via a modal.

    self.startAutosavingAreaThen = function($widget, fn) {
      var $area = $widget.closest('[data-apos-area]');
      return $area.data('editor').startAutosavingThen(fn);
    };
  }
958740
function () {
        var self = this, doc = self.getDoc();

        if (!self.hidden) {
          // Fixed bug where IE has a blinking cursor left from the editor
          if (ie && doc && !self.inline) {
            doc.execCommand('SelectAll');
          }

          // We must save before we hide so Safari doesn't crash
          self.save();

          if (self.inline) {
            self.getBody().contentEditable = false;

            // Make sure the editor gets blurred
            if (self == self.editorManager.focusedEditor) {
              self.editorManager.focusedEditor = null;
            }
          } else {
            DOM.hide(self.getContainer());
            DOM.setStyle(self.id, 'display', self.orgDisplay);
          }

          self.hidden = true;
          self.fire('hide');
        }
      }
1206630
function( editor ) {
			// Save plugin is for replace mode only.
			if ( editor.elementMode != CKEDITOR.ELEMENT_MODE_REPLACE )
				return;

			var command = editor.addCommand( pluginName, saveCmd );
			command.modes = { wysiwyg: !!( editor.element.$.form ) };

			editor.ui.addButton && editor.ui.addButton( 'Save', {
				label: editor.lang.save.toolbar,
				command: pluginName,
				toolbar: 'document,10'
			} );
		}
274550
function( editor ) {
		var pluginName = 'specialchar',
			plugin = this;

		// Register the dialog.
		CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/specialchar.js' );

		editor.addCommand( pluginName, {
			exec: function() {
				var langCode = editor.langCode;
				langCode =
					plugin.availableLangs[ langCode ] ? langCode :
					plugin.availableLangs[ langCode.replace( /-.*/, '' ) ] ? langCode.replace( /-.*/, '' ) :
					'en';

				CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( plugin.path + 'dialogs/lang/' + langCode + '.js' ), function() {
					CKEDITOR.tools.extend( editor.lang.specialchar, plugin.langEntries[ langCode ] );
					editor.openDialog( pluginName );
				} );
			},
			modes: { wysiwyg: 1 },
			canUndo: false
		} );

		// Register the toolbar button.
		editor.ui.addButton && editor.ui.addButton( 'SpecialChar', {
			label: editor.lang.specialchar.toolbar,
			command: pluginName,
			toolbar: 'insert,50'
		} );
	}
652854
def createEditor(self, delegate, parent, option):
        
        return IntCtiEditor(self, delegate, parent=parent)
956177
function( editor )
		{
			var hr = editor.document.createElement( 'hr' ),
				range = new CKEDITOR.dom.range( editor.document );

			editor.insertElement( hr );

			// If there's nothing or a non-editable block followed by, establish a new paragraph
			// to make sure cursor is not trapped.
			range.moveToPosition( hr, CKEDITOR.POSITION_AFTER_END );
			var next = hr.getNext();
			if ( !next || next.type == CKEDITOR.NODE_ELEMENT && !next.isEditable() )
				range.fixBlock( true, editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p'  );

			range.select();
		}
288111
function( editor ) {
			var textificationFilter;

			initClipboard( editor );

			CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );

			editor.on( 'paste', function( evt ) {
				var data = evt.data.dataValue,
					blockElements = CKEDITOR.dtd.$block;

				// Filter webkit garbage.
				if ( data.indexOf( 'Apple-' ) > -1 ) {
					// Replace special webkit's &nbsp; with simple space, because webkit
					// produces them even for normal spaces.
					data = data.replace( /<span class="Apple-converted-space">&nbsp;<\/span>/gi, ' ' );

					// Strip <span> around white-spaces when not in forced 'html' content type.
					// This spans are created only when pasting plain text into Webkit,
					// but for safety reasons remove them always.
					if ( evt.data.type != 'html' )
						data = data.replace( /<span class="Apple-tab-span"[^>]*>([^<]*)<\/span>/gi, function( all, spaces ) {
						// Replace tabs with 4 spaces like Fx does.
						return spaces.replace( /\t/g, '&nbsp;&nbsp; &nbsp;' );
					} );

					// This br is produced only when copying & pasting HTML content.
					if ( data.indexOf( '<br class="Apple-interchange-newline">' ) > -1 ) {
						evt.data.startsWithEOL = 1;
						evt.data.preSniffing = 'html'; // Mark as not text.
						data = data.replace( /<br class="Apple-interchange-newline">/, '' );
					}

					// Remove all other classes.
					data = data.replace( /(<[^>]+) class="Apple-[^"]*"/gi, '$1' );
				}

				// Strip editable that was copied from inside. (#9534)
				if ( data.match( /^<[^<]+cke_(editable|contents)/i ) ) {
					var tmp,
						editable_wrapper,
						wrapper = new CKEDITOR.dom.element( 'div' );

					wrapper.setHtml( data );
					// Verify for sure and check for nested editor UI parts. (#9675)
					while ( wrapper.getChildCount() == 1 &&
							( tmp = wrapper.getFirst() ) &&
							tmp.type == CKEDITOR.NODE_ELEMENT &&	// Make sure first-child is element.
							( tmp.hasClass( 'cke_editable' ) || tmp.hasClass( 'cke_contents' ) ) ) {
						wrapper = editable_wrapper = tmp;
					}

					// If editable wrapper was found strip it and bogus <br> (added on FF).
					if ( editable_wrapper )
						data = editable_wrapper.getHtml().replace( /<br>$/i, '' );
				}

				if ( CKEDITOR.env.ie ) {
					// &nbsp; <p> -> <p> (br.cke-pasted-remove will be removed later)
					data = data.replace( /^&nbsp;(?: |\r\n)?<(\w+)/g, function( match, elementName ) {
						if ( elementName.toLowerCase() in blockElements ) {
							evt.data.preSniffing = 'html'; // Mark as not a text.
							return '<' + elementName;
						}
						return match;
					} );
				} else if ( CKEDITOR.env.webkit ) {
					// </p><div><br></div> -> </p><br>
					// We don't mark br, because this situation can happen for htmlified text too.
					data = data.replace( /<\/(\w+)><div><br><\/div>$/, function( match, elementName ) {
						if ( elementName in blockElements ) {
							evt.data.endsWithEOL = 1;
							return '</' + elementName + '>';
						}
						return match;
					} );
				} else if ( CKEDITOR.env.gecko ) {
					// Firefox adds bogus <br> when user pasted text followed by space(s).
					data = data.replace( /(\s)<br>$/, '$1' );
				}

				evt.data.dataValue = data;
			}, null, null, 3 );

			editor.on( 'paste', function( evt ) {
				var dataObj = evt.data,
					type = dataObj.type,
					data = dataObj.dataValue,
					trueType,
					// Default is 'html'.
					defaultType = editor.config.clipboard_defaultContentType || 'html';

				// If forced type is 'html' we don't need to know true data type.
				if ( type == 'html' || dataObj.preSniffing == 'html' )
					trueType = 'html';
				else
					trueType = recogniseContentType( data );

				// Unify text markup.
				if ( trueType == 'htmlifiedtext' )
					data = htmlifiedTextHtmlification( editor.config, data );
				// Strip presentional markup & unify text markup.
				else if ( type == 'text' && trueType == 'html' ) {
					// Init filter only if needed and cache it.
					data = htmlTextification( editor.config, data, textificationFilter || ( textificationFilter = getTextificationFilter( editor ) ) );
				}

				if ( dataObj.startsWithEOL )
					data = '<br data-cke-eol="1">' + data;
				if ( dataObj.endsWithEOL )
					data += '<br data-cke-eol="1">';

				if ( type == 'auto' )
					type = ( trueType == 'html' || defaultType == 'html' ) ? 'html' : 'text';

				dataObj.type = type;
				dataObj.dataValue = data;
				delete dataObj.preSniffing;
				delete dataObj.startsWithEOL;
				delete dataObj.endsWithEOL;
			}, null, null, 6 );

			// Inserts processed data into the editor at the end of the
			// events chain.
			editor.on( 'paste', function( evt ) {
				var data = evt.data;

				editor.insertHtml( data.dataValue, data.type );

				// Deferr 'afterPaste' so all other listeners for 'paste' will be fired first.
				setTimeout( function() {
					editor.fire( 'afterPaste' );
				}, 0 );
			}, null, null, 1000 );

			editor.on( 'pasteDialog', function( evt ) {
				// TODO it's possible that this setTimeout is not needed any more,
				// because of changes introduced in the same commit as this comment.
				// Editor.getClipboardData adds listner to the dialog's events which are
				// fired after a while (not like 'showDialog').
				setTimeout( function() {
					// Open default paste dialog.
					editor.openDialog( 'paste', evt.data );
				}, 0 );
			} );
		}
3743
protected function initEditor(): void
    {
        $view = $this->getView();

        CKEditorAsset::register($view);
        CKEditorAssetAddition::register($view);

        $id = $this->options['id'];

        $clientOptions = !empty($this->clientOptions) ? Json::encode($this->clientOptions) : '{}';

        $js = [];

        $js[] = "CKEDITOR.replace('$id', $clientOptions);";
        $js[] = "initItstructureOnChangeHandler('$id');";

        if (array_key_exists('filebrowserUploadUrl', $this->clientOptions) ||
            array_key_exists('filebrowserImageUploadUrl', $this->clientOptions)) {
            $js[] = "initItstructureCsrfHandler();";
        }

        $view->registerJs(implode("\n", $js));
    }
286275
function(editorContext, ctxt) {
		var promise = new Deferred();
		var launchConf = this._setup.runBar.getSelectedLaunchConfiguration();
		if (launchConf) {
			this._projectClient.getProjectDeployService(launchConf.ServiceId, launchConf.Type).then(function(service){
				if (service && service.computeHoverInfo) {
					service.computeHoverInfo(launchConf, editorContext, ctxt).then(function(value) {
						promise.resolve(value);
					}, function() {
						promise.resolve(null);
					});
				} else {
					console.error('Failed to evaluate hover.');
					promise.resolve(null);
				}
			});
		} else {
			promise.resolve(null);
		}
		return promise;
	}
1712
function updateEditorElement() {
		var element = this.element;

		// Some editor creation mode will not have the
		// associated element.
		if ( element && this.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO ) {
			var data = this.getData();

			if ( this.config.htmlEncodeOutput )
				data = CKEDITOR.tools.htmlEncode( data );

			if ( element.is( 'textarea' ) )
				element.setValue( data );
			else
				element.setHtml( data );

			return true;
		}
		return false;
	}
834666
function setGeckoEditingOptions() {
        function setOpts() {
          refreshContentEditable();

          setEditorCommandState("StyleWithCSS", false);
          setEditorCommandState("enableInlineTableEditing", false);

          if (!settings.object_resizing) {
            setEditorCommandState("enableObjectResizing", false);
          }
        }

        if (!settings.readonly) {
          editor.on('BeforeExecCommand MouseDown', setOpts);
        }
      }