mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 15:37:46 +03:00
🔥 useShadowDOM setting
This commit is contained in:
parent
e1f8a72995
commit
738a2b90dc
@ -87,7 +87,6 @@ beforeEach ->
|
||||
atom.config.set "editor.autoIndent", false
|
||||
atom.config.set "core.disabledPackages", ["package-that-throws-an-exception",
|
||||
"package-with-broken-package-json", "package-with-broken-keymap"]
|
||||
atom.config.set "editor.useShadowDOM", true
|
||||
advanceClock(1000)
|
||||
window.setTimeout.reset()
|
||||
|
||||
|
@ -39,32 +39,17 @@ describe "TextEditorElement", ->
|
||||
expect(element.hasAttribute('mini')).toBe true
|
||||
|
||||
describe "when the editor is attached to the DOM", ->
|
||||
describe "when the editor.useShadowDOM config option is true", ->
|
||||
it "mounts the react component and unmounts when removed from the dom", ->
|
||||
atom.config.set('editor.useShadowDOM', true)
|
||||
it "mounts the component and unmounts when removed from the dom", ->
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
component = element.component
|
||||
expect(component.mounted).toBe true
|
||||
element.remove()
|
||||
expect(component.mounted).toBe false
|
||||
|
||||
component = element.component
|
||||
expect(component.mounted).toBe true
|
||||
element.remove()
|
||||
expect(component.mounted).toBe false
|
||||
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.component.mounted).toBe true
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
it "mounts the react component and unmounts when removed from the dom", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmine.attachToDOM(element)
|
||||
|
||||
component = element.component
|
||||
expect(component.mounted).toBe true
|
||||
element.getModel().destroy()
|
||||
expect(component.mounted).toBe false
|
||||
jasmine.attachToDOM(element)
|
||||
expect(element.component.mounted).toBe true
|
||||
|
||||
describe "when the editor is detached from the DOM and then reattached", ->
|
||||
it "does not render duplicate line numbers", ->
|
||||
@ -96,42 +81,21 @@ describe "TextEditorElement", ->
|
||||
expect(element.shadowRoot.querySelectorAll('.decoration').length).toBe initialDecorationCount
|
||||
|
||||
describe "focus and blur handling", ->
|
||||
describe "when the editor.useShadowDOM config option is true", ->
|
||||
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
|
||||
atom.config.set('editor.useShadowDOM', true)
|
||||
it "proxies focus/blur events to/from the hidden input inside the shadow root", ->
|
||||
element = new TextEditorElement
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmineContent.appendChild(element)
|
||||
blurCalled = false
|
||||
element.addEventListener 'blur', -> blurCalled = true
|
||||
|
||||
blurCalled = false
|
||||
element.addEventListener 'blur', -> blurCalled = true
|
||||
element.focus()
|
||||
expect(blurCalled).toBe false
|
||||
expect(element.hasFocus()).toBe true
|
||||
expect(document.activeElement).toBe element
|
||||
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
|
||||
|
||||
element.focus()
|
||||
expect(blurCalled).toBe false
|
||||
expect(element.hasFocus()).toBe true
|
||||
expect(document.activeElement).toBe element
|
||||
expect(element.shadowRoot.activeElement).toBe element.shadowRoot.querySelector('input')
|
||||
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
|
||||
describe "when the editor.useShadowDOM config option is false", ->
|
||||
it "proxies focus/blur events to/from the hidden input", ->
|
||||
atom.config.set('editor.useShadowDOM', false)
|
||||
|
||||
element = new TextEditorElement
|
||||
jasmineContent.appendChild(element)
|
||||
|
||||
blurCalled = false
|
||||
element.addEventListener 'blur', -> blurCalled = true
|
||||
|
||||
element.focus()
|
||||
expect(blurCalled).toBe false
|
||||
expect(element.hasFocus()).toBe true
|
||||
expect(document.activeElement).toBe element.querySelector('input')
|
||||
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
document.body.focus()
|
||||
expect(blurCalled).toBe true
|
||||
|
||||
describe "when focused while a parent node is being attached to the DOM", ->
|
||||
class ElementThatFocusesChild extends HTMLDivElement
|
||||
@ -162,8 +126,6 @@ describe "TextEditorElement", ->
|
||||
themeReloadCallback = fn
|
||||
new Disposable
|
||||
|
||||
atom.config.set("editor.useShadowDOM", false)
|
||||
|
||||
element = new TextEditorElement()
|
||||
element.style.height = '200px'
|
||||
element.getModel().setText [0..20].join("\n")
|
||||
|
@ -218,11 +218,6 @@ module.exports =
|
||||
default: 300
|
||||
minimum: 0
|
||||
description: 'Time interval in milliseconds within which text editing operations will be grouped together in the undo history.'
|
||||
useShadowDOM:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
title: 'Use Shadow DOM'
|
||||
description: 'Disable if you experience styling issues with packages or themes. Be sure to open an issue on the relevant package or theme, because this option is going away eventually.'
|
||||
confirmCheckoutHeadRevision:
|
||||
type: 'boolean'
|
||||
default: true
|
||||
|
@ -21,7 +21,7 @@ module.exports =
|
||||
class LinesComponent extends TiledComponent
|
||||
placeholderTextDiv: null
|
||||
|
||||
constructor: ({@presenter, @useShadowDOM, @domElementPool, @assert, @grammars}) ->
|
||||
constructor: ({@presenter, @domElementPool, @assert, @grammars}) ->
|
||||
@domNode = document.createElement('div')
|
||||
@domNode.classList.add('lines')
|
||||
@tilesNode = document.createElement("div")
|
||||
@ -34,10 +34,9 @@ class LinesComponent extends TiledComponent
|
||||
@cursorsComponent = new CursorsComponent
|
||||
@domNode.appendChild(@cursorsComponent.getDomNode())
|
||||
|
||||
if @useShadowDOM
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', '.overlayer')
|
||||
@domNode.appendChild(insertionPoint)
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', '.overlayer')
|
||||
@domNode.appendChild(insertionPoint)
|
||||
|
||||
getDomNode: ->
|
||||
@domNode
|
||||
|
@ -42,7 +42,7 @@ class TextEditorComponent
|
||||
@assert domNode?, "TextEditorComponent::domNode was set to null."
|
||||
@domNodeValue = domNode
|
||||
|
||||
constructor: ({@editor, @hostElement, @rootElement, @stylesElement, @useShadowDOM, tileSize, @views, @themes, @config, @workspace, @assert, @grammars, scrollPastEnd}) ->
|
||||
constructor: ({@editor, @hostElement, @rootElement, @stylesElement, tileSize, @views, @themes, @workspace, @assert, @grammars, scrollPastEnd}) ->
|
||||
@tileSize = tileSize if tileSize?
|
||||
@disposables = new CompositeDisposable
|
||||
|
||||
@ -55,7 +55,6 @@ class TextEditorComponent
|
||||
cursorBlinkPeriod: @cursorBlinkPeriod
|
||||
cursorBlinkResumeDelay: @cursorBlinkResumeDelay
|
||||
stoppedScrollingDelay: 200
|
||||
config: @config
|
||||
lineTopIndex: lineTopIndex
|
||||
scrollPastEnd: scrollPastEnd
|
||||
|
||||
@ -63,17 +62,13 @@ class TextEditorComponent
|
||||
|
||||
@domElementPool = new DOMElementPool
|
||||
@domNode = document.createElement('div')
|
||||
if @useShadowDOM
|
||||
@domNode.classList.add('editor-contents--private')
|
||||
@domNode.classList.add('editor-contents--private')
|
||||
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', 'atom-overlay')
|
||||
@domNode.appendChild(insertionPoint)
|
||||
@overlayManager = new OverlayManager(@presenter, @hostElement, @views)
|
||||
@blockDecorationsComponent = new BlockDecorationsComponent(@hostElement, @views, @presenter, @domElementPool)
|
||||
else
|
||||
@domNode.classList.add('editor-contents')
|
||||
@overlayManager = new OverlayManager(@presenter, @domNode, @views)
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', 'atom-overlay')
|
||||
@domNode.appendChild(insertionPoint)
|
||||
@overlayManager = new OverlayManager(@presenter, @hostElement, @views)
|
||||
@blockDecorationsComponent = new BlockDecorationsComponent(@hostElement, @views, @presenter, @domElementPool)
|
||||
|
||||
@scrollViewNode = document.createElement('div')
|
||||
@scrollViewNode.classList.add('scroll-view')
|
||||
@ -82,7 +77,7 @@ class TextEditorComponent
|
||||
@hiddenInputComponent = new InputComponent
|
||||
@scrollViewNode.appendChild(@hiddenInputComponent.getDomNode())
|
||||
|
||||
@linesComponent = new LinesComponent({@presenter, @hostElement, @useShadowDOM, @domElementPool, @assert, @grammars})
|
||||
@linesComponent = new LinesComponent({@presenter, @hostElement, @domElementPool, @assert, @grammars})
|
||||
@scrollViewNode.appendChild(@linesComponent.getDomNode())
|
||||
|
||||
if @blockDecorationsComponent?
|
||||
|
@ -22,7 +22,6 @@ class TextEditorElement extends HTMLElement
|
||||
|
||||
createdCallback: ->
|
||||
# Use globals when the following instance variables aren't set.
|
||||
@config = atom.config
|
||||
@themes = atom.themes
|
||||
@workspace = atom.workspace
|
||||
@assert = atom.assert
|
||||
@ -43,31 +42,22 @@ class TextEditorElement extends HTMLElement
|
||||
unless @autoHeight
|
||||
@style.height = "100%"
|
||||
|
||||
if @config.get('editor.useShadowDOM')
|
||||
@useShadowDOM = true
|
||||
unless ShadowStyleSheet?
|
||||
ShadowStyleSheet = document.createElement('style')
|
||||
ShadowStyleSheet.textContent = @themes.loadLessStylesheet(require.resolve('../static/text-editor-shadow.less'))
|
||||
|
||||
unless ShadowStyleSheet?
|
||||
ShadowStyleSheet = document.createElement('style')
|
||||
ShadowStyleSheet.textContent = @themes.loadLessStylesheet(require.resolve('../static/text-editor-shadow.less'))
|
||||
@createShadowRoot()
|
||||
|
||||
@createShadowRoot()
|
||||
@shadowRoot.appendChild(ShadowStyleSheet.cloneNode(true))
|
||||
@stylesElement = new StylesElement
|
||||
@stylesElement.initialize(@styles)
|
||||
@stylesElement.setAttribute('context', 'atom-text-editor')
|
||||
|
||||
@shadowRoot.appendChild(ShadowStyleSheet.cloneNode(true))
|
||||
@stylesElement = new StylesElement
|
||||
@stylesElement.initialize(@styles)
|
||||
@stylesElement.setAttribute('context', 'atom-text-editor')
|
||||
@rootElement = document.createElement('div')
|
||||
@rootElement.classList.add('editor--private')
|
||||
|
||||
@rootElement = document.createElement('div')
|
||||
@rootElement.classList.add('editor--private')
|
||||
|
||||
@shadowRoot.appendChild(@stylesElement)
|
||||
@shadowRoot.appendChild(@rootElement)
|
||||
else
|
||||
@useShadowDOM = false
|
||||
|
||||
@classList.add('editor', 'editor-colors')
|
||||
@stylesElement = document.head.querySelector('atom-styles')
|
||||
@rootElement = this
|
||||
@shadowRoot.appendChild(@stylesElement)
|
||||
@shadowRoot.appendChild(@rootElement)
|
||||
|
||||
attachedCallback: ->
|
||||
@buildModel() unless @getModel()?
|
||||
@ -91,9 +81,8 @@ class TextEditorElement extends HTMLElement
|
||||
@subscriptions.add @component.onDidChangeScrollLeft =>
|
||||
@emitter.emit("did-change-scroll-left", arguments...)
|
||||
|
||||
initialize: (model, {@views, @config, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @scrollPastEnd = true) ->
|
||||
initialize: (model, {@views, @themes, @workspace, @assert, @styles, @grammars}, @autoHeight = true, @scrollPastEnd = true) ->
|
||||
throw new Error("Must pass a views parameter when initializing TextEditorElements") unless @views?
|
||||
throw new Error("Must pass a config parameter when initializing TextEditorElements") unless @config?
|
||||
throw new Error("Must pass a themes parameter when initializing TextEditorElements") unless @themes?
|
||||
throw new Error("Must pass a workspace parameter when initializing TextEditorElements") unless @workspace?
|
||||
throw new Error("Must pass an assert parameter when initializing TextEditorElements") unless @assert?
|
||||
@ -141,10 +130,8 @@ class TextEditorElement extends HTMLElement
|
||||
stylesElement: @stylesElement
|
||||
editor: @model
|
||||
tileSize: @tileSize
|
||||
useShadowDOM: @useShadowDOM
|
||||
views: @views
|
||||
themes: @themes
|
||||
config: @config
|
||||
workspace: @workspace
|
||||
assert: @assert
|
||||
grammars: @grammars
|
||||
@ -152,12 +139,7 @@ class TextEditorElement extends HTMLElement
|
||||
)
|
||||
@rootElement.appendChild(@component.getDomNode())
|
||||
|
||||
if @useShadowDOM
|
||||
@shadowRoot.addEventListener('blur', @shadowRootBlurred.bind(this), true)
|
||||
else
|
||||
inputNode = @component.hiddenInputComponent.getDomNode()
|
||||
inputNode.addEventListener 'focus', @focused.bind(this)
|
||||
inputNode.addEventListener 'blur', => @dispatchEvent(new FocusEvent('blur', bubbles: false))
|
||||
@shadowRoot.addEventListener('blur', @shadowRootBlurred.bind(this), true)
|
||||
|
||||
unmountComponent: ->
|
||||
if @component?
|
||||
@ -169,11 +151,6 @@ class TextEditorElement extends HTMLElement
|
||||
@component?.focused()
|
||||
|
||||
blurred: (event) ->
|
||||
unless @useShadowDOM
|
||||
if event.relatedTarget is @component.hiddenInputComponent.getDomNode()
|
||||
event.stopImmediatePropagation()
|
||||
return
|
||||
|
||||
@component?.blurred()
|
||||
|
||||
# Work around what seems to be a bug in Chromium. Focus can be stolen from the
|
||||
|
Loading…
Reference in New Issue
Block a user