Giter VIP home page Giter VIP logo

space-pen's People

Contributors

adamyonk avatar avanderhoorn avatar benogle avatar kevinsawicki avatar kuon avatar metaskills avatar nathansobo avatar nddrylliog avatar peterdavehello avatar rgbkrk avatar toady00 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

space-pen's Issues

Can A View Re-Render/Build?

Hey again Nathan! What are you thoughts on this topic either via an unpublished feature or patch that would make this possible? Some background... I am using SpacePen as my view system in all my Spine.JS apps. I typically have a handle to some views from my controller and as well often set my model instance to the views data() via the attach event. So no matter what, my view knows which model/params it was rendered with.

Spine.JS has a lovely feature in its ORM that basically means any model instance automatically reflects changes when any other instance is saved. So that means that if I did dig down to my SpacePen's view.data('mymodel') that I would see said changes. So now I am wondering if I can just trigger some sort of re-build or re-render at the view layer. Looking over the SpacePen code I did not see a way I could easily do this. I tried calling .buildHtml(model) on the view again, but to no avail. That threw this error.

TypeError: Object function ( selector, context ) { // The jQuery object is actually just the init constructor 'enhanced' return new jQuery.fn.init( selector, context, rootjQuery ); } has no method 'content'

Thoughts? Should I just render a new view and tell one view to replace itself with the new?

npm install/start failed on windows

When I follow the instructions in the readme to test I get this error. I would go in and try to fix it but I don't know grunt or browserify ...

I'm on windows 8.1 with space-pen 5.0.1.

Edit: The error seems to be due to forward slashes in a windows command.

C:\apps\space-pen>npm start

> [email protected] start C:\apps\space-pen
> grunt start

Running "coffee:lib" (coffee) task
File lib/space-pen.js created.

Running "coffeelint:src" (coffeelint) task
>> 1 file lint free.

Running "coffeelint:test" (coffeelint) task
>> 5 files lint free.

Running "coffeelint:gruntfile" (coffeelint) task
>> 1 file lint free.

Running "shell:browserify" (shell) task
'node_modules' is not recognized as an internal or external command,
operable program or batch file.
Warning: Command failed: cmd.exe /s /c "node_modules/.bin/browserify -t coffeeify spec/spec-helper.coffee -o spec/spec-helper.js"
'node_modules' is not recognized as an internal or external command,
operable program or batch file.
 Use --force to continue.

Correct use of subviews

Maybe im mistaken on the correct use of the @subview method.

class TableView extends View
  @content: (rows) ->
    @div =>
      @table name: 'rate', outlet: 'rate', =>
        @thead =>
          @th "header 1"
          @th "header 2"
          @th "header 3"
        @tbody =>
          for row, index in rows
            @subview "row_#{index}", new RowView(row)

class RowView extends View
  @content: (row) ->
    @tr =>
      @td row[0]
      @td row[1]
      @td row[2]
rows = [["1.1", "1.2", "1.3"], ["2.1", "2.2", "2.3"]]
$('.content').html(new TableView(rows))

generates the following HTML

<div callattachhooks="true">
  <tr callattachhooks="true">
    <td>1.1</td>
    <td>1.2</td>
    <td>1.3</td>
  </tr>
  <tr callattachhooks="true">
    <td>2.1</td>
    <td>2.2</td>
    <td>2.3</td>
  </tr>
  <table>
    <thead>
      <tr>
        <th>header 1</th>
        <th>header 2</th>
        <th>header 3</th>
      </tr>
    </thead>
    <tbody></tbody>
  </table>
</div>

and I was expecting

<div callattachhooks="true">
  <table>
    <thead>
      <tr>
        <th>header 1</th>
        <th>header 2</th>
        <th>header 3</th>
      </tr>
    </thead>
    <tbody>
      <tr callattachhooks="true">
        <td>1.1</td>
        <td>1.2</td>
        <td>1.3</td>
      </tr>
      <tr callattachhooks="true">
        <td>2.1</td>
        <td>2.2</td>
        <td>2.3</td>
      </tr>
    </tbody>
  </table>
</div>

Was thinking about "DOMNodeInserted" vs "attach" event.

This is less of an issue and more of a conversation piece. I was looking at the code that did the attach event trigger and how you have to redefine methods like append, prepend, etc. I was wondering why you did not tell people about "DOMNodeInserted" and avoid all that method redefinition?

View::content is called before View::constructor

I would expect the constructor of a View to be able to set up variables to be used in the content, as below. This is not the case, because the content function is called before the constructor, which is very surprising, and not mentioned in the docs.

Since View::initialize is called from View::constructor, it also has the same surprising behavior.

Test case:

class FooView extends View
    initialize: ->
        @fooCount = 1
    @content: ->
        @p "There are #{@fooCount} foos."

The document then contains There are undefined foos. instead of the expected There are 1 foos..

atom-text-editor in @tag

I was playing around and tried to do @tag 'atom-text-editor', <stuff> and it complains with a very specific error indicating that because it is a custom element inheritance needs to be used.

Any way to make that work?

Bower package

I'm wanting to use space-pen on the client and wanting to use bower for my front end package management. Just wondering if you guys have thought about creating a bower package?

Getting Started

Is there a tutorial on getting started using this in my project anywhere to be found?

CSS selector as a tag method argument

Having a look at the following method

  extractOptions: (args) ->
    options = {}
    for arg in args
      switch typeof(arg)
        when 'function'
          options.content = arg
        when 'string', 'number'
          options.text = arg.toString()
        else
          options.attributes = arg
    options

I think it would be interesting to add the following change:

  extractOptions: (args) ->
    options = {}
    for arg in args
      switch typeof(arg)
        when 'function'
          options.content = arg
        when 'string', 'number'
          options.text = arg.toString()
        # CSS selector #
        when 'array'
          options.selector = arg.join('.')
        else
          options.attributes = arg
    options

This way one could write something like this:

# before makeup
@a id: "submit", class: "button shinny", href: "http:example,com", "Submit"
# after
@a ["#submit.button.shinny"], href: "http:example,com", "Submit"
# or
@a ["#submit", "button.shinny"], href: "http:example,com", "Submit"
# or even
@a ["#submit", "button", "shinny"], href: "http:example,com", "Submit"

It would be reverse compatible with the current DSL while providing a closer CSS selector approach.
Also if you don't use the array selector it shouldn't impact much current performance.

Sorry I'm coming from HAML world and feel more comfortable with that notation, but I think I'm not the only one that would benefit from this.

Tell me if you like this and I can propose a pull request.

Github pages is out of date

The Github pages index still documents the old attach/detach handlers instead of the new ones. Took me a bit of time to realize it was out of date with the readme. It'd be nice if someone could rerun the page generator so that doesn't confuse anyone else in the future.

Built-in tags with @tag

Probably related to #57.

I have an issue trying to create an atom-panel element: @tag 'atom-panel'.
However I don't have any issue using a custom element that is not built-in: @tag 'foobar'.

Here is the error message:

Failed to execute 'registerElement' on 'Document': Registration failed for type
'space-pen-atom-panel'. The tag name specified in 'extends' is a custom element
name. Use inheritance instead.

Improper jQuery code

The code here: https://github.com/atom/space-pen/blob/master/src/space-pen.coffee#L349 has an improper use of .attr. .attr changed it's operation in jQuery 1.6. From the jQuery docs ...

The .prop() method should be used to set disabled and checked instead of the .attr() method.

This type of jQuery nailed me bad recently. See atom/atom-space-pen-views#4.

This is the offending code. Do you want a PR?

$.fn.isDisabled = ->
  !!@attr('disabled')
$.fn.enable = ->
  @removeAttr('disabled')
$.fn.disable = ->
  @attr('disabled', 'disabled')

how to interact with external linked js and execute inline javascript on page

I have a view in atom where I wish to display a canvas using raphael.js (thread here). This requires functions such as:

paper = new Raphael(document.getElementById("canvas_container"), 500, 500);

I've created a view which contains script tags for raphael and the script I'd like to execute:

@content: ->
    @div class: 'block', id: 'plasmidDisplayBase', =>
      @script type: 'text/javascript', src: 'https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js'
      @div id: 'canvas_container', width: 'width: 500px; border: 1px solid #aaa'
      @script type: 'text/javascript', =>
        @raw fs.readFileSync("#{__dirname}/raphael-display.js").toString()

where raphael-display.js simply contains the code:

window.onload = function(){
  console.log("EXECUTING");
  paper = new Raphael(document.getElementById("canvas_container"), 500, 500);
  var circle = paper.circle(50, 40, 10);
  circle.attr("fill", "#f00");
  circle.attr("stroke", "#fff");
}

When I console.log the created view, I get

<div class="block" id="plasmidDisplayBase" callattachhooks="true">
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/raphael/2.1.2/raphael-min.js"></script>
<div id="canvas_container" width="width: 500px; border: 1px solid #aaa"></div>
<script type="text/javascript">
window.onload = function(){
  console.log("EXECUTING");
  paper = new Raphael(document.getElementById("canvas_container"), 500, 500);
  var circle = paper.circle(50, 40, 10);
  circle.attr("fill", "#f00");
  circle.attr("stroke", "#fff");
}
</script>
</div>

This appears to be what I want, but no EXECUTING message is logged to the console, and no raphael canvas is displayed. How should I interact with external javascript in this manner? Can I do this with space pen?

Subclassing

I tried to create a convenience for myself in a ModelView subclass of View that my models will subclass (e.g. UserView).

As a simplified example:

class ModelView extends View
  constructor: (@model, @mutable) -> super @model, @mutable
  @propertyView: (property, klass, label) ->
    @subview property, new klass { @model, property, label, @mutable }

class UserView extends ModelView
  @content: ->
    @propertyView 'firstName', TextView

class TextView extends View
  @content: (params) -> @input params.model.get params.property

class User:  # a model, say from Parse
  get: (property) -> 'Brian'  # whatever

me = new User
me.set 'firstName', 'Brian'

$('body').append (new UserView me, yes)

However, this isn't working as expected and I could use a push in the right direction since I'm new to CoffeeScript and SpacePen.

The error is that in TextView, params.model is undefined.

As I expected, in the constructor of ModelView, @model is being saved as an instance var.

    function ModelView(model, mutable) {
     this.model = model;
     this.mutable = mutable;
     ModelView.__super__.constructor.call(this, this.model, this.mutable);
    }

The View constructor calls @content immediately so it seems that @model is not being set after all? I think I'm a bit confused why the content is @content (static property) and not 'content' ... What am I missing? Thanks!

@partial method to keep using space-pen syntax on instance

It would be nice to use space-pen notations in instances of an View an not just on construction.
So this example:

class TableView extends View
  @content: ->
    @table =>
      @tbody outlet: 'body'
  update_rows: (rows) ->
    for row in rows
      @body.append "<tr><td>#{row[0]}</td><td>#{row[1]}</td></tr>"

That also can be written this way:

class TableView extends View
  @content: ->
    @table =>
      @tbody outlet: 'body'
  update_rows: (rows) ->
    for row in rows
      @body.append new Row(row)
class Row extends View
  @content: (row) ->
    @tr =>
      @td row[0]
      @td row[1]

could be turned into this which I would prefer:

class TableView extends View
  @content: ->
    @table =>
      @tbody outlet: 'body'
  update_rows: (rows) ->
    for row in rows
      @body.append @row(row)
  row: (row) ->
    @partial =>
      @tr =>
        @td row[0]
        @td row[1]

This way you don't have to instantiate a new class for using space-pen syntax

Can't have an outlet on the top level

I tried to do:

@content: ->
  @div outlet: 'foo'

Much to my chagrin, @foo was not accessible. If I put an outlet on a nested div, it works fine. Is this intended?

Does not play well when multiple versions of spacepen

In converting find and replace, I am getting this error:

screen shot 2014-11-26 at 5 51 43 pm

I assume this is because I have a different version than that of some other package who got to registering this tag. Looks like there is no method to check if the element has been registered. I suppose we could try/catch. My guess is that this will happen in the wild.

callAttachHook execute twice.

When i use prependTo, appendTo, insertAfter, insertBefore method, callAttachHook execute twice.

But use append, prepend, after, before method, hooks just execute once.

How to <br> ?

It seems using @br doesn't work. Right now I'm using @raw '<br>' but I'm wondering if there's a better way to do this.

Thanks.

attached isn't called

I have a very simple view:

{View} = require 'atom'

class MyView extends View
  focus: -> @input.focus()
  initialize: (on_url) =>
    ...
  attached: ->
    debugger; # never reached

  @content: ->
    @div =>
      @input outlet: 'input', style: "width: 100%;", value: "https://asdf.com/"

and dump it into the DOM via:

atom.workspace.addModalPanel({item: new MyView()});

Am I missing something simple?

"No longer maintained" - more description in Readme?

I watched this project with great interest. While it's fine that it wasn't continued as an Atom component, I am interested in why it has been abandoned, and what replaced it. This is more just for educational purposes and an effort to improve my conception of that might be a factor in such ui-speed-driven (I assume?) decisions.

A short blurb in the intro might fix this for me and the other ~500 people who have starred it.

Unable to require after npm install

The package.json says that main is lib/space-pen.js, but this file (generated by grunt I'm guessing) isn't included under files. Or at least that's my guess for why require isn't working.

subviews require a top-level block element

For example, this would silently fail to construct the subview:

class Spacecraft extends View
  @content: (params) ->
    @subview 'launchController', new LaunchController(countdown: params.countdown)
    @h1 "Spacecraft"
    ...

The requirement seems fine (slightly restrictive, but not more than similar frameworks); the only real problem is the silent and undocumented failure.

Current dependencies

I'm really like that space-pen works and am trying to really use it in anger for client side web development. I know that this mightn't be its current primary use, but I think it has a lot of potential. The main thing that I keep scratching my head on is the dependency on jqeury, jquery extensions, underscore and underscore extensions.

I understand why these exist and that they make life extremely covenant but I'm wondering if the core of space-pen actually needs this. The question that I'm wondering is what functions does the actual core engine itself need to work vs how much is nice for devs to work with when using space-pen. If the core didn't depend on these, the overall amount of bytes one needs to use space-pen is reduced dramatically.

To start with, from what I can tell, very few of the methods in jQuery extensions are actually used, and the only function in underscore plus used is humanizeEventName and likewise with underscore the only one used is extend. From this quick look, it would appear that underscore and underscore-plus could be removed as a core dependency saving around 20kb and another 4-5kb saved by removing jQuery extensions.

Removing jQuery on the surface seems like its a bit more difficult, given that it inherits from view. But putting aside for a moment, the only functions in jQuery itself that seem to be in use is data and on, the former seems like it could be removed fairly easily and I'm wondering if the later could be an enhancement. As for the view being an actual jQuery object, could this also be treaded as an optional enhancement if jQuery exists. In my case, I could jQuery or one of the jQuery-compatible APIs if I want/need.

So, knowing space-pen more than I, do you think that this would be possible, could the current extra code that isn't need by core but needed by atom be abstracted out and included just it in another way?

Listener added via View.preempt() cannot be removed.

A handler passed to $.fn.preempt gets wrapped by jQuery in some fancy object that includes a guid. It would be most excellent if $.fn.preempt could return that wrapped handler so that it could later be passed to off() to remove said handler.

Simplify removing a listener

From this discussion, it sounds like the goal is to use Emitter as a mixin for SpacePen's View so that on() returns a Subscription that has an off() method that can be used to remove the listener.

I worry that this is going to be a bit of a pain because space-pen-extensions.coffee already mixes in a similar class:

Subscriber.includeInto(spacePen.View)

Currently, the implementation of command() is super(commandName, selector, options, handler), which I believe delegates to this method:

$.fn.command = (eventName, selector, options, handler) ->
  if not options?
    handler  = selector
    selector = null
  else if not handler?
    handler = options
    options = null

  if selector? and typeof(selector) is 'object'
    options  = selector
    selector = null

  @document(eventName, _.humanizeEventName(eventName, options?['doc']))
  @on(eventName, selector, options?['data'], handler)

So perhaps, at least as a stopgap, this method could return an object with an off() method that removes the listener (and releases appropriate references), and at some point in the future, the return value could be a true Subscription, which would have the same contract? As it stands today, SpacePen appears to have minimal dependencies (underscore-plus being the only one), so it would be nice to be able to get this feature today without having to wait for all of this jQuery/Emitter/Subscription stuff to be figured out.

Why the dependency on jquery-extensions

I'm in the process of looking at creating the bower package for space-pen and looking at the dependencies I noticed something weird.

Space-pen tries to take a dependency on jquery-extensions if it "requirable" but if its not, just falls back to window.jquery - here.

So I have couple of questions:

  1. If it works fine with just jquery, why try for jquery-extensions
  2. I'm looking at using space-pen within the context of bowserfy and it would be nice if within the require check, if jquery-extensions wasn't available (assuming its needed), it tried to require jquery. Then, at that point, if require shows up empty, go to window.jquery

Does this make sense?

@subview in top level of given view

Hi there
if you use a subview in root level of a view it does not work. Like this:

$('.other-class').append $$ ->
  @div id: 'foobar', =>
        @button class: 'btn selected', 'data-display-class': 'show-bar', 'bar'
        @button class: 'btn', 'data-display-class': 'show-data', 'data'
  @subview '__', [subview...]

I digged into it and found what could be the problem. Within Builder.prototype.subview there is following part which will not work with the example above:

      return this.postProcessingSteps.push(function(view) {
        view[outletName] = subview;
        subview.parentView = view;
        return view.find("div#" + subviewId).replaceWith(subview);
      });

The returned view contains all the root elements (here: div#foobar, div#subview-\d+).
Now .find(...) tries to find div#subview-\d+ but as it is one of the root elements it can't find it.

A workaround for me was simply to add a div around the subview. But you have to know that first. : )

Compiling to js

Any docs regarding how to compile and serve the coffee view files as JS?

Thanks!

Missing a LICENSE

What license is this distributed under? Can you add a LICENSE or MIT-LICENSE file?

Subview appears above table

I have a view defined as this:

    @content: ->
      @div =>
        @h1 "Take a Register"
        @table class: 'table hovered', =>
          @thead =>
            @tr =>
              @th "Class"
              for session in Session.all()
                @th session.name

          @tbody =>
            for klass in Class.all()
              @tr =>
                @td klass.name
                for session in Session.all()
                  @subview 'sessioncell', new SessionCellView(klass, session)

the first for session... works fine adding X number of table headings the second is supposed to add a subview which (for the moment) looks like this:

@content: (klass, session) ->
      @td =>
        @span klass.name + session.name

but when this gets rendered the page html is actually:

<div callattachhooks="true">
<h1>Take a Register</h1>
<td callattachhooks="true"><span>CL1Morning</span></td>
<td callattachhooks="true"><span>CL1Afternoon</span></td>
<td callattachhooks="true"><span>CL2Morning</span></td>
<td callattachhooks="true"><span>CL2Afternoon</span></td>
<td callattachhooks="true"><span>CL3Morning</span></td>
<td callattachhooks="true"><span>CL3Afternoon</span></td>
<td callattachhooks="true"><span>CL4Morning</span></td>
<td callattachhooks="true"><span>CL4Afternoon</span></td>
<td callattachhooks="true"><span>CL5Morning</span></td>
<td callattachhooks="true"><span>CL5Afternoon</span></td>
<td callattachhooks="true"><span>CL6Morning</span></td>
<td callattachhooks="true"><span>CL6Afternoon</span></td>
<td callattachhooks="true"><span>RECMorning</span></td>
<td callattachhooks="true"><span>RECAfternoon</span></td>
<table class="table hovered">
  <thead>
    <tr>
      <th>Class</th>
      <th>Morning</th>
      <th>Afternoon</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>CL1</td>
    </tr>
    <tr>
      <td>CL2</td>
    </tr>
    <tr>
      <td>CL3</td>
    </tr>
    <tr>
      <td>CL4</td>
    </tr>
    <tr>
      <td>CL5</td>
    </tr>
    <tr>
      <td>CL6</td>
    </tr>
    <tr>
       <td>REC</td>
    </tr>
  </tbody>
</table>
</div>

Anyone got any ideas as to the problem?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.