mirror of
https://github.com/atom/atom.git
synced 2026-01-23 13:58:08 -05:00
Merge remote-tracking branch 'origin/dev' into better-anchors
This commit is contained in:
11
.atom/config.json
Normal file
11
.atom/config.json
Normal file
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"editor": {
|
||||
"fontSize": 16
|
||||
},
|
||||
"core": {
|
||||
"themes": [
|
||||
"atom-dark-ui",
|
||||
"atom-dark-syntax"
|
||||
]
|
||||
}
|
||||
}
|
||||
1
.atom/themes/README.md
Normal file
1
.atom/themes/README.md
Normal file
@@ -0,0 +1 @@
|
||||
All themes in this directory will be automatically loaded
|
||||
8
.atom/user.css
Normal file
8
.atom/user.css
Normal file
@@ -0,0 +1,8 @@
|
||||
/* User styles */
|
||||
.tree-view {
|
||||
|
||||
}
|
||||
|
||||
.editor {
|
||||
|
||||
}
|
||||
@@ -15,6 +15,8 @@
|
||||
styleguides
|
||||
* Include thoughtfully worded [Jasmine](http://pivotal.github.com/jasmine/)
|
||||
specs
|
||||
* Style new elements in both the light and dark default themes when
|
||||
appropriate
|
||||
* New packages go in `src/packages/`
|
||||
* Add 3rd-party packages by submoduling in `vendor/packages/`
|
||||
* Commit messages are in the present tense
|
||||
|
||||
@@ -21,7 +21,7 @@ Requirements
|
||||
Atom is installed! Type `atom [path]` from the commmand line or find it in `/Applications/Atom.app`
|
||||
|
||||
## Your ~/.atom Directory
|
||||
A basic ~/.atom directory is installed when you run `rake install`. Take a look at ~/.atom/atom.coffee for more information.
|
||||
A basic ~/.atom directory is installed when you run `rake install`. Take a look at ~/.atom/user.coffee for more information.
|
||||
|
||||
## Basic Keyboard shortcuts
|
||||
Atom doesn't have much in the way of menus yet. Use these keyboard shortcuts to
|
||||
@@ -53,7 +53,7 @@ Most default OS X keybindings also work.
|
||||
|
||||
## Init Script
|
||||
|
||||
Atom will require `~/.atom/atom.coffee` whenever a window is opened or reloaded if it is present in your
|
||||
Atom will require `~/.atom/user.coffee` whenever a window is opened or reloaded if it is present in your
|
||||
home directory. This is a rudimentary jumping off point for your own customizations.
|
||||
|
||||
## Command Panel
|
||||
|
||||
20
Rakefile
20
Rakefile
@@ -76,14 +76,26 @@ task "create-dot-atom" do
|
||||
|
||||
dot_atom_template_path = ATOM_SRC_PATH + "/.atom"
|
||||
replace_dot_atom = false
|
||||
next if File.exists?(DOT_ATOM_PATH)
|
||||
|
||||
if File.exists?(DOT_ATOM_PATH)
|
||||
user_config = "#{DOT_ATOM_PATH}/user.coffee"
|
||||
old_user_config = "#{DOT_ATOM_PATH}/atom.coffee"
|
||||
|
||||
if File.exists?(old_user_config)
|
||||
`mv #{old_user_config} #{user_config}`
|
||||
puts "\033[32mRenamed #{old_user_config} to #{user_config}\033[0m"
|
||||
end
|
||||
|
||||
next
|
||||
end
|
||||
|
||||
`rm -rf "#{DOT_ATOM_PATH}"`
|
||||
`mkdir "#{DOT_ATOM_PATH}"`
|
||||
`cp "#{dot_atom_template_path}/atom.coffee" "#{DOT_ATOM_PATH}"`
|
||||
`cp "#{dot_atom_template_path}/packages" "#{DOT_ATOM_PATH}"`
|
||||
|
||||
`cp "#{dot_atom_template_path}/user.coffee" "#{DOT_ATOM_PATH}"`
|
||||
`cp "#{dot_atom_template_path}/user.css" "#{DOT_ATOM_PATH}"`
|
||||
`cp -r "#{dot_atom_template_path}/packages" "#{DOT_ATOM_PATH}"`
|
||||
`cp -r "#{ATOM_SRC_PATH}/themes" "#{DOT_ATOM_PATH}"`
|
||||
`cp "#{ATOM_SRC_PATH}/vendor/themes/IR_Black.tmTheme" "#{DOT_ATOM_PATH}/themes"`
|
||||
end
|
||||
|
||||
desc "Clone default bundles into vendor/bundles directory"
|
||||
|
||||
@@ -9,8 +9,8 @@ gutter.
|
||||
You can change the background color using the following CSS:
|
||||
|
||||
```css
|
||||
.editor.focused .line.cursor-line,
|
||||
.editor.focused .line-number.cursor-line {
|
||||
.editor.is-focused .line.cursor-line,
|
||||
.editor.is-focused .line-number.cursor-line {
|
||||
background-color: green;
|
||||
}
|
||||
```
|
||||
@@ -18,7 +18,7 @@ You can change the background color using the following CSS:
|
||||
You can change the line number foreground color using the following CSS:
|
||||
|
||||
```css
|
||||
.editor.focused .line-number.cursor-line {
|
||||
.editor.is-focused .line-number.cursor-line {
|
||||
color: blue;
|
||||
}
|
||||
```
|
||||
|
||||
@@ -26,17 +26,20 @@ describe "the `atom` global", ->
|
||||
|
||||
describe "keymap loading", ->
|
||||
describe "when package.json does not contain a 'keymaps' manifest", ->
|
||||
it "loads all keymaps in the directory", ->
|
||||
it "loads all the .cson/.json files in the keymaps directory", ->
|
||||
element1 = $$ -> @div class: 'test-1'
|
||||
element2 = $$ -> @div class: 'test-2'
|
||||
element3 = $$ -> @div class: 'test-3'
|
||||
|
||||
expect(keymap.bindingsForElement(element1)['ctrl-z']).toBeUndefined()
|
||||
expect(keymap.bindingsForElement(element2)['ctrl-z']).toBeUndefined()
|
||||
expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined()
|
||||
|
||||
atom.loadPackage("package-with-module")
|
||||
|
||||
expect(keymap.bindingsForElement(element1)['ctrl-z']).toBe "test-1"
|
||||
expect(keymap.bindingsForElement(element2)['ctrl-z']).toBe "test-2"
|
||||
expect(keymap.bindingsForElement(element3)['ctrl-z']).toBeUndefined()
|
||||
|
||||
describe "when package.json contains a 'keymaps' manifest", ->
|
||||
it "loads only the keymaps specified by the manifest, in the specified order", ->
|
||||
|
||||
@@ -111,11 +111,11 @@ describe "Editor", ->
|
||||
editor.isFocused = false
|
||||
editor.hiddenInput.focus()
|
||||
expect(editor.isFocused).toBeTruthy()
|
||||
expect(editor).toHaveClass('focused')
|
||||
expect(editor).toHaveClass('is-focused')
|
||||
|
||||
editor.hiddenInput.focusout()
|
||||
expect(editor.isFocused).toBeFalsy()
|
||||
expect(editor).not.toHaveClass('focused')
|
||||
expect(editor).not.toHaveClass('is-focused')
|
||||
|
||||
describe "when the activeEditSession's file is modified on disk", ->
|
||||
it "triggers an alert", ->
|
||||
@@ -520,9 +520,8 @@ describe "Editor", ->
|
||||
beforeEach ->
|
||||
expect(editor.css('font-family')).not.toBe 'Courier'
|
||||
|
||||
it "sets the initial font family based on the value from config", ->
|
||||
expect($("head style.font-family")).toExist()
|
||||
expect($("head style.font-family").text()).toMatch "{font-family: #{config.get('editor.fontFamily')}}"
|
||||
it "when there is no config in fontFamily don't set it", ->
|
||||
expect($("head style.font-family")).not.toExist()
|
||||
|
||||
describe "when the font family changes", ->
|
||||
it "updates the font family on new and existing editors", ->
|
||||
@@ -544,7 +543,7 @@ describe "Editor", ->
|
||||
|
||||
lineHeightBefore = editor.lineHeight
|
||||
charWidthBefore = editor.charWidth
|
||||
config.set("editor.fontFamily", "Courier")
|
||||
config.set("editor.fontFamily", "Inconsolata")
|
||||
editor.setCursorScreenPosition [5, 6]
|
||||
expect(editor.charWidth).not.toBe charWidthBefore
|
||||
expect(editor.getCursorView().position()).toEqual { top: 5 * editor.lineHeight, left: 6 * editor.charWidth }
|
||||
@@ -553,6 +552,7 @@ describe "Editor", ->
|
||||
describe "font size", ->
|
||||
beforeEach ->
|
||||
expect(editor.css('font-size')).not.toBe "20px"
|
||||
expect(editor.css('font-size')).not.toBe "10px"
|
||||
|
||||
it "sets the initial font size based on the value from config", ->
|
||||
expect($("head style.font-size")).toExist()
|
||||
@@ -615,6 +615,23 @@ describe "Editor", ->
|
||||
config.set("editor.fontSize", 10)
|
||||
expect(editor.renderedLines.find(".line").length).toBeGreaterThan originalLineCount
|
||||
|
||||
describe "when the editor is detached", ->
|
||||
it "updates the font-size correctly and recalculates the dimensions by placing the rendered lines on the DOM", ->
|
||||
rootView.attachToDom()
|
||||
rootView.height(200)
|
||||
rootView.width(200)
|
||||
|
||||
newEditor = editor.splitRight()
|
||||
newEditorParent = newEditor.parent()
|
||||
newEditor.detach()
|
||||
config.set("editor.fontSize", 10)
|
||||
newEditorParent.append(newEditor)
|
||||
|
||||
expect(newEditor.lineHeight).toBe editor.lineHeight
|
||||
expect(newEditor.charWidth).toBe editor.charWidth
|
||||
expect(newEditor.getCursorView().position()).toEqual editor.getCursorView().position()
|
||||
expect(newEditor.verticalScrollbarContent.height()).toBe editor.verticalScrollbarContent.height()
|
||||
|
||||
describe "mouse events", ->
|
||||
beforeEach ->
|
||||
editor.attachToDom()
|
||||
|
||||
@@ -23,8 +23,7 @@ describe "the `syntax` global", ->
|
||||
expect(syntax.grammarForFilePath("/tmp/.git/config").name).toBe "Git Config"
|
||||
|
||||
it "uses plain text if no grammar can be found", ->
|
||||
filePath = require.resolve("this-is-not-a-real-file")
|
||||
expect(syntax.grammarForFilePath(filePath).name).toBe "Plain Text"
|
||||
expect(syntax.grammarForFilePath("this-is-not-a-real-file").name).toBe "Plain Text"
|
||||
|
||||
describe ".getProperty(scopeDescriptor)", ->
|
||||
it "returns the property with the most specific scope selector", ->
|
||||
|
||||
@@ -42,7 +42,7 @@ describe "TextMateTheme", ->
|
||||
selector: ".invalid.deprecated"
|
||||
properties:
|
||||
'color': "#D2A8A1"
|
||||
# 'font-style': 'italic'
|
||||
'font-style': 'italic'
|
||||
'text-decoration': 'underline'
|
||||
|
||||
expect(rulesets[13]).toEqual
|
||||
|
||||
@@ -13,6 +13,14 @@ describe "Window", ->
|
||||
atom.setRootViewStateForPath(rootView.project.getPath(), null)
|
||||
$(window).off 'beforeunload'
|
||||
|
||||
describe "window is loaded", ->
|
||||
it "has .is-focused on the body tag", ->
|
||||
expect($("body").hasClass("is-focused")).toBe true
|
||||
|
||||
it "doesn't have .is-focused on the window blur", ->
|
||||
$(window).blur()
|
||||
expect($("body").hasClass("is-focused")).toBe false
|
||||
|
||||
describe ".close()", ->
|
||||
it "is triggered by the 'core:close' event", ->
|
||||
spyOn window, 'close'
|
||||
|
||||
2
spec/fixtures/packages/package-with-module/keymaps/keymap-3.cjson
vendored
Normal file
2
spec/fixtures/packages/package-with-module/keymaps/keymap-3.cjson
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
".test-3":
|
||||
"ctrl-z": "test-3"
|
||||
@@ -85,7 +85,7 @@ jasmine.unspy = (object, methodName) ->
|
||||
throw new Error("Not a spy") unless object[methodName].originalValue?
|
||||
object[methodName] = object[methodName].originalValue
|
||||
|
||||
jasmine.getEnv().defaultTimeoutInterval = 500
|
||||
jasmine.getEnv().defaultTimeoutInterval = 1000
|
||||
|
||||
window.keyIdentifierForKey = (key) ->
|
||||
if key.length > 1 # named key
|
||||
|
||||
60
spec/stdlib/cson-spec.coffee
Normal file
60
spec/stdlib/cson-spec.coffee
Normal file
@@ -0,0 +1,60 @@
|
||||
CSON = require 'cson'
|
||||
|
||||
describe "CSON", ->
|
||||
describe "@stringify(object)", ->
|
||||
describe "when the object is undefined", ->
|
||||
it "throws an exception", ->
|
||||
expect(-> CSON.stringify()).toThrow()
|
||||
|
||||
describe "when the object is a function", ->
|
||||
it "throws an exception", ->
|
||||
expect(-> CSON.stringify(-> 'function')).toThrow()
|
||||
|
||||
describe "when the object contains a function", ->
|
||||
it "throws an exception", ->
|
||||
expect(-> CSON.stringify(a: -> 'function')).toThrow()
|
||||
|
||||
describe "when formatting an undefined key", ->
|
||||
it "does not include the key in the formatted CSON", ->
|
||||
expect(CSON.stringify(b: 1, c: undefined)).toBe "'b': 1"
|
||||
|
||||
describe "when formatting an empty object", ->
|
||||
it "returns the empty string", ->
|
||||
expect(CSON.stringify({})).toBe ""
|
||||
|
||||
describe "when formatting a string", ->
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: 'b')).toBe "'a': 'b'"
|
||||
|
||||
it "escapes single quotes", ->
|
||||
expect(CSON.stringify(a: "'b'")).toBe "'a': '\\\'b\\\''"
|
||||
|
||||
it "doesn't escape double quotes", ->
|
||||
expect(CSON.stringify(a: '"b"')).toBe "'a': '\"b\"'"
|
||||
|
||||
describe "when formatting a boolean", ->
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: true)).toBe "'a': true"
|
||||
expect(CSON.stringify(a: false)).toBe "'a': false"
|
||||
|
||||
describe "when formatting a number", ->
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: 14)).toBe "'a': 14"
|
||||
expect(CSON.stringify(a: 1.23)).toBe "'a': 1.23"
|
||||
|
||||
describe "when formatting null", ->
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: null)).toBe "'a': null"
|
||||
|
||||
describe "when formatting an array", ->
|
||||
describe "when the array is empty", ->
|
||||
it "puts the array on a single line", ->
|
||||
expect(CSON.stringify([])).toBe "[]"
|
||||
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: ['b'])).toBe "'a': [\n 'b'\n]"
|
||||
expect(CSON.stringify(a: ['b', 4])).toBe "'a': [\n 'b'\n 4\n]"
|
||||
|
||||
describe "when formatting an object", ->
|
||||
it "returns formatted CSON", ->
|
||||
expect(CSON.stringify(a: {b: 'c'})).toBe "'a':\n 'b': 'c'"
|
||||
@@ -128,3 +128,8 @@ describe "fs", ->
|
||||
describe ".md5ForPath(path)", ->
|
||||
it "returns the MD5 hash of the file at the given path", ->
|
||||
expect(fs.md5ForPath(require.resolve('fixtures/sample.js'))).toBe 'dd38087d0d7e3e4802a6d3f9b9745f2b'
|
||||
|
||||
describe ".list(path, extensions)", ->
|
||||
it "returns the paths with the specified extensions", ->
|
||||
path = require.resolve('fixtures/css.css')
|
||||
expect(fs.list(require.resolve('fixtures'), ['.css'])).toEqual [path]
|
||||
|
||||
@@ -26,15 +26,12 @@ class AtomPackage extends Package
|
||||
@metadata = fs.readObject(metadataPath)
|
||||
|
||||
loadKeymaps: ->
|
||||
for keymapPath in @getKeymapPaths()
|
||||
keymap.load(keymapPath)
|
||||
|
||||
getKeymapPaths: ->
|
||||
if keymaps = @metadata?.keymaps
|
||||
keymaps.map (relativePath) =>
|
||||
keymaps = keymaps.map (relativePath) =>
|
||||
fs.resolve(@keymapsDirPath, relativePath, ['cson', 'json', ''])
|
||||
keymap.load(keymapPath) for keymapPath in keymaps
|
||||
else
|
||||
fs.list(@keymapsDirPath)
|
||||
keymap.loadDirectory(@keymapsDirPath)
|
||||
|
||||
loadStylesheets: ->
|
||||
for stylesheetPath in @getStylesheetPaths()
|
||||
|
||||
@@ -3,9 +3,16 @@ Theme = require 'theme'
|
||||
|
||||
module.exports =
|
||||
class AtomTheme extends Theme
|
||||
|
||||
loadStylesheet: (stylesheetPath)->
|
||||
@stylesheets[stylesheetPath] = fs.read(stylesheetPath)
|
||||
|
||||
load: ->
|
||||
json = fs.read(fs.join(@path, "package.json"))
|
||||
for stylesheetName in JSON.parse(json).stylesheets
|
||||
stylesheetPath = fs.join(@path, stylesheetName)
|
||||
@stylesheets[stylesheetPath] = fs.read(stylesheetPath)
|
||||
if /\.css$/.test(@path)
|
||||
@loadStylesheet @path
|
||||
else
|
||||
json = fs.read(fs.join(@path, "package.json"))
|
||||
for stylesheetName in JSON.parse(json).stylesheets
|
||||
stylesheetPath = fs.join(@path, stylesheetName)
|
||||
@loadStylesheet stylesheetPath
|
||||
super
|
||||
|
||||
@@ -50,15 +50,21 @@ _.extend atom,
|
||||
.filter (name) -> not _.contains(disabledPackages, name)
|
||||
|
||||
loadThemes: ->
|
||||
themeNames = config.get("core.themes") ? ['Atom - Dark', 'IR_Black']
|
||||
themeNames = config.get("core.themes") ? ['atom-dark-ui', 'atom-dark-syntax']
|
||||
themeNames = [themeNames] unless _.isArray(themeNames)
|
||||
@loadTheme(themeName) for themeName in themeNames
|
||||
@loadUserStylesheet()
|
||||
|
||||
loadTheme: (name) ->
|
||||
@loadedThemes.push Theme.load(name)
|
||||
|
||||
loadUserStylesheet: ->
|
||||
userStylesheetPath = fs.join(config.configDirPath, 'user.css')
|
||||
if fs.isFile(userStylesheetPath)
|
||||
applyStylesheet(userStylesheetPath, fs.read(userStylesheetPath), 'userTheme')
|
||||
|
||||
getAtomThemeStylesheets: ->
|
||||
themeNames = config.get("core.themes") ? ['Atom - Dark', 'IR_Black']
|
||||
themeNames = config.get("core.themes") ? ['atom-dark-ui', 'atom-dark-syntax']
|
||||
themeNames = [themeNames] unless _.isArray(themeNames)
|
||||
|
||||
open: (args...) ->
|
||||
|
||||
@@ -4,7 +4,7 @@ EventEmitter = require 'event-emitter'
|
||||
|
||||
configDirPath = fs.absolute("~/.atom")
|
||||
configJsonPath = fs.join(configDirPath, "config.json")
|
||||
userInitScriptPath = fs.join(configDirPath, "atom.coffee")
|
||||
userInitScriptPath = fs.join(configDirPath, "user.coffee")
|
||||
bundledPackagesDirPath = fs.join(resourcePath, "src/packages")
|
||||
bundledThemesDirPath = fs.join(resourcePath, "themes")
|
||||
vendoredPackagesDirPath = fs.join(resourcePath, "vendor/packages")
|
||||
|
||||
@@ -18,7 +18,7 @@ class EditSession
|
||||
if fs.exists(state.buffer)
|
||||
session = project.buildEditSessionForPath(state.buffer)
|
||||
else
|
||||
console.warn "Could not build edit session for path '#{state.buffer}' because that file no longer exists"
|
||||
console.warn "Could not build edit session for path '#{state.buffer}' because that file no longer exists" if state.buffer
|
||||
session = project.buildEditSessionForPath(null)
|
||||
session.setScrollTop(state.scrollTop)
|
||||
session.setScrollLeft(state.scrollLeft)
|
||||
|
||||
@@ -14,7 +14,6 @@ _ = require 'underscore'
|
||||
module.exports =
|
||||
class Editor extends View
|
||||
@configDefaults:
|
||||
fontFamily: "Inconsolata, Monaco, Courier"
|
||||
fontSize: 20
|
||||
showInvisibles: false
|
||||
autosave: false
|
||||
@@ -352,11 +351,11 @@ class Editor extends View
|
||||
@hiddenInput.on 'focus', =>
|
||||
@rootView()?.editorFocused(this)
|
||||
@isFocused = true
|
||||
@addClass 'focused'
|
||||
@addClass 'is-focused'
|
||||
|
||||
@hiddenInput.on 'focusout', =>
|
||||
@isFocused = false
|
||||
@removeClass 'focused'
|
||||
@removeClass 'is-focused'
|
||||
@autosave() if config.get "editor.autosave"
|
||||
|
||||
@underlayer.on 'click', (e) =>
|
||||
@@ -697,6 +696,7 @@ class Editor extends View
|
||||
parseInt(@css("font-size"))
|
||||
|
||||
setFontFamily: (fontFamily) ->
|
||||
return if fontFamily == undefined
|
||||
headTag = $("head")
|
||||
styleTag = headTag.find("style.font-family")
|
||||
if styleTag.length == 0
|
||||
@@ -804,6 +804,10 @@ class Editor extends View
|
||||
@overlayer.append(view)
|
||||
|
||||
calculateDimensions: ->
|
||||
if not @isOnDom()
|
||||
detachedEditorParent = _.last(@parents()) ? this
|
||||
$(document.body).append(detachedEditorParent)
|
||||
|
||||
fragment = $('<pre class="line" style="position: absolute; visibility: hidden;"><span>x</span></div>')
|
||||
@renderedLines.append(fragment)
|
||||
|
||||
@@ -815,6 +819,8 @@ class Editor extends View
|
||||
@height(@lineHeight) if @mini
|
||||
fragment.remove()
|
||||
|
||||
$(detachedEditorParent).detach()
|
||||
|
||||
updateLayerDimensions: ->
|
||||
@gutter.calculateWidth()
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
$ = require 'jquery'
|
||||
_ = require 'underscore'
|
||||
Subscriber = require 'subscriber'
|
||||
GitRepository = require 'git-repository'
|
||||
@@ -6,9 +5,9 @@ GitRepository = require 'git-repository'
|
||||
module.exports =
|
||||
class Git
|
||||
|
||||
@open: (path) ->
|
||||
@open: (path, options) ->
|
||||
try
|
||||
new Git(path)
|
||||
new Git(path, options)
|
||||
catch e
|
||||
null
|
||||
|
||||
@@ -24,9 +23,12 @@ class Git
|
||||
working_dir_typechange: 1 << 10
|
||||
ignore: 1 << 14
|
||||
|
||||
constructor: (path) ->
|
||||
constructor: (path, options={}) ->
|
||||
@repo = new GitRepository(path)
|
||||
@subscribe $(window), 'focus', => @refreshIndex()
|
||||
refreshIndexOnFocus = options.refreshIndexOnFocus ? true
|
||||
if refreshIndexOnFocus
|
||||
$ = require 'jquery'
|
||||
@subscribe $(window), 'focus', => @refreshIndex()
|
||||
|
||||
getRepo: ->
|
||||
unless @repo?
|
||||
|
||||
@@ -35,7 +35,7 @@ class Keymap
|
||||
@loadDirectory(fs.join(config.configDirPath, 'keymaps'))
|
||||
|
||||
loadDirectory: (directoryPath) ->
|
||||
@load(filePath) for filePath in fs.list(directoryPath)
|
||||
@load(filePath) for filePath in fs.list(directoryPath, ['.cson', '.json'])
|
||||
|
||||
load: (path) ->
|
||||
@add(fs.readObject(path))
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Task = require 'Task'
|
||||
Task = require 'task'
|
||||
|
||||
module.exports =
|
||||
class LoadTextMatePackagesTask extends Task
|
||||
|
||||
@@ -44,17 +44,17 @@ class TextMateTheme extends Theme
|
||||
'color': @translateColor(foreground)
|
||||
|
||||
@rulesets.push
|
||||
selector: '.editor.focused .cursor'
|
||||
selector: '.editor.is-focused .cursor'
|
||||
properties:
|
||||
'border-color': @translateColor(caret)
|
||||
|
||||
@rulesets.push
|
||||
selector: '.editor.focused .selection .region'
|
||||
selector: '.editor.is-focused .selection .region'
|
||||
properties:
|
||||
'background-color': @translateColor(selection)
|
||||
|
||||
@rulesets.push
|
||||
selector: '.editor.focused .line-number.cursor-line-no-selection, .editor.focused .line.cursor-line'
|
||||
selector: '.editor.is-focused .line-number.cursor-line-no-selection, .editor.is-focused .line.cursor-line'
|
||||
properties:
|
||||
'background-color': @translateColor(lineHighlight)
|
||||
|
||||
@@ -75,8 +75,8 @@ class TextMateTheme extends Theme
|
||||
|
||||
if fontStyle
|
||||
fontStyles = fontStyle.split(/\s+/)
|
||||
# properties['font-weight'] = 'bold' if _.contains(fontStyles, 'bold')
|
||||
# properties['font-style'] = 'italic' if _.contains(fontStyles, 'italic')
|
||||
properties['font-weight'] = 'bold' if _.contains(fontStyles, 'bold')
|
||||
properties['font-style'] = 'italic' if _.contains(fontStyles, 'italic')
|
||||
properties['text-decoration'] = 'underline' if _.contains(fontStyles, 'underline')
|
||||
|
||||
properties['color'] = @translateColor(foreground) if foreground
|
||||
|
||||
@@ -11,7 +11,7 @@ class Theme
|
||||
if fs.exists(name)
|
||||
path = name
|
||||
else
|
||||
path = fs.resolve(config.themeDirPaths..., name, ['', '.tmTheme'])
|
||||
path = fs.resolve(config.themeDirPaths..., name, ['', '.tmTheme', '.css'])
|
||||
|
||||
throw new Error("No theme exists named '#{name}'") unless path
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ windowAdditions =
|
||||
|
||||
$(window).on 'core:close', => @close()
|
||||
$(window).command 'window:close', => @close()
|
||||
$(window).on 'focus blur', => $("body").toggleClass("is-focused")
|
||||
|
||||
# This method is intended only to be run when starting a normal application
|
||||
# Note: RootView assigns itself on window on initialization so that
|
||||
|
||||
@@ -6,9 +6,8 @@ describe "CommandLogger", ->
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView(require.resolve('fixtures/sample.js'))
|
||||
atom.loadPackage('command-logger').getInstance()
|
||||
commandLogger = atom.loadPackage('command-logger')
|
||||
editor = rootView.getActiveEditor()
|
||||
commandLogger = CommandLogger.instance
|
||||
|
||||
afterEach ->
|
||||
rootView.deactivate()
|
||||
@@ -44,9 +43,11 @@ describe "CommandLogger", ->
|
||||
|
||||
describe "when an event is ignored", ->
|
||||
it "does not create a node for that event", ->
|
||||
commandLogger.ignoredEvents.push 'editor:delete-line'
|
||||
commandLoggerView = commandLogger.getInstance()
|
||||
commandLoggerView.ignoredEvents.push 'editor:delete-line'
|
||||
editor.trigger 'editor:delete-line'
|
||||
nodes = commandLogger.createNodes()
|
||||
commandLoggerView.eventLog = commandLogger.eventLog
|
||||
nodes = commandLoggerView.createNodes()
|
||||
for node in nodes
|
||||
continue unless node.name is 'Editor'
|
||||
for child in node.children
|
||||
|
||||
@@ -34,6 +34,7 @@ class CommandLoggerView extends ScrollView
|
||||
super
|
||||
|
||||
@command 'core:cancel', => @detach()
|
||||
@on 'blur', => @detach() unless document.activeElement is this[0]
|
||||
|
||||
toggle: (@eventLog={}) ->
|
||||
if @hasParent()
|
||||
@@ -143,10 +144,10 @@ class CommandLoggerView extends ScrollView
|
||||
.append('div')
|
||||
.style('width', "#{w}px")
|
||||
.style('height', "#{h}px")
|
||||
.append('svg:svg')
|
||||
.append('svg')
|
||||
.attr('width', w)
|
||||
.attr('height', h)
|
||||
.append('svg:g')
|
||||
.append('g')
|
||||
.attr('transform', 'translate(.5,.5)')
|
||||
|
||||
nodes = treemap.nodes(root).filter((d) -> not d.children)
|
||||
@@ -154,17 +155,17 @@ class CommandLoggerView extends ScrollView
|
||||
cell = svg.selectAll('g')
|
||||
.data(nodes)
|
||||
.enter()
|
||||
.append('svg:g')
|
||||
.append('g')
|
||||
.attr('class', 'node')
|
||||
.attr('transform', (d) -> "translate(#{d.x},#{d.y})")
|
||||
.on('click', (d) -> if node is d.parent then zoom(root) else zoom(d.parent))
|
||||
|
||||
cell.append('svg:rect')
|
||||
cell.append('rect')
|
||||
.attr('width', (d) -> d.dx - 1)
|
||||
.attr('height', (d) -> d.dy - 1)
|
||||
.style('fill', (d) -> color(d.parent.name))
|
||||
|
||||
cell.append('svg:foreignObject')
|
||||
cell.append('foreignObject')
|
||||
.attr('width', (d) -> d.dx - 1)
|
||||
.attr('height', (d) -> d.dy - 1)
|
||||
.attr('class', 'foreign-object')
|
||||
@@ -180,8 +181,11 @@ class CommandLoggerView extends ScrollView
|
||||
@focus()
|
||||
|
||||
detach: ->
|
||||
super()
|
||||
return if @detaching
|
||||
@detaching = true
|
||||
super
|
||||
@rootView.focus()
|
||||
@detaching = false
|
||||
|
||||
serialize: ->
|
||||
eventLog: @eventLog
|
||||
|
||||
@@ -438,13 +438,13 @@ describe "CommandPanel", ->
|
||||
expect(previewList.getSelectedOperation()).toBe previewList.getOperations()[0]
|
||||
|
||||
describe "when core:confirm is triggered on the preview list", ->
|
||||
it "opens the operation's buffer, selects and scrolls to the search result, and focuses the active editor", ->
|
||||
it "opens the operation's buffer, selects and scrolls to the search result, and refocuses the preview list", ->
|
||||
rootView.height(200)
|
||||
rootView.attachToDom()
|
||||
|
||||
waitsForPromise -> commandPanel.execute('X x/apply/') # use apply because it is at the end of the file
|
||||
runs ->
|
||||
spyOn(rootView, 'focus')
|
||||
spyOn(previewList, 'focus')
|
||||
executeHandler = jasmine.createSpy('executeHandler')
|
||||
commandPanel.on 'core:confirm', executeHandler
|
||||
|
||||
@@ -458,13 +458,13 @@ describe "CommandPanel", ->
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(editor.isScreenRowVisible(editor.getCursorScreenRow())).toBeTruthy()
|
||||
expect(rootView.focus).toHaveBeenCalled()
|
||||
expect(previewList.focus).toHaveBeenCalled()
|
||||
|
||||
expect(executeHandler).not.toHaveBeenCalled()
|
||||
|
||||
describe "when an operation in the preview list is clicked", ->
|
||||
it "opens the operation's buffer, selects the search result, and focuses the active editor", ->
|
||||
spyOn(rootView, 'focus')
|
||||
it "opens the operation's buffer, selects the search result, and refocuses the preview list", ->
|
||||
spyOn(previewList, 'focus')
|
||||
operation = previewList.getOperations()[4]
|
||||
|
||||
previewList.find('li.operation:eq(4) span').mousedown()
|
||||
@@ -473,4 +473,4 @@ describe "CommandPanel", ->
|
||||
editSession = rootView.getActiveEditSession()
|
||||
expect(editSession.buffer.getPath()).toBe project.resolve(operation.getPath())
|
||||
expect(editSession.getSelectedBufferRange()).toEqual operation.getBufferRange()
|
||||
expect(rootView.focus).toHaveBeenCalled()
|
||||
expect(previewList.focus).toHaveBeenCalled()
|
||||
|
||||
@@ -83,7 +83,7 @@ class PreviewList extends ScrollView
|
||||
editSession = @rootView.open(operation.getPath())
|
||||
bufferRange = operation.execute(editSession)
|
||||
editSession.setSelectedBufferRange(bufferRange, autoscroll: true) if bufferRange
|
||||
@rootView.focus()
|
||||
@focus()
|
||||
false
|
||||
|
||||
getPathCount: ->
|
||||
|
||||
16
src/packages/editor-stats/index.coffee
Normal file
16
src/packages/editor-stats/index.coffee
Normal file
@@ -0,0 +1,16 @@
|
||||
DeferredAtomPackage = require 'deferred-atom-package'
|
||||
Stats = require './src/stats'
|
||||
|
||||
module.exports =
|
||||
class EditorStats extends DeferredAtomPackage
|
||||
loadEvents: ['editor-stats:toggle']
|
||||
instanceClass: 'editor-stats/src/editor-stats-view'
|
||||
stats: new Stats
|
||||
|
||||
activate: (rootView) ->
|
||||
super
|
||||
|
||||
rootView.on 'keydown', => @stats.track()
|
||||
rootView.on 'mouseup', => @stats.track()
|
||||
|
||||
onLoadEvent: (event, instance) -> instance.toggle(@stats)
|
||||
2
src/packages/editor-stats/keymaps/editor-stats.cson
Normal file
2
src/packages/editor-stats/keymaps/editor-stats.cson
Normal file
@@ -0,0 +1,2 @@
|
||||
'body':
|
||||
'meta-alt-s': 'editor-stats:toggle'
|
||||
46
src/packages/editor-stats/spec/editor-stats-spec.coffee
Normal file
46
src/packages/editor-stats/spec/editor-stats-spec.coffee
Normal file
@@ -0,0 +1,46 @@
|
||||
$ = require 'jquery'
|
||||
RootView = require 'root-view'
|
||||
EditorStats = require 'editor-stats/src/editor-stats-view'
|
||||
|
||||
describe "EditorStats", ->
|
||||
[rootView, editorStats, time] = []
|
||||
|
||||
simulateKeyUp = (key) ->
|
||||
e = $.Event "keydown", keyCode: key.charCodeAt(0)
|
||||
rootView.trigger(e)
|
||||
|
||||
simulateClick = ->
|
||||
e = $.Event "mouseup"
|
||||
rootView.trigger(e)
|
||||
|
||||
beforeEach ->
|
||||
rootView = new RootView(require.resolve('fixtures/sample.js'))
|
||||
|
||||
date = new Date()
|
||||
mins = date.getMinutes()
|
||||
hours = date.getHours()
|
||||
|
||||
mins = if mins == 60 then '01' else mins + 1
|
||||
time = "#{hours}:#{mins}"
|
||||
|
||||
editorStatsPackage = atom.loadPackage('editor-stats')
|
||||
editorStatsPackage.getInstance()
|
||||
editorStats = editorStatsPackage.stats
|
||||
editorStats.clear()
|
||||
|
||||
afterEach ->
|
||||
rootView.deactivate()
|
||||
|
||||
describe "when a keyup event is triggered", ->
|
||||
it "records the number of times a keyup is triggered", ->
|
||||
simulateKeyUp('a')
|
||||
expect(editorStats.eventLog[time]).toBe 1
|
||||
simulateKeyUp('b')
|
||||
expect(editorStats.eventLog[time]).toBe 2
|
||||
|
||||
describe "when a mouseup event is triggered", ->
|
||||
it "records the number of times a mouseup is triggered", ->
|
||||
simulateClick()
|
||||
expect(editorStats.eventLog[time]).toBe 1
|
||||
simulateClick()
|
||||
expect(editorStats.eventLog[time]).toBe 2
|
||||
103
src/packages/editor-stats/src/editor-stats-view.coffee
Normal file
103
src/packages/editor-stats/src/editor-stats-view.coffee
Normal file
@@ -0,0 +1,103 @@
|
||||
ScrollView = require 'scroll-view'
|
||||
d3 = require 'd3.v3'
|
||||
_ = require 'underscore'
|
||||
$ = require 'jquery'
|
||||
|
||||
module.exports =
|
||||
class EditorStatsView extends ScrollView
|
||||
@activate: (rootView, state) ->
|
||||
@instance = new EditorStatsView(rootView)
|
||||
|
||||
@content: (rootView) ->
|
||||
@div class: 'editor-stats-wrapper', tabindex: -1, =>
|
||||
@div class: 'editor-stats', outlet: 'editorStats'
|
||||
|
||||
pt: 15
|
||||
pl: 10
|
||||
pb: 3
|
||||
pr: 25
|
||||
|
||||
initialize: (@rootView) ->
|
||||
super
|
||||
|
||||
resizer = =>
|
||||
return unless @isOnDom()
|
||||
@draw()
|
||||
@update()
|
||||
@subscribe $(window), 'resize', _.debounce(resizer, 300)
|
||||
|
||||
draw: ->
|
||||
@editorStats.empty()
|
||||
@x ?= d3.scale.ordinal().domain d3.range(@stats.hours * 60)
|
||||
@y ?= d3.scale.linear()
|
||||
w = @rootView.vertical.width()
|
||||
h = @height()
|
||||
data = d3.entries @stats.eventLog
|
||||
max = d3.max data, (d) -> d.value
|
||||
|
||||
@x.rangeBands [0, w - @pl - @pr], 0.2
|
||||
@y.domain([0, max]).range [h - @pt - @pb, 0]
|
||||
|
||||
@xaxis ?= d3.svg.axis().scale(@x).orient('top')
|
||||
.tickSize(-h + @pt + @pb)
|
||||
.tickFormat (d) =>
|
||||
d = new Date(@stats.startDate.getTime() + (d * 6e4))
|
||||
mins = d.getMinutes()
|
||||
mins = "0#{mins}" if mins <= 9
|
||||
"#{d.getHours()}:#{mins}"
|
||||
|
||||
vis = d3.select(@editorStats.get(0)).append('svg')
|
||||
.attr('width', w)
|
||||
.attr('height', h)
|
||||
.append('g')
|
||||
.attr('transform', "translate(#{@pl},#{@pt})")
|
||||
|
||||
vis.append('g')
|
||||
.attr('class', 'x axis')
|
||||
.call(@xaxis)
|
||||
.selectAll('g')
|
||||
.classed('minor', (d, i) -> i % 5 == 0 && i % 15 != 0)
|
||||
.style 'display', (d, i) ->
|
||||
if i % 15 == 0 || i % 5 == 0 || i == data.length - 1
|
||||
'block'
|
||||
else
|
||||
'none'
|
||||
|
||||
@bars = vis.selectAll('rect.bar')
|
||||
.data(data)
|
||||
.enter().append('rect')
|
||||
.attr('x', (d, i) => @x i)
|
||||
.attr('height', (d, i) => h - @y(d.value) - @pt - @pb)
|
||||
.attr('y', (d) => @y(d.value))
|
||||
.attr('width', @x.rangeBand())
|
||||
.attr('class', 'bar')
|
||||
|
||||
clearInterval(@updateInterval)
|
||||
updater = => @update() if @isOnDom()
|
||||
setTimeout(updater, 100)
|
||||
@updateInterval = setInterval(updater, 5000)
|
||||
|
||||
update: ->
|
||||
newData = d3.entries @stats.eventLog
|
||||
max = d3.max newData, (d) -> d.value
|
||||
@y.domain [0, max]
|
||||
h = @height()
|
||||
@bars.data(newData).transition()
|
||||
.attr('height', (d, i) => h - @y(d.value) - @pt - @pb)
|
||||
.attr('y', (d, i) => @y(d.value))
|
||||
@bars.classed('max', (d, i) -> d.value == max)
|
||||
|
||||
toggle: (@stats) ->
|
||||
if @hasParent()
|
||||
@detach()
|
||||
else
|
||||
@attach()
|
||||
|
||||
attach: ->
|
||||
@rootView.vertical.append(@)
|
||||
@draw()
|
||||
|
||||
detach: ->
|
||||
super()
|
||||
clearInterval(@updateInterval)
|
||||
@rootView.focus()
|
||||
29
src/packages/editor-stats/src/stats.coffee
Normal file
29
src/packages/editor-stats/src/stats.coffee
Normal file
@@ -0,0 +1,29 @@
|
||||
module.exports =
|
||||
class Stats
|
||||
startDate: new Date
|
||||
hours: 6
|
||||
eventLog: []
|
||||
|
||||
constructor: ->
|
||||
date = new Date(@startDate)
|
||||
future = new Date(date.getTime() + (36e5 * @hours))
|
||||
@eventLog[@time(date)] = 0
|
||||
|
||||
while date < future
|
||||
@eventLog[@time(date)] = 0
|
||||
|
||||
clear: ->
|
||||
@eventLog = []
|
||||
|
||||
track: ->
|
||||
date = new Date
|
||||
times = @time date
|
||||
@eventLog[times] ?= 0
|
||||
@eventLog[times] += 1
|
||||
@eventLog.shift() if @eventLog.length > (@hours * 60)
|
||||
|
||||
time: (date) ->
|
||||
date.setTime(date.getTime() + 6e4)
|
||||
hour = date.getHours()
|
||||
minute = date.getMinutes()
|
||||
"#{hour}:#{minute}"
|
||||
45
src/packages/editor-stats/stylesheets/editor-stats.css
Normal file
45
src/packages/editor-stats/stylesheets/editor-stats.css
Normal file
@@ -0,0 +1,45 @@
|
||||
.editor-stats-wrapper {
|
||||
padding: 5px;
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid rgba(255, 255, 255, 0.05);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.editor-stats {
|
||||
height: 50px;
|
||||
width: 100%;
|
||||
background: #1d1f21;
|
||||
border: 1px solid rgba(0, 0, 0, 0.3);
|
||||
border-bottom: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-right: 1px solid rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
.editor-stats rect.bar {
|
||||
fill: rgba(255, 255, 255, 0.2);
|
||||
shape-rendering: crispedges;
|
||||
}
|
||||
|
||||
.editor-stats rect.bar.max {
|
||||
fill: rgba(0, 163, 255, 1);
|
||||
}
|
||||
|
||||
.editor-stats text {
|
||||
font-size: 10px;
|
||||
fill: rgba(255, 255, 255, 0.2);
|
||||
font-family: Courier;
|
||||
}
|
||||
|
||||
.editor-stats .minor text {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.editor-stats line {
|
||||
stroke: #ccc;
|
||||
stroke-opacity: 0.05;
|
||||
stroke-width: 1px;
|
||||
shape-rendering: crispedges;
|
||||
}
|
||||
|
||||
.editor-stats path.domain {
|
||||
fill: none;
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
DeferredAtomPackage = require 'deferred-atom-package'
|
||||
LoadPathsTask = require './src/load-paths-task'
|
||||
|
||||
module.exports =
|
||||
class FuzzyFinder extends DeferredAtomPackage
|
||||
|
||||
loadEvents: [
|
||||
'fuzzy-finder:toggle-file-finder'
|
||||
'fuzzy-finder:toggle-buffer-finder'
|
||||
@@ -11,7 +11,18 @@ class FuzzyFinder extends DeferredAtomPackage
|
||||
|
||||
instanceClass: 'fuzzy-finder/src/fuzzy-finder-view'
|
||||
|
||||
activate: (rootView) ->
|
||||
super
|
||||
|
||||
if rootView.project.getPath()?
|
||||
callback = (paths) => @projectPaths = paths
|
||||
new LoadPathsTask(rootView, callback).start()
|
||||
|
||||
onLoadEvent: (event, instance) ->
|
||||
if @projectPaths? and not @instance.projectPaths?
|
||||
@instance.projectPaths = @projectPaths
|
||||
@instance.reloadProjectPaths = false
|
||||
|
||||
switch event.type
|
||||
when 'fuzzy-finder:toggle-file-finder'
|
||||
instance.toggleFileFinder()
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
RootView = require 'root-view'
|
||||
FuzzyFinder = require 'fuzzy-finder/src/fuzzy-finder-view'
|
||||
LoadPathsTask = require 'fuzzy-finder/src/load-paths-task'
|
||||
$ = require 'jquery'
|
||||
{$$} = require 'space-pen'
|
||||
fs = require 'fs'
|
||||
@@ -48,14 +49,13 @@ describe 'FuzzyFinder', ->
|
||||
expect(finder.find(".loading")).toBeVisible()
|
||||
expect(finder.find(".loading")).toHaveText "Indexing..."
|
||||
|
||||
waitsForPromise ->
|
||||
rootView.project.getFilePaths().done (foundPaths) -> paths = foundPaths
|
||||
|
||||
waitsFor ->
|
||||
finder.list.children('li').length > 0
|
||||
waitsFor "all project paths to load", 5000, ->
|
||||
if finder.projectPaths?.length > 0
|
||||
paths = finder.projectPaths
|
||||
true
|
||||
|
||||
runs ->
|
||||
expect(finder.list.children('li').length).toBe paths.length, finder.maxResults
|
||||
expect(finder.list.children('li').length).toBe paths.length
|
||||
for path in paths
|
||||
expect(finder.list.find("li:contains(#{fs.base(path)})")).toExist()
|
||||
expect(finder.list.children().first()).toHaveClass 'selected'
|
||||
@@ -222,15 +222,15 @@ describe 'FuzzyFinder', ->
|
||||
|
||||
describe "cached file paths", ->
|
||||
it "caches file paths after first time", ->
|
||||
spyOn(rootView.project, "getFilePaths").andCallThrough()
|
||||
spyOn(LoadPathsTask.prototype, "start").andCallThrough()
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
waitsFor ->
|
||||
finder.list.children('li').length > 0
|
||||
|
||||
runs ->
|
||||
expect(rootView.project.getFilePaths).toHaveBeenCalled()
|
||||
rootView.project.getFilePaths.reset()
|
||||
expect(finder.loadPathsTask.start).toHaveBeenCalled()
|
||||
finder.loadPathsTask.start.reset()
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
@@ -238,45 +238,44 @@ describe 'FuzzyFinder', ->
|
||||
finder.list.children('li').length > 0
|
||||
|
||||
runs ->
|
||||
expect(rootView.project.getFilePaths).not.toHaveBeenCalled()
|
||||
expect(finder.loadPathsTask.start).not.toHaveBeenCalled()
|
||||
|
||||
it "doesn't cache buffer paths", ->
|
||||
spyOn(rootView.project, "getFilePaths").andCallThrough()
|
||||
spyOn(rootView, "getOpenBufferPaths").andCallThrough()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
|
||||
waitsFor ->
|
||||
finder.list.children('li').length > 0
|
||||
|
||||
runs ->
|
||||
expect(rootView.project.getFilePaths).not.toHaveBeenCalled()
|
||||
rootView.project.getFilePaths.reset()
|
||||
expect(rootView.getOpenBufferPaths).toHaveBeenCalled()
|
||||
rootView.getOpenBufferPaths.reset()
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
rootView.trigger 'fuzzy-finder:toggle-buffer-finder'
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
waitsFor ->
|
||||
finder.list.children('li').length > 0
|
||||
|
||||
runs ->
|
||||
expect(rootView.project.getFilePaths).toHaveBeenCalled()
|
||||
expect(rootView.getOpenBufferPaths).toHaveBeenCalled()
|
||||
|
||||
it "busts the cache when the window gains focus", ->
|
||||
spyOn(rootView.project, "getFilePaths").andCallThrough()
|
||||
spyOn(LoadPathsTask.prototype, "start").andCallThrough()
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
|
||||
waitsFor ->
|
||||
finder.list.children('li').length > 0
|
||||
|
||||
runs ->
|
||||
expect(rootView.project.getFilePaths).toHaveBeenCalled()
|
||||
rootView.project.getFilePaths.reset()
|
||||
expect(finder.loadPathsTask.start).toHaveBeenCalled()
|
||||
finder.loadPathsTask.start.reset()
|
||||
$(window).trigger 'focus'
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
expect(rootView.project.getFilePaths).toHaveBeenCalled()
|
||||
expect(finder.loadPathsTask.start).toHaveBeenCalled()
|
||||
|
||||
describe "path ignoring", ->
|
||||
it "ignores paths that match entries in config.fuzzyFinder.ignoredNames", ->
|
||||
spyOn(rootView.project, "getFilePaths").andCallThrough()
|
||||
config.set("fuzzyFinder.ignoredNames", ["tree-view.js"])
|
||||
rootView.trigger 'fuzzy-finder:toggle-file-finder'
|
||||
finder.maxItems = Infinity
|
||||
@@ -293,7 +292,6 @@ describe 'FuzzyFinder', ->
|
||||
beforeEach ->
|
||||
editor = rootView.getActiveEditor()
|
||||
rootView.attachToDom()
|
||||
spyOn(rootView.project, "getFilePaths").andCallThrough()
|
||||
|
||||
it "opens the fuzzy finder window when there are multiple matches", ->
|
||||
editor.setText("sample")
|
||||
|
||||
@@ -3,6 +3,7 @@ SelectList = require 'select-list'
|
||||
_ = require 'underscore'
|
||||
$ = require 'jquery'
|
||||
fs = require 'fs'
|
||||
LoadPathsTask = require 'fuzzy-finder/src/load-paths-task'
|
||||
|
||||
module.exports =
|
||||
class FuzzyFinderView extends SelectList
|
||||
@@ -126,16 +127,9 @@ class FuzzyFinderView extends SelectList
|
||||
@setLoading("Indexing...")
|
||||
|
||||
if @reloadProjectPaths
|
||||
@rootView.project.getFilePaths().done (paths) =>
|
||||
ignoredNames = config.get("fuzzyFinder.ignoredNames") or []
|
||||
ignoredNames = ignoredNames.concat(config.get("core.ignoredNames") or [])
|
||||
@loadPathsTask?.terminate()
|
||||
callback = (paths) =>
|
||||
@projectPaths = paths
|
||||
if ignoredNames
|
||||
@projectPaths = @projectPaths.filter (path) ->
|
||||
for segment in path.split("/")
|
||||
return false if _.contains(ignoredNames, segment)
|
||||
return true
|
||||
|
||||
@reloadProjectPaths = false
|
||||
listedItems =
|
||||
if options.filter?
|
||||
@@ -146,6 +140,8 @@ class FuzzyFinderView extends SelectList
|
||||
|
||||
@setArray(listedItems)
|
||||
options.done(listedItems) if options.done?
|
||||
@loadPathsTask = new LoadPathsTask(@rootView, callback)
|
||||
@loadPathsTask.start()
|
||||
|
||||
populateOpenBufferPaths: ->
|
||||
@paths = @rootView.getOpenBufferPaths().map (path) =>
|
||||
|
||||
20
src/packages/fuzzy-finder/src/load-paths-handler.coffee
Normal file
20
src/packages/fuzzy-finder/src/load-paths-handler.coffee
Normal file
@@ -0,0 +1,20 @@
|
||||
fs = require 'fs'
|
||||
_ = require 'underscore'
|
||||
Git = require 'git'
|
||||
|
||||
module.exports =
|
||||
loadPaths: (rootPath, ignoredNames, ignoreGitIgnoredFiles) ->
|
||||
paths = []
|
||||
repo = Git.open(rootPath, refreshIndexOnFocus: false) if ignoreGitIgnoredFiles
|
||||
isIgnored = (path) ->
|
||||
for segment in path.split('/')
|
||||
return true if _.contains(ignoredNames, segment)
|
||||
return true if repo?.isPathIgnored(fs.join(rootPath, path))
|
||||
false
|
||||
onFile = (path) ->
|
||||
paths.push(path) unless isIgnored(path)
|
||||
onDirectory = (path) ->
|
||||
not isIgnored(path)
|
||||
fs.traverseTree(rootPath, onFile, onDirectory)
|
||||
repo?.destroy()
|
||||
callTaskMethod('pathsLoaded', paths)
|
||||
17
src/packages/fuzzy-finder/src/load-paths-task.coffee
Normal file
17
src/packages/fuzzy-finder/src/load-paths-task.coffee
Normal file
@@ -0,0 +1,17 @@
|
||||
Task = require 'task'
|
||||
|
||||
module.exports =
|
||||
class LoadPathsTask extends Task
|
||||
constructor: (@rootView, @callback)->
|
||||
super('fuzzy-finder/src/load-paths-handler')
|
||||
|
||||
started: ->
|
||||
ignoredNames = config.get("fuzzyFinder.ignoredNames") ? []
|
||||
ignoredNames = ignoredNames.concat(config.get("core.ignoredNames") ? [])
|
||||
ignoreGitIgnoredFiles = config.get("core.hideGitIgnoredFiles")
|
||||
rootPath = @rootView.project.getPath()
|
||||
@callWorkerMethod('loadPaths', rootPath, ignoredNames, ignoreGitIgnoredFiles)
|
||||
|
||||
pathsLoaded: (paths) ->
|
||||
@terminate()
|
||||
@callback(paths)
|
||||
@@ -277,6 +277,7 @@ describe "Snippets extension", ->
|
||||
|
||||
it "terminates the worker when loading completes", ->
|
||||
jasmine.unspy(LoadSnippetsTask.prototype, 'loadAtomSnippets')
|
||||
spyOn(console, "warn")
|
||||
spyOn(Worker.prototype, 'terminate').andCallThrough()
|
||||
snippets.loaded = false
|
||||
snippets.loadAll()
|
||||
@@ -284,6 +285,8 @@ describe "Snippets extension", ->
|
||||
waitsFor "all snippets to load", 5000, -> snippets.loaded
|
||||
|
||||
runs ->
|
||||
expect(console.warn).toHaveBeenCalled()
|
||||
expect(console.warn.argsForCall[0]).toMatch /Error reading snippets file '.*?\/spec\/fixtures\/packages\/package-with-snippets\/snippets\/junk-file'/
|
||||
expect(Worker.prototype.terminate).toHaveBeenCalled()
|
||||
expect(Worker.prototype.terminate.calls.length).toBe 1
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Task = require 'Task'
|
||||
Task = require 'task'
|
||||
TextMatePackage = require 'text-mate-package'
|
||||
|
||||
module.exports =
|
||||
|
||||
@@ -770,6 +770,9 @@ describe "TreeView", ->
|
||||
treeView.trigger "tree-view:move"
|
||||
moveDialog = rootView.find(".tree-view-dialog").view()
|
||||
|
||||
afterEach ->
|
||||
waits 50 # The move specs cause too many false positives because of their async nature, so wait a little bit before we cleanup
|
||||
|
||||
it "opens a move dialog with the file's current path (excluding extension) populated", ->
|
||||
extension = fs.extension(filePath)
|
||||
fileNameWithoutExtension = fs.base(filePath, extension)
|
||||
|
||||
79
src/stdlib/cson.coffee
Normal file
79
src/stdlib/cson.coffee
Normal file
@@ -0,0 +1,79 @@
|
||||
_ = require 'underscore'
|
||||
|
||||
module.exports =
|
||||
stringifyIndent: (level=0) -> _.multiplyString(' ', Math.max(level, 0))
|
||||
|
||||
stringifyString: (string) ->
|
||||
string = JSON.stringify(string)
|
||||
string = string[1...-1] # Remove surrounding double quotes
|
||||
string = string.replace(/\\"/g, '"') # Unescape escaped double quotes
|
||||
string = string.replace(/'/g, '\\\'') # Escape single quotes
|
||||
"'#{string}'" # Wrap in single quotes
|
||||
|
||||
stringifyBoolean: (boolean) -> "#{boolean}"
|
||||
|
||||
stringifyNumber: (number) -> "#{number}"
|
||||
|
||||
stringifyNull: -> 'null'
|
||||
|
||||
stringifyArray: (array, indentLevel=0) ->
|
||||
return '[]' if array.length is 0
|
||||
|
||||
cson = '[\n'
|
||||
for value in array
|
||||
cson += @stringifyIndent(indentLevel + 2)
|
||||
if _.isString(value)
|
||||
cson += @stringifyString(value)
|
||||
else if _.isBoolean(value)
|
||||
cson += @stringifyBoolean(value)
|
||||
else if _.isNumber(value)
|
||||
cson += @stringifyNumber(value)
|
||||
else if _.isNull(value)
|
||||
cson += @stringifyNull(value)
|
||||
else if _.isArray(value)
|
||||
cson += @stringifyArray(value, indentLevel + 2)
|
||||
else if _.isObject(value)
|
||||
cson += @stringifyObject(value, indentLevel + 2)
|
||||
else
|
||||
throw new Error("Unrecognized type for array value: #{value}")
|
||||
cson += '\n'
|
||||
"#{cson}#{@stringifyIndent(indentLevel)}]"
|
||||
|
||||
stringifyObject: (object, indentLevel=0) ->
|
||||
cson = ''
|
||||
prefix = ''
|
||||
for key, value of object
|
||||
continue if value is undefined
|
||||
if _.isFunction(value)
|
||||
throw new Error("Function specified as value to key: #{key}")
|
||||
|
||||
cson += "#{prefix}#{@stringifyIndent(indentLevel)}'#{key}':"
|
||||
if _.isString(value)
|
||||
cson += " #{@stringifyString(value)}"
|
||||
else if _.isBoolean(value)
|
||||
cson += " #{@stringifyBoolean(value)}"
|
||||
else if _.isNumber(value)
|
||||
cson += " #{@stringifyNumber(value)}"
|
||||
else if _.isNull(value)
|
||||
cson += " #{@stringifyNull(value)}"
|
||||
else if _.isArray(value)
|
||||
cson += " #{@stringifyArray(value, indentLevel)}"
|
||||
else if _.isObject(value)
|
||||
cson += "\n#{@stringifyObject(value, indentLevel + 2)}"
|
||||
else
|
||||
throw new Error("Unrecognized value type for key: #{key} with value: #{value}")
|
||||
prefix = '\n'
|
||||
cson
|
||||
|
||||
stringify: (object) ->
|
||||
throw new Error("Cannot stringify undefined object") if object is undefined
|
||||
throw new Error("Cannot stringify function: #{object}") if _.isFunction(object)
|
||||
|
||||
return @stringifyString(object) if _.isString(object)
|
||||
return @stringifyBoolean(object) if _.isBoolean(object)
|
||||
return @stringifyNumber(object) if _.isNumber(object)
|
||||
return @stringifyNull(object) if _.isNull(object)
|
||||
return @stringifyArray(object) if _.isArray(object)
|
||||
return @stringifyObject(object) if _.isObject(object)
|
||||
|
||||
throw new Error("Unrecognized type to stringify: #{object}")
|
||||
@@ -59,11 +59,16 @@ module.exports =
|
||||
|
||||
# Returns an array with all the names of files contained
|
||||
# in the directory path.
|
||||
list: (rootPath) ->
|
||||
list: (rootPath, extensions) ->
|
||||
paths = []
|
||||
onPath = (path) =>
|
||||
paths.push(@join(rootPath, path))
|
||||
false
|
||||
if extensions
|
||||
onPath = (path) =>
|
||||
paths.push(@join(rootPath, path)) if _.contains(extensions, @extension(path))
|
||||
false
|
||||
else
|
||||
onPath = (path) =>
|
||||
paths.push(@join(rootPath, path))
|
||||
false
|
||||
@traverseTree(rootPath, onPath, onPath)
|
||||
paths
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ $.fn.pageUp = ->
|
||||
$.fn.pageDown = ->
|
||||
@scrollTop(@scrollTop() + @height())
|
||||
|
||||
$.fn.isOnDom = ->
|
||||
@closest(document.body).length is 1
|
||||
|
||||
$.fn.containsElement = (element) ->
|
||||
(element[0].compareDocumentPosition(this[0]) & 8) == 8
|
||||
|
||||
|
||||
@@ -56,7 +56,6 @@
|
||||
overflow-x: hidden;
|
||||
}
|
||||
|
||||
|
||||
.editor .underlayer, .editor .lines, .editor .overlayer {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
@@ -83,11 +82,11 @@
|
||||
|
||||
.editor .cursor {
|
||||
position: absolute;
|
||||
border-left: 2px solid;
|
||||
border-left: 1px solid;
|
||||
}
|
||||
|
||||
.editor:not(.focused) .cursor,
|
||||
.editor.focused .cursor.blink-off {
|
||||
.editor:not(.is-focused) .cursor,
|
||||
.editor.is-focused .cursor.blink-off {
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,170 +1,80 @@
|
||||
.jasmine_reporter {
|
||||
font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif;
|
||||
font-size: 16px;
|
||||
}
|
||||
body { background-color: #eeeeee; padding: 0; overflow-y: scroll; }
|
||||
|
||||
body {
|
||||
background: #eee;
|
||||
}
|
||||
#HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
|
||||
#HTMLReporter a { text-decoration: none; }
|
||||
#HTMLReporter a:hover { text-decoration: underline; }
|
||||
#HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
|
||||
#HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
|
||||
#HTMLReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#HTMLReporter .version { color: #aaaaaa; }
|
||||
#HTMLReporter .banner { margin-top: 14px; }
|
||||
#HTMLReporter .duration { color: #aaaaaa; float: right; }
|
||||
#HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
|
||||
#HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
|
||||
#HTMLReporter .symbolSummary li.passed { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.failed { line-height: 9px; }
|
||||
#HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
|
||||
#HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
|
||||
#HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
|
||||
#HTMLReporter .symbolSummary li.pending { line-height: 11px; }
|
||||
#HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
|
||||
#HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
|
||||
#HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
|
||||
#HTMLReporter .runningAlert { background-color: #666666; }
|
||||
#HTMLReporter .skippedAlert { background-color: #aaaaaa; }
|
||||
#HTMLReporter .skippedAlert:first-child { background-color: #333333; }
|
||||
#HTMLReporter .passingAlert { background-color: #a6b779; }
|
||||
#HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
|
||||
#HTMLReporter .failingAlert { background-color: #cf867e; }
|
||||
#HTMLReporter .failingAlert:first-child { background-color: #b03911; }
|
||||
#HTMLReporter .results { margin-top: 5px }
|
||||
#HTMLReporter #details { display: none; }
|
||||
#HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
|
||||
#HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
|
||||
#HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; }
|
||||
#HTMLReporter.showDetails .summary { display: none; }
|
||||
#HTMLReporter.showDetails #details { display: block; }
|
||||
#HTMLReporter .summaryMenuItem { font-weight: bold; }
|
||||
#HTMLReporter .summary { margin-top: 14px; }
|
||||
#HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
|
||||
#HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
|
||||
#HTMLReporter .summary .specSummary.failed a { color: #b03911; }
|
||||
#HTMLReporter .description + .suite { margin-top: 0; }
|
||||
#HTMLReporter .suite { margin-top: 14px; }
|
||||
#HTMLReporter .suite a { color: #333333; }
|
||||
#HTMLReporter #details .specDetail { margin-bottom: 28px; }
|
||||
#HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; font-size: 14px; padding: 3px 9px }
|
||||
#HTMLReporter .resultMessage { padding-top: 5px; color: #333333; }
|
||||
#HTMLReporter .resultMessage span.result { display: block; }
|
||||
#HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 500px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
|
||||
|
||||
.jasmine_reporter a:visited, .jasmine_reporter a {
|
||||
color: #303;
|
||||
}
|
||||
|
||||
.jasmine_reporter a:hover, .jasmine_reporter a:active {
|
||||
color: blue;
|
||||
}
|
||||
|
||||
.run_spec {
|
||||
float:right;
|
||||
padding-right: 5px;
|
||||
font-size: .8em;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.jasmine_reporter {
|
||||
margin: 0 5px;
|
||||
}
|
||||
|
||||
.banner {
|
||||
color: #303;
|
||||
background-color: #fef;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.logo {
|
||||
float: left;
|
||||
font-size: 1.1em;
|
||||
padding-left: 5px;
|
||||
}
|
||||
|
||||
.logo .version {
|
||||
font-size: .6em;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.runner.running {
|
||||
background-color: yellow;
|
||||
}
|
||||
|
||||
|
||||
.options {
|
||||
text-align: right;
|
||||
font-size: .8em;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.suite {
|
||||
border: 1px outset gray;
|
||||
margin: 5px 0;
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
.suite .suite {
|
||||
margin: 5px;
|
||||
}
|
||||
|
||||
.suite.passed {
|
||||
background-color: #dfd;
|
||||
}
|
||||
|
||||
.suite.failed {
|
||||
background-color: #fdd;
|
||||
}
|
||||
|
||||
.spec {
|
||||
margin: 5px;
|
||||
padding-left: 1em;
|
||||
clear: both;
|
||||
}
|
||||
|
||||
.spec.failed, .spec.passed, .spec.skipped {
|
||||
padding-bottom: 5px;
|
||||
border: 1px solid gray;
|
||||
}
|
||||
|
||||
.spec.failed {
|
||||
background-color: #fbb;
|
||||
border-color: red;
|
||||
}
|
||||
|
||||
.spec.passed {
|
||||
background-color: #bfb;
|
||||
border-color: green;
|
||||
}
|
||||
|
||||
.spec.skipped {
|
||||
background-color: #bbb;
|
||||
}
|
||||
|
||||
.messages {
|
||||
border-left: 1px dashed gray;
|
||||
padding-left: 1em;
|
||||
padding-right: 1em;
|
||||
}
|
||||
|
||||
.passed {
|
||||
background-color: #cfc;
|
||||
display: none;
|
||||
}
|
||||
|
||||
.failed {
|
||||
background-color: #fbb;
|
||||
}
|
||||
|
||||
.skipped {
|
||||
color: #777;
|
||||
background-color: #eee;
|
||||
display: none;
|
||||
}
|
||||
|
||||
|
||||
/*.resultMessage {*/
|
||||
/*white-space: pre;*/
|
||||
/*}*/
|
||||
|
||||
.resultMessage span.result {
|
||||
display: block;
|
||||
line-height: 2em;
|
||||
color: black;
|
||||
}
|
||||
|
||||
.resultMessage .mismatch {
|
||||
color: black;
|
||||
}
|
||||
|
||||
.stackTrace {
|
||||
white-space: pre;
|
||||
font-size: .8em;
|
||||
margin-left: 10px;
|
||||
max-height: 5em;
|
||||
overflow: auto;
|
||||
border: 1px inset red;
|
||||
padding: 1em;
|
||||
background: #eef;
|
||||
}
|
||||
|
||||
.finished-at {
|
||||
padding-left: 1em;
|
||||
font-size: .6em;
|
||||
}
|
||||
|
||||
.show-passed .passed,
|
||||
.show-skipped .skipped {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
||||
#jasmine_content {
|
||||
position:fixed;
|
||||
right: 100%;
|
||||
}
|
||||
|
||||
.runner {
|
||||
border: 1px solid gray;
|
||||
display: block;
|
||||
margin: 5px 0;
|
||||
padding: 2px 0 2px 10px;
|
||||
}
|
||||
#TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
|
||||
#TrivialReporter a:visited, #TrivialReporter a { color: #303; }
|
||||
#TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
|
||||
#TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
|
||||
#TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
|
||||
#TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
|
||||
#TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
|
||||
#TrivialReporter .runner.running { background-color: yellow; }
|
||||
#TrivialReporter .options { text-align: right; font-size: .8em; }
|
||||
#TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
|
||||
#TrivialReporter .suite .suite { margin: 5px; }
|
||||
#TrivialReporter .suite.passed { background-color: #dfd; }
|
||||
#TrivialReporter .suite.failed { background-color: #fdd; }
|
||||
#TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
|
||||
#TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
|
||||
#TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
|
||||
#TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
|
||||
#TrivialReporter .spec.skipped { background-color: #bbb; }
|
||||
#TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
|
||||
#TrivialReporter .passed { background-color: #cfc; display: none; }
|
||||
#TrivialReporter .failed { background-color: #fbb; }
|
||||
#TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
|
||||
#TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
|
||||
#TrivialReporter .resultMessage .mismatch { color: black; }
|
||||
#TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
|
||||
#TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
|
||||
#TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
|
||||
#TrivialReporter #jasmine_content { position: fixed; right: 100%; }
|
||||
#TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
.wrap-guide {
|
||||
background: rgba(150, 150, 150, .30);
|
||||
}
|
||||
@@ -1,3 +0,0 @@
|
||||
.wrap-guide {
|
||||
background: rgba(150, 150, 150, .30);
|
||||
}
|
||||
269
themes/atom-dark-syntax.css
Normal file
269
themes/atom-dark-syntax.css
Normal file
@@ -0,0 +1,269 @@
|
||||
.editor, .editor .gutter {
|
||||
background-color: #1d1f21;
|
||||
color: #c5c8c6;
|
||||
}
|
||||
|
||||
.editor.is-focused .cursor {
|
||||
border-color: #FFFFFF;
|
||||
}
|
||||
|
||||
.editor.is-focused .selection .region {
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
.editor.is-focused .line-number.cursor-line-no-selection, .editor.is-focused .line.cursor-line {
|
||||
background-color: rgba(255, 255, 255, 0.14);
|
||||
}
|
||||
|
||||
.comment {
|
||||
color: #7C7C7C;
|
||||
}
|
||||
|
||||
.entity {
|
||||
color: #FFD2A7;
|
||||
}
|
||||
|
||||
.keyword {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.keyword.control {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.keyword.operator {
|
||||
color: #EDEDED;
|
||||
}
|
||||
|
||||
.entity.name.type {
|
||||
text-decoration: underline;
|
||||
color: #FFFFB6;
|
||||
}
|
||||
|
||||
.support {
|
||||
color: #FFFFB6;
|
||||
}
|
||||
|
||||
.storage {
|
||||
color: #CFCB90;
|
||||
}
|
||||
|
||||
.storage.modifier {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.constant {
|
||||
color: #99CC99;
|
||||
}
|
||||
|
||||
.string {
|
||||
color: #A8FF60;
|
||||
}
|
||||
|
||||
.constant.numeric {
|
||||
color: #FF73FD;
|
||||
}
|
||||
|
||||
.punctuation {
|
||||
}
|
||||
|
||||
.variable {
|
||||
color: #C6C5FE;
|
||||
}
|
||||
|
||||
.invalid.deprecated {
|
||||
text-decoration: underline;
|
||||
color: #FD5FF1;
|
||||
}
|
||||
|
||||
.invalid.illegal {
|
||||
color: #FD5FF1;
|
||||
background-color: rgba(86, 45, 86, 0.75);
|
||||
}
|
||||
|
||||
.text .source {
|
||||
background-color: rgba(177, 179, 186, 0.03);
|
||||
}
|
||||
|
||||
.entity.other.inherited-class {
|
||||
color: #9B5C2E;
|
||||
}
|
||||
|
||||
.source .string .source {
|
||||
color: #EDEDED;
|
||||
}
|
||||
|
||||
.source .string .source .punctuation.section.embedded {
|
||||
color: #00A0A0;
|
||||
}
|
||||
|
||||
.string .constant {
|
||||
color: #00A0A0;
|
||||
}
|
||||
|
||||
.string.regexp {
|
||||
color: #E9C062;
|
||||
}
|
||||
|
||||
.string.regexp .constant.character.escape, .string.regexp .source.ruby.embedded, .string.regexp .string.regexp.arbitrary-repitition {
|
||||
color: #FF8000;
|
||||
}
|
||||
|
||||
.string.regexp.group {
|
||||
color: #C6A24F;
|
||||
background-color: rgba(255, 255, 255, 0.06);
|
||||
}
|
||||
|
||||
.string.regexp.character-class {
|
||||
color: #B18A3D;
|
||||
}
|
||||
|
||||
.string .variable {
|
||||
color: #8A9A95;
|
||||
}
|
||||
|
||||
.support.function {
|
||||
color: #DAD085;
|
||||
}
|
||||
|
||||
.support.constant {
|
||||
color: #FFD2A7;
|
||||
}
|
||||
|
||||
.meta.preprocessor.c {
|
||||
color: #8996A8;
|
||||
}
|
||||
|
||||
.meta.preprocessor.c .keyword {
|
||||
color: #AFC4DB;
|
||||
}
|
||||
|
||||
.meta.cast {
|
||||
color: #676767;
|
||||
}
|
||||
|
||||
.meta.sgml.html .meta.doctype, .meta.sgml.html .meta.doctype .entity, .meta.sgml.html .meta.doctype .string, .meta.xml-processing, .meta.xml-processing .entity, .meta.xml-processing .string {
|
||||
color: #494949;
|
||||
}
|
||||
|
||||
.meta.tag, .meta.tag .entity {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.source .entity.name.tag, .source .entity.other.attribute-name, .meta.tag.inline, .meta.tag.inline .entity {
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.entity.other.attribute-name {
|
||||
color: #FFD7B1;
|
||||
}
|
||||
|
||||
.entity.name.tag.namespace, .entity.other.attribute-name.namespace {
|
||||
color: #E18964;
|
||||
}
|
||||
|
||||
.meta.selector.css .entity.name.tag {
|
||||
text-decoration: underline;
|
||||
color: #96CBFE;
|
||||
}
|
||||
|
||||
.meta.selector.css .entity.other.attribute-name.tag.pseudo-class {
|
||||
color: #8F9D6A;
|
||||
}
|
||||
|
||||
.meta.selector.css .entity.other.attribute-name.id {
|
||||
color: #8B98AB;
|
||||
}
|
||||
|
||||
.meta.selector.css .entity.other.attribute-name.class {
|
||||
color: #62B1FE;
|
||||
}
|
||||
|
||||
.support.type.property-name.css {
|
||||
color: #EDEDED;
|
||||
}
|
||||
|
||||
.meta.property-group .support.constant.property-value.css, .meta.property-value .support.constant.property-value.css {
|
||||
color: #F9EE98;
|
||||
}
|
||||
|
||||
.meta.preprocessor.at-rule .keyword.control.at-rule {
|
||||
color: #8693A5;
|
||||
}
|
||||
|
||||
.meta.property-value .support.constant.named-color.css, .meta.property-value .constant {
|
||||
color: #87C38A;
|
||||
}
|
||||
|
||||
.meta.constructor.argument.css {
|
||||
color: #8F9D6A;
|
||||
}
|
||||
|
||||
.meta.diff, .meta.diff.header {
|
||||
color: #F8F8F8;
|
||||
background-color: #0E2231;
|
||||
}
|
||||
|
||||
.markup.deleted {
|
||||
color: #F8F8F8;
|
||||
background-color: #420E09;
|
||||
}
|
||||
|
||||
.markup.changed {
|
||||
color: #F8F8F8;
|
||||
background-color: #4A410D;
|
||||
}
|
||||
|
||||
.markup.inserted {
|
||||
color: #F8F8F8;
|
||||
background-color: #253B22;
|
||||
}
|
||||
|
||||
.markup.italic {
|
||||
color: #E9C062;
|
||||
}
|
||||
|
||||
.markup.bold {
|
||||
color: #E9C062;
|
||||
}
|
||||
|
||||
.markup.underline {
|
||||
text-decoration: underline;
|
||||
color: #E18964;
|
||||
}
|
||||
|
||||
.markup.quote {
|
||||
color: #E1D4B9;
|
||||
background-color: rgba(254, 224, 156, 0.07);
|
||||
}
|
||||
|
||||
.markup.heading, .markup.heading .entity {
|
||||
color: #FEDCC5;
|
||||
background-color: #632D04;
|
||||
}
|
||||
|
||||
.markup.list {
|
||||
color: #E1D4B9;
|
||||
}
|
||||
|
||||
.markup.raw {
|
||||
color: #578BB3;
|
||||
background-color: rgba(177, 179, 186, 0.03);
|
||||
}
|
||||
|
||||
.markup .comment {
|
||||
color: #F67B37;
|
||||
}
|
||||
|
||||
.meta.separator {
|
||||
color: #60A633;
|
||||
background-color: #242424;
|
||||
}
|
||||
|
||||
.meta.line.entry.logfile, .meta.line.exit.logfile {
|
||||
background-color: rgba(238, 238, 238, 0.16);
|
||||
}
|
||||
|
||||
.meta.line.error.logfile {
|
||||
background-color: #751012;
|
||||
}
|
||||
@@ -4,23 +4,16 @@ html, body,
|
||||
background-color: #333333;
|
||||
}
|
||||
|
||||
#root-view #panes:before {
|
||||
display: block;
|
||||
content: "\f208";
|
||||
font-family: 'Octicons Regular';
|
||||
color: #303030;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
font-size: 100vmin;
|
||||
line-height: 100vmin;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#root-view #panes .row > * + * {
|
||||
border-left: 5px solid #515151;
|
||||
-webkit-box-shadow:
|
||||
-2px 0 rgba(0, 0, 0, 0.3),
|
||||
-1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
#root-view #panes .column > * + * {
|
||||
border-top: 5px solid #515151;
|
||||
-webkit-box-shadow:
|
||||
0 -2px rgba(0, 0, 0, 0.3),
|
||||
0 -1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.error {
|
||||
@@ -1,18 +1,21 @@
|
||||
.command-panel {
|
||||
background-color: #303030;
|
||||
border: 1px solid #252525;
|
||||
color: #ededed;
|
||||
color: #dedede;
|
||||
padding: 5px;
|
||||
}
|
||||
|
||||
.command-panel .preview-list {
|
||||
max-height: 300px;
|
||||
overflow: auto;
|
||||
margin-bottom: 3px;
|
||||
margin: 0 1px 5px 10px;
|
||||
position: relative;
|
||||
background-color: #000000;
|
||||
color: #ededed;
|
||||
background-color: #1e1e1e;
|
||||
color: #C5C8C6;
|
||||
cursor: default;
|
||||
border: 1px solid rgba(0, 0, 0, 0.5);
|
||||
border-bottom: 1px solid rgba(180, 180, 180, 0.2);
|
||||
border-right: 1px solid rgba(180, 180, 180, 0.2);
|
||||
}
|
||||
|
||||
.command-panel .preview-count {
|
||||
@@ -32,7 +35,7 @@
|
||||
|
||||
.command-panel .preview-list .path {
|
||||
padding-left: 5px;
|
||||
color: #00a693;
|
||||
color: #fff;
|
||||
}
|
||||
|
||||
.command-panel .preview-list .path:before {
|
||||
@@ -73,6 +76,7 @@
|
||||
background-color: rgba(255, 255, 255, .2);
|
||||
-webkit-border-radius: 2px;
|
||||
padding: 1px;
|
||||
color: yellow;
|
||||
}
|
||||
|
||||
.command-panel .prompt-and-editor {
|
||||
@@ -1,5 +1,6 @@
|
||||
.editor {
|
||||
font-family: Inconsolata, Monaco, Courier;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.editor.mini {
|
||||
@@ -17,7 +18,7 @@
|
||||
}
|
||||
|
||||
.editor .gutter .line-number {
|
||||
padding-right: 1.3em;
|
||||
padding-right: .5em;
|
||||
min-width: 35px;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
@@ -52,16 +53,28 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor .fold-marker:before {
|
||||
content: '\f060';
|
||||
-webkit-transform: rotate(90deg);
|
||||
.editor .gutter .line-number:after {
|
||||
font-size: 0.8em;
|
||||
content: '\f078';
|
||||
font-family: 'Octicons Regular';
|
||||
display: inline-block;
|
||||
margin-left: .3em;
|
||||
margin-top: .1em;
|
||||
line-height: .8em;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
color: #fba0e3;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.editor .gutter .line-number.fold:after {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.editor .fold-marker:after {
|
||||
content: '\2026';
|
||||
opacity: .8;
|
||||
color: #fba0e3;
|
||||
padding-left: .2em;
|
||||
}
|
||||
|
||||
.editor .line.cursor-line .fold-marker {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor .invisible {
|
||||
@@ -2,10 +2,11 @@
|
||||
background: #333333;
|
||||
border-bottom: 4px solid #424242;
|
||||
font: caption;
|
||||
box-shadow: inset 0 -1px 0 #2e2e2e;
|
||||
box-shadow: inset 0 -1px 0 #2e2e2e, 0 1px 0 #191919;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.tab {
|
||||
.is-focused .tab {
|
||||
cursor: default;
|
||||
padding: 2px 21px 2px 9px;
|
||||
background-image: -webkit-linear-gradient(#444, #3d3d3d);
|
||||
@@ -15,6 +16,42 @@
|
||||
box-shadow: inset 0 0 5px #383838, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a, inset 1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.is-focused .tab:first-child {
|
||||
box-shadow: inset 0 0 5px #383838, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.is-focused .tab.active,
|
||||
.is-focused .tab.active:hover {
|
||||
border-top: 1px solid #4a4a4a;
|
||||
box-shadow: inset -1px 0 0 #595959, inset 1px 0 0 #595959;
|
||||
border-bottom-color: #424242;
|
||||
background-image: -webkit-linear-gradient(#555555, #424242);
|
||||
}
|
||||
|
||||
.tab {
|
||||
cursor: default;
|
||||
padding: 2px 21px 2px 9px;
|
||||
background-color: #555;
|
||||
background-image: none;
|
||||
border-top: 1px solid #383838;
|
||||
border-right: 1px solid #2e2e2e;
|
||||
border-bottom: 1px solid #2e2e2e;
|
||||
box-shadow: inset 0 0 5px #555, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a, inset 1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.tab:first-child {
|
||||
box-shadow: inset 0 0 5px #555, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.tab.active,
|
||||
.tab.active:hover {
|
||||
border-top: 1px solid #4a4a4a;
|
||||
box-shadow: inset -1px 0 0 #595959, inset 1px 0 0 #595959;
|
||||
border-bottom-color: #424242;
|
||||
background-image: none;
|
||||
background-color: #424242;
|
||||
}
|
||||
|
||||
.tab,
|
||||
.tab .close-icon {
|
||||
color: #aaa;
|
||||
@@ -24,9 +61,9 @@
|
||||
border-color: #aaa;
|
||||
}
|
||||
|
||||
.tab.active,
|
||||
.tab.active:hover,
|
||||
.tab.active .close-icon {
|
||||
.is-focused .tab.active,
|
||||
.is-focused .tab.active:hover,
|
||||
.is-focused .tab.active .close-icon {
|
||||
color: #e6e6e6;
|
||||
}
|
||||
|
||||
@@ -48,23 +85,11 @@
|
||||
content: "";
|
||||
}
|
||||
|
||||
.tab:first-child {
|
||||
box-shadow: inset 0 0 5px #383838, 0 1px 0 #585858, inset -1px 0 0 #4a4a4a;
|
||||
}
|
||||
|
||||
.tab.active:first-child,
|
||||
.tab.active:first-child:hover {
|
||||
.is-focused .tab.active:first-child,
|
||||
.is-focused .tab.active:first-child:hover {
|
||||
box-shadow: inset -1px 0 0 #595959;
|
||||
}
|
||||
|
||||
.tab.active,
|
||||
.tab.active:hover {
|
||||
border-top: 1px solid #4a4a4a;
|
||||
box-shadow: inset -1px 0 0 #595959, inset 1px 0 0 #595959;
|
||||
border-bottom-color: #424242;
|
||||
background-image: -webkit-linear-gradient(#555555, #424242);
|
||||
}
|
||||
|
||||
.tab.active:before,
|
||||
.tab.active:after {
|
||||
position: absolute;
|
||||
@@ -75,6 +100,19 @@
|
||||
z-index: 3;
|
||||
border: 1px solid #595959;
|
||||
}
|
||||
|
||||
.is-focused .tab.active:before {
|
||||
border-bottom-right-radius: 4px;
|
||||
border-width: 0 1px 1px 0;
|
||||
box-shadow: 2px 2px 0 #424242;
|
||||
left: -4px;
|
||||
}
|
||||
.is-focused .tab.active:after {
|
||||
right: -4px;
|
||||
border-bottom-left-radius: 4px;
|
||||
border-width: 0 0 1px 1px;
|
||||
box-shadow: -2px 2px 0 #424242;
|
||||
}
|
||||
.tab.active:before {
|
||||
border-bottom-right-radius: 4px;
|
||||
border-width: 0 1px 1px 0;
|
||||
@@ -87,7 +125,7 @@
|
||||
border-width: 0 0 1px 1px;
|
||||
box-shadow: -2px 2px 0 #424242;
|
||||
}
|
||||
.tab.active:first-child:before {
|
||||
.is-focused .tab.active:first-child:before {
|
||||
display: none;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
.tree-view {
|
||||
.is-focused .tree-view {
|
||||
background: #1e1e1e;
|
||||
border-right: 2px solid #191919;
|
||||
border-right: 1px solid #191919;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
background: #2e2e2e;
|
||||
border-right: 1px solid #191919;
|
||||
}
|
||||
|
||||
.tree-view .entry {
|
||||
@@ -20,10 +25,15 @@
|
||||
color: #d2d2d2;
|
||||
}
|
||||
|
||||
.tree-view .selected > .highlight {
|
||||
.is-focused .tree-view .selected > .highlight {
|
||||
background-image: -webkit-linear-gradient(#4e4e4e, #434343);
|
||||
}
|
||||
|
||||
.tree-view .selected > .highlight {
|
||||
background-image: none;
|
||||
background-color: #6e6e6e;
|
||||
}
|
||||
|
||||
.tree-view:focus .selected > .highlight {
|
||||
background-image: -webkit-linear-gradient(#7e7e7e, #737373);
|
||||
}
|
||||
3
themes/atom-dark-ui/wrap-guide.css
Normal file
3
themes/atom-dark-ui/wrap-guide.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.wrap-guide {
|
||||
background: rgba(150, 150, 150, 0.1);
|
||||
}
|
||||
168
themes/atom-light-syntax.css
Normal file
168
themes/atom-light-syntax.css
Normal file
@@ -0,0 +1,168 @@
|
||||
.editor, .editor .gutter {
|
||||
background-color: #FFFFFF;
|
||||
color: #555;
|
||||
}
|
||||
|
||||
.editor.is-focused .cursor {
|
||||
border-color: #000;
|
||||
}
|
||||
|
||||
.editor.is-focused .selection .region {
|
||||
background-color: #afc4da;
|
||||
}
|
||||
|
||||
.editor.is-focused .line-number.cursor-line-no-selection, .editor.is-focused .line.cursor-line {
|
||||
background-color: rgba(255, 255, 134, 0.34);
|
||||
}
|
||||
|
||||
.editor .comment {
|
||||
color: #999988;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
.editor .string {
|
||||
color: #D14;
|
||||
}
|
||||
|
||||
.editor .constant.numeric {
|
||||
color: #D14;
|
||||
}
|
||||
|
||||
.editor .constant.language {
|
||||
color: #606aa1;
|
||||
}
|
||||
|
||||
.editor .constant.character, .editor .constant.other {
|
||||
color: #606aa1;
|
||||
}
|
||||
|
||||
.editor .constant.symbol {
|
||||
color: #990073;
|
||||
}
|
||||
|
||||
.editor .variable {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
/* Keywords */
|
||||
.editor .keyword {
|
||||
color: #222;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editor .keyword.unit {
|
||||
color: #445588;
|
||||
}
|
||||
|
||||
.editor .keyword.special-method {
|
||||
color: #0086B3;
|
||||
}
|
||||
|
||||
.editor .storage {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.editor .storage.type {
|
||||
color: #222;
|
||||
}
|
||||
|
||||
.editor .entity.name.class {
|
||||
text-decoration: underline;
|
||||
color: #606aa1;
|
||||
}
|
||||
|
||||
.editor .entity.other.inherited-class {
|
||||
text-decoration: underline;
|
||||
color: #606aa1;
|
||||
}
|
||||
|
||||
.editor .entity.name.function {
|
||||
color: #900;
|
||||
}
|
||||
|
||||
.editor .variable.parameter {
|
||||
color: #606aa1;
|
||||
}
|
||||
|
||||
.editor .entity.name.tag {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.editor .entity.other.attribute-name {
|
||||
color: #458;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editor .support.function {
|
||||
color: #458;
|
||||
}
|
||||
|
||||
.editor .support.constant {
|
||||
color: #458;
|
||||
}
|
||||
|
||||
.editor .support.type {
|
||||
color: #458;
|
||||
}
|
||||
|
||||
.editor .support.class {
|
||||
color: #008080;
|
||||
}
|
||||
|
||||
.editor .invalid {
|
||||
color: #F8F8F0;
|
||||
background-color: #00A8C6;
|
||||
}
|
||||
|
||||
.editor .invalid.deprecated {
|
||||
color: #F8F8F0;
|
||||
background-color: #8FBE00;
|
||||
}
|
||||
|
||||
.editor .meta.structure.dictionary.json > .string.quoted.double.json,
|
||||
.editor .meta.structure.dictionary.json > .string.quoted.double.json .punctuation.string {
|
||||
color: #000080;
|
||||
}
|
||||
|
||||
.editor .meta.structure.dictionary.value.json > .string.quoted.double.json {
|
||||
color: #d14;
|
||||
}
|
||||
|
||||
.editor .meta.diff, .editor .meta.diff.header {
|
||||
color: #75715E;
|
||||
}
|
||||
|
||||
.editor .meta.function span {
|
||||
color: #990000;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.editor .markup.deleted {
|
||||
color: #00A8C6;
|
||||
}
|
||||
|
||||
.editor .markup.inserted {
|
||||
color: #A6E22E;
|
||||
}
|
||||
|
||||
.editor .markup.changed {
|
||||
color: #E6DB74;
|
||||
}
|
||||
|
||||
.editor .constant.numeric.line-number.find-in-files .- .match {
|
||||
color: rgba(143, 190, 0, 0.63);
|
||||
}
|
||||
|
||||
.editor .entity.name.filename.find-in-files {
|
||||
color: #E6DB74;
|
||||
}
|
||||
|
||||
/* CSS Styles */
|
||||
.editor .css.support.property-name {
|
||||
font-weight: bold;
|
||||
color: #333;
|
||||
}
|
||||
|
||||
.editor .css.constant {
|
||||
color: #099;
|
||||
}
|
||||
@@ -5,11 +5,15 @@ html, body,
|
||||
}
|
||||
|
||||
#root-view #panes .row > * + * {
|
||||
border-left: 1px solid #989898;
|
||||
-webkit-box-shadow:
|
||||
-2px 0 rgba(0, 0, 0, 0.3),
|
||||
-1px 0 rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
#root-view #panes .column > * + * {
|
||||
border-top: 1px solid #989898;
|
||||
-webkit-box-shadow:
|
||||
0 -2px rgba(0, 0, 0, 0.3),
|
||||
0 -1px rgba(255, 255, 255, 0.2);
|
||||
}
|
||||
|
||||
.error {
|
||||
@@ -1,5 +1,6 @@
|
||||
.editor {
|
||||
font-family: Inconsolata, Monaco, Courier;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.editor.mini {
|
||||
@@ -20,7 +21,7 @@
|
||||
}
|
||||
|
||||
.editor .gutter .line-number {
|
||||
padding-right: 1.3em;
|
||||
padding-right: .5em;
|
||||
min-width: 35px;
|
||||
box-sizing: border-box;
|
||||
text-align: right;
|
||||
@@ -55,16 +56,28 @@
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor .fold-marker:before {
|
||||
content: '\f060';
|
||||
-webkit-transform: rotate(90deg);
|
||||
.editor .gutter .line-number:after {
|
||||
font-size: 0.8em;
|
||||
content: '\f078';
|
||||
font-family: 'Octicons Regular';
|
||||
display: inline-block;
|
||||
margin-left: .3em;
|
||||
margin-top: .1em;
|
||||
line-height: .8em;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
color: #fba0e3;
|
||||
visibility: hidden;
|
||||
}
|
||||
|
||||
.editor .gutter .line-number.fold:after {
|
||||
visibility: visible;
|
||||
}
|
||||
|
||||
.editor .fold-marker:after {
|
||||
content: '\2026';
|
||||
opacity: .8;
|
||||
color: #fba0e3;
|
||||
padding-left: .2em;
|
||||
}
|
||||
|
||||
.editor .line.cursor-line .fold-marker {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
.editor .invisible {
|
||||
@@ -2,13 +2,26 @@
|
||||
background: #e3e3e3;
|
||||
border-bottom: 4px solid #e5e5e5;
|
||||
font: caption;
|
||||
box-shadow: inset 0 -1px 0 #959595;
|
||||
box-shadow: inset 0 -1px 0 #959595, 0 1px 0 #989898;
|
||||
margin-bottom: 1px;
|
||||
}
|
||||
|
||||
.is-focused .tab {
|
||||
cursor: default;
|
||||
padding: 2px 21px 2px 9px;
|
||||
background-image: -webkit-linear-gradient(#e0e0e0, #bfbfbf);
|
||||
border-top: none;
|
||||
border-right: 1px solid #959595;
|
||||
border-bottom: 1px solid #959595;
|
||||
box-shadow: inset 0 0 5px #eee, 0 1px 0 #eee, inset -1px 0 0 #e0e0e0, inset 1px 0 0 #e0e0e0;
|
||||
color: #323232;
|
||||
}
|
||||
|
||||
.tab {
|
||||
cursor: default;
|
||||
padding: 2px 21px 2px 9px;
|
||||
background-image: -webkit-linear-gradient(#e0e0e0, #bfbfbf);
|
||||
background-image: none;
|
||||
background-color: #e0e0e0);
|
||||
border-top: none;
|
||||
border-right: 1px solid #959595;
|
||||
border-bottom: 1px solid #959595;
|
||||
@@ -1,8 +1,13 @@
|
||||
.tree-view {
|
||||
.is-focused .tree-view {
|
||||
background: #dde3e8;
|
||||
border-right: 1px solid #989898;
|
||||
}
|
||||
|
||||
.tree-view {
|
||||
background: #f3f3f3;
|
||||
border-right: 1px solid #c5c5c5;
|
||||
}
|
||||
|
||||
.tree-view .entry {
|
||||
text-shadow: 0 1px 0 #fff;
|
||||
}
|
||||
@@ -20,7 +25,7 @@
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.tree-view .selected > .highlight {
|
||||
.is-focused .tree-view .selected > .highlight {
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid #97a4a7;
|
||||
border-bottom: 1px solid #97a4a7;
|
||||
@@ -28,12 +33,27 @@
|
||||
background-image: -webkit-linear-gradient(#cad5d8, #bcccce);
|
||||
}
|
||||
|
||||
.tree-view:focus .selected > .highlight {
|
||||
.tree-view .selected > .highlight {
|
||||
box-sizing: border-box;
|
||||
border-top: 1px solid #97a4a7;
|
||||
border-bottom: 1px solid #97a4a7;
|
||||
background-image: none;
|
||||
background-color: #DFDFDF;
|
||||
}
|
||||
|
||||
.is-focused .tree-view:focus .selected > .highlight {
|
||||
border-top: 1px solid #3D4552;
|
||||
border-bottom: 1px solid #3D4552;
|
||||
background-image: -webkit-linear-gradient(#7e868d, #69717b);
|
||||
}
|
||||
|
||||
.tree-view:focus .selected > .highlight {
|
||||
border-top: 1px solid #3D4552;
|
||||
border-bottom: 1px solid #3D4552;
|
||||
background-image: none;
|
||||
background-color: #69717b;
|
||||
}
|
||||
|
||||
.tree-view:focus .directory.selected > .header > .name,
|
||||
.tree-view:focus .selected > .name,
|
||||
.tree-view:focus .directory.selected > .header > .name:before,
|
||||
@@ -50,10 +70,14 @@
|
||||
color: #262626;
|
||||
}
|
||||
|
||||
.tree-view .name:before {
|
||||
.is-focused .tree-view .name:before {
|
||||
color: #7e8692;
|
||||
}
|
||||
|
||||
.tree-view .name:before {
|
||||
color: #7e7e7e;
|
||||
}
|
||||
|
||||
.tree-view .entry:hover,
|
||||
.tree-view .directory .header:hover .name,
|
||||
.tree-view .directory .header:hover .disclosure-arrow {
|
||||
3
themes/atom-light-ui/wrap-guide.css
Normal file
3
themes/atom-light-ui/wrap-guide.css
Normal file
@@ -0,0 +1,3 @@
|
||||
.wrap-guide {
|
||||
background: rgba(150, 150, 150, 0.3);
|
||||
}
|
||||
491
vendor/jasmine-atom-reporter.js
vendored
491
vendor/jasmine-atom-reporter.js
vendored
@@ -1,10 +1,6 @@
|
||||
jasmine.AtomReporter = function(doc) {
|
||||
this.document = doc || document;
|
||||
this.suiteDivs = {};
|
||||
this.logRunningSpecs = false;
|
||||
};
|
||||
jasmine.AtomReporterHelpers = {};
|
||||
|
||||
jasmine.AtomReporter.prototype.createDom = function(type, attrs, childrenVarArgs) {
|
||||
jasmine.AtomReporterHelpers.createDom = function(type, attrs, childrenVarArgs) {
|
||||
var el = document.createElement(type);
|
||||
|
||||
for (var i = 2; i < arguments.length; i++) {
|
||||
@@ -13,7 +9,9 @@ jasmine.AtomReporter.prototype.createDom = function(type, attrs, childrenVarArgs
|
||||
if (typeof child === 'string') {
|
||||
el.appendChild(document.createTextNode(child));
|
||||
} else {
|
||||
if (child) { el.appendChild(child); }
|
||||
if (child) {
|
||||
el.appendChild(child);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,117 +26,344 @@ jasmine.AtomReporter.prototype.createDom = function(type, attrs, childrenVarArgs
|
||||
return el;
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.reportRunnerStarting = function(runner) {
|
||||
var showPassed, showSkipped;
|
||||
|
||||
this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' },
|
||||
this.createDom('div', { className: 'banner' },
|
||||
this.createDom('div', { className: 'logo' },
|
||||
this.createDom('span', { className: 'title' }, "Jasmine"),
|
||||
this.createDom('span', { className: 'version' }, runner.env.versionString())),
|
||||
this.createDom('div', { className: 'options' },
|
||||
"Show ",
|
||||
showPassed = this.createDom('input', { id: "__jasmine_AtomReporter_showPassed__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_AtomReporter_showPassed__" }, " passed "),
|
||||
showSkipped = this.createDom('input', { id: "__jasmine_AtomReporter_showSkipped__", type: 'checkbox' }),
|
||||
this.createDom('label', { "for": "__jasmine_AtomReporter_showSkipped__" }, " skipped")
|
||||
)
|
||||
),
|
||||
|
||||
this.runnerDiv = this.createDom('div', { className: 'runner running' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?' }, "run all"),
|
||||
this.runnerMessageSpan = this.createDom('span', {}, "Running..."),
|
||||
this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, ""))
|
||||
);
|
||||
|
||||
this.document.body.appendChild(this.outerDiv);
|
||||
|
||||
var suites = runner.suites();
|
||||
for (var i = 0; i < suites.length; i++) {
|
||||
var suite = suites[i];
|
||||
var suiteDiv = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"),
|
||||
this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description));
|
||||
this.suiteDivs[suite.id] = suiteDiv;
|
||||
var parentDiv = this.outerDiv;
|
||||
if (suite.parentSuite) {
|
||||
parentDiv = this.suiteDivs[suite.parentSuite.id];
|
||||
}
|
||||
parentDiv.appendChild(suiteDiv);
|
||||
}
|
||||
|
||||
this.startedAt = new Date();
|
||||
|
||||
var self = this;
|
||||
showPassed.onclick = function(evt) {
|
||||
if (showPassed.checked) {
|
||||
self.outerDiv.className += ' show-passed';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, '');
|
||||
}
|
||||
};
|
||||
|
||||
showSkipped.onclick = function(evt) {
|
||||
if (showSkipped.checked) {
|
||||
self.outerDiv.className += ' show-skipped';
|
||||
} else {
|
||||
self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, '');
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.reportRunnerResults = function(runner) {
|
||||
var results = runner.results();
|
||||
var className = (results.failedCount > 0) ? "runner failed" : "runner passed";
|
||||
this.runnerDiv.setAttribute("class", className);
|
||||
//do it twice for IE
|
||||
this.runnerDiv.setAttribute("className", className);
|
||||
var specs = runner.specs();
|
||||
var specCount = 0;
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
if (this.specFilter(specs[i])) {
|
||||
specCount++;
|
||||
}
|
||||
}
|
||||
var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s");
|
||||
message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s";
|
||||
this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild);
|
||||
|
||||
this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString()));
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.reportSuiteResults = function(suite) {
|
||||
var results = suite.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.totalCount === 0) { // todo: change this to check results.skipped
|
||||
status = 'skipped';
|
||||
}
|
||||
this.suiteDivs[suite.id].className += " " + status;
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.reportSpecStarting = function(spec) {
|
||||
if (this.logRunningSpecs) {
|
||||
this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.reportSpecResults = function(spec) {
|
||||
var results = spec.results();
|
||||
jasmine.AtomReporterHelpers.getSpecStatus = function(child) {
|
||||
var results = child.results();
|
||||
var status = results.passed() ? 'passed' : 'failed';
|
||||
if (results.skipped) {
|
||||
status = 'skipped';
|
||||
}
|
||||
var specDiv = this.createDom('div', { className: 'spec ' + status },
|
||||
this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"),
|
||||
|
||||
return status;
|
||||
};
|
||||
|
||||
jasmine.AtomReporterHelpers.appendToSummary = function(child, childElement) {
|
||||
var parentDiv = this.dom.summary;
|
||||
var parentSuite = (typeof child.parentSuite == 'undefined') ? 'suite' : 'parentSuite';
|
||||
var parent = child[parentSuite];
|
||||
|
||||
if (parent) {
|
||||
if (typeof this.views.suites[parent.id] == 'undefined') {
|
||||
this.views.suites[parent.id] = new jasmine.AtomReporter.SuiteView(parent, this.dom, this.views);
|
||||
}
|
||||
parentDiv = this.views.suites[parent.id].element;
|
||||
}
|
||||
|
||||
parentDiv.appendChild(childElement);
|
||||
};
|
||||
|
||||
|
||||
jasmine.AtomReporterHelpers.addHelpers = function(ctor) {
|
||||
for(var fn in jasmine.AtomReporterHelpers) {
|
||||
ctor.prototype[fn] = jasmine.AtomReporterHelpers[fn];
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.AtomReporter = function(_doc) {
|
||||
var self = this;
|
||||
var doc = _doc || window.document;
|
||||
|
||||
var reporterView;
|
||||
|
||||
var dom = {};
|
||||
|
||||
// Jasmine Reporter Public Interface
|
||||
self.logRunningSpecs = false;
|
||||
|
||||
self.reportRunnerStarting = function(runner) {
|
||||
var specs = runner.specs() || [];
|
||||
|
||||
if (specs.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
createReporterDom();
|
||||
doc.body.appendChild(dom.reporter);
|
||||
|
||||
reporterView = new jasmine.AtomReporter.ReporterView(dom);
|
||||
reporterView.addSpecs(specs, self.specFilter);
|
||||
};
|
||||
|
||||
self.reportRunnerResults = function(runner) {
|
||||
reporterView && reporterView.complete();
|
||||
};
|
||||
|
||||
self.reportSuiteResults = function(suite) {
|
||||
reporterView.suiteComplete(suite);
|
||||
};
|
||||
|
||||
self.reportSpecStarting = function(spec) {
|
||||
if (self.logRunningSpecs) {
|
||||
self.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...');
|
||||
}
|
||||
|
||||
reporterView.specStarted(spec);
|
||||
};
|
||||
|
||||
self.reportSpecResults = function(spec) {
|
||||
reporterView.specComplete(spec);
|
||||
};
|
||||
|
||||
self.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
self.specFilter = function(spec) {
|
||||
return self.fSpecFilter(spec);
|
||||
};
|
||||
|
||||
return self;
|
||||
|
||||
function createReporterDom() {
|
||||
dom.reporter = self.createDom('div', { id: 'HTMLReporter', className: 'jasmine_reporter' },
|
||||
dom.banner = self.createDom('div', { className: 'banner' },
|
||||
self.createDom('span', { className: 'title' }, "Atom "),
|
||||
self.createDom('span', { className: 'version' }, "0.0.0")),
|
||||
|
||||
dom.symbolSummary = self.createDom('ul', {className: 'symbolSummary'}),
|
||||
dom.alert = self.createDom('div', {className: 'alert'}),
|
||||
dom.results = self.createDom('div', {className: 'results'},
|
||||
dom.summary = self.createDom('div', { className: 'summary' }),
|
||||
dom.details = self.createDom('div', { id: 'details' }))
|
||||
);
|
||||
}
|
||||
|
||||
function searchWithCatch() {
|
||||
var params = jasmine.AtomReporter.parameters(window.document);
|
||||
var removed = false;
|
||||
var i = 0;
|
||||
|
||||
while (!removed && i < params.length) {
|
||||
if (params[i].match(/catch=/)) {
|
||||
params.splice(i, 1);
|
||||
removed = true;
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (jasmine.CATCH_EXCEPTIONS) {
|
||||
params.push("catch=false");
|
||||
}
|
||||
|
||||
return params.join("&");
|
||||
}
|
||||
};
|
||||
jasmine.AtomReporter.parameters = function(doc) {
|
||||
var paramStr = doc.location.search.substring(1);
|
||||
var params = [];
|
||||
|
||||
if (paramStr.length > 0) {
|
||||
params = paramStr.split('&');
|
||||
}
|
||||
return params;
|
||||
}
|
||||
jasmine.AtomReporter.sectionLink = function(sectionName) {
|
||||
var link = '?';
|
||||
var params = [];
|
||||
|
||||
if (sectionName) {
|
||||
params.push('spec=' + encodeURIComponent(sectionName));
|
||||
}
|
||||
if (!jasmine.CATCH_EXCEPTIONS) {
|
||||
params.push("catch=false");
|
||||
}
|
||||
if (params.length > 0) {
|
||||
link += params.join("&");
|
||||
}
|
||||
|
||||
return link;
|
||||
};
|
||||
jasmine.AtomReporterHelpers.addHelpers(jasmine.AtomReporter);
|
||||
jasmine.AtomReporter.ReporterView = function(dom) {
|
||||
this.startedAt = new Date();
|
||||
this.runningSpecCount = 0;
|
||||
this.completeSpecCount = 0;
|
||||
this.passedCount = 0;
|
||||
this.failedCount = 0;
|
||||
this.skippedCount = 0;
|
||||
|
||||
this.createResultsMenu = function() {
|
||||
this.resultsMenu = this.createDom('span', {className: 'resultsMenu bar'},
|
||||
this.summaryMenuItem = this.createDom('span', {className: 'summaryMenuItem'}, '0 specs'),
|
||||
' | ',
|
||||
this.detailsMenuItem = this.createDom('span', {className: 'detailsMenuItem'}, '0 failing'),
|
||||
this.currentSpecMenuItem = this.createDom('div', {className: 'currentSpecMenuItem'}, '')
|
||||
);
|
||||
|
||||
};
|
||||
|
||||
this.addSpecs = function(specs, specFilter) {
|
||||
this.totalSpecCount = specs.length;
|
||||
|
||||
this.views = {
|
||||
specs: {},
|
||||
suites: {}
|
||||
};
|
||||
|
||||
for (var i = 0; i < specs.length; i++) {
|
||||
var spec = specs[i];
|
||||
this.views.specs[spec.id] = new jasmine.AtomReporter.SpecView(spec, dom, this.views);
|
||||
if (specFilter(spec)) {
|
||||
this.runningSpecCount++;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this.specStarted = function(spec) {
|
||||
if (this.currentSpecMenuItem) {
|
||||
this.currentSpecMenuItem.innerHTML = spec.getFullName()
|
||||
}
|
||||
}
|
||||
|
||||
this.specComplete = function(spec) {
|
||||
this.completeSpecCount++;
|
||||
|
||||
if (isUndefined(this.views.specs[spec.id])) {
|
||||
this.views.specs[spec.id] = new jasmine.AtomReporter.SpecView(spec, dom);
|
||||
}
|
||||
|
||||
var specView = this.views.specs[spec.id];
|
||||
|
||||
switch (specView.status()) {
|
||||
case 'passed':
|
||||
this.passedCount++;
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.failedCount++;
|
||||
break;
|
||||
|
||||
case 'skipped':
|
||||
this.skippedCount++;
|
||||
break;
|
||||
}
|
||||
|
||||
specView.refresh(spec);
|
||||
this.refresh();
|
||||
};
|
||||
|
||||
this.suiteComplete = function(suite) {
|
||||
var suiteView = this.views.suites[suite.id];
|
||||
if (isUndefined(suiteView)) {
|
||||
return;
|
||||
}
|
||||
suiteView.refresh();
|
||||
};
|
||||
|
||||
this.refresh = function() {
|
||||
if (isUndefined(this.resultsMenu)) {
|
||||
this.createResultsMenu();
|
||||
dom.alert.appendChild(this.resultsMenu);
|
||||
}
|
||||
|
||||
// summary info
|
||||
this.summaryMenuItem.innerHTML = "" + specPluralizedFor(this.runningSpecCount);
|
||||
this.detailsMenuItem.innerHTML = "" + this.failedCount + " failing";
|
||||
};
|
||||
|
||||
this.complete = function() {
|
||||
dom.alert.removeChild(this.resultsMenu);
|
||||
var skippedSpecs = this.skippedCount == 0 ? "" : " (" + this.skippedCount + " specs skipped)"
|
||||
|
||||
if (this.failedCount === 0) {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'passingAlert bar'}, this.passedCount + "/" + specPluralizedFor(this.totalSpecCount - this.skippedCount) + " passed" + skippedSpecs));
|
||||
} else {
|
||||
dom.alert.appendChild(this.createDom('span', {className: 'failingAlert bar'}, specPluralizedFor(this.failedCount) + " failed" + skippedSpecs));
|
||||
showDetails();
|
||||
}
|
||||
|
||||
dom.banner.appendChild(this.createDom('span', {className: 'duration'}, "finished in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"));
|
||||
};
|
||||
|
||||
return this;
|
||||
|
||||
function showDetails() {
|
||||
if (dom.reporter.className.search(/showDetails/) === -1) {
|
||||
dom.reporter.className += " showDetails";
|
||||
}
|
||||
}
|
||||
|
||||
function isUndefined(obj) {
|
||||
return typeof obj === 'undefined';
|
||||
}
|
||||
|
||||
function isDefined(obj) {
|
||||
return !isUndefined(obj);
|
||||
}
|
||||
|
||||
function specPluralizedFor(count) {
|
||||
var str = count + " spec";
|
||||
if (count > 1) {
|
||||
str += "s"
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
jasmine.AtomReporterHelpers.addHelpers(jasmine.AtomReporter.ReporterView);
|
||||
|
||||
|
||||
jasmine.AtomReporter.SpecView = function(spec, dom, views) {
|
||||
this.spec = spec;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.symbol = this.createDom('li', { className: 'pending' });
|
||||
this.dom.symbolSummary.appendChild(this.symbol);
|
||||
|
||||
this.summary = this.createDom('div', { className: 'specSummary' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: jasmine.AtomReporter.sectionLink(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.description)
|
||||
);
|
||||
|
||||
this.detail = this.createDom('div', { className: 'specDetail' },
|
||||
this.createDom('a', {
|
||||
className: 'description',
|
||||
href: '?spec=' + encodeURIComponent(spec.getFullName()),
|
||||
title: spec.getFullName()
|
||||
}, spec.description));
|
||||
href: '?spec=' + encodeURIComponent(this.spec.getFullName()),
|
||||
title: this.spec.getFullName()
|
||||
}, this.spec.getFullName())
|
||||
);
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.SpecView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.spec);
|
||||
};
|
||||
|
||||
var resultItems = results.getItems();
|
||||
jasmine.AtomReporter.SpecView.prototype.refresh = function() {
|
||||
this.symbol.className = this.status();
|
||||
|
||||
switch (this.status()) {
|
||||
case 'skipped':
|
||||
case 'passed':
|
||||
break;
|
||||
|
||||
case 'failed':
|
||||
this.appendSummaryToSuiteDiv();
|
||||
this.appendFailureDetail();
|
||||
break;
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.SpecView.prototype.appendSummaryToSuiteDiv = function() {
|
||||
this.summary.className += ' ' + this.status();
|
||||
this.appendToSummary(this.spec, this.summary);
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.SpecView.prototype.appendFailureDetail = function() {
|
||||
this.detail.className += ' ' + this.status();
|
||||
|
||||
var resultItems = this.spec.results().getItems();
|
||||
var messagesDiv = this.createDom('div', { className: 'messages' });
|
||||
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
|
||||
@@ -154,37 +379,29 @@ jasmine.AtomReporter.prototype.reportSpecResults = function(spec) {
|
||||
}
|
||||
|
||||
if (messagesDiv.childNodes.length > 0) {
|
||||
specDiv.appendChild(messagesDiv);
|
||||
}
|
||||
|
||||
this.suiteDivs[spec.suite.id].appendChild(specDiv);
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.log = function() {
|
||||
var console = jasmine.getGlobal().console;
|
||||
if (console && console.log) {
|
||||
if (console.log.apply) {
|
||||
console.log.apply(console, arguments);
|
||||
} else {
|
||||
console.log(arguments); // ie fix: console.log.apply doesn't exist on ie
|
||||
}
|
||||
this.detail.appendChild(messagesDiv);
|
||||
this.dom.details.appendChild(this.detail);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.getLocation = function() {
|
||||
return this.document.location;
|
||||
jasmine.AtomReporterHelpers.addHelpers(jasmine.AtomReporter.SpecView);jasmine.AtomReporter.SuiteView = function(suite, dom, views) {
|
||||
this.suite = suite;
|
||||
this.dom = dom;
|
||||
this.views = views;
|
||||
|
||||
this.element = this.createDom('div', { className: 'suite' },
|
||||
this.createDom('a', { className: 'description', href: jasmine.AtomReporter.sectionLink(this.suite.getFullName()) }, this.suite.description)
|
||||
);
|
||||
|
||||
this.appendToSummary(this.suite, this.element);
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec) {
|
||||
return true;
|
||||
}
|
||||
return spec.getFullName().indexOf(paramMap.spec) === 0;
|
||||
jasmine.AtomReporter.SuiteView.prototype.status = function() {
|
||||
return this.getSpecStatus(this.suite);
|
||||
};
|
||||
|
||||
jasmine.AtomReporter.SuiteView.prototype.refresh = function() {
|
||||
this.element.className += " " + this.status();
|
||||
};
|
||||
|
||||
jasmine.AtomReporterHelpers.addHelpers(jasmine.AtomReporter.SuiteView);
|
||||
10
vendor/jasmine-console-reporter.js
vendored
10
vendor/jasmine-console-reporter.js
vendored
@@ -31,7 +31,9 @@ jasmine.ConsoleReporter.prototype.reportSpecResults = function(spec) {
|
||||
for (var i = 0; i < resultItems.length; i++) {
|
||||
var result = resultItems[i];
|
||||
if (this.logErrors && result.type == 'expect' && result.passed && !result.passed()) {
|
||||
console.log("ERROR: " + spec.getFullName())
|
||||
message = spec.getFullName()
|
||||
console.log("\n\n" + message)
|
||||
console.log((new Array(message.length + 1)).join('-'))
|
||||
if (result.trace.stack) {
|
||||
console.log(result.trace.stack)
|
||||
}
|
||||
@@ -43,9 +45,5 @@ jasmine.ConsoleReporter.prototype.reportSpecResults = function(spec) {
|
||||
};
|
||||
|
||||
jasmine.ConsoleReporter.prototype.specFilter = function(spec) {
|
||||
if (!jasmine.getEnv().focusPriority) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return fSpecFilter(spec);
|
||||
return true;
|
||||
};
|
||||
|
||||
22
vendor/jasmine-focused.js
vendored
22
vendor/jasmine-focused.js
vendored
@@ -36,28 +36,12 @@ var fffit = function(description, specDefinitions) {
|
||||
fit(description, specDefinitions, 3);
|
||||
};
|
||||
|
||||
var fSpecFilter = function(specOrSuite) {
|
||||
jasmine.AtomReporter.prototype.fSpecFilter = function(specOrSuite) {
|
||||
globalFocusPriority = jasmine.getEnv().focusPriority;
|
||||
if (!globalFocusPriority) return true;
|
||||
if (specOrSuite.focusPriority >= globalFocusPriority) return true;
|
||||
|
||||
var parent = specOrSuite.parentSuite || specOrSuite.suite;
|
||||
if (!parent) return false;
|
||||
return fSpecFilter(parent);
|
||||
}
|
||||
|
||||
jasmine.AtomReporter.prototype.specFilter = function(spec) {
|
||||
var paramMap = {};
|
||||
var params = this.getLocation().search.substring(1).split('&');
|
||||
for (var i = 0; i < params.length; i++) {
|
||||
var p = params[i].split('=');
|
||||
paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]);
|
||||
}
|
||||
|
||||
if (!paramMap.spec && !jasmine.getEnv().focusPriority) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return (spec.getFullName().indexOf(paramMap.spec) === 0) || fSpecFilter(spec);
|
||||
};
|
||||
|
||||
return this.fSpecFilter(parent);
|
||||
};
|
||||
7
vendor/jasmine-helper.coffee
vendored
7
vendor/jasmine-helper.coffee
vendored
@@ -8,9 +8,6 @@ module.exports.runSpecSuite = (specSuite, logErrors=true) ->
|
||||
$ = require 'jquery'
|
||||
TimeReporter = require 'time-reporter'
|
||||
|
||||
$('body').append $$ ->
|
||||
@div id: 'jasmine-content'
|
||||
|
||||
reporter = if atom.exitWhenDone
|
||||
new jasmine.ConsoleReporter(document, logErrors)
|
||||
else
|
||||
@@ -22,4 +19,8 @@ module.exports.runSpecSuite = (specSuite, logErrors=true) ->
|
||||
|
||||
jasmineEnv.addReporter(new TimeReporter())
|
||||
jasmineEnv.specFilter = (spec) -> reporter.specFilter(spec)
|
||||
|
||||
$('body').append $$ ->
|
||||
@div id: 'jasmine-content'
|
||||
|
||||
jasmineEnv.execute()
|
||||
|
||||
583
vendor/jasmine.js
vendored
583
vendor/jasmine.js
vendored
@@ -1,8 +1,10 @@
|
||||
// Modified line 1769
|
||||
// - if (self.blocks[self.index].abort) {
|
||||
// + if (self.blocks[self.index] && self.blocks[self.index].abort) {
|
||||
// Modified line
|
||||
// - var isCommonJS = typeof window == "undefined" && typeof exports == "object";
|
||||
// +
|
||||
//
|
||||
// Modified method jasmine.WaitsForBlock.prototype.execute
|
||||
|
||||
var isCommonJS = typeof window == "undefined";
|
||||
var isCommonJS = typeof window == "undefined" && typeof exports == "object";
|
||||
|
||||
/**
|
||||
* Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework.
|
||||
@@ -38,11 +40,23 @@ jasmine.VERBOSE = false;
|
||||
*/
|
||||
jasmine.DEFAULT_UPDATE_INTERVAL = 250;
|
||||
|
||||
/**
|
||||
* Maximum levels of nesting that will be included when an object is pretty-printed
|
||||
*/
|
||||
jasmine.MAX_PRETTY_PRINT_DEPTH = 40;
|
||||
|
||||
/**
|
||||
* Default timeout interval in milliseconds for waitsFor() blocks.
|
||||
*/
|
||||
jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000;
|
||||
|
||||
/**
|
||||
* By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite.
|
||||
* Set to false to let the exception bubble up in the browser.
|
||||
*
|
||||
*/
|
||||
jasmine.CATCH_EXCEPTIONS = true;
|
||||
|
||||
jasmine.getGlobal = function() {
|
||||
function getGlobal() {
|
||||
return window;
|
||||
@@ -200,6 +214,21 @@ jasmine.any = function(clazz) {
|
||||
return new jasmine.Matchers.Any(clazz);
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the
|
||||
* attributes on the object.
|
||||
*
|
||||
* @example
|
||||
* // don't care about any other attributes than foo.
|
||||
* expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"});
|
||||
*
|
||||
* @param sample {Object} sample
|
||||
* @returns matchable object for the sample
|
||||
*/
|
||||
jasmine.objectContaining = function (sample) {
|
||||
return new jasmine.Matchers.ObjectContaining(sample);
|
||||
};
|
||||
|
||||
/**
|
||||
* Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks.
|
||||
*
|
||||
@@ -452,7 +481,7 @@ jasmine.log = function() {
|
||||
* @see jasmine.createSpy
|
||||
* @param obj
|
||||
* @param methodName
|
||||
* @returns a Jasmine spy that can be chained with all spy methods
|
||||
* @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods
|
||||
*/
|
||||
var spyOn = function(obj, methodName) {
|
||||
return jasmine.getEnv().currentSpec.spyOn(obj, methodName);
|
||||
@@ -497,6 +526,7 @@ if (isCommonJS) exports.xit = xit;
|
||||
* jasmine.Matchers functions.
|
||||
*
|
||||
* @param {Object} actual Actual value to test against and expected value
|
||||
* @return {jasmine.Matchers}
|
||||
*/
|
||||
var expect = function(actual) {
|
||||
return jasmine.getEnv().currentSpec.expect(actual);
|
||||
@@ -856,6 +886,25 @@ jasmine.Env.prototype.xit = function(desc, func) {
|
||||
};
|
||||
};
|
||||
|
||||
jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
if (a.source != b.source)
|
||||
mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/");
|
||||
|
||||
if (a.ignoreCase != b.ignoreCase)
|
||||
mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier");
|
||||
|
||||
if (a.global != b.global)
|
||||
mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier");
|
||||
|
||||
if (a.multiline != b.multiline)
|
||||
mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier");
|
||||
|
||||
if (a.sticky != b.sticky)
|
||||
mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier");
|
||||
|
||||
return (mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) {
|
||||
return true;
|
||||
@@ -918,11 +967,19 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
return a.getTime() == b.getTime();
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.Any) {
|
||||
if (a.jasmineMatches) {
|
||||
return a.jasmineMatches(b);
|
||||
}
|
||||
|
||||
if (b.jasmineMatches) {
|
||||
return b.jasmineMatches(a);
|
||||
}
|
||||
|
||||
if (a instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return a.matches(b);
|
||||
}
|
||||
|
||||
if (b instanceof jasmine.Matchers.Any) {
|
||||
if (b instanceof jasmine.Matchers.ObjectContaining) {
|
||||
return b.matches(a);
|
||||
}
|
||||
|
||||
@@ -934,6 +991,10 @@ jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) {
|
||||
return (a == b);
|
||||
}
|
||||
|
||||
if (a instanceof RegExp && b instanceof RegExp) {
|
||||
return this.compareRegExps_(a, b, mismatchKeys, mismatchValues);
|
||||
}
|
||||
|
||||
if (typeof a === "object" && typeof b === "object") {
|
||||
return this.compareObjects_(a, b, mismatchKeys, mismatchValues);
|
||||
}
|
||||
@@ -1001,10 +1062,15 @@ jasmine.Block = function(env, func, spec) {
|
||||
};
|
||||
|
||||
jasmine.Block.prototype.execute = function(onComplete) {
|
||||
try {
|
||||
if (!jasmine.CATCH_EXCEPTIONS) {
|
||||
this.func.apply(this.spec);
|
||||
} catch (e) {
|
||||
this.spec.fail(e);
|
||||
}
|
||||
else {
|
||||
try {
|
||||
this.func.apply(this.spec);
|
||||
} catch (e) {
|
||||
this.spec.fail(e);
|
||||
}
|
||||
}
|
||||
onComplete();
|
||||
};
|
||||
@@ -1216,7 +1282,7 @@ jasmine.Matchers.prototype.toEqual = function(expected) {
|
||||
/**
|
||||
* toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual
|
||||
* @param expected
|
||||
* @deprecated as of 1.0. Use not.toNotEqual() instead.
|
||||
* @deprecated as of 1.0. Use not.toEqual() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotEqual = function(expected) {
|
||||
return !this.env.equals_(this.actual, expected);
|
||||
@@ -1262,6 +1328,17 @@ jasmine.Matchers.prototype.toBeNull = function() {
|
||||
return (this.actual === null);
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that compares the actual to NaN.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toBeNaN = function() {
|
||||
this.message = function() {
|
||||
return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ];
|
||||
};
|
||||
|
||||
return (this.actual !== this.actual);
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that boolean not-nots the actual.
|
||||
*/
|
||||
@@ -1339,18 +1416,14 @@ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() {
|
||||
throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.');
|
||||
}
|
||||
this.message = function() {
|
||||
var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was.";
|
||||
var positiveMessage = "";
|
||||
if (this.actual.callCount === 0) {
|
||||
// todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw]
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.",
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."
|
||||
];
|
||||
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.";
|
||||
} else {
|
||||
return [
|
||||
"Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall),
|
||||
"Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall)
|
||||
];
|
||||
positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '')
|
||||
}
|
||||
return [positiveMessage, invertedMessage];
|
||||
};
|
||||
|
||||
return this.env.contains_(this.actual.argsForCall, expectedArgs);
|
||||
@@ -1389,7 +1462,7 @@ jasmine.Matchers.prototype.toContain = function(expected) {
|
||||
* Matcher that checks that the expected item is NOT an element in the actual Array.
|
||||
*
|
||||
* @param {Object} expected
|
||||
* @deprecated as of 1.0. Use not.toNotContain() instead.
|
||||
* @deprecated as of 1.0. Use not.toContain() instead.
|
||||
*/
|
||||
jasmine.Matchers.prototype.toNotContain = function(expected) {
|
||||
return !this.env.contains_(this.actual, expected);
|
||||
@@ -1408,22 +1481,19 @@ jasmine.Matchers.prototype.toBeGreaterThan = function(expected) {
|
||||
* up to a given level of decimal precision (default 2).
|
||||
*
|
||||
* @param {Number} expected
|
||||
* @param {Number} precision
|
||||
* @param {Number} precision, as number of decimal places
|
||||
*/
|
||||
jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) {
|
||||
if (!(precision === 0)) {
|
||||
precision = precision || 2;
|
||||
}
|
||||
var multiplier = Math.pow(10, precision);
|
||||
var actual = Math.round(this.actual * multiplier);
|
||||
expected = Math.round(expected * multiplier);
|
||||
return expected == actual;
|
||||
return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2);
|
||||
};
|
||||
|
||||
/**
|
||||
* Matcher that checks that the expected exception was thrown by the actual.
|
||||
*
|
||||
* @param {String} expected
|
||||
* @param {String} [expected]
|
||||
*/
|
||||
jasmine.Matchers.prototype.toThrow = function(expected) {
|
||||
var result = false;
|
||||
@@ -1457,7 +1527,7 @@ jasmine.Matchers.Any = function(expectedClass) {
|
||||
this.expectedClass = expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
jasmine.Matchers.Any.prototype.jasmineMatches = function(other) {
|
||||
if (this.expectedClass == String) {
|
||||
return typeof other == 'string' || other instanceof String;
|
||||
}
|
||||
@@ -1477,10 +1547,222 @@ jasmine.Matchers.Any.prototype.matches = function(other) {
|
||||
return other instanceof this.expectedClass;
|
||||
};
|
||||
|
||||
jasmine.Matchers.Any.prototype.toString = function() {
|
||||
jasmine.Matchers.Any.prototype.jasmineToString = function() {
|
||||
return '<jasmine.any(' + this.expectedClass + ')>';
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining = function (sample) {
|
||||
this.sample = sample;
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) {
|
||||
mismatchKeys = mismatchKeys || [];
|
||||
mismatchValues = mismatchValues || [];
|
||||
|
||||
var env = jasmine.getEnv();
|
||||
|
||||
var hasKey = function(obj, keyName) {
|
||||
return obj != null && obj[keyName] !== jasmine.undefined;
|
||||
};
|
||||
|
||||
for (var property in this.sample) {
|
||||
if (!hasKey(other, property) && hasKey(this.sample, property)) {
|
||||
mismatchKeys.push("expected has key '" + property + "', but missing from actual.");
|
||||
}
|
||||
else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) {
|
||||
mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual.");
|
||||
}
|
||||
}
|
||||
|
||||
return (mismatchKeys.length === 0 && mismatchValues.length === 0);
|
||||
};
|
||||
|
||||
jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () {
|
||||
return "<jasmine.objectContaining(" + jasmine.pp(this.sample) + ")>";
|
||||
};
|
||||
// Mock setTimeout, clearTimeout
|
||||
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
|
||||
|
||||
jasmine.FakeTimer = function() {
|
||||
this.reset();
|
||||
|
||||
var self = this;
|
||||
self.setTimeout = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.setInterval = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.clearTimeout = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
self.clearInterval = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.reset = function() {
|
||||
this.timeoutsMade = 0;
|
||||
this.scheduledFunctions = {};
|
||||
this.nowMillis = 0;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.tick = function(millis) {
|
||||
var oldMillis = this.nowMillis;
|
||||
var newMillis = oldMillis + millis;
|
||||
this.runFunctionsWithinRange(oldMillis, newMillis);
|
||||
this.nowMillis = newMillis;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
|
||||
var scheduledFunc;
|
||||
var funcsToRun = [];
|
||||
for (var timeoutKey in this.scheduledFunctions) {
|
||||
scheduledFunc = this.scheduledFunctions[timeoutKey];
|
||||
if (scheduledFunc != jasmine.undefined &&
|
||||
scheduledFunc.runAtMillis >= oldMillis &&
|
||||
scheduledFunc.runAtMillis <= nowMillis) {
|
||||
funcsToRun.push(scheduledFunc);
|
||||
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (funcsToRun.length > 0) {
|
||||
funcsToRun.sort(function(a, b) {
|
||||
return a.runAtMillis - b.runAtMillis;
|
||||
});
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
try {
|
||||
var funcToRun = funcsToRun[i];
|
||||
this.nowMillis = funcToRun.runAtMillis;
|
||||
funcToRun.funcToCall();
|
||||
if (funcToRun.recurring) {
|
||||
this.scheduleFunction(funcToRun.timeoutKey,
|
||||
funcToRun.funcToCall,
|
||||
funcToRun.millis,
|
||||
true);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
this.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
|
||||
this.scheduledFunctions[timeoutKey] = {
|
||||
runAtMillis: this.nowMillis + millis,
|
||||
funcToCall: funcToCall,
|
||||
recurring: recurring,
|
||||
timeoutKey: timeoutKey,
|
||||
millis: millis
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
jasmine.Clock = {
|
||||
defaultFakeTimer: new jasmine.FakeTimer(),
|
||||
|
||||
reset: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.reset();
|
||||
},
|
||||
|
||||
tick: function(millis) {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.tick(millis);
|
||||
},
|
||||
|
||||
runFunctionsWithinRange: function(oldMillis, nowMillis) {
|
||||
jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
},
|
||||
|
||||
scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
|
||||
jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
|
||||
},
|
||||
|
||||
useMock: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
var spec = jasmine.getEnv().currentSpec;
|
||||
spec.after(jasmine.Clock.uninstallMock);
|
||||
|
||||
jasmine.Clock.installMock();
|
||||
}
|
||||
},
|
||||
|
||||
installMock: function() {
|
||||
jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
uninstallMock: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
},
|
||||
|
||||
real: {
|
||||
setTimeout: jasmine.getGlobal().setTimeout,
|
||||
clearTimeout: jasmine.getGlobal().clearTimeout,
|
||||
setInterval: jasmine.getGlobal().setInterval,
|
||||
clearInterval: jasmine.getGlobal().clearInterval
|
||||
},
|
||||
|
||||
assertInstalled: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
|
||||
}
|
||||
},
|
||||
|
||||
isInstalled: function() {
|
||||
return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
installed: null
|
||||
};
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
|
||||
//else for IE support
|
||||
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setTimeout.apply) {
|
||||
return jasmine.Clock.installed.setTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setTimeout(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setInterval.apply) {
|
||||
return jasmine.Clock.installed.setInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setInterval(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearTimeout(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearInterval = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearInterval(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* @constructor
|
||||
*/
|
||||
@@ -1609,10 +1891,6 @@ jasmine.PrettyPrinter = function() {
|
||||
* @param value
|
||||
*/
|
||||
jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
if (this.ppNestLevel_ > 40) {
|
||||
throw new Error('jasmine.PrettyPrinter: format() nested too deeply!');
|
||||
}
|
||||
|
||||
this.ppNestLevel_++;
|
||||
try {
|
||||
if (value === jasmine.undefined) {
|
||||
@@ -1621,8 +1899,8 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
this.emitScalar('null');
|
||||
} else if (value === jasmine.getGlobal()) {
|
||||
this.emitScalar('<global>');
|
||||
} else if (value instanceof jasmine.Matchers.Any) {
|
||||
this.emitScalar(value.toString());
|
||||
} else if (value.jasmineToString) {
|
||||
this.emitScalar(value.jasmineToString());
|
||||
} else if (typeof value === 'string') {
|
||||
this.emitString(value);
|
||||
} else if (jasmine.isSpy(value)) {
|
||||
@@ -1655,6 +1933,7 @@ jasmine.PrettyPrinter.prototype.format = function(value) {
|
||||
|
||||
jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) {
|
||||
for (var property in obj) {
|
||||
if (!obj.hasOwnProperty(property)) continue;
|
||||
if (property == '__Jasmine_been_here_before__') continue;
|
||||
fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined &&
|
||||
obj.__lookupGetter__(property) !== null) : false);
|
||||
@@ -1682,6 +1961,11 @@ jasmine.StringPrettyPrinter.prototype.emitString = function(value) {
|
||||
};
|
||||
|
||||
jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
|
||||
if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append("Array");
|
||||
return;
|
||||
}
|
||||
|
||||
this.append('[ ');
|
||||
for (var i = 0; i < array.length; i++) {
|
||||
if (i > 0) {
|
||||
@@ -1693,6 +1977,11 @@ jasmine.StringPrettyPrinter.prototype.emitArray = function(array) {
|
||||
};
|
||||
|
||||
jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) {
|
||||
if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) {
|
||||
this.append("Object");
|
||||
return;
|
||||
}
|
||||
|
||||
var self = this;
|
||||
this.append('{ ');
|
||||
var first = true;
|
||||
@@ -1721,6 +2010,10 @@ jasmine.StringPrettyPrinter.prototype.append = function(value) {
|
||||
};
|
||||
jasmine.Queue = function(env) {
|
||||
this.env = env;
|
||||
|
||||
// parallel to blocks. each true value in this array means the block will
|
||||
// get executed even if we abort
|
||||
this.ensured = [];
|
||||
this.blocks = [];
|
||||
this.running = false;
|
||||
this.index = 0;
|
||||
@@ -1728,15 +2021,30 @@ jasmine.Queue = function(env) {
|
||||
this.abort = false;
|
||||
};
|
||||
|
||||
jasmine.Queue.prototype.addBefore = function(block) {
|
||||
jasmine.Queue.prototype.addBefore = function(block, ensure) {
|
||||
if (ensure === jasmine.undefined) {
|
||||
ensure = false;
|
||||
}
|
||||
|
||||
this.blocks.unshift(block);
|
||||
this.ensured.unshift(ensure);
|
||||
};
|
||||
|
||||
jasmine.Queue.prototype.add = function(block) {
|
||||
jasmine.Queue.prototype.add = function(block, ensure) {
|
||||
if (ensure === jasmine.undefined) {
|
||||
ensure = false;
|
||||
}
|
||||
|
||||
this.blocks.push(block);
|
||||
this.ensured.push(ensure);
|
||||
};
|
||||
|
||||
jasmine.Queue.prototype.insertNext = function(block) {
|
||||
jasmine.Queue.prototype.insertNext = function(block, ensure) {
|
||||
if (ensure === jasmine.undefined) {
|
||||
ensure = false;
|
||||
}
|
||||
|
||||
this.ensured.splice((this.index + this.offset + 1), 0, ensure);
|
||||
this.blocks.splice((this.index + this.offset + 1), 0, block);
|
||||
this.offset++;
|
||||
};
|
||||
@@ -1760,7 +2068,7 @@ jasmine.Queue.prototype.next_ = function() {
|
||||
while (goAgain) {
|
||||
goAgain = false;
|
||||
|
||||
if (self.index < self.blocks.length && !this.abort) {
|
||||
if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) {
|
||||
var calledSynchronously = true;
|
||||
var completedSynchronously = false;
|
||||
|
||||
@@ -2051,7 +2359,7 @@ jasmine.Spec.prototype.finish = function(onComplete) {
|
||||
|
||||
jasmine.Spec.prototype.after = function(doAfter) {
|
||||
if (this.queue.isRunning()) {
|
||||
this.queue.add(new jasmine.Block(this.env, doAfter, this));
|
||||
this.queue.add(new jasmine.Block(this.env, doAfter, this), true);
|
||||
} else {
|
||||
this.afterCallbacks.unshift(doAfter);
|
||||
}
|
||||
@@ -2089,15 +2397,15 @@ jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() {
|
||||
this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this));
|
||||
}
|
||||
for (i = 0; i < this.afterCallbacks.length; i++) {
|
||||
this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this));
|
||||
this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true);
|
||||
}
|
||||
for (suite = this.suite; suite; suite = suite.parentSuite) {
|
||||
for (i = 0; i < suite.after_.length; i++) {
|
||||
this.queue.add(new jasmine.Block(this.env, suite.after_[i], this));
|
||||
this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true);
|
||||
}
|
||||
}
|
||||
for (i = 0; i < runner.after_.length; i++) {
|
||||
this.queue.add(new jasmine.Block(this.env, runner.after_[i], this));
|
||||
this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -2351,192 +2659,9 @@ jasmine.WaitsForBlock.MultiCompletion.prototype.buildCompletionFunction = functi
|
||||
};
|
||||
};
|
||||
|
||||
// Mock setTimeout, clearTimeout
|
||||
// Contributed by Pivotal Computer Systems, www.pivotalsf.com
|
||||
|
||||
jasmine.FakeTimer = function() {
|
||||
this.reset();
|
||||
|
||||
var self = this;
|
||||
self.setTimeout = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.setInterval = function(funcToCall, millis) {
|
||||
self.timeoutsMade++;
|
||||
self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true);
|
||||
return self.timeoutsMade;
|
||||
};
|
||||
|
||||
self.clearTimeout = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
self.clearInterval = function(timeoutKey) {
|
||||
self.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.reset = function() {
|
||||
this.timeoutsMade = 0;
|
||||
this.scheduledFunctions = {};
|
||||
this.nowMillis = 0;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.tick = function(millis) {
|
||||
var oldMillis = this.nowMillis;
|
||||
var newMillis = oldMillis + millis;
|
||||
this.runFunctionsWithinRange(oldMillis, newMillis);
|
||||
this.nowMillis = newMillis;
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) {
|
||||
var scheduledFunc;
|
||||
var funcsToRun = [];
|
||||
for (var timeoutKey in this.scheduledFunctions) {
|
||||
scheduledFunc = this.scheduledFunctions[timeoutKey];
|
||||
if (scheduledFunc != jasmine.undefined &&
|
||||
scheduledFunc.runAtMillis >= oldMillis &&
|
||||
scheduledFunc.runAtMillis <= nowMillis) {
|
||||
funcsToRun.push(scheduledFunc);
|
||||
this.scheduledFunctions[timeoutKey] = jasmine.undefined;
|
||||
}
|
||||
}
|
||||
|
||||
if (funcsToRun.length > 0) {
|
||||
funcsToRun.sort(function(a, b) {
|
||||
return a.runAtMillis - b.runAtMillis;
|
||||
});
|
||||
for (var i = 0; i < funcsToRun.length; ++i) {
|
||||
try {
|
||||
var funcToRun = funcsToRun[i];
|
||||
this.nowMillis = funcToRun.runAtMillis;
|
||||
funcToRun.funcToCall();
|
||||
if (funcToRun.recurring) {
|
||||
this.scheduleFunction(funcToRun.timeoutKey,
|
||||
funcToRun.funcToCall,
|
||||
funcToRun.millis,
|
||||
true);
|
||||
}
|
||||
} catch(e) {
|
||||
}
|
||||
}
|
||||
this.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) {
|
||||
this.scheduledFunctions[timeoutKey] = {
|
||||
runAtMillis: this.nowMillis + millis,
|
||||
funcToCall: funcToCall,
|
||||
recurring: recurring,
|
||||
timeoutKey: timeoutKey,
|
||||
millis: millis
|
||||
};
|
||||
};
|
||||
|
||||
/**
|
||||
* @namespace
|
||||
*/
|
||||
jasmine.Clock = {
|
||||
defaultFakeTimer: new jasmine.FakeTimer(),
|
||||
|
||||
reset: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.reset();
|
||||
},
|
||||
|
||||
tick: function(millis) {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.defaultFakeTimer.tick(millis);
|
||||
},
|
||||
|
||||
runFunctionsWithinRange: function(oldMillis, nowMillis) {
|
||||
jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis);
|
||||
},
|
||||
|
||||
scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) {
|
||||
jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring);
|
||||
},
|
||||
|
||||
useMock: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
var spec = jasmine.getEnv().currentSpec;
|
||||
spec.after(jasmine.Clock.uninstallMock);
|
||||
|
||||
jasmine.Clock.installMock();
|
||||
}
|
||||
},
|
||||
|
||||
installMock: function() {
|
||||
jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
uninstallMock: function() {
|
||||
jasmine.Clock.assertInstalled();
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
},
|
||||
|
||||
real: {
|
||||
setTimeout: jasmine.getGlobal().setTimeout,
|
||||
clearTimeout: jasmine.getGlobal().clearTimeout,
|
||||
setInterval: jasmine.getGlobal().setInterval,
|
||||
clearInterval: jasmine.getGlobal().clearInterval
|
||||
},
|
||||
|
||||
assertInstalled: function() {
|
||||
if (!jasmine.Clock.isInstalled()) {
|
||||
throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()");
|
||||
}
|
||||
},
|
||||
|
||||
isInstalled: function() {
|
||||
return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer;
|
||||
},
|
||||
|
||||
installed: null
|
||||
};
|
||||
jasmine.Clock.installed = jasmine.Clock.real;
|
||||
|
||||
//else for IE support
|
||||
jasmine.getGlobal().setTimeout = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setTimeout.apply) {
|
||||
return jasmine.Clock.installed.setTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setTimeout(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().setInterval = function(funcToCall, millis) {
|
||||
if (jasmine.Clock.installed.setInterval.apply) {
|
||||
return jasmine.Clock.installed.setInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.setInterval(funcToCall, millis);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearTimeout = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearTimeout.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearTimeout(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.getGlobal().clearInterval = function(timeoutKey) {
|
||||
if (jasmine.Clock.installed.clearTimeout.apply) {
|
||||
return jasmine.Clock.installed.clearInterval.apply(this, arguments);
|
||||
} else {
|
||||
return jasmine.Clock.installed.clearInterval(timeoutKey);
|
||||
}
|
||||
};
|
||||
|
||||
jasmine.version_= {
|
||||
"major": 1,
|
||||
"minor": 1,
|
||||
"build": 0,
|
||||
"revision": 1315677058
|
||||
"minor": 3,
|
||||
"build": 1,
|
||||
"revision": 1354556913
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user