mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-09-20 15:37:46 +03:00
commit
1ee1fa02ba
@ -2588,3 +2588,79 @@ describe "Editor", ->
|
||||
expect(buffer.lineForRow(14)).toBe ''
|
||||
expect(buffer.lineForRow(15)).toBeUndefined()
|
||||
expect(editor.getCursorBufferPosition()).toEqual [14, 0]
|
||||
|
||||
describe ".moveEditSessionToIndex(fromIndex, toIndex)", ->
|
||||
describe "when the edit session moves to a later index", ->
|
||||
it "updates the edit session order", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
expect(editor.editSessions[0].getPath()).toBe jsPath
|
||||
expect(editor.editSessions[1].getPath()).toBe txtPath
|
||||
editor.moveEditSessionToIndex(0, 1)
|
||||
expect(editor.editSessions[0].getPath()).toBe txtPath
|
||||
expect(editor.editSessions[1].getPath()).toBe jsPath
|
||||
|
||||
it "fires an editor:edit-session-order-changed event", ->
|
||||
eventHandler = jasmine.createSpy("eventHandler")
|
||||
rootView.open("sample.txt")
|
||||
editor.on "editor:edit-session-order-changed", eventHandler
|
||||
editor.moveEditSessionToIndex(0, 1)
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
it "sets the moved session as the editor's active session", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
expect(editor.activeEditSession.getPath()).toBe txtPath
|
||||
editor.moveEditSessionToIndex(0, 1)
|
||||
expect(editor.activeEditSession.getPath()).toBe jsPath
|
||||
|
||||
describe "when the edit session moves to an earlier index", ->
|
||||
it "updates the edit session order", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
expect(editor.editSessions[0].getPath()).toBe jsPath
|
||||
expect(editor.editSessions[1].getPath()).toBe txtPath
|
||||
editor.moveEditSessionToIndex(1, 0)
|
||||
expect(editor.editSessions[0].getPath()).toBe txtPath
|
||||
expect(editor.editSessions[1].getPath()).toBe jsPath
|
||||
|
||||
it "fires an editor:edit-session-order-changed event", ->
|
||||
eventHandler = jasmine.createSpy("eventHandler")
|
||||
rootView.open("sample.txt")
|
||||
editor.on "editor:edit-session-order-changed", eventHandler
|
||||
editor.moveEditSessionToIndex(1, 0)
|
||||
expect(eventHandler).toHaveBeenCalled()
|
||||
|
||||
it "sets the moved session as the editor's active session", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
expect(editor.activeEditSession.getPath()).toBe txtPath
|
||||
editor.moveEditSessionToIndex(1, 0)
|
||||
expect(editor.activeEditSession.getPath()).toBe txtPath
|
||||
|
||||
describe ".moveEditSessionToEditor(fromIndex, toEditor, toIndex)", ->
|
||||
it "closes the edit session in the source editor", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
rightEditor = editor.splitRight()
|
||||
expect(editor.editSessions[0].getPath()).toBe jsPath
|
||||
expect(editor.editSessions[1].getPath()).toBe txtPath
|
||||
editor.moveEditSessionToEditor(0, rightEditor, 1)
|
||||
expect(editor.editSessions[0].getPath()).toBe txtPath
|
||||
expect(editor.editSessions[1]).toBeUndefined()
|
||||
|
||||
it "opens the edit session in the destination editor at the target index", ->
|
||||
jsPath = editor.getPath()
|
||||
rootView.open("sample.txt")
|
||||
txtPath = editor.getPath()
|
||||
rightEditor = editor.splitRight()
|
||||
expect(rightEditor.editSessions[0].getPath()).toBe txtPath
|
||||
expect(rightEditor.editSessions[1]).toBeUndefined()
|
||||
editor.moveEditSessionToEditor(0, rightEditor, 0)
|
||||
expect(rightEditor.editSessions[0].getPath()).toBe jsPath
|
||||
expect(rightEditor.editSessions[1].getPath()).toBe txtPath
|
||||
|
@ -1,5 +1,6 @@
|
||||
Keymap = require 'keymap'
|
||||
$ = require 'jquery'
|
||||
RootView = require 'root-view'
|
||||
|
||||
describe "Keymap", ->
|
||||
fragment = null
|
||||
@ -23,8 +24,8 @@ describe "Keymap", ->
|
||||
keymap.bindKeys '.command-mode', 'x': 'deleteChar'
|
||||
keymap.bindKeys '.insert-mode', 'x': 'insertChar'
|
||||
|
||||
deleteCharHandler = jasmine.createSpy 'deleteCharHandler'
|
||||
insertCharHandler = jasmine.createSpy 'insertCharHandler'
|
||||
deleteCharHandler = jasmine.createSpy('deleteCharHandler')
|
||||
insertCharHandler = jasmine.createSpy('insertCharHandler')
|
||||
fragment.on 'deleteChar', deleteCharHandler
|
||||
fragment.on 'insertChar', insertCharHandler
|
||||
|
||||
@ -149,6 +150,19 @@ describe "Keymap", ->
|
||||
keymap.handleKeyEvent(keydownEvent('y', target: target))
|
||||
expect(bazHandler).toHaveBeenCalled()
|
||||
|
||||
describe "when the event's target is the document body", ->
|
||||
it "triggers the mapped event on the rootView", ->
|
||||
rootView = new RootView
|
||||
keymap.bindKeys 'body', 'x': 'foo'
|
||||
fooHandler = jasmine.createSpy("fooHandler")
|
||||
rootView.on 'foo', fooHandler
|
||||
|
||||
result = keymap.handleKeyEvent(keydownEvent('x', target: document.body))
|
||||
expect(result).toBe(false)
|
||||
expect(fooHandler).toHaveBeenCalled()
|
||||
expect(deleteCharHandler).not.toHaveBeenCalled()
|
||||
expect(insertCharHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "when at least one binding partially matches the event's keystroke", ->
|
||||
[quitHandler, closeOtherWindowsHandler] = []
|
||||
|
||||
|
@ -190,11 +190,11 @@ describe "RootView", ->
|
||||
expect(rootView.find('#two')).not.toMatchSelector(':focus')
|
||||
|
||||
describe "when there are no visible focusable elements", ->
|
||||
it "retains focus itself", ->
|
||||
it "surrenders focus to the body", ->
|
||||
rootView.remove()
|
||||
rootView = new RootView(require.resolve 'fixtures')
|
||||
rootView.attachToDom()
|
||||
expect(rootView).toMatchSelector(':focus')
|
||||
expect(document.activeElement).toBe $('body')[0]
|
||||
|
||||
describe "panes", ->
|
||||
[pane1, newPaneContent] = []
|
||||
|
@ -102,9 +102,8 @@ window.keyIdentifierForKey = (key) ->
|
||||
"U+00" + charCode.toString(16)
|
||||
|
||||
window.keydownEvent = (key, properties={}) ->
|
||||
event = $.Event "keydown", _.extend({originalEvent: { keyIdentifier: keyIdentifierForKey(key) }}, properties)
|
||||
# event.keystroke = (new Keymap).keystrokeStringForEvent(event)
|
||||
event
|
||||
properties = $.extend({originalEvent: { keyIdentifier: keyIdentifierForKey(key) }}, properties)
|
||||
$.Event("keydown", properties)
|
||||
|
||||
window.mouseEvent = (type, properties) ->
|
||||
if properties.point
|
||||
|
@ -549,6 +549,20 @@ class Editor extends View
|
||||
"Cancel"
|
||||
)
|
||||
|
||||
moveEditSessionToIndex: (fromIndex, toIndex) ->
|
||||
return if fromIndex is toIndex
|
||||
editSession = @editSessions.splice(fromIndex, 1)
|
||||
@editSessions.splice(toIndex, 0, editSession[0])
|
||||
@trigger 'editor:edit-session-order-changed', [editSession, fromIndex, toIndex]
|
||||
@setActiveEditSessionIndex(toIndex)
|
||||
|
||||
moveEditSessionToEditor: (fromIndex, toEditor, toIndex) ->
|
||||
fromEditSession = @editSessions[fromIndex]
|
||||
toEditSession = fromEditSession.copy()
|
||||
@destroyEditSessionIndex(fromIndex)
|
||||
toEditor.edit(toEditSession)
|
||||
toEditor.moveEditSessionToIndex(toEditor.getActiveEditSessionIndex(), toIndex)
|
||||
|
||||
activateEditSessionForPath: (path) ->
|
||||
for editSession, index in @editSessions
|
||||
if editSession.buffer.getPath() == path
|
||||
|
@ -73,6 +73,7 @@ class Keymap
|
||||
return true unless bindingSetsForFirstKeystroke?
|
||||
|
||||
currentNode = $(event.target)
|
||||
currentNode = rootView if currentNode is $('body')[0]
|
||||
while currentNode.length
|
||||
candidateBindingSets = @bindingSetsForNode(currentNode, bindingSetsForFirstKeystroke)
|
||||
for bindingSet in candidateBindingSets
|
||||
@ -99,6 +100,7 @@ class Keymap
|
||||
b.specificity - a.specificity
|
||||
|
||||
triggerCommandEvent: (keyEvent, commandName) ->
|
||||
keyEvent.target = rootView[0] if keyEvent.target == document.body and window.rootView
|
||||
commandEvent = $.Event(commandName)
|
||||
commandEvent.keyEvent = keyEvent
|
||||
aborted = false
|
||||
|
@ -18,7 +18,7 @@ class RootView extends View
|
||||
disabledPackages: []
|
||||
|
||||
@content: ->
|
||||
@div id: 'root-view', tabindex: 0, =>
|
||||
@div id: 'root-view', =>
|
||||
@div id: 'horizontal', outlet: 'horizontal', =>
|
||||
@div id: 'vertical', outlet: 'vertical', =>
|
||||
@div id: 'panes', outlet: 'panes'
|
||||
@ -261,3 +261,11 @@ class RootView extends View
|
||||
|
||||
eachBuffer: (callback) ->
|
||||
@project.eachBuffer(callback)
|
||||
|
||||
indexOfPane: (pane) ->
|
||||
index = -1
|
||||
for p, idx in @panes.find('.pane')
|
||||
if pane.is(p)
|
||||
index = idx
|
||||
break
|
||||
index
|
||||
|
53
src/app/sortable-list.coffee
Normal file
53
src/app/sortable-list.coffee
Normal file
@ -0,0 +1,53 @@
|
||||
{View} = require 'space-pen'
|
||||
$ = require 'jquery'
|
||||
|
||||
module.exports =
|
||||
class SortableList extends View
|
||||
@viewClass: -> 'sortable-list'
|
||||
|
||||
initialize: ->
|
||||
@on 'dragstart', '.sortable', @onDragStart
|
||||
@on 'dragend', '.sortable', @onDragEnd
|
||||
@on 'dragover', '.sortable', @onDragOver
|
||||
@on 'dragenter', '.sortable', @onDragEnter
|
||||
@on 'dragleave', '.sortable', @onDragLeave
|
||||
@on 'drop', '.sortable', @onDrop
|
||||
|
||||
onDragStart: (event) =>
|
||||
return false if !@shouldAllowDrag(event)
|
||||
|
||||
el = @getSortableElement(event)
|
||||
el.addClass 'is-dragging'
|
||||
event.originalEvent.dataTransfer.setData 'sortable-index', el.index()
|
||||
|
||||
onDragEnd: (event) =>
|
||||
@getSortableElement(event).removeClass 'is-dragging'
|
||||
|
||||
onDragEnter: (event) =>
|
||||
event.preventDefault()
|
||||
|
||||
onDragOver: (event) =>
|
||||
event.preventDefault()
|
||||
@getSortableElement(event).addClass 'is-drop-target'
|
||||
|
||||
onDragLeave: (event) =>
|
||||
@getSortableElement(event).removeClass 'is-drop-target'
|
||||
|
||||
onDrop: (event) =>
|
||||
return false if !@shouldAllowDrop(event)
|
||||
event.stopPropagation()
|
||||
@find('.is-drop-target').removeClass 'is-drop-target'
|
||||
|
||||
shouldAllowDrag: (event) ->
|
||||
true
|
||||
|
||||
shouldAllowDrop: (event) ->
|
||||
true
|
||||
|
||||
getDroppedElement: (event) ->
|
||||
idx = event.originalEvent.dataTransfer.getData 'sortable-index'
|
||||
@find ".sortable:eq(#{idx})"
|
||||
|
||||
getSortableElement: (event) ->
|
||||
el = $(event.target)
|
||||
if !el.hasClass('sortable') then el.closest('.sortable') else el
|
97
src/packages/tabs/lib/tab-view.coffee
Normal file
97
src/packages/tabs/lib/tab-view.coffee
Normal file
@ -0,0 +1,97 @@
|
||||
$ = require 'jquery'
|
||||
SortableList = require 'sortable-list'
|
||||
Tab = require './tab'
|
||||
|
||||
module.exports =
|
||||
class TabView extends SortableList
|
||||
@activate: ->
|
||||
rootView.eachEditor (editor) =>
|
||||
@prependToEditorPane(editor) if editor.attached
|
||||
|
||||
@prependToEditorPane: (editor) ->
|
||||
if pane = editor.pane()
|
||||
pane.prepend(new TabView(editor))
|
||||
|
||||
@content: ->
|
||||
@ul class: "tabs #{@viewClass()}"
|
||||
|
||||
initialize: (@editor) ->
|
||||
super
|
||||
|
||||
@addTabForEditSession(editSession) for editSession in @editor.editSessions
|
||||
|
||||
@setActiveTab(@editor.getActiveEditSessionIndex())
|
||||
@editor.on 'editor:active-edit-session-changed', (e, editSession, index) => @setActiveTab(index)
|
||||
@editor.on 'editor:edit-session-added', (e, editSession) => @addTabForEditSession(editSession)
|
||||
@editor.on 'editor:edit-session-removed', (e, editSession, index) => @removeTabAtIndex(index)
|
||||
@editor.on 'editor:edit-session-order-changed', (e, editSession, fromIndex, toIndex) =>
|
||||
fromTab = @find(".tab:eq(#{fromIndex})")
|
||||
toTab = @find(".tab:eq(#{toIndex})")
|
||||
fromTab.detach()
|
||||
if fromIndex < toIndex
|
||||
fromTab.insertAfter(toTab)
|
||||
else
|
||||
fromTab.insertBefore(toTab)
|
||||
|
||||
@on 'click', '.tab', (e) =>
|
||||
@editor.setActiveEditSessionIndex($(e.target).closest('.tab').index())
|
||||
@editor.focus()
|
||||
|
||||
@on 'click', '.tab .close-icon', (e) =>
|
||||
index = $(e.target).closest('.tab').index()
|
||||
@editor.destroyEditSessionIndex(index)
|
||||
false
|
||||
|
||||
addTabForEditSession: (editSession) ->
|
||||
@append(new Tab(editSession, @editor))
|
||||
|
||||
setActiveTab: (index) ->
|
||||
@find(".tab.active").removeClass('active')
|
||||
@find(".tab:eq(#{index})").addClass('active')
|
||||
|
||||
removeTabAtIndex: (index) ->
|
||||
@find(".tab:eq(#{index})").remove()
|
||||
|
||||
containsEditSession: (editor, editSession) ->
|
||||
for session in editor.editSessions
|
||||
return true if editSession.getPath() is session.getPath()
|
||||
|
||||
shouldAllowDrag: (event) ->
|
||||
panes = rootView.find('.pane')
|
||||
!(panes.length == 1 && panes.find('.sortable').length == 1)
|
||||
|
||||
onDragStart: (event) =>
|
||||
super
|
||||
|
||||
pane = $(event.target).closest('.pane')
|
||||
paneIndex = rootView.indexOfPane(pane)
|
||||
event.originalEvent.dataTransfer.setData 'from-pane-index', paneIndex
|
||||
|
||||
onDrop: (event) =>
|
||||
super
|
||||
|
||||
droppedNearTab = @getSortableElement(event)
|
||||
transfer = event.originalEvent.dataTransfer
|
||||
previousDraggedTabIndex = transfer.getData 'sortable-index'
|
||||
|
||||
fromPaneIndex = ~~transfer.getData 'from-pane-index'
|
||||
toPaneIndex = rootView.indexOfPane($(event.target).closest('.pane'))
|
||||
fromPane = $(rootView.find('.pane')[fromPaneIndex])
|
||||
fromEditor = fromPane.find('.editor').view()
|
||||
draggedTab = fromPane.find(".#{TabView.viewClass()} .sortable:eq(#{previousDraggedTabIndex})")
|
||||
return if draggedTab.is(droppedNearTab)
|
||||
|
||||
if fromPaneIndex == toPaneIndex
|
||||
droppedNearTab = @getSortableElement(event)
|
||||
fromIndex = draggedTab.index()
|
||||
toIndex = droppedNearTab.index()
|
||||
toIndex++ if fromIndex > toIndex
|
||||
fromEditor.moveEditSessionToIndex(fromIndex, toIndex)
|
||||
fromEditor.focus()
|
||||
else
|
||||
toPane = $(rootView.find('.pane')[toPaneIndex])
|
||||
toEditor = toPane.find('.editor').view()
|
||||
|
||||
unless @containsEditSession(toEditor, fromEditor.editSessions[draggedTab.index()])
|
||||
fromEditor.moveEditSessionToEditor(draggedTab.index(), toEditor, droppedNearTab.index() + 1)
|
||||
toEditor.focus()
|
@ -4,7 +4,7 @@ fs = require 'fs'
|
||||
module.exports =
|
||||
class Tab extends View
|
||||
@content: (editSession) ->
|
||||
@li class: 'tab', =>
|
||||
@li class: 'tab sortable', =>
|
||||
@span class: 'file-name', outlet: 'fileName'
|
||||
@span class: 'close-icon'
|
||||
|
||||
|
@ -1,44 +0,0 @@
|
||||
$ = require 'jquery'
|
||||
{View} = require 'space-pen'
|
||||
Tab = require './tab'
|
||||
|
||||
module.exports =
|
||||
class Tabs extends View
|
||||
@activate: ->
|
||||
rootView.eachEditor (editor) =>
|
||||
@prependToEditorPane(rootView, editor) if editor.attached
|
||||
|
||||
@prependToEditorPane: (rootView, editor) ->
|
||||
if pane = editor.pane()
|
||||
pane.prepend(new Tabs(editor))
|
||||
|
||||
@content: ->
|
||||
@ul class: 'tabs'
|
||||
|
||||
initialize: (@editor) ->
|
||||
for editSession, index in @editor.editSessions
|
||||
@addTabForEditSession(editSession)
|
||||
|
||||
@setActiveTab(@editor.getActiveEditSessionIndex())
|
||||
@editor.on 'editor:active-edit-session-changed', (e, editSession, index) => @setActiveTab(index)
|
||||
@editor.on 'editor:edit-session-added', (e, editSession) => @addTabForEditSession(editSession)
|
||||
@editor.on 'editor:edit-session-removed', (e, editSession, index) => @removeTabAtIndex(index)
|
||||
|
||||
@on 'click', '.tab', (e) =>
|
||||
@editor.setActiveEditSessionIndex($(e.target).closest('.tab').index())
|
||||
@editor.focus()
|
||||
|
||||
@on 'click', '.tab .close-icon', (e) =>
|
||||
index = $(e.target).closest('.tab').index()
|
||||
@editor.destroyEditSessionIndex(index)
|
||||
false
|
||||
|
||||
addTabForEditSession: (editSession) ->
|
||||
@append(new Tab(editSession, @editor))
|
||||
|
||||
setActiveTab: (index) ->
|
||||
@find(".tab.active").removeClass('active')
|
||||
@find(".tab:eq(#{index})").addClass('active')
|
||||
|
||||
removeTabAtIndex: (index) ->
|
||||
@find(".tab:eq(#{index})").remove()
|
@ -1 +1 @@
|
||||
'main': 'lib/tabs-view'
|
||||
'main': 'lib/tab-view'
|
||||
|
@ -3,11 +3,11 @@ _ = require 'underscore'
|
||||
RootView = require 'root-view'
|
||||
fs = require 'fs'
|
||||
|
||||
describe "Tabs", ->
|
||||
describe "TabView", ->
|
||||
[editor, buffer, tabs] = []
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView(require.resolve('fixtures/sample.js'))
|
||||
new RootView(require.resolve('fixtures/sample.js'))
|
||||
rootView.open('sample.txt')
|
||||
rootView.simulateDomAttachment()
|
||||
atom.loadPackage("tabs")
|
||||
@ -144,3 +144,68 @@ describe "Tabs", ->
|
||||
expect(tabs.find('.tab:last .file-name').text()).toBe 'sample.js - tmp'
|
||||
editor.destroyActiveEditSession()
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe 'sample.js'
|
||||
|
||||
describe "when an editor:edit-session-order-changed event is triggered", ->
|
||||
it "updates the order of the tabs to match the new edit session order", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
|
||||
editor.moveEditSessionToIndex(0, 1)
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
|
||||
editor.moveEditSessionToIndex(1, 0)
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
|
||||
describe "dragging and dropping tabs", ->
|
||||
describe "when a tab is dragged from and dropped onto the same editor", ->
|
||||
it "moves the edit session, updates the order of the tabs, and focuses the editor", ->
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.js"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.txt"
|
||||
|
||||
sortableElement = [tabs.find('.tab:eq(0)')]
|
||||
spyOn(tabs, 'getSortableElement').andCallFake -> sortableElement[0]
|
||||
event = $.Event()
|
||||
event.target = tabs[0]
|
||||
event.originalEvent =
|
||||
dataTransfer:
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
|
||||
editor.hiddenInput.focusout()
|
||||
tabs.onDragStart(event)
|
||||
sortableElement = [tabs.find('.tab:eq(1)')]
|
||||
tabs.onDrop(event)
|
||||
|
||||
expect(tabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(tabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
expect(editor.isFocused).toBeTruthy()
|
||||
|
||||
describe "when a tab is dragged from one editor and dropped onto another editor", ->
|
||||
it "moves the edit session, updates the order of the tabs, and focuses the destination editor", ->
|
||||
leftTabs = tabs
|
||||
rightEditor = editor.splitRight()
|
||||
rightTabs = rootView.find('.tabs:last').view()
|
||||
|
||||
sortableElement = [leftTabs.find('.tab:eq(0)')]
|
||||
spyOn(tabs, 'getSortableElement').andCallFake -> sortableElement[0]
|
||||
event = $.Event()
|
||||
event.target = leftTabs
|
||||
event.originalEvent =
|
||||
dataTransfer:
|
||||
data: {}
|
||||
setData: (key, value) -> @data[key] = value
|
||||
getData: (key) -> @data[key]
|
||||
|
||||
rightEditor.hiddenInput.focusout()
|
||||
tabs.onDragStart(event)
|
||||
|
||||
event.target = rightTabs
|
||||
sortableElement = [rightTabs.find('.tab:eq(0)')]
|
||||
tabs.onDrop(event)
|
||||
|
||||
expect(rightTabs.find('.tab:eq(0) .file-name').text()).toBe "sample.txt"
|
||||
expect(rightTabs.find('.tab:eq(1) .file-name').text()).toBe "sample.js"
|
||||
expect(rightEditor.isFocused).toBeTruthy()
|
||||
|
@ -1,4 +1,4 @@
|
||||
'#root-view':
|
||||
'body':
|
||||
'meta-\\': 'tree-view:toggle'
|
||||
'meta-|': 'tree-view:reveal-active-file'
|
||||
|
||||
|
@ -1,14 +1,14 @@
|
||||
.tabs {
|
||||
font: caption;
|
||||
-webkit-user-select: none;
|
||||
display: -webkit-box;
|
||||
-webkit-box-align: center;
|
||||
}
|
||||
|
||||
.tab {
|
||||
-webkit-user-select: none;
|
||||
-webkit-user-drag: element;
|
||||
cursor: default;
|
||||
-webkit-box-flex: 2;
|
||||
position: relative;
|
||||
width: 175px;
|
||||
max-width: 175px;
|
||||
min-width: 40px;
|
||||
@ -16,6 +16,7 @@
|
||||
text-shadow: -1px -1px 0 #000;
|
||||
font-size: 11px;
|
||||
padding: 5px 10px;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.tab.active {
|
||||
@ -75,4 +76,35 @@
|
||||
.tab.file-modified:hover .close-icon:before {
|
||||
content: "\f081";
|
||||
color: #66a6ff;
|
||||
}
|
||||
|
||||
/* Drag and Drop */
|
||||
.tab.is-dragging {
|
||||
|
||||
}
|
||||
|
||||
.tab.is-drop-target:after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: -2px;
|
||||
content: "";
|
||||
z-index: 999;
|
||||
display: inline-block;
|
||||
width: 2px;
|
||||
height: 30px;
|
||||
display: inline-block;
|
||||
background: #0098ff;
|
||||
}
|
||||
|
||||
.tab.is-drop-target:before {
|
||||
content: "";
|
||||
position: absolute;
|
||||
width: 4px;
|
||||
height: 4px;
|
||||
background: #0098ff;
|
||||
right: -4px;
|
||||
top: 30px;
|
||||
border-radius: 4px;
|
||||
z-index: 9999;
|
||||
border: 1px solid transparent;
|
||||
}
|
Loading…
Reference in New Issue
Block a user