How to get View(Element) from TextEditor of TextEditorView?


#1

I can get the model(editor) in command callback like the below

atom.commands.add 'atom-text-editor', 'my-command', ->
  editor = @getModel()

but If I use ‘editorView= atom.views.getView(editor)’, this editorView returns incorrect view in TextEditorView.
This works well if editor is in workspace.

When launch a contextmenu, the menu can be also fired in TextEditorView.
In this case, the model(editor) will be editor of TextEditorView.
But editorView(element) is not the one of TextEditorView if I use ‘getView’

In TextEditorView constructor source code. It doesn’t create View from Views.createView API. it just create manually.

constructor: (modelOrParams, props) ->
# Handle direct construction with an editor or params
unless modelOrParams instanceof HTMLElement
  if modelOrParams instanceof TextEditor
    model = modelOrParams
  else
    {editor, mini, placeholderText, attributes} = modelOrParams
    model = editor ? new TextEditor
      buffer: new TextBuffer
      softWrapped: false
      tabLength: 2
      softTabs: true
      mini: mini
      placeholderText: placeholderText

  element = new TextEditorElement
  element.tileSize = props?.tileSize
  element.setAttribute(name, value) for name, value of attributes if attributes?
  element.setModel(model)
  return element.__spacePenView

# Handle construction with an element
@element = modelOrParams
super

I think View(element) of TextEditorView also should be created via ViewRegistry’s createView

Regards,
Kang-seok,Lee


#2

Actually space-pen views are just here for legacy support, but TextEditorElement is the proper view to use so there no reason the view registry returns a TextEditorView for a text editor.


#3

I understand what you are talking about and agree.
So… Is there no way to catch texteditorview’s element correctly by other packages?


#4

The Atom API is designed such that, for most cases, you shouldn’t need to get a hold of the actual view. What is it you’re trying to do?


#5

Hi,

With Quick-Edit and Color-picker,
(Actually Color-picker uses “atom.workspace.getActiveTextEditor” now)
But, If the color-picker tries to use @getModel() to get correct editor instead of the above on Quick-Edit,
I think there is no way to catch correct editer element from editor
(Inside color-picker, it uses editor and editor element to calculate popup positioning)

The packages that use TextEditor and EditorElement and fired from contextmenu will work abnomally on quick-edit.

thanks~


#6

I’m not sure what you mean by “quick-edit”?


#7

Quick-Editor Package(https://atom.io/packages/quick-editor).

I think I found a solution. Atom doesn’t need to register the view.
Quick-Editor developer should adds the below code

view = new TextEdtiorView()
atom.views.addViewProvider view.editor, (editor) => view.element

:smile:

Is this right?

Thanks


#8

I still don’t get why you need that. The TextEditorView in itself do nothing expect retrieving the text editor element returned by the view registry. I mean, it’s a 50 line class…

What do you need to do that you can’t do with the text editor element?

If it’s a problem with a package that still assume it’ll get a TextEditorView when retrieving the view for a TextEditor then this package probably should be updated to make use of the new API rather than constraining its users to fix themselves.


#9

Maybe I said with some mistake. sorry.

I need “TextEditorElement” not “TextEditorView”

As the above code, TextEditorView gets element from view registry.
My question is that why the new element created by TextEditorView is not registered to view registry?

If the TextEditorView have no responsibility of the registration, developer who use the view should do it


#10

Ok, I finally get the problem. Yes, you’re right, if you create a new text editor element without creating the text editor first and using the registry to get its view it won’t get registered.

But actually there’s a good reason for that:

When creating a atom-text-editor element using document.createElement, or through its constructor, the createdCallback will automatically create a model. This ensure you’ll have an instance that works properly even when you didn’t used the registry. Now, when using the getView method, the registry will also create a new element, so this element will create a model, but then the registry will call setModel on the view with the provided editor, and that’s when it’ll register the view with the model to ensure there’s only one view associated to the model. And by doing so it’ll also ensure that a view is always registered for one model only. If it was to register the model created in its constructor in the registry, one view could be potentially retrieved for 2 different models.

I hope I was clear enough in my explanations.

Now to come back to your initial example:

atom.commands.add 'atom-text-editor', 'my-command', ->
  editor = @getModel()

If you need the TextEditorElement then it’s just the this in the command callback.


#11

Thanks for your kind explanation.
Now I understand how atom view registry works.

It was a little bit difficult for me to implement some complicated combination packages.
I already have known the guide you told me. but it was not enough to solve the problem I faced.

Anyway, from this discussion. I got the other ways to solve the problem.

Thanks. Have a great day~