mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
Merge pull request #4165 from atom/ns-shadow-dom-style-updates
Make it easier to style atom-text-editor from outside its shadow root
This commit is contained in:
@@ -16,7 +16,7 @@ keystrokes pass through `atom-text-editor` elements:
|
||||
'ctrl-shift-e': 'editor:select-to-end-of-line'
|
||||
'cmd-left': 'editor:move-to-first-character-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)'
|
||||
'atom-text-editor:not([mini])'
|
||||
'cmd-alt-[': 'editor:fold-current-row'
|
||||
'cmd-alt-]': 'editor:unfold-current-row'
|
||||
```
|
||||
@@ -27,8 +27,8 @@ patterns* to *commands*. When an element with the `atom-text-editor` class is fo
|
||||
`editor:delete-to-beginning-of-line` is emitted on the `atom-text-editor` element.
|
||||
|
||||
The second selector group also targets editors, but only if they don't have the
|
||||
`.mini` class. In this example, the commands for code folding don't really make
|
||||
sense on mini-editors, so the selector restricts them to regular editors.
|
||||
`mini` attribute. In this example, the commands for code folding don't really
|
||||
make sense on mini-editors, so the selector restricts them to regular editors.
|
||||
|
||||
### Keystroke Patterns
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ built-in keymaps:
|
||||
'atom-text-editor':
|
||||
'enter': 'editor:newline'
|
||||
|
||||
'atom-text-editor.mini input':
|
||||
'atom-text-editor[mini] input':
|
||||
'enter': 'core:confirm'
|
||||
```
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
'shift-home': 'editor:select-to-first-character-of-line'
|
||||
'shift-end': 'editor:select-to-end-of-line'
|
||||
|
||||
'atom-text-editor:not(.mini)':
|
||||
'atom-text-editor:not([mini])':
|
||||
# Atom Specific
|
||||
'ctrl-C': 'editor:copy-path'
|
||||
|
||||
@@ -15,13 +15,13 @@
|
||||
'shift-tab': 'editor:outdent-selected-rows'
|
||||
'ctrl-K': 'editor:delete-line'
|
||||
|
||||
'.select-list atom-text-editor.mini':
|
||||
'.select-list atom-text-editor[mini]':
|
||||
'enter': 'core:confirm'
|
||||
|
||||
'.tool-panel.panel-left, .tool-panel.panel-right':
|
||||
'escape': 'tool-panel:unfocus'
|
||||
|
||||
'atom-text-editor !important, atom-text-editor.mini !important':
|
||||
'atom-text-editor !important, atom-text-editor[mini] !important':
|
||||
'escape': 'editor:consolidate-selections'
|
||||
|
||||
# allow standard input fields to work correctly
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
'cmd-l': 'editor:select-line'
|
||||
'ctrl-t': 'editor:transpose'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-cmd-z': 'editor:checkout-head-revision'
|
||||
'cmd-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -101,7 +101,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
@@ -98,7 +98,7 @@
|
||||
'ctrl-k ctrl-l': 'editor:lower-case'
|
||||
'ctrl-l': 'editor:select-line'
|
||||
|
||||
'atom-workspace atom-text-editor:not(.mini)':
|
||||
'atom-workspace atom-text-editor:not([mini])':
|
||||
# Atom specific
|
||||
'alt-ctrl-z': 'editor:checkout-head-revision'
|
||||
'ctrl-<': 'editor:scroll-to-cursor'
|
||||
|
||||
20
package.json
20
package.json
@@ -37,7 +37,7 @@
|
||||
"guid": "0.0.10",
|
||||
"jasmine-json": "~0.0",
|
||||
"jasmine-tagged": "^1.1.2",
|
||||
"less-cache": "0.17.0",
|
||||
"less-cache": "0.19.0",
|
||||
"mixto": "^1",
|
||||
"mkdirp": "0.3.5",
|
||||
"nslog": "^1.0.1",
|
||||
@@ -64,14 +64,14 @@
|
||||
"vm-compatibility-layer": "0.1.0"
|
||||
},
|
||||
"packageDependencies": {
|
||||
"atom-dark-syntax": "0.21.0",
|
||||
"atom-dark-ui": "0.35.0",
|
||||
"atom-light-syntax": "0.21.0",
|
||||
"atom-light-ui": "0.30.0",
|
||||
"base16-tomorrow-dark-theme": "0.21.0",
|
||||
"base16-tomorrow-light-theme": "0.4.0",
|
||||
"solarized-dark-syntax": "0.22.0",
|
||||
"solarized-light-syntax": "0.12.0",
|
||||
"atom-dark-syntax": "0.22.0",
|
||||
"atom-dark-ui": "0.37.0",
|
||||
"atom-light-syntax": "0.22.0",
|
||||
"atom-light-ui": "0.31.0",
|
||||
"base16-tomorrow-dark-theme": "0.22.0",
|
||||
"base16-tomorrow-light-theme": "0.5.0",
|
||||
"solarized-dark-syntax": "0.23.0",
|
||||
"solarized-light-syntax": "0.13.0",
|
||||
"archive-view": "0.37.0",
|
||||
"autocomplete": "0.33.0",
|
||||
"autoflow": "0.18.0",
|
||||
@@ -98,7 +98,7 @@
|
||||
"open-on-github": "0.30.0",
|
||||
"package-generator": "0.32.0",
|
||||
"release-notes": "0.36.0",
|
||||
"settings-view": "0.159.0",
|
||||
"settings-view": "0.160.0",
|
||||
"snippets": "0.56.0",
|
||||
"spell-check": "0.43.0",
|
||||
"status-bar": "0.46.0",
|
||||
|
||||
@@ -74,3 +74,34 @@ describe "StylesElement", ->
|
||||
expect(element.children.length).toBe 2
|
||||
expect(element.children[0].textContent).toBe "a {color: red;}"
|
||||
expect(element.children[1].textContent).toBe "a {color: blue;}"
|
||||
|
||||
describe "atom-text-editor shadow DOM selector upgrades", ->
|
||||
beforeEach ->
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
spyOn(console, 'warn')
|
||||
|
||||
it "upgrades selectors containing .editor-colors", ->
|
||||
atom.styles.addStyleSheet(".editor-colors {background: black;}", context: 'atom-text-editor')
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
it "upgrades selectors containing .editor", ->
|
||||
atom.styles.addStyleSheet """
|
||||
.editor {background: black;}
|
||||
.editor.mini {background: black;}
|
||||
.editor:focus {background: black;}
|
||||
""", context: 'atom-text-editor'
|
||||
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
expect(element.firstChild.sheet.cssRules[1].selectorText).toBe ':host(.mini)'
|
||||
expect(element.firstChild.sheet.cssRules[2].selectorText).toBe ':host(:focus)'
|
||||
|
||||
it "defers selector upgrade until the element is attached", ->
|
||||
element = new StylesElement
|
||||
element.setAttribute('context', 'atom-text-editor')
|
||||
element.initialize()
|
||||
|
||||
atom.styles.addStyleSheet ".editor {background: black;}", context: 'atom-text-editor'
|
||||
expect(element.firstChild.sheet).toBeNull()
|
||||
|
||||
document.querySelector('#jasmine-content').appendChild(element)
|
||||
expect(element.firstChild.sheet.cssRules[0].selectorText).toBe ':host'
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
TextEditorElement = require '../src/text-editor-element'
|
||||
TextEditor = require '../src/text-editor'
|
||||
|
||||
# The rest of text-editor-component-spec will be moved to this file when React
|
||||
# is eliminated. This covers only concerns related to the wrapper element for now
|
||||
@@ -19,6 +20,13 @@ describe "TextEditorElement", ->
|
||||
element = jasmineContent.firstChild
|
||||
expect(element.getModel().getPlaceholderText()).toBe 'testing'
|
||||
|
||||
describe "when the model is assigned", ->
|
||||
it "adds the 'mini' attribute if .isMini() returns true on the model", ->
|
||||
element = new TextEditorElement
|
||||
model = new TextEditor(mini: true)
|
||||
element.setModel(model)
|
||||
expect(element.hasAttribute('mini')).toBe true
|
||||
|
||||
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", ->
|
||||
|
||||
@@ -59,7 +59,7 @@ LinesComponent = React.createClass
|
||||
@renderedDecorationsByLineId = {}
|
||||
|
||||
componentDidMount: ->
|
||||
if atom.config.get('editor.useShadowDOM')
|
||||
if @props.useShadowDOM
|
||||
insertionPoint = document.createElement('content')
|
||||
insertionPoint.setAttribute('select', '.overlayer')
|
||||
@getDOMNode().appendChild(insertionPoint)
|
||||
|
||||
@@ -18,6 +18,9 @@ class StylesElement extends HTMLElement
|
||||
@styleElementClonesByOriginalElement = new WeakMap
|
||||
|
||||
attachedCallback: ->
|
||||
if @context is 'atom-text-editor'
|
||||
for styleElement in @children
|
||||
@upgradeDeprecatedSelectors(styleElement)
|
||||
@initialize()
|
||||
|
||||
detachedCallback: ->
|
||||
@@ -48,6 +51,7 @@ class StylesElement extends HTMLElement
|
||||
return unless @styleElementMatchesContext(styleElement)
|
||||
|
||||
styleElementClone = styleElement.cloneNode(true)
|
||||
styleElementClone.sourcePath = styleElement.sourcePath
|
||||
styleElementClone.context = styleElement.context
|
||||
@styleElementClonesByOriginalElement.set(styleElement, styleElementClone)
|
||||
|
||||
@@ -59,6 +63,10 @@ class StylesElement extends HTMLElement
|
||||
break
|
||||
|
||||
@insertBefore(styleElementClone, insertBefore)
|
||||
|
||||
if @context is 'atom-text-editor'
|
||||
@upgradeDeprecatedSelectors(styleElementClone)
|
||||
|
||||
@emitter.emit 'did-add-style-element', styleElementClone
|
||||
|
||||
styleElementRemoved: (styleElement) ->
|
||||
@@ -78,4 +86,30 @@ class StylesElement extends HTMLElement
|
||||
styleElementMatchesContext: (styleElement) ->
|
||||
not @context? or styleElement.context is @context
|
||||
|
||||
upgradeDeprecatedSelectors: (styleElement) ->
|
||||
return unless styleElement.sheet?
|
||||
|
||||
upgradedSelectors = []
|
||||
|
||||
for rule in styleElement.sheet.cssRules
|
||||
continue if /\:host/.test(rule.selectorText)
|
||||
|
||||
inputSelector = rule.selectorText
|
||||
outputSelector = rule.selectorText
|
||||
.replace(/\.editor-colors($|[ >])/g, ':host$1')
|
||||
.replace(/\.editor([:.][^ ,>]+)/g, ':host($1)')
|
||||
.replace(/\.editor($|[ ,>])/g, ':host$1')
|
||||
|
||||
unless inputSelector is outputSelector
|
||||
rule.selectorText = outputSelector
|
||||
upgradedSelectors.push({inputSelector, outputSelector})
|
||||
|
||||
if upgradedSelectors.length > 0
|
||||
warning = "Upgraded the following syntax theme selectors in `#{styleElement.sourcePath}` for shadow DOM compatibility:\n\n"
|
||||
for {inputSelector, outputSelector} in upgradedSelectors
|
||||
warning += "`#{inputSelector}` => `#{outputSelector}`\n"
|
||||
|
||||
warning += "\nSee the upgrade guide for information on removing this warning."
|
||||
console.warn(warning)
|
||||
|
||||
module.exports = StylesElement = document.registerElement 'atom-styles', prototype: StylesElement.prototype
|
||||
|
||||
@@ -50,7 +50,7 @@ TextEditorComponent = React.createClass
|
||||
|
||||
render: ->
|
||||
{focused, showIndentGuide, showLineNumbers, visible} = @state
|
||||
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay, hostElement} = @props
|
||||
{editor, mini, cursorBlinkPeriod, cursorBlinkResumeDelay, hostElement, useShadowDOM} = @props
|
||||
maxLineNumberDigits = editor.getLineCount().toString().length
|
||||
hasSelection = editor.getLastSelection()? and !editor.getLastSelection().isEmpty()
|
||||
style = {}
|
||||
@@ -90,7 +90,10 @@ TextEditorComponent = React.createClass
|
||||
|
||||
style.height = scrollViewHeight if @autoHeight
|
||||
|
||||
className = 'editor-contents'
|
||||
if useShadowDOM
|
||||
className = 'editor-contents--private'
|
||||
else
|
||||
className = 'editor-contents'
|
||||
className += ' is-focused' if focused
|
||||
className += ' has-selection' if hasSelection
|
||||
|
||||
@@ -117,7 +120,7 @@ TextEditorComponent = React.createClass
|
||||
@scrollingVertically, scrollHeight, scrollWidth, mouseWheelScreenRow,
|
||||
visible, scrollViewHeight, @scopedCharacterWidthsChangeCount, lineWidth, @useHardwareAcceleration,
|
||||
placeholderText, @performedInitialMeasurement, @backgroundColor, cursorPixelRects,
|
||||
cursorBlinkPeriod, cursorBlinkResumeDelay, mini
|
||||
cursorBlinkPeriod, cursorBlinkResumeDelay, mini, useShadowDOM
|
||||
}
|
||||
|
||||
ScrollbarComponent
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
{View, $, callRemoveHooks} = require 'space-pen'
|
||||
React = require 'react-atom-fork'
|
||||
Path = require 'path'
|
||||
{defaults} = require 'underscore-plus'
|
||||
TextBuffer = require 'text-buffer'
|
||||
TextEditor = require './text-editor'
|
||||
TextEditorComponent = require './text-editor-component'
|
||||
TextEditorView = null
|
||||
|
||||
ShadowStyleSheet = null
|
||||
|
||||
class TextEditorElement extends HTMLElement
|
||||
model: null
|
||||
componentDescriptor: null
|
||||
@@ -25,24 +28,31 @@ class TextEditorElement extends HTMLElement
|
||||
@setAttribute('tabindex', -1)
|
||||
|
||||
if atom.config.get('editor.useShadowDOM')
|
||||
@useShadowDOM = true
|
||||
|
||||
unless ShadowStyleSheet?
|
||||
ShadowStyleSheet = document.createElement('style')
|
||||
ShadowStyleSheet.textContent = atom.themes.loadLessStylesheet(require.resolve('../static/text-editor-shadow.less'))
|
||||
|
||||
@createShadowRoot()
|
||||
|
||||
@shadowRoot.appendChild(ShadowStyleSheet.cloneNode(true))
|
||||
@stylesElement = document.createElement('atom-styles')
|
||||
@stylesElement.setAttribute('context', 'atom-text-editor')
|
||||
@stylesElement.initialize()
|
||||
|
||||
@rootElement = document.createElement('div')
|
||||
@rootElement.classList.add('shadow')
|
||||
@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
|
||||
|
||||
@rootElement.classList.add('editor', 'editor-colors')
|
||||
|
||||
|
||||
createSpacePenShim: ->
|
||||
TextEditorView ?= require './text-editor-view'
|
||||
@__spacePenView = new TextEditorView(this)
|
||||
@@ -60,6 +70,7 @@ class TextEditorElement extends HTMLElement
|
||||
@model = model
|
||||
@mountComponent()
|
||||
@addGrammarScopeAttribute()
|
||||
@addMiniAttributeIfNeeded()
|
||||
@model.onDidChangeGrammar => @addGrammarScopeAttribute()
|
||||
@addEncodingAttribute()
|
||||
@model.onDidChangeEncoding => @addEncodingAttribute()
|
||||
@@ -88,10 +99,11 @@ class TextEditorElement extends HTMLElement
|
||||
editor: @model
|
||||
mini: @model.mini
|
||||
lineOverdrawMargin: @lineOverdrawMargin
|
||||
useShadowDOM: @useShadowDOM
|
||||
)
|
||||
@component = React.renderComponent(@componentDescriptor, @rootElement)
|
||||
|
||||
unless atom.config.get('editor.useShadowDOM')
|
||||
unless @useShadowDOM
|
||||
inputNode = @component.refs.input.getDOMNode()
|
||||
inputNode.addEventListener 'focus', @focused.bind(this)
|
||||
inputNode.addEventListener 'blur', => @dispatchEvent(new FocusEvent('blur', bubbles: false))
|
||||
@@ -109,7 +121,7 @@ class TextEditorElement extends HTMLElement
|
||||
@focusOnAttach = true
|
||||
|
||||
blurred: (event) ->
|
||||
unless atom.config.get('editor.useShadowDOM')
|
||||
unless @useShadowDOM
|
||||
if event.relatedTarget is @component?.refs.input?.getDOMNode()
|
||||
event.stopImmediatePropagation()
|
||||
return
|
||||
@@ -120,6 +132,9 @@ class TextEditorElement extends HTMLElement
|
||||
grammarScope = @model.getGrammar()?.scopeName?.replace(/\./g, ' ')
|
||||
@dataset.grammar = grammarScope
|
||||
|
||||
addMiniAttributeIfNeeded: ->
|
||||
@setAttributeNode(document.createAttribute("mini")) if @model.isMini()
|
||||
|
||||
addEncodingAttribute: ->
|
||||
@dataset.encoding = @model.getEncoding()
|
||||
|
||||
@@ -199,7 +214,7 @@ atom.commands.add 'atom-text-editor', stopEventPropagationAndGroupUndo(
|
||||
'editor:lower-case': -> @lowerCase()
|
||||
)
|
||||
|
||||
atom.commands.add 'atom-text-editor:not(.mini)', stopEventPropagationAndGroupUndo(
|
||||
atom.commands.add 'atom-text-editor:not([mini])', stopEventPropagationAndGroupUndo(
|
||||
'core:move-up': -> @moveUp()
|
||||
'core:move-down': -> @moveDown()
|
||||
'core:move-to-top': -> @moveToTop()
|
||||
|
||||
@@ -6,7 +6,7 @@ Delegator = require 'delegato'
|
||||
{Model} = require 'theorist'
|
||||
EmitterMixin = require('emissary').Emitter
|
||||
{CompositeDisposable, Emitter} = require 'event-kit'
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{Point, Range} = TextBuffer = require 'text-buffer'
|
||||
LanguageMode = require './language-mode'
|
||||
DisplayBuffer = require './display-buffer'
|
||||
Cursor = require './cursor'
|
||||
@@ -84,6 +84,7 @@ class TextEditor extends Model
|
||||
@cursors = []
|
||||
@selections = []
|
||||
|
||||
buffer ?= new TextBuffer
|
||||
@displayBuffer ?= new DisplayBuffer({buffer, tabLength, softWrapped})
|
||||
@buffer = @displayBuffer.buffer
|
||||
@softTabs = @usesSoftTabs() ? @softTabs ? atom.config.get('editor.softTabs') ? true
|
||||
|
||||
@@ -249,9 +249,6 @@ class ThemeManager
|
||||
if nativeStylesheetPath = fs.resolveOnLoadPath(process.platform, ['css', 'less'])
|
||||
@requireStylesheet(nativeStylesheetPath)
|
||||
|
||||
textEditorStylesPath = path.join(@resourcePath, 'static', 'text-editor-shadow.less')
|
||||
atom.styles.addStyleSheet(@loadLessStylesheet(textEditorStylesPath), sourcePath: textEditorStylesPath, context: 'atom-text-editor')
|
||||
|
||||
stylesheetElementForId: (id) ->
|
||||
document.head.querySelector("atom-styles style[source-path=\"#{id}\"]")
|
||||
|
||||
|
||||
@@ -99,7 +99,7 @@ atom-panel[location="modal"] {
|
||||
font-size: 1.3em;
|
||||
}
|
||||
|
||||
atom-text-editor.mini {
|
||||
atom-text-editor[mini] {
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
@import "ui-variables";
|
||||
@import "octicon-utf-codes";
|
||||
@import "octicon-mixins";
|
||||
|
||||
atom-text-editor {
|
||||
display: block;
|
||||
@@ -6,7 +8,7 @@ atom-text-editor {
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
atom-text-editor.mini {
|
||||
atom-text-editor[mini] {
|
||||
font-size: @input-font-size;
|
||||
line-height: @component-line-height;
|
||||
max-height: @component-line-height + 2; // +2 for borders
|
||||
@@ -18,8 +20,206 @@ atom-overlay {
|
||||
z-index: 4;
|
||||
}
|
||||
|
||||
// TODO: remove this when the shadow DOM is the default
|
||||
atom-text-editor .highlight {
|
||||
background: none;
|
||||
padding: 0;
|
||||
// TODO: Remove the following styles when the editor shadow DOM can no longer be disabled
|
||||
atom-text-editor {
|
||||
display: -webkit-flex;
|
||||
|
||||
.editor-contents {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
cursor: text;
|
||||
display: -webkit-flex;
|
||||
-webkit-user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
cursor: default;
|
||||
min-width: 1em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.line-numbers {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line-number {
|
||||
white-space: nowrap;
|
||||
padding-left: .5em;
|
||||
opacity: 0.6;
|
||||
|
||||
&.cursor-line {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.icon-right {
|
||||
.octicon(chevron-down, 0.8em);
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
opacity: .6;
|
||||
padding: 0 .4em;
|
||||
|
||||
&:before {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gutter:hover {
|
||||
.line-number.foldable .icon-right {
|
||||
visibility: visible;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gutter, .gutter:hover {
|
||||
.line-number.folded .icon-right {
|
||||
.octicon(chevron-right, 0.8em);
|
||||
|
||||
visibility: visible;
|
||||
|
||||
&:before {
|
||||
position: relative;
|
||||
left: -.1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
overflow: hidden;
|
||||
-webkit-flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.underlayer {
|
||||
position: absolute;
|
||||
z-index: -2;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.highlight .region {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.lines {
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.line {
|
||||
white-space: pre;
|
||||
|
||||
&.cursor-line .fold-marker:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fold-marker {
|
||||
cursor: default;
|
||||
|
||||
&:after {
|
||||
.icon(0.8em, inline);
|
||||
|
||||
content: @ellipsis;
|
||||
padding-left: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
position: absolute;
|
||||
color: @text-color-subtle;
|
||||
}
|
||||
|
||||
.invisible-character {
|
||||
font-weight: normal !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
.indent-guide {
|
||||
box-shadow: inset 1px 0;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
z-index: 4;
|
||||
pointer-events: none;
|
||||
box-sizing: border-box;
|
||||
position: absolute;
|
||||
border-left: 1px solid;
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
&.is-focused .cursor {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.cursors.blink-off .cursor {
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.horizontal-scrollbar {
|
||||
position: absolute;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
height: 15px;
|
||||
overflow-x: auto;
|
||||
overflow-y: hidden;
|
||||
z-index: 3;
|
||||
cursor: default;
|
||||
|
||||
.scrollbar-content {
|
||||
height: 15px;
|
||||
}
|
||||
}
|
||||
|
||||
.vertical-scrollbar {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
|
||||
width: 15px;
|
||||
overflow-x: hidden;
|
||||
overflow-y: auto;
|
||||
z-index: 3;
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.scrollbar-corner {
|
||||
position: absolute;
|
||||
overflow: auto;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,26 +2,154 @@
|
||||
@import "octicon-utf-codes";
|
||||
@import "octicon-mixins";
|
||||
|
||||
.editor-contents {
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.editor.shadow, .editor.shadow .editor-contents {
|
||||
.editor--private, .editor-contents--private {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.editor-contents--private {
|
||||
width: 100%;
|
||||
overflow: hidden;
|
||||
cursor: text;
|
||||
display: -webkit-flex;
|
||||
-webkit-user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
cursor: default;
|
||||
min-width: 1em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.line-numbers {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.line-number {
|
||||
white-space: nowrap;
|
||||
padding-left: .5em;
|
||||
opacity: 0.6;
|
||||
|
||||
&.cursor-line {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.icon-right {
|
||||
.octicon(chevron-down, 0.8em);
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
opacity: .6;
|
||||
padding: 0 .4em;
|
||||
|
||||
&:before {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gutter:hover {
|
||||
.line-number.foldable .icon-right {
|
||||
visibility: visible;
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.gutter, .gutter:hover {
|
||||
.line-number.folded .icon-right {
|
||||
.octicon(chevron-right, 0.8em);
|
||||
|
||||
visibility: visible;
|
||||
|
||||
&:before {
|
||||
position: relative;
|
||||
left: -.1em;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
position: relative;
|
||||
z-index: 0;
|
||||
|
||||
overflow: hidden;
|
||||
-webkit-flex: 1;
|
||||
min-width: 0;
|
||||
}
|
||||
|
||||
.underlayer {
|
||||
position: absolute;
|
||||
z-index: -2;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: -2;
|
||||
}
|
||||
|
||||
.highlight {
|
||||
background: none;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.highlight .region {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
.lines {
|
||||
min-width: 100%;
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.line {
|
||||
white-space: pre;
|
||||
|
||||
&.cursor-line .fold-marker:after {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.fold-marker {
|
||||
cursor: default;
|
||||
|
||||
&:after {
|
||||
.icon(0.8em, inline);
|
||||
|
||||
content: @ellipsis;
|
||||
padding-left: 0.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
position: absolute;
|
||||
color: @text-color-subtle;
|
||||
}
|
||||
|
||||
.invisible-character {
|
||||
font-weight: normal !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
.indent-guide {
|
||||
box-shadow: inset 1px 0;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.cursor {
|
||||
@@ -33,7 +161,7 @@
|
||||
opacity: 0;
|
||||
}
|
||||
|
||||
.is-focused .cursor {
|
||||
&.is-focused .cursor {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
@@ -77,176 +205,3 @@
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
}
|
||||
|
||||
.scroll-view {
|
||||
overflow: hidden;
|
||||
z-index: 0;
|
||||
-webkit-flex: 1;
|
||||
min-width: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
.line-number {
|
||||
white-space: nowrap;
|
||||
padding-left: .5em;
|
||||
|
||||
.icon-right {
|
||||
padding: 0 .4em;
|
||||
&:before {
|
||||
text-align: center;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.placeholder-text {
|
||||
position: absolute;
|
||||
color: @text-color-subtle;
|
||||
}
|
||||
|
||||
.editor {
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.editor, .editor-contents {
|
||||
overflow: hidden;
|
||||
cursor: text;
|
||||
display: -webkit-flex;
|
||||
-webkit-user-select: none;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gutter .line-number.cursor-line {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gutter {
|
||||
overflow: hidden;
|
||||
text-align: right;
|
||||
cursor: default;
|
||||
min-width: 1em;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.gutter .line-number {
|
||||
padding-left: .5em;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
.gutter .line-numbers {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gutter .line-number.folded.cursor-line {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.gutter .line-number .icon-right {
|
||||
.octicon(chevron-down, 0.8em);
|
||||
display: inline-block;
|
||||
visibility: hidden;
|
||||
padding-left: .1em;
|
||||
padding-right: .5em;
|
||||
opacity: .6;
|
||||
}
|
||||
|
||||
.gutter:hover .line-number.foldable .icon-right {
|
||||
visibility: visible;
|
||||
|
||||
&:before {
|
||||
content: @chevron-down;
|
||||
}
|
||||
|
||||
&:hover {
|
||||
opacity: 1;
|
||||
}
|
||||
}
|
||||
|
||||
.gutter, .gutter:hover {
|
||||
.line-number.folded .icon-right {
|
||||
.octicon(chevron-right, 0.8em);
|
||||
visibility: visible;
|
||||
|
||||
&:before { // chevron-right renders too far right compared to chevron-down
|
||||
position: relative;
|
||||
left: -.1em;
|
||||
content: @chevron-right;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fold-marker {
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.fold-marker:after {
|
||||
.icon(0.8em, inline);
|
||||
content: @ellipsis;
|
||||
padding-left: 0.2em;
|
||||
}
|
||||
|
||||
.line.cursor-line .fold-marker:after {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor.is-blurred .line.cursor-line {
|
||||
background: rgba(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
.invisible-character {
|
||||
font-weight: normal !important;
|
||||
font-style: normal !important;
|
||||
}
|
||||
|
||||
.indent-guide {
|
||||
display: inline-block;
|
||||
box-shadow: inset 1px 0;
|
||||
}
|
||||
|
||||
.editor.soft-wrap .scroll-view {
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
.underlayer {
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.lines {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.overlayer {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.line {
|
||||
white-space: pre;
|
||||
}
|
||||
|
||||
.line span {
|
||||
vertical-align: top;
|
||||
}
|
||||
|
||||
.hidden-input {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
position: absolute;
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
opacity: 0;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.highlight .region,
|
||||
.selection .region {
|
||||
position: absolute;
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user