⬆️ etch to allow arbitrary objects as keys

This commit is contained in:
Nathan Sobo
2017-03-23 07:28:33 -06:00
committed by Antonio Scandurra
parent d8b22fb3bd
commit 1b1cffb32d
10 changed files with 193 additions and 95 deletions

View File

@@ -106,9 +106,12 @@ class DecorationManager {
}
if (hasMarkerDecorations) {
this.decorationsByMarker.get(marker).forEach((decoration) => {
decorationPropertiesForMarker.push(decoration.getProperties())
})
const decorationsForMarker = this.decorationsByMarker.get(marker)
if (decorationsForMarker) {
decorationsForMarker.forEach((decoration) => {
decorationPropertiesForMarker.push(decoration.getProperties())
})
}
}
}
})

View File

@@ -1,4 +1,5 @@
{Emitter} = require 'event-kit'
CustomGutterComponent = null
DefaultPriority = -100
@@ -102,3 +103,6 @@ class Gutter
# Returns a {Decoration} object
decorateMarker: (marker, options) ->
@gutterContainer.addGutterDecoration(this, marker, options)
getElement: ->
@element ?= document.createElement('div')

View File

@@ -58,7 +58,7 @@ if global.isGeneratingSnapshot
clipboard = new Clipboard
TextEditor.setClipboard(clipboard)
TextEditor.viewForOverlayItem = (item) -> atom.views.getView(item)
TextEditor.viewForItem = (item) -> atom.views.getView(item)
global.atom = new AtomEnvironment({
clipboard,

View File

@@ -54,7 +54,7 @@ export default async function () {
const clipboard = new Clipboard()
TextEditor.setClipboard(clipboard)
TextEditor.viewForOverlayItem = (item) -> atom.views.getView(item)
TextEditor.viewForItem = (item) -> atom.views.getView(item)
const applicationDelegate = new ApplicationDelegate()
const environmentParams = {

View File

@@ -70,7 +70,7 @@ module.exports = ({blobStore}) ->
clipboard = new Clipboard
TextEditor.setClipboard(clipboard)
TextEditor.viewForOverlayItem = (item) -> atom.views.getView(item)
TextEditor.viewForItem = (item) -> atom.views.getView(item)
testRunner = require(testRunnerPath)
legacyTestRunner = require(legacyTestRunnerPath)

View File

@@ -240,12 +240,15 @@ class TextEditorComponent {
innerStyle.transform = `translateY(${-this.getScrollTop()}px)`
gutterNodes = this.guttersToRender.map((gutter) => {
if (gutter.name === 'line-number') {
return this.renderLineNumberGutter()
return this.renderLineNumberGutter(gutter)
} else {
return $(CustomGutterComponent, {
key: gutter,
gutter: gutter,
height: this.getScrollHeight()
element: gutter.getElement(),
name: gutter.name,
visible: gutter.isVisible(),
height: this.getScrollHeight(),
decorations: this.decorationsToRender.customGutter.get(gutter.name)
})
}
})
@@ -267,7 +270,7 @@ class TextEditorComponent {
)
}
renderLineNumberGutter () {
renderLineNumberGutter (gutter) {
const {model} = this.props
if (!model.isLineNumberGutterVisible()) return null
@@ -302,6 +305,7 @@ class TextEditorComponent {
this.currentFrameLineNumberGutterProps = {
ref: 'lineNumberGutter',
element: gutter.getElement(),
parentComponent: this,
height: this.getScrollHeight(),
width: this.getLineNumberGutterWidth(),
@@ -680,6 +684,9 @@ class TextEditorComponent {
case 'overlay':
this.addOverlayDecorationToRender(decoration, marker)
break
case 'gutter':
this.addCustomGutterDecorationToRender(decoration, screenRange)
break
}
}
}
@@ -770,7 +777,7 @@ class TextEditorComponent {
addOverlayDecorationToRender (decoration, marker) {
const {class: className, item, position, avoidOverflow} = decoration
const element = TextEditor.viewForOverlayItem(item)
const element = TextEditor.viewForItem(item)
const screenPosition = (position === 'tail')
? marker.getTailScreenPosition()
: marker.getHeadScreenPosition()
@@ -779,6 +786,22 @@ class TextEditorComponent {
this.decorationsToRender.overlays.push({className, element, avoidOverflow, screenPosition})
}
addCustomGutterDecorationToRender (decoration, screenRange) {
let decorations = this.decorationsToRender.customGutter.get(decoration.gutterName)
if (!decorations) {
decorations = []
this.decorationsToRender.customGutter.set(decoration.gutterName, decorations)
}
const top = this.pixelTopForRow(screenRange.start.row)
const height = this.pixelTopForRow(screenRange.end.row + 1) - top
decorations.push({
className: decoration.class,
element: TextEditor.viewForItem(decoration.item),
top, height
})
}
updateAbsolutePositionedDecorations () {
this.updateHighlightsToRender()
this.updateCursorsToRender()
@@ -1984,7 +2007,10 @@ class DummyScrollbarComponent {
class LineNumberGutterComponent {
constructor (props) {
this.props = props
etch.initialize(this)
this.element = this.props.element
this.virtualNode = $.div(null)
this.virtualNode.domNode = this.element
etch.updateSync(this)
}
update (newProps) {
@@ -2100,8 +2126,10 @@ class LineNumberGutterComponent {
class CustomGutterComponent {
constructor (props) {
this.props = props
etch.initialize(this)
this.props.gutter.element = this.element
this.element = this.props.element
this.virtualNode = $.div(null)
this.virtualNode.domNode = this.element
etch.updateSync(this)
}
update (props) {
@@ -2109,21 +2137,68 @@ class CustomGutterComponent {
etch.updateSync(this)
}
destroy () {
etch.destroy(this)
}
render () {
return $.div(
{
className: 'gutter',
attributes: {'gutter-name': this.props.gutter.name},
attributes: {'gutter-name': this.props.name},
style: {
display: this.props.gutter.isVisible() ? '' : 'none'
display: this.props.visible ? '' : 'none'
}
},
$.div({
className: 'custom-decorations',
style: {height: this.props.height + 'px'}
})
$.div(
{
className: 'custom-decorations',
style: {height: this.props.height + 'px'}
},
this.renderDecorations()
)
)
}
renderDecorations () {
if (!this.props.decorations) return null
return this.props.decorations.map(({className, element, top, height}) => {
return $(CustomGutterDecorationComponent, {
className,
element,
top,
height
})
})
}
}
class CustomGutterDecorationComponent {
constructor (props) {
this.props = props
this.element = document.createElement('div')
const {top, height, className, element} = this.props
this.element.style.position = 'absolute'
this.element.style.top = top + 'px'
this.element.style.height = height + 'px'
if (className != null) this.element.className = className
if (element != null) this.element.appendChild(element)
}
update (newProps) {
const oldProps = this.props
this.props = newProps
if (newProps.top != oldProps.top) this.element.style.top = newProps.top + 'px'
if (newProps.height != oldProps.height) this.element.style.height = newProps.height + 'px'
if (newProps.className != oldProps.className) this.element.className = newProps.className || ''
if (newProps.element != oldProps.element) {
if (this.element.firstChild) this.element.firstChild.remove()
this.element.appendChild(newProps.element)
}
}
}
class LinesTileComponent {
@@ -2453,6 +2528,22 @@ class OverlayComponent {
}
}
class ComponentWrapper {
constructor (props) {
this.component = props.component
this.element = this.component.element
this.component.update(props)
}
update (props) {
this.component.update(props)
}
destroy () {
this.component.destroy()
}
}
const classNamesByScopeName = new Map()
function classNameForScopeName (scopeName) {
let classString = classNamesByScopeName.get(scopeName)

View File

@@ -69,7 +69,7 @@ class TextEditor extends Model
TextEditorComponent ?= require './text-editor-component'
TextEditorComponent.didUpdateScrollbarStyles()
@viewForOverlayItem: (item) -> item
@viewForItem: (item) -> item.element ? item
serializationVersion: 1