Merge branch 'master' into mb-defer-work-when-opening-files

This commit is contained in:
Max Brunsfeld 2016-10-12 11:56:27 -07:00
commit c870d1bbe9
52 changed files with 298 additions and 168 deletions

View File

@ -3,8 +3,6 @@
import TextBuffer, {Point, Range} from 'text-buffer'
import {File, Directory} from 'pathwatcher'
import {Emitter, Disposable, CompositeDisposable} from 'event-kit'
import Grim from 'grim'
import dedent from 'dedent'
import BufferedNodeProcess from '../src/buffered-node-process'
import BufferedProcess from '../src/buffered-process'
import GitRepository from '../src/git-repository'
@ -39,25 +37,7 @@ if (process.platform === 'win32') {
// only be exported when not running as a child node process
if (process.type === 'renderer') {
atomExport.Task = require('../src/task')
const TextEditor = (params) => {
return atom.workspace.buildTextEditor(params)
}
TextEditor.prototype = require('../src/text-editor').prototype
Object.defineProperty(atomExport, 'TextEditor', {
enumerable: true,
get () {
Grim.deprecate(dedent`
The \`TextEditor\` constructor is no longer public.
To construct a text editor, use \`atom.workspace.buildTextEditor()\`.
To check if an object is a text editor, use \`atom.workspace.isTextEditor(object)\`.
`)
return TextEditor
}
})
atomExport.TextEditor = require('../src/text-editor')
}
export default atomExport

View File

@ -1,7 +1,7 @@
{
"name": "atom",
"productName": "Atom",
"version": "1.12.0-dev",
"version": "1.13.0-dev",
"description": "A hackable text editor for the 21st Century.",
"main": "./src/main-process/main.js",
"repository": {
@ -21,13 +21,13 @@
"cached-run-in-this-context": "0.4.1",
"chai": "3.5.0",
"clear-cut": "^2.0.1",
"coffee-script": "1.11.0",
"coffee-script": "1.11.1",
"color": "^0.7.3",
"dedent": "^0.6.0",
"devtron": "1.3.0",
"event-kit": "^2.1.0",
"find-parent-dir": "^0.3.0",
"first-mate": "6.0.0",
"first-mate": "6.1.0",
"fs-plus": "2.9.2",
"fstream": "0.1.24",
"fuzzaldrin": "^2.1",
@ -71,14 +71,14 @@
"atom-light-ui": "0.45.0",
"base16-tomorrow-dark-theme": "1.3.0",
"base16-tomorrow-light-theme": "1.3.0",
"one-dark-ui": "1.6.1",
"one-light-ui": "1.6.1",
"one-dark-ui": "1.6.2",
"one-light-ui": "1.6.2",
"one-dark-syntax": "1.5.0",
"one-light-syntax": "1.5.0",
"solarized-dark-syntax": "1.0.5",
"solarized-light-syntax": "1.0.5",
"about": "1.7.0",
"archive-view": "0.61.1",
"archive-view": "0.62.0",
"autocomplete-atom-api": "0.10.0",
"autocomplete-css": "0.13.1",
"autocomplete-html": "0.7.2",
@ -89,7 +89,7 @@
"background-tips": "0.26.1",
"bookmarks": "0.42.0",
"bracket-matcher": "0.82.2",
"command-palette": "0.38.0",
"command-palette": "0.39.0",
"deprecation-cop": "0.54.1",
"dev-live-reload": "0.47.0",
"encoding-selector": "0.22.0",
@ -99,42 +99,42 @@
"git-diff": "1.1.0",
"go-to-line": "0.31.0",
"grammar-selector": "0.48.2",
"image-view": "0.59.0",
"image-view": "0.60.0",
"incompatible-packages": "0.26.1",
"keybinding-resolver": "0.35.0",
"line-ending-selector": "0.5.0",
"link": "0.31.2",
"markdown-preview": "0.158.7",
"markdown-preview": "0.158.8",
"metrics": "1.0.0",
"notifications": "0.65.1",
"open-on-github": "1.2.1",
"package-generator": "1.0.1",
"settings-view": "0.243.0",
"settings-view": "0.243.1",
"snippets": "1.0.3",
"spell-check": "0.68.3",
"status-bar": "1.4.1",
"spell-check": "0.68.4",
"status-bar": "1.6.0",
"styleguide": "0.47.2",
"symbols-view": "0.113.1",
"tabs": "0.102.0",
"tabs": "0.102.2",
"timecop": "0.33.2",
"tree-view": "0.209.3",
"tree-view": "0.210.0",
"update-package-dependencies": "0.10.0",
"welcome": "0.35.1",
"whitespace": "0.33.0",
"whitespace": "0.35.0",
"wrap-guide": "0.38.2",
"language-c": "0.53.2",
"language-clojure": "0.22.0",
"language-coffee-script": "0.47.3",
"language-c": "0.54.0",
"language-clojure": "0.22.1",
"language-coffee-script": "0.48.0",
"language-csharp": "0.12.1",
"language-css": "0.40.0",
"language-css": "0.40.1",
"language-gfm": "0.88.0",
"language-git": "0.15.0",
"language-go": "0.42.1",
"language-html": "0.46.0",
"language-go": "0.43.0",
"language-html": "0.46.1",
"language-hyperlink": "0.16.1",
"language-java": "0.24.0",
"language-javascript": "0.121.0",
"language-json": "0.18.2",
"language-javascript": "0.122.0",
"language-json": "0.18.3",
"language-less": "0.29.6",
"language-make": "0.22.2",
"language-mustache": "0.13.0",
@ -143,7 +143,7 @@
"language-php": "0.37.3",
"language-property-list": "0.8.0",
"language-python": "0.45.1",
"language-ruby": "0.70.1",
"language-ruby": "0.70.2",
"language-ruby-on-rails": "0.25.1",
"language-sass": "0.57.0",
"language-shellscript": "0.23.0",
@ -152,7 +152,7 @@
"language-text": "0.7.1",
"language-todo": "0.29.1",
"language-toml": "0.18.1",
"language-xml": "0.34.11",
"language-xml": "0.34.12",
"language-yaml": "0.27.1"
},
"private": true,

Binary file not shown.

Before

Width:  |  Height:  |  Size: 629 KiB

After

Width:  |  Height:  |  Size: 355 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 907 B

After

Width:  |  Height:  |  Size: 838 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 60 KiB

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.4 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 601 KiB

After

Width:  |  Height:  |  Size: 325 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 19 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 905 B

After

Width:  |  Height:  |  Size: 809 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 184 KiB

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.7 KiB

After

Width:  |  Height:  |  Size: 5.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 628 KiB

After

Width:  |  Height:  |  Size: 357 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 944 B

After

Width:  |  Height:  |  Size: 851 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 61 KiB

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

After

Width:  |  Height:  |  Size: 3.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 192 KiB

After

Width:  |  Height:  |  Size: 120 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.0 KiB

After

Width:  |  Height:  |  Size: 6.0 KiB

View File

@ -6,6 +6,7 @@ const fs = require('fs-extra')
const glob = require('glob')
const os = require('os')
const path = require('path')
const spawnSync = require('./spawn-sync')
const CONFIG = require('../config')
@ -21,7 +22,8 @@ module.exports = function (packagedAppPath, codeSign) {
}
const certPath = path.join(os.tmpdir(), 'win.p12')
if (codeSign && process.env.WIN_P12KEY_URL) {
const signing = codeSign && process.env.WIN_P12KEY_URL
if (signing) {
downloadFileFromGithub(process.env.WIN_P12KEY_URL, certPath)
options.certificateFile = certPath
options.certificatePassword = process.env.WIN_P12KEY_PASSWORD
@ -42,9 +44,30 @@ module.exports = function (packagedAppPath, codeSign) {
}
}
}
// Squirrel signs its own copy of the executables but we need them for the portable ZIP
const extractSignedExes = function() {
if (signing) {
for (let nupkgPath of glob.sync(`${CONFIG.buildOutputPath}/*-full.nupkg`)) {
if (nupkgPath.includes(CONFIG.appMetadata.version)) {
console.log(`Extracting signed executables from ${nupkgPath} for use in portable zip`)
var atomOutPath = path.join(path.dirname(packagedAppPath), 'Atom')
spawnSync('7z.exe', ['e', nupkgPath, 'lib\\net45\\*.exe', '-aoa'], {cwd: atomOutPath})
spawnSync(process.env.COMSPEC, ['/c', `move /y ${path.join(atomOutPath, 'squirrel.exe')} ${path.join(atomOutPath, 'update.exe')}`])
return
}
}
}
}
console.log(`Creating Windows Installer for ${packagedAppPath}`)
return electronInstaller.createWindowsInstaller(options).then(cleanUp, function (error) {
console.log(`Windows installer creation failed:\n${error}`)
cleanUp()
})
return electronInstaller.createWindowsInstaller(options)
.then(extractSignedExes, function (error) {
console.log(`Extracting signed executables failed:\n${error}`)
cleanUp()
})
.then(cleanUp, function (error) {
console.log(`Windows installer creation failed:\n${error}`)
cleanUp()
})
}

View File

@ -31,6 +31,19 @@ describe "PackageManager", ->
it "returns the value of the core.apmPath config setting", ->
expect(atom.packages.getApmPath()).toBe "/path/to/apm"
describe "::loadPackages()", ->
beforeEach ->
spyOn(atom.packages, 'loadPackage')
afterEach ->
atom.packages.deactivatePackages()
atom.packages.unloadPackages()
it "sets hasLoadedInitialPackages", ->
expect(atom.packages.hasLoadedInitialPackages()).toBe false
atom.packages.loadPackages()
expect(atom.packages.hasLoadedInitialPackages()).toBe true
describe "::loadPackage(name)", ->
beforeEach ->
atom.config.set("core.disabledPackages", [])
@ -1022,6 +1035,12 @@ describe "PackageManager", ->
jasmine.restoreDeprecationsSnapshot()
it "sets hasActivatedInitialPackages", ->
spyOn(atom.packages, 'activatePackages')
expect(atom.packages.hasActivatedInitialPackages()).toBe false
waitsForPromise -> atom.packages.activate()
runs -> expect(atom.packages.hasActivatedInitialPackages()).toBe true
it "activates all the packages, and none of the themes", ->
packageActivator = spyOn(atom.packages, 'activatePackages')
themeActivator = spyOn(atom.themes, 'activatePackages')

View File

@ -1,9 +1,11 @@
TextEditor = require '../src/text-editor'
describe "Selection", ->
[buffer, editor, selection] = []
beforeEach ->
buffer = atom.project.bufferForPathSync('sample.js')
editor = atom.workspace.buildTextEditor(buffer: buffer, tabLength: 2)
editor = new TextEditor({buffer: buffer, tabLength: 2})
selection = editor.getLastSelection()
afterEach ->

View File

@ -2,6 +2,7 @@
import {it, fit, ffit, fffit, beforeEach, afterEach, conditionPromise} from './async-spec-helpers'
import Grim from 'grim'
import TextEditor from '../src/text-editor'
import TextEditorElement from '../src/text-editor-element'
import _, {extend, flatten, last, toArray} from 'underscore-plus'
@ -4419,7 +4420,7 @@ describe('TextEditorComponent', function () {
describe('when autoHeight is not assigned on the editor', function () {
it('implicitly assigns autoHeight to true and emits a deprecation warning if the editor has its height assigned via an inline style', function () {
editor = atom.workspace.buildTextEditor()
editor = new TextEditor()
element = editor.getElement()
element.setUpdatedSynchronously(false)
element.style.height = '200px'
@ -4434,7 +4435,7 @@ describe('TextEditorComponent', function () {
})
it('implicitly assigns autoHeight to true and emits a deprecation warning if the editor has its height assigned via position absolute with an assigned top and bottom', function () {
editor = atom.workspace.buildTextEditor()
editor = new TextEditor()
element = editor.getElement()
element.setUpdatedSynchronously(false)
parentElement = document.createElement('div')

View File

@ -1,3 +1,4 @@
TextEditor = require '../src/text-editor'
TextEditorElement = require '../src/text-editor-element'
{Disposable} = require 'event-kit'
@ -33,7 +34,7 @@ describe "TextEditorElement", ->
describe "when the model is assigned", ->
it "adds the 'mini' attribute if .isMini() returns true on the model", ->
element = new TextEditorElement
model = atom.workspace.buildTextEditor(mini: true)
model = new TextEditor({mini: true})
element.setModel(model)
expect(element.hasAttribute('mini')).toBe true
@ -52,7 +53,7 @@ describe "TextEditorElement", ->
describe "when the editor is detached from the DOM and then reattached", ->
it "does not render duplicate line numbers", ->
editor = atom.workspace.buildTextEditor()
editor = new TextEditor
editor.setText('1\n2\n3')
element = atom.views.getView(editor)
@ -65,7 +66,7 @@ describe "TextEditorElement", ->
expect(element.shadowRoot.querySelectorAll('.line-number').length).toBe initialCount
it "does not render duplicate decorations in custom gutters", ->
editor = atom.workspace.buildTextEditor()
editor = new TextEditor
editor.setText('1\n2\n3')
editor.addGutter({name: 'test-gutter'})
marker = editor.markBufferRange([[0, 0], [2, 0]])
@ -200,7 +201,7 @@ describe "TextEditorElement", ->
describe "::getMaxScrollTop", ->
it "returns the maximum scroll top that can be applied to the element", ->
editor = atom.workspace.buildTextEditor()
editor = new TextEditor
editor.setText('1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n11\n12\n13\n14\n15\n16')
element = atom.views.getView(editor)
element.style.lineHeight = "10px"

View File

@ -2,6 +2,7 @@ _ = require 'underscore-plus'
randomWords = require 'random-words'
TextBuffer = require 'text-buffer'
{Point, Range} = TextBuffer
TextEditor = require '../src/text-editor'
TextEditorPresenter = require '../src/text-editor-presenter'
FakeLinesYardstick = require './fake-lines-yardstick'
LineTopIndex = require 'line-top-index'
@ -18,7 +19,7 @@ describe "TextEditorPresenter", ->
spyOn(window, "clearInterval").andCallFake window.fakeClearInterval
buffer = new TextBuffer(filePath: require.resolve('./fixtures/sample.js'))
editor = atom.workspace.buildTextEditor({buffer})
editor = new TextEditor({buffer})
waitsForPromise -> buffer.load()
afterEach ->
@ -474,6 +475,7 @@ describe "TextEditorPresenter", ->
waitsForPromise -> atom.packages.activatePackage('language-javascript')
runs ->
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
maxLineLength = editor.getMaxScreenLineLength()
presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10)
@ -758,6 +760,7 @@ describe "TextEditorPresenter", ->
waitsForPromise -> atom.packages.activatePackage('language-javascript')
runs ->
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
editor.setCursorBufferPosition([3, 6])
presenter = buildPresenter()
expect(getState(presenter).hiddenInput.width).toBe 10
@ -917,6 +920,7 @@ describe "TextEditorPresenter", ->
waitsForPromise -> atom.packages.activatePackage('language-javascript')
runs ->
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
maxLineLength = editor.getMaxScreenLineLength()
presenter = buildPresenter(contentFrameWidth: 50, baseCharacterWidth: 10)
@ -1264,6 +1268,8 @@ describe "TextEditorPresenter", ->
expectValues lineStateForScreenRow(presenter, 3), {screenRow: 3, tagCodes: editor.screenLineForScreenRow(3).tagCodes}
it "includes the .endOfLineInvisibles if the editor.showInvisibles config option is true", ->
editor.update({showInvisibles: false, invisibles: {eol: 'X'}})
editor.setText("hello\nworld\r\n")
presenter = buildPresenter(explicitHeight: 25, scrollTop: 0, lineHeight: 10)
expect(tagsForCodes(presenter, lineStateForScreenRow(presenter, 0).tagCodes).openTags).not.toContain('invisible-character eol')
@ -1730,6 +1736,7 @@ describe "TextEditorPresenter", ->
atom.packages.activatePackage('language-javascript')
runs ->
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
editor.setCursorBufferPosition([1, 4])
presenter = buildPresenter(explicitHeight: 20)
@ -2075,6 +2082,7 @@ describe "TextEditorPresenter", ->
atom.packages.activatePackage('language-javascript')
runs ->
editor.setGrammar(atom.grammars.grammarForScopeName('source.js'))
editor.setSelectedBufferRanges([
[[2, 4], [2, 6]],
])
@ -3666,7 +3674,7 @@ describe "TextEditorPresenter", ->
performSetup = ->
buffer = new TextBuffer
editor = atom.workspace.buildTextEditor({buffer})
editor = new TextEditor({buffer})
editor.setEditorWidthInChars(80)
presenterParams =
model: editor

View File

@ -15,15 +15,11 @@ describe('TextEditorRegistry', function () {
registry = new TextEditorRegistry({
assert: atom.assert,
config: atom.config,
clipboard: atom.clipboard,
grammarRegistry: atom.grammars,
packageManager: {deferredActivationHooks: null}
})
editor = new TextEditor({
config: atom.config,
clipboard: atom.clipboard,
})
editor = new TextEditor()
})
afterEach(function () {
@ -194,10 +190,7 @@ describe('TextEditorRegistry', function () {
it('does not update the editor when config settings change for unrelated scope selectors', async function () {
await atom.packages.activatePackage('language-javascript')
const editor2 = new TextEditor({
config: atom.config,
clipboard: atom.clipboard,
})
const editor2 = new TextEditor()
editor2.setGrammar(atom.grammars.selectGrammar('test.js'))
@ -224,7 +217,6 @@ describe('TextEditorRegistry', function () {
registry = new TextEditorRegistry({
assert: atom.assert,
config: atom.config,
clipboard: atom.clipboard,
grammarRegistry: atom.grammars,
packageManager: {
deferredActivationHooks: [],
@ -669,10 +661,7 @@ describe('TextEditorRegistry', function () {
describe('serialization', function () {
it('persists editors\' grammar overrides', async function () {
const editor2 = new TextEditor({
config: atom.config,
clipboard: atom.clipboard,
})
const editor2 = new TextEditor()
await atom.packages.activatePackage('language-c')
await atom.packages.activatePackage('language-html')
@ -691,7 +680,6 @@ describe('TextEditorRegistry', function () {
const registryCopy = new TextEditorRegistry({
assert: atom.assert,
config: atom.config,
clipboard: atom.clipboard,
grammarRegistry: atom.grammars,
packageManager: {deferredActivationHooks: null}
})

View File

@ -54,7 +54,6 @@ describe "TextEditor", ->
# reusing the same buffer instance
editor2 = TextEditor.deserialize(editor.serialize(), {
assert: atom.assert,
clipboard: atom.clipboard,
textEditors: atom.textEditors,
project: {
bufferForIdSync: (id) -> TextBuffer.deserialize(editor.buffer.serialize())
@ -5525,7 +5524,7 @@ describe "TextEditor", ->
describe "auto height", ->
it "returns true by default but can be customized", ->
editor = atom.workspace.buildTextEditor()
editor = new TextEditor
expect(editor.getAutoHeight()).toBe(true)
editor.update({autoHeight: false})
expect(editor.getAutoHeight()).toBe(false)
@ -5543,10 +5542,10 @@ describe "TextEditor", ->
describe '.get/setPlaceholderText()', ->
it 'can be created with placeholderText', ->
newEditor = atom.workspace.buildTextEditor(
newEditor = new TextEditor({
mini: true
placeholderText: 'yep'
)
})
expect(newEditor.getPlaceholderText()).toBe 'yep'
it 'models placeholderText and emits an event when changed', ->
@ -5831,11 +5830,7 @@ describe "TextEditor", ->
atom.packages.activatePackage('language-coffee-script')
it "sets the grammar", ->
editor = new TextEditor({
grammar: atom.grammars.grammarForScopeName('source.coffee')
clipboard: atom.clipboard
})
editor = new TextEditor({grammar: atom.grammars.grammarForScopeName('source.coffee')})
expect(editor.getGrammar().name).toBe 'CoffeeScript'
describe "softWrapAtPreferredLineLength", ->

View File

@ -8,7 +8,7 @@ describe "TooltipManager", ->
ctrlY = _.humanizeKeystroke("ctrl-y")
beforeEach ->
manager = new TooltipManager(keymapManager: atom.keymaps)
manager = new TooltipManager(keymapManager: atom.keymaps, viewRegistry: atom.views)
element = document.createElement('div')
element.classList.add('foo')
jasmine.attachToDOM(element)
@ -16,23 +16,62 @@ describe "TooltipManager", ->
hover = (element, fn) ->
element.dispatchEvent(new CustomEvent('mouseenter', bubbles: false))
element.dispatchEvent(new CustomEvent('mouseover', bubbles: true))
advanceClock(manager.defaults.delay.show)
advanceClock(manager.hoverDefaults.delay.show)
fn()
element.dispatchEvent(new CustomEvent('mouseleave', bubbles: false))
element.dispatchEvent(new CustomEvent('mouseout', bubbles: true))
advanceClock(manager.defaults.delay.hide)
advanceClock(manager.hoverDefaults.delay.hide)
describe "::add(target, options)", ->
it "creates a tooltip based on the given options when hovering over the target element", ->
manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
describe "when the trigger is 'hover' (the default)", ->
it "creates a tooltip when hovering over the target element", ->
manager.add element, title: "Title"
hover element, ->
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
it "creates a tooltip immediately if the trigger type is manual", ->
disposable = manager.add element, title: "Title", trigger: "manual"
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
disposable.dispose()
expect(document.body.querySelector(".tooltip")).toBeNull()
describe "when the trigger is 'manual'", ->
it "creates a tooltip immediately and only hides it on dispose", ->
disposable = manager.add element, title: "Title", trigger: "manual"
expect(document.body.querySelector(".tooltip")).toHaveText("Title")
disposable.dispose()
expect(document.body.querySelector(".tooltip")).toBeNull()
describe "when the trigger is 'click'", ->
it "shows and hides the tooltip when the target element is clicked", ->
disposable = manager.add element, title: "Title", trigger: "click"
expect(document.body.querySelector(".tooltip")).toBeNull()
element.click()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
element.click()
expect(document.body.querySelector(".tooltip")).toBeNull()
# Hide the tooltip when clicking anywhere but inside the tooltip element
element.click()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
document.body.querySelector(".tooltip").click()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
document.body.querySelector(".tooltip").firstChild.click()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
document.body.click()
expect(document.body.querySelector(".tooltip")).toBeNull()
# Tooltip can show again after hiding due to clicking outside of the tooltip
element.click()
expect(document.body.querySelector(".tooltip")).not.toBeNull()
element.click()
expect(document.body.querySelector(".tooltip")).toBeNull()
it "allows a custom item to be specified for the content of the tooltip", ->
tooltipElement = document.createElement('div')
manager.add element, item: {element: tooltipElement}
hover element, ->
expect(tooltipElement.closest(".tooltip")).not.toBeNull()
it "allows a custom class to be specified for the tooltip", ->
tooltipElement = document.createElement('div')
manager.add element, title: 'Title', class: 'custom-tooltip-class'
hover element, ->
expect(document.body.querySelector(".tooltip").classList.contains('custom-tooltip-class')).toBe(true)
it "allows jQuery elements to be passed as the target", ->
element2 = document.createElement('div')
@ -52,20 +91,6 @@ describe "TooltipManager", ->
hover element, -> expect(document.body.querySelector(".tooltip")).toBeNull()
hover element2, -> expect(document.body.querySelector(".tooltip")).toBeNull()
describe "when a selector is specified", ->
it "creates a tooltip when hovering over a descendant of the target that matches the selector", ->
child = document.createElement('div')
child.classList.add('bar')
grandchild = document.createElement('div')
element.appendChild(child)
child.appendChild(grandchild)
manager.add element, selector: '.bar', title: 'Bar'
hover grandchild, ->
expect(document.body.querySelector('.tooltip')).toHaveText('Bar')
expect(document.body.querySelector('.tooltip')).toBeNull()
describe "when a keyBindingCommand is specified", ->
describe "when a title is specified", ->
it "appends the key binding corresponding to the command to the title", ->

View File

@ -1,6 +1,7 @@
{ipcRenderer} = require 'electron'
path = require 'path'
temp = require('temp').track()
{Disposable} = require 'event-kit'
describe "WorkspaceElement", ->
describe "when the workspace element is focused", ->
@ -17,9 +18,11 @@ describe "WorkspaceElement", ->
it "has a class based on the style of the scrollbar", ->
observeCallback = null
scrollbarStyle = require 'scrollbar-style'
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake (cb) -> observeCallback = cb
workspaceElement = atom.views.getView(atom.workspace)
spyOn(scrollbarStyle, 'observePreferredScrollbarStyle').andCallFake (cb) ->
observeCallback = cb
new Disposable(->)
workspaceElement = atom.views.getView(atom.workspace)
observeCallback('legacy')
expect(workspaceElement.className).toMatch 'scrollbars-visible-always'

View File

@ -1,5 +1,6 @@
path = require 'path'
temp = require 'temp'
TextEditor = require '../src/text-editor'
Workspace = require '../src/workspace'
Project = require '../src/project'
platform = require './spec-helper-platform'
@ -29,7 +30,7 @@ describe "Workspace", ->
atom.workspace = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
grammarRegistry: atom.grammars, deserializerManager: atom.deserializers,
notificationManager: atom.notifications, clipboard: atom.clipboard,
notificationManager: atom.notifications,
applicationDelegate: atom.applicationDelegate,
viewRegistry: atom.views, assert: atom.assert.bind(atom),
textEditorRegistry: atom.textEditors
@ -795,7 +796,7 @@ describe "Workspace", ->
describe "::isTextEditor(obj)", ->
it "returns true when the passed object is an instance of `TextEditor`", ->
expect(workspace.isTextEditor(atom.workspace.buildTextEditor())).toBe(true)
expect(workspace.isTextEditor(new TextEditor)).toBe(true)
expect(workspace.isTextEditor({getText: -> null})).toBe(false)
expect(workspace.isTextEditor(null)).toBe(false)
expect(workspace.isTextEditor(undefined)).toBe(false)
@ -871,7 +872,7 @@ describe "Workspace", ->
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
viewRegistry: atom.views, grammarRegistry: atom.grammars,
applicationDelegate: atom.applicationDelegate, assert: atom.assert.bind(atom),
textEditorRegistry: atom.textEditors
})
@ -934,7 +935,7 @@ describe "Workspace", ->
workspace2 = new Workspace({
config: atom.config, project: atom.project, packageManager: atom.packages,
notificationManager: atom.notifications, deserializerManager: atom.deserializers,
clipboard: atom.clipboard, viewRegistry: atom.views, grammarRegistry: atom.grammars,
viewRegistry: atom.views, grammarRegistry: atom.grammars,
applicationDelegate: atom.applicationDelegate, assert: atom.assert.bind(atom),
textEditorRegistry: atom.textEditors
})
@ -1727,7 +1728,7 @@ describe "Workspace", ->
describe "when there's no repository for the editor's file", ->
it "doesn't do anything", ->
editor = atom.workspace.buildTextEditor()
editor = new TextEditor
editor.setText("stuff")
atom.workspace.checkoutHeadRevision(editor)

View File

@ -28,7 +28,6 @@ ThemeManager = require './theme-manager'
MenuManager = require './menu-manager'
ContextMenuManager = require './context-menu-manager'
CommandInstaller = require './command-installer'
Clipboard = require './clipboard'
Project = require './project'
TitleBar = require './title-bar'
Workspace = require './workspace'
@ -127,7 +126,7 @@ class AtomEnvironment extends Model
# Call .loadOrCreate instead
constructor: (params={}) ->
{@blobStore, @applicationDelegate, @window, @document, @configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
{@blobStore, @applicationDelegate, @window, @document, @clipboard, @configDirPath, @enablePersistence, onlyLoadBaseStyleSheets} = params
@unloaded = false
@loadTime = null
@ -154,7 +153,7 @@ class AtomEnvironment extends Model
@keymaps = new KeymapManager({@configDirPath, resourcePath, notificationManager: @notifications})
@tooltips = new TooltipManager(keymapManager: @keymaps)
@tooltips = new TooltipManager(keymapManager: @keymaps, viewRegistry: @views)
@commands = new CommandRegistry
@commands.attach(@window)
@ -182,20 +181,18 @@ class AtomEnvironment extends Model
@packages.setContextMenuManager(@contextMenu)
@packages.setThemeManager(@themes)
@clipboard = new Clipboard()
@project = new Project({notificationManager: @notifications, packageManager: @packages, @config, @applicationDelegate})
@commandInstaller = new CommandInstaller(@getVersion(), @applicationDelegate)
@textEditors = new TextEditorRegistry({
@config, grammarRegistry: @grammars, assert: @assert.bind(this), @clipboard,
@config, grammarRegistry: @grammars, assert: @assert.bind(this),
packageManager: @packages
})
@workspace = new Workspace({
@config, @project, packageManager: @packages, grammarRegistry: @grammars, deserializerManager: @deserializers,
notificationManager: @notifications, @applicationDelegate, @clipboard, viewRegistry: @views, assert: @assert.bind(this),
notificationManager: @notifications, @applicationDelegate, viewRegistry: @views, assert: @assert.bind(this),
textEditorRegistry: @textEditors,
})

View File

@ -20,16 +20,21 @@ module.exports = ({blobStore}) ->
AtomEnvironment = require './atom-environment'
ApplicationDelegate = require './application-delegate'
Clipboard = require './clipboard'
TextEditor = require './text-editor'
clipboard = new Clipboard
TextEditor.setClipboard(clipboard)
window.atom = new AtomEnvironment({
window, document, blobStore,
window, document, clipboard, blobStore,
applicationDelegate: new ApplicationDelegate,
configDirPath: process.env.ATOM_HOME
enablePersistence: true
configDirPath: process.env.ATOM_HOME,
enablePersistence: true,
env: process.env
})
atom.startEditorWindow().then ->
# Workaround for focus getting cleared upon window creation
windowFocused = ->
window.removeEventListener('focus', windowFocused)

View File

@ -21,6 +21,8 @@ module.exports = ({blobStore}) ->
{getWindowLoadSettings} = require './window-load-settings-helpers'
AtomEnvironment = require '../src/atom-environment'
ApplicationDelegate = require '../src/application-delegate'
Clipboard = require '../src/clipboard'
TextEditor = require '../src/text-editor'
require '../src/electron-shims'
{testRunnerPath, legacyTestRunnerPath, headless, logFile, testPaths} = getWindowLoadSettings()
@ -58,11 +60,15 @@ module.exports = ({blobStore}) ->
document.title = "Spec Suite"
clipboard = new Clipboard
TextEditor.setClipboard(clipboard)
testRunner = require(testRunnerPath)
legacyTestRunner = require(legacyTestRunnerPath)
buildDefaultApplicationDelegate = -> new ApplicationDelegate()
buildAtomEnvironment = (params) ->
params = cloneObject(params)
params.clipboard = clipboard unless params.hasOwnProperty("clipboard")
params.blobStore = blobStore unless params.hasOwnProperty("blobStore")
params.onlyLoadBaseStyleSheets = true unless params.hasOwnProperty("onlyLoadBaseStyleSheets")
new AtomEnvironment(params)

View File

@ -2,6 +2,7 @@
_ = require 'underscore-plus'
{OnigRegExp} = require 'oniguruma'
ScopeDescriptor = require './scope-descriptor'
NullGrammar = require './null-grammar'
module.exports =
class LanguageMode
@ -245,7 +246,10 @@ class LanguageMode
@suggestedIndentForTokenizedLineAtBufferRow(bufferRow, line, tokenizedLine, options)
suggestedIndentForLineAtBufferRow: (bufferRow, line, options) ->
tokenizedLine = @editor.tokenizedBuffer.buildTokenizedLineForRowWithText(bufferRow, line)
if @editor.largeFileMode or @editor.tokenizedBuffer.grammar is NullGrammar
tokenizedLine = @editor.tokenizedBuffer.buildPlaceholderTokenizedLineForRowWithText(bufferRow, line)
else
tokenizedLine = @editor.tokenizedBuffer.buildTokenizedLineForRowWithText(bufferRow, line)
@suggestedIndentForTokenizedLineAtBufferRow(bufferRow, line, tokenizedLine, options)
suggestedIndentForTokenizedLineAtBufferRow: (bufferRow, line, tokenizedLine, options) ->

View File

@ -45,6 +45,8 @@ class PackageManager
@packageDirPaths.push(path.join(configDirPath, "packages"))
@packagesCache = require('../package.json')?._atomPackages ? {}
@initialPackagesLoaded = false
@initialPackagesActivated = false
@loadedPackages = {}
@activePackages = {}
@activatingPackages = {}
@ -241,6 +243,9 @@ class PackageManager
isPackageActive: (name) ->
@getActivePackage(name)?
# Public: Returns a {Boolean} indicating whether package activation has occurred.
hasActivatedInitialPackages: -> @initialPackagesActivated
###
Section: Accessing loaded packages
###
@ -271,6 +276,9 @@ class PackageManager
isPackageLoaded: (name) ->
@getLoadedPackage(name)?
# Public: Returns a {Boolean} indicating whether package loading has occurred.
hasLoadedInitialPackages: -> @initialPackagesLoaded
###
Section: Accessing available packages
###
@ -364,6 +372,7 @@ class PackageManager
@config.transact =>
@loadPackage(packagePath) for packagePath in packagePaths
return
@initialPackagesLoaded = true
@emitter.emit 'did-load-initial-packages'
loadPackage: (nameOrPath) ->
@ -426,6 +435,7 @@ class PackageManager
promises = promises.concat(activator.activatePackages(packages))
Promise.all(promises).then =>
@triggerDeferredActivationHooks()
@initialPackagesActivated = true
@emitter.emit 'did-activate-initial-packages'
# another type of package manager can handle other package types.

View File

@ -14,7 +14,7 @@ class Selection extends Model
initialScreenRange: null
wordwise: false
constructor: ({@cursor, @marker, @editor, id, @clipboard}) ->
constructor: ({@cursor, @marker, @editor, id}) ->
@emitter = new Emitter
@assignId(id)
@ -605,7 +605,7 @@ class Selection extends Model
startLevel = @editor.indentLevelForLine(precedingText)
if maintainClipboard
{text: clipboardText, metadata} = @clipboard.readWithMetadata()
{text: clipboardText, metadata} = @editor.constructor.clipboard.readWithMetadata()
metadata ?= {}
unless metadata.selections?
metadata.selections = [{
@ -618,9 +618,9 @@ class Selection extends Model
indentBasis: startLevel,
fullLine: fullLine
})
@clipboard.write([clipboardText, selectionText].join("\n"), metadata)
@editor.constructor.clipboard.write([clipboardText, selectionText].join("\n"), metadata)
else
@clipboard.write(selectionText, {
@editor.constructor.clipboard.write(selectionText, {
indentBasis: startLevel,
fullLine: fullLine
})

View File

@ -39,9 +39,8 @@ const GRAMMAR_SELECTION_RANGE = Range(Point.ZERO, Point(10, 0)).freeze()
// done using your editor, be sure to call `dispose` on the returned disposable
// to avoid leaking editors.
export default class TextEditorRegistry {
constructor ({config, grammarRegistry, clipboard, assert, packageManager}) {
constructor ({config, grammarRegistry, assert, packageManager}) {
this.assert = assert
this.clipboard = clipboard
this.config = config
this.grammarRegistry = grammarRegistry
this.scopedSettingsDelegate = new ScopedSettingsDelegate(config)
@ -109,10 +108,7 @@ export default class TextEditorRegistry {
}
build (params) {
params = Object.assign({
clipboard: this.clipboard,
assert: this.assert
}, params)
params = Object.assign({assert: this.assert}, params)
let scope = null
if (params.buffer) {

View File

@ -59,6 +59,9 @@ ZERO_WIDTH_NBSP = '\ufeff'
# soft wraps and folds to ensure your code interacts with them correctly.
module.exports =
class TextEditor extends Model
@setClipboard: (clipboard) ->
@clipboard = clipboard
serializationVersion: 1
buffer: null
@ -114,7 +117,6 @@ class TextEditor extends Model
if state.displayLayer = state.buffer.getDisplayLayer(state.displayLayerId)
state.selectionsMarkerLayer = state.displayLayer.getMarkerLayer(state.selectionsMarkerLayerId)
state.clipboard = atomEnvironment.clipboard
state.assert = atomEnvironment.assert.bind(atomEnvironment)
editor = new this(state)
if state.registered
@ -123,19 +125,20 @@ class TextEditor extends Model
editor
constructor: (params={}) ->
unless @constructor.clipboard?
throw new Error("Must call TextEditor.setClipboard at least once before creating TextEditor instances")
super
{
@softTabs, @firstVisibleScreenRow, @firstVisibleScreenColumn, initialLine, initialColumn, tabLength,
@softWrapped, @decorationManager, @selectionsMarkerLayer, @buffer, suppressCursorCreation,
@mini, @placeholderText, lineNumberGutterVisible, @largeFileMode, @clipboard,
@mini, @placeholderText, lineNumberGutterVisible, @largeFileMode,
@assert, grammar, @showInvisibles, @autoHeight, @autoWidth, @scrollPastEnd, @editorWidthInChars,
@tokenizedBuffer, @displayLayer, @invisibles, @showIndentGuide,
@softWrapped, @softWrapAtPreferredLineLength, @preferredLineLength
} = params
throw new Error("Must pass a clipboard parameter when constructing TextEditors") unless @clipboard?
@assert ?= (condition) -> condition
@firstVisibleScreenRow ?= 0
@firstVisibleScreenColumn ?= 0
@ -147,7 +150,7 @@ class TextEditor extends Model
@hasTerminatedPendingState = false
@mini ?= false
@scrollPastEnd ?= true
@scrollPastEnd ?= false
@showInvisibles ?= true
@softTabs ?= true
tabLength ?= 2
@ -719,7 +722,7 @@ class TextEditor extends Model
suppressCursorCreation: true,
tabLength: @tokenizedBuffer.getTabLength(),
@firstVisibleScreenRow, @firstVisibleScreenColumn,
@clipboard, @assert, displayLayer, grammar: @getGrammar(),
@assert, displayLayer, grammar: @getGrammar(),
@autoWidth, @autoHeight
})
@ -2737,7 +2740,7 @@ class TextEditor extends Model
# Returns the new {Selection}.
addSelection: (marker, options={}) ->
cursor = @addCursor(marker)
selection = new Selection(Object.assign({editor: this, marker, cursor, @clipboard}, options))
selection = new Selection(Object.assign({editor: this, marker, cursor}, options))
@selections.push(selection)
selectionBufferRange = selection.getBufferRange()
@mergeIntersectingSelections(preserveFolds: options.preserveFolds)
@ -3146,7 +3149,7 @@ class TextEditor extends Model
#
# * `options` (optional) See {Selection::insertText}.
pasteText: (options={}) ->
{text: clipboardText, metadata} = @clipboard.readWithMetadata()
{text: clipboardText, metadata} = @constructor.clipboard.readWithMetadata()
return false unless @emitWillInsertTextEvent(clipboardText)
metadata ?= {}

View File

@ -263,11 +263,13 @@ class TokenizedBuffer extends Model
@buildPlaceholderTokenizedLineForRow(row) for row in [startRow..endRow] by 1
buildPlaceholderTokenizedLineForRow: (row) ->
@buildPlaceholderTokenizedLineForRowWithText(row, @buffer.lineForRow(row))
buildPlaceholderTokenizedLineForRowWithText: (row, text) ->
if @grammar isnt NullGrammar
openScopes = [@grammar.startIdForScope(@grammar.scopeName)]
else
openScopes = []
text = @buffer.lineForRow(row)
tags = [text.length]
lineEnding = @buffer.lineEndingForRow(row)
new TokenizedLine({openScopes, text, tags, lineEnding, @tokenIterator})

View File

@ -2,7 +2,7 @@ _ = require 'underscore-plus'
{Disposable, CompositeDisposable} = require 'event-kit'
Tooltip = null
# Essential: Associates tooltips with HTML elements or selectors.
# Essential: Associates tooltips with HTML elements.
#
# You can get the `TooltipManager` via `atom.tooltips`.
#
@ -46,25 +46,55 @@ Tooltip = null
module.exports =
class TooltipManager
defaults:
delay:
show: 1000
hide: 100
trigger: 'hover'
container: 'body'
html: true
placement: 'auto top'
viewportPadding: 2
constructor: ({@keymapManager}) ->
hoverDefaults:
{delay: {show: 1000, hide: 100}}
constructor: ({@keymapManager, @viewRegistry}) ->
# Essential: Add a tooltip to the given element.
#
# * `target` An `HTMLElement`
# * `options` See http://getbootstrap.com/javascript/#tooltips-options for a
# full list of options. You can also supply the following additional options:
# * `options` An object with one or more of the following options:
# * `title` A {String} or {Function} to use for the text in the tip. If
# given a function, `this` will be set to the `target` element.
# * `trigger` A {String} that's the same as Bootstrap 'click | hover | focus
# | manual', except 'manual' will show the tooltip immediately.
# a function is passed, `this` will be set to the `target` element. This
# option is mutually exclusive with the `item` option.
# * `html` A {Boolean} affecting the interpetation of the `title` option.
# If `true` (the default), the `title` string will be interpreted as HTML.
# Otherwise it will be interpreted as plain text.
# * `item` A view (object with an `.element` property) or a DOM element
# containing custom content for the tooltip. This option is mutually
# exclusive with the `title` option.
# * `class` A {String} with a class to apply to the tooltip element to
# enable custom styling.
# * `placement` A {String} or {Function} returning a string to indicate
# the position of the tooltip relative to `element`. Can be `'top'`,
# `'bottom'`, `'left'`, `'right'`, or `'auto'`. When `'auto'` is
# specified, it will dynamically reorient the tooltip. For example, if
# placement is `'auto left'`, the tooltip will display to the left when
# possible, otherwise it will display right.
# When a function is used to determine the placement, it is called with
# the tooltip DOM node as its first argument and the triggering element
# DOM node as its second. The `this` context is set to the tooltip
# instance.
# * `trigger` A {String} indicating how the tooltip should be displayed.
# Choose from one of the following options:
# * `'hover'` Show the tooltip when the mouse hovers over the element.
# This is the default.
# * `'click'` Show the tooltip when the element is clicked. The tooltip
# will be hidden after clicking the element again or anywhere else
# outside of the tooltip itself.
# * `'focus'` Show the tooltip when the element is focused.
# * `'manual'` Show the tooltip immediately and only hide it when the
# returned disposable is disposed.
# * `delay` An object specifying the show and hide delay in milliseconds.
# Defaults to `{show: 1000, hide: 100}` if the `trigger` is `hover` and
# otherwise defaults to `0` for both values.
# * `keyBindingCommand` A {String} containing a command name. If you specify
# this option and a key binding exists that matches the command, it will
# be appended to the title or rendered alone if no title is specified.
@ -92,7 +122,12 @@ class TooltipManager
else if keystroke?
options.title = getKeystroke(bindings)
tooltip = new Tooltip(target, _.defaults(options, @defaults))
delete options.selector
options = _.defaults(options, @defaults)
if options.trigger is 'hover'
options = _.defaults(options, @hoverDefaults)
tooltip = new Tooltip(target, options, @viewRegistry)
hideTooltip = ->
tooltip.leave(currentTarget: target)

View File

@ -7,13 +7,14 @@ const listen = require('./delegated-listener')
// This tooltip class is derived from Bootstrap 3, but modified to not require
// jQuery, which is an expensive dependency we want to eliminate.
var Tooltip = function (element, options) {
var Tooltip = function (element, options, viewRegistry) {
this.options = null
this.enabled = null
this.timeout = null
this.hoverState = null
this.element = null
this.inState = null
this.viewRegistry = viewRegistry
this.init(element, options)
}
@ -64,6 +65,14 @@ Tooltip.prototype.init = function (element, options) {
if (trigger === 'click') {
this.disposables.add(listen(this.element, 'click', this.options.selector, this.toggle.bind(this)))
this.hideOnClickOutsideOfTooltip = (event) => {
const tooltipElement = this.getTooltipElement()
if (tooltipElement === event.target) return
if (tooltipElement.contains(event.target)) return
if (this.element === event.target) return
if (this.element.contains(event.target)) return
this.hide()
}
} else if (trigger === 'manual') {
this.show()
} else {
@ -182,8 +191,11 @@ Tooltip.prototype.leave = function (event) {
Tooltip.prototype.show = function () {
if (this.hasContent() && this.enabled) {
var tip = this.getTooltipElement()
if (this.hideOnClickOutsideOfTooltip) {
window.addEventListener('click', this.hideOnClickOutsideOfTooltip, true)
}
var tip = this.getTooltipElement()
var tipId = this.getUID('tooltip')
this.setContent()
@ -294,19 +306,33 @@ Tooltip.prototype.replaceArrow = function (delta, dimension, isVertical) {
Tooltip.prototype.setContent = function () {
var tip = this.getTooltipElement()
var title = this.getTitle()
if (this.options.class) {
tip.classList.add(this.options.class)
}
var inner = tip.querySelector('.tooltip-inner')
if (this.options.html) {
inner.innerHTML = title
if (this.options.item) {
inner.appendChild(this.viewRegistry.getView(this.options.item))
} else {
inner.textContent = title
var title = this.getTitle()
if (this.options.html) {
inner.innerHTML = title
} else {
inner.textContent = title
}
}
tip.classList.remove('fade', 'in', 'top', 'bottom', 'left', 'right')
}
Tooltip.prototype.hide = function (callback) {
this.inState = {}
if (this.hideOnClickOutsideOfTooltip) {
window.removeEventListener('click', this.hideOnClickOutsideOfTooltip, true)
}
this.tip && this.tip.classList.remove('in')
if (this.hoverState !== 'in') this.tip && this.tip.remove()
@ -328,7 +354,7 @@ Tooltip.prototype.fixTitle = function () {
}
Tooltip.prototype.hasContent = function () {
return this.getTitle()
return this.getTitle() || this.options.item
}
Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
@ -436,7 +462,7 @@ Tooltip.prototype.destroy = function () {
Tooltip.prototype.getDelegateComponent = function (element) {
var component = tooltipComponentsByElement.get(element)
if (!component) {
component = new Tooltip(element, this.getDelegateOptions())
component = new Tooltip(element, this.getDelegateOptions(), this.viewRegistry)
tooltipComponentsByElement.set(element, component)
}
return component

View File

@ -28,7 +28,7 @@ class Workspace extends Model
{
@packageManager, @config, @project, @grammarRegistry, @notificationManager,
@clipboard, @viewRegistry, @grammarRegistry, @applicationDelegate, @assert,
@viewRegistry, @grammarRegistry, @applicationDelegate, @assert,
@deserializerManager, @textEditorRegistry
} = params