Respond to dirty flag change event. If the dirty flag is associated with an inline editor, show (or hide) the dirty indicator.
    function _dirtyFlagChangeHandler(event, doc) {
        var $dirtyIndicators = $(".inline-text-editor .dirty-indicator"),
            $indicator;
        $dirtyIndicators.each(function (index, indicator) {
            $indicator = $(this);
            if ($indicator.data("fullPath") === doc.file.fullPath) {
                _showDirtyIndicator($indicator, doc.isDirty);
            }
        });
    }Shows or hides the dirty indicator
    function _showDirtyIndicator($indicatorDiv, isDirty) {
        // Show or hide the dirty indicator by adjusting
        // the width of the div.
        $indicatorDiv.css("width", isDirty ? 16 : 0);
    }Given a host editor and its inline editors, find the widest gutter and make all the others match
    function _syncGutterWidths(hostEditor) {
        var allHostedEditors = EditorManager.getInlineEditors(hostEditor);
        // add the host itself to the list too
        allHostedEditors.push(hostEditor);
        var maxWidth = 0;
        allHostedEditors.forEach(function (editor) {
            var $gutter = $(editor._codeMirror.getGutterElement()).find(".CodeMirror-linenumbers");
            $gutter.css("min-width", "");
            var curWidth = $gutter.width();
            if (curWidth > maxWidth) {
                maxWidth = curWidth;
            }
        });
        if (allHostedEditors.length === 1) {
            //There's only the host, just refresh the gutter
            allHostedEditors[0]._codeMirror.setOption("gutters", allHostedEditors[0]._codeMirror.getOption("gutters"));
            return;
        }
        maxWidth = maxWidth + "px";
        allHostedEditors.forEach(function (editor) {
            $(editor._codeMirror.getGutterElement()).find(".CodeMirror-linenumbers").css("min-width", maxWidth);
            // Force CodeMirror to refresh the gutter
            editor._codeMirror.setOption("gutters", editor._codeMirror.getOption("gutters"));
        });
    }    function InlineTextEditor() {
        InlineWidget.call(this);
        this.editor = null;
        // We need to set this as a capture handler so CodeMirror doesn't handle Esc before we see it.
        this.handleKeyDown = this.handleKeyDown.bind(this);
        this.htmlContent.addEventListener("keydown", this.handleKeyDown, true);
    }
    InlineTextEditor.prototype = Object.create(InlineWidget.prototype);
    InlineTextEditor.prototype.constructor = InlineTextEditor;
    InlineTextEditor.prototype.parentClass = InlineWidget.prototype;
    InlineTextEditor.prototype.$wrapper = null;If Document's file is deleted, or Editor loses sync with Document, just close
    InlineTextEditor.prototype._onLostContent = function () {
        // Note: this closes the entire inline widget if any one Editor loses sync. This seems
        // better than leaving it open but suddenly removing one rule from the result list.
        this.close();
    };
    // Consolidate all dirty document updates
    // Due to circular dependencies, not safe to call on() directly
    EventDispatcher.on_duringInit(DocumentManager, "dirtyFlagChange", _dirtyFlagChangeHandler);
    exports.InlineTextEditor = InlineTextEditor;
});Updates start line display.
    InlineTextEditor.prototype._updateLineRange = function (editor) {
        this._startLine = editor.getFirstVisibleLine();
        this._endLine = editor.getLastVisibleLine();
        this._lineCount = this._endLine - this._startLine;
        this.$lineNumber.text(this._startLine + 1);
    };    InlineTextEditor.prototype.getFocusedEditor = function () {
        if (this.editor && this.editor.hasFocus()) {
            return this.editor;
        }
        return null;
    };    InlineTextEditor.prototype.handleKeyDown = function (e) {
        if (e.keyCode === KeyEvent.DOM_VK_ESCAPE && this.editor && this.editor.getSelections().length > 1) {
            CodeMirror.commands.singleSelection(this.editor._codeMirror);
            e.stopImmediatePropagation();
        }
    };    InlineTextEditor.prototype.load = function (hostEditor) {
        InlineTextEditor.prototype.parentClass.load.apply(this, arguments);
        // We don't create the actual editor here--that will happen the first time
        // setInlineContent() is called.
        this.$wrapper = $("<div/>").addClass("inline-text-editor").appendTo(this.$htmlContent);
        this.$header = $("<div/>").addClass("inline-editor-header").appendTo(this.$wrapper);
        this.$filename = $("<a/>").addClass("filename").appendTo(this.$header);
        this.$editorHolder = $("<div/>").addClass("inline-editor-holder").appendTo(this.$wrapper);
    };Some tasks have to wait until we've been parented into the outer editor
    InlineTextEditor.prototype.onAdded = function () {
        var self = this;
        InlineTextEditor.prototype.parentClass.onAdded.apply(this, arguments);
        if (this.editor) {
            this.editor.refresh();
        }
        // Update display of inline editors when the hostEditor signals a redraw
        CodeMirror.on(this.info, "redraw", function () {
            // At the point where we get the redraw, CodeMirror might not yet have actually
            // re-added the widget to the DOM. This is filed as https://github.com/codemirror/CodeMirror/issues/1226.
            // For now, we can work around it by doing the refresh on a setTimeout().
            window.setTimeout(function () {
                if (self.editor) {
                    self.editor.refresh();
                }
            }, 0);
        });
        _syncGutterWidths(this.hostEditor);
        if (this.editor) {
            this.editor.focus();
        }
    };Called any time inline was closed, whether manually (via close()) or automatically
    InlineTextEditor.prototype.onClosed = function () {
        InlineTextEditor.prototype.parentClass.onClosed.apply(this, arguments);
        _syncGutterWidths(this.hostEditor);
        // Destroy the inline editor.
        this.setInlineContent(null);
        this.htmlContent.removeEventListener("keydown", this.handleKeyDown, true);
    };Called when the editor containing the inline is made visible.
    InlineTextEditor.prototype.onParentShown = function () {
        InlineTextEditor.prototype.parentClass.onParentShown.apply(this, arguments);
        // Refresh line number display and codemirror line number gutter
        if (this.editor) {
            this._updateLineRange(this.editor);
            this.editor.refresh();
        }
        // We need to call this explicitly whenever the host editor is reshown
        this.sizeInlineWidgetToContents();
    };Sets the document and range to show in the inline editor, or null to destroy the current editor and leave the content blank.
    InlineTextEditor.prototype.setInlineContent = function (doc, startLine, endLine) {
        var self = this;
        // Destroy the previous editor if we had one and clear out the filename info.
        if (this.editor) {
            this.editor.off(".InlineTextEditor");
            this.editor.destroy(); // remove from DOM and release ref on Document
            this.editor = null;
            this.$filename.off(".InlineTextEditor")
                .removeAttr("title");
            this.$filename.html("");
        }
        if (!doc) {
            return;
        }
        var range = {
            startLine: startLine,
            endLine: endLine
        };
        // dirty indicator, with file path stored on it
        var $dirtyIndicatorDiv = $("<div/>")
            .addClass("dirty-indicator")
            .html("•")
            .width(0); // initialize indicator as hidden
        $dirtyIndicatorDiv.data("fullPath", doc.file.fullPath);
        this.$lineNumber = $("<span class='line-number'/>");
        // update contents of filename link
        this.$filename.append($dirtyIndicatorDiv)
            .append(doc.file.name + " : ")
            .append(this.$lineNumber)
            .attr("title", doc.file.fullPath);
        // clicking filename jumps to full editor view
        this.$filename.on("click.InlineTextEditor", function () {
            CommandManager.execute(Commands.FILE_OPEN, { fullPath: doc.file.fullPath })
                .done(function () {
                    EditorManager.getCurrentFullEditor().setCursorPos(startLine, 0, true);
                });
        });
        var inlineInfo = EditorManager.createInlineEditorForDocument(doc, range, this.$editorHolder.get(0));
        this.editor = inlineInfo.editor;
        // Init line number display
        this._updateLineRange(inlineInfo.editor);
        // Always update the widget height when an inline editor completes a
        // display update
        this.editor.on("update.InlineTextEditor", function (event, editor) {
            self.sizeInlineWidgetToContents();
        });
        // Size editor to content whenever text changes (via edits here or any
        // other view of the doc: Editor fires "change" any time its text
        // changes, regardless of origin)
        this.editor.on("change.InlineTextEditor", function (event, editor) {
            if (self.hostEditor.isFullyVisible()) {
                self.sizeInlineWidgetToContents();
                self._updateLineRange(editor);
            }
        });
        // If Document's file is deleted, or Editor loses sync with Document, delegate to this._onLostContent()
        this.editor.on("lostContent.InlineTextEditor", function () {
            self._onLostContent.apply(self, arguments);
        });
        // set dirty indicator state
        _showDirtyIndicator($dirtyIndicatorDiv, doc.isDirty);
    };Update the inline editor's height when the number of lines change. The base implementation of this method does nothing.
    InlineTextEditor.prototype.sizeInlineWidgetToContents = function () {
        // brackets_codemirror_overrides.css adds height:auto to CodeMirror
        // Inline editors themselves do not need to be sized, but layouts like
        // the one used in CSSInlineEditor do need some manual layout.
    };