diff --git a/spec/workspace-spec.coffee b/spec/workspace-spec.coffee index f95910d01..45452dca3 100644 --- a/spec/workspace-spec.coffee +++ b/spec/workspace-spec.coffee @@ -1,4 +1,5 @@ Workspace = require '../src/workspace' +{View} = require '../src/space-pen-extensions' describe "Workspace", -> workspace = null @@ -7,6 +8,49 @@ describe "Workspace", -> atom.project.setPath(atom.project.resolve('dir')) atom.workspace = workspace = new Workspace + describe "::getView(object)", -> + describe "when passed a DOM node", -> + it "returns the given DOM node", -> + node = document.createElement('div') + expect(workspace.getView(node)).toBe node + + describe "when passed a SpacePen view", -> + it "returns the root node of the view with a __spacePenView property pointing at the SpacePen view", -> + class TestView extends View + @content: -> @div "Hello" + + view = new TestView + node = workspace.getView(view) + expect(node.textContent).toBe "Hello" + expect(node.__spacePenView).toBe view + + describe "when passed a model object", -> + describe "when no view provider is registered for the object's constructor", -> + describe "when the object has a .getViewClass() method", -> + it "builds an instance of the view class with the model, then returns its root node with a __spacePenView property pointing at the view", -> + class TestView extends View + @content: (model) -> @div model.name + initialize: (@model) -> + + class TestModel + constructor: (@name) -> + getViewClass: -> TestView + + model = new TestModel("hello") + node = workspace.getView(model) + + expect(node.textContent).toBe "hello" + view = node.__spacePenView + expect(view instanceof TestView).toBe true + expect(view.model).toBe model + + # returns the same DOM node for repeated calls + expect(workspace.getView(model)).toBe node + + describe "when the object has no .getViewClass() method", -> + it "throws an exception", -> + expect(-> workspace.getView(new Object)).toThrow() + describe "::open(uri, options)", -> openEvents = null diff --git a/src/workspace.coffee b/src/workspace.coffee index 76450181b..8c0bedf10 100644 --- a/src/workspace.coffee +++ b/src/workspace.coffee @@ -9,6 +9,7 @@ Delegator = require 'delegato' Editor = require './editor' PaneContainer = require './pane-container' Pane = require './pane' +{jQuery} = require './space-pen-extensions' # Essential: Represents the state of the user interface for the entire window. # An instance of this class is available via the `atom.workspace` global. @@ -35,6 +36,7 @@ class Workspace extends Model super @emitter = new Emitter + @viewsByModel = new WeakMap @openers = [] @paneContainer.onDidDestroyPaneItem(@onPaneItemDestroyed) @@ -488,3 +490,23 @@ class Workspace extends Model # Called by Model superclass when destroyed destroyed: -> @paneContainer.destroy() + + getView: (object) -> + if view = @viewsByModel.get(object) + view + else if object instanceof HTMLElement + object + else if object instanceof jQuery + object[0].__spacePenView ?= object + object[0] + else + @createView(object) + + createView: (model) -> + if viewClass = model?.getViewClass?() + view = new viewClass(model) + @viewsByModel.set(model, view[0]) + view[0].__spacePenView ?= view + view[0] + else + throw new Error("Can't create a view for #{object.constructor.name} instance. Please register a view provider.")