diff --git a/spec/text-editor-element-spec.coffee b/spec/text-editor-element-spec.coffee index 18143ebb9..b5f05f4d9 100644 --- a/spec/text-editor-element-spec.coffee +++ b/spec/text-editor-element-spec.coffee @@ -104,6 +104,27 @@ describe "TextEditorElement", -> scrollbarWidth = verticalScrollbarNode.offsetWidth - verticalScrollbarNode.clientWidth expect(scrollbarWidth).toEqual(8) + describe "::onDidAttach and ::onDidDetach", -> + it "invokes callbacks when the element is attached and detached", -> + element = new TextEditorElement + + attachedCallback = jasmine.createSpy("attachedCallback") + detachedCallback = jasmine.createSpy("detachedCallback") + + element.onDidAttach(attachedCallback) + element.onDidDetach(detachedCallback) + + jasmine.attachToDOM(element) + + expect(attachedCallback).toHaveBeenCalled() + expect(detachedCallback).not.toHaveBeenCalled() + + attachedCallback.reset() + element.remove() + + expect(attachedCallback).not.toHaveBeenCalled() + expect(detachedCallback).toHaveBeenCalled() + describe "::setUpdatedSynchronously", -> it "controls whether the text editor is updated synchronously", -> spyOn(window, 'requestAnimationFrame').andCallFake (fn) -> fn() @@ -124,3 +145,13 @@ describe "TextEditorElement", -> element.getModel().setText("goodbye") expect(window.requestAnimationFrame).not.toHaveBeenCalled() expect(element.shadowRoot.textContent).toContain "goodbye" + + describe "::getDefaultCharacterWidth", -> + it "returns null before the element is attached", -> + element = new TextEditorElement + expect(element.getDefaultCharacterWidth()).toBeNull() + + it "returns the width of a character in the root scope", -> + element = new TextEditorElement + jasmine.attachToDOM(element) + expect(element.getDefaultCharacterWidth()).toBeGreaterThan(0) diff --git a/src/text-editor-element.coffee b/src/text-editor-element.coffee index 550c491fa..47fc3f67a 100644 --- a/src/text-editor-element.coffee +++ b/src/text-editor-element.coffee @@ -1,3 +1,4 @@ +{Emitter} = require 'event-kit' {View, $, callRemoveHooks} = require 'space-pen' React = require 'react-atom-fork' Path = require 'path' @@ -13,10 +14,12 @@ class TextEditorElement extends HTMLElement model: null componentDescriptor: null component: null + attached: false lineOverdrawMargin: null focusOnAttach: false createdCallback: -> + @emitter = new Emitter @initializeContent() @createSpacePenShim() @addEventListener 'focus', @focused.bind(this) @@ -61,6 +64,10 @@ class TextEditorElement extends HTMLElement @mountComponent() unless @component?.isMounted() @component.checkForVisibilityChange() @focus() if @focusOnAttach + @emitter.emit("did-attach") + + detachedCallback: -> + @emitter.emit("did-detach") initialize: (model) -> @setModel(model) @@ -160,6 +167,24 @@ class TextEditorElement extends HTMLElement isUpdatedSynchronously: -> @updatedSynchronously + # Extended: get the width of a character of text displayed in this element. + # + # Returns a {Number} of pixels. + getDefaultCharacterWidth: -> + @getModel().getDefaultCharWidth() + + # Extended: call the given `callback` when the editor is attached to the DOM. + # + # * `callback` {Function} + onDidAttach: (callback) -> + @emitter.on("did-attach", callback) + + # Extended: call the given `callback` when the editor is detached from the DOM. + # + # * `callback` {Function} + onDidDetach: (callback) -> + @emitter.on("did-detach", callback) + stopEventPropagation = (commandListeners) -> newCommandListeners = {} for commandName, commandListener of commandListeners