Skip to content

Commit

Permalink
DOM element getter component, refs #66
Browse files Browse the repository at this point in the history
  • Loading branch information
bergie committed Apr 19, 2013
1 parent 05f52be commit 42b1d0f
Show file tree
Hide file tree
Showing 5 changed files with 134 additions and 0 deletions.
2 changes: 2 additions & 0 deletions component.json
Expand Up @@ -26,12 +26,14 @@
"lib/ComponentLoader.js",
"lib/NoFlo.js",
"lib/Network.js",
"components/GetElement.js",
"components/Callback.js",
"components/Split.js",
"components/Merge.js"
],
"noflo": {
"components": {
"GetElement": "components/GetElement.js",
"Callback": "components/Callback.js",
"Split": "components/Split.js",
"Merge": "components/Merge.js"
Expand Down
1 change: 1 addition & 0 deletions components.js
Expand Up @@ -5,4 +5,5 @@ exports.register = function (loader) {
loader.registerComponent('', 'Split', '/noflo/components/Split.js');
loader.registerComponent('', 'Merge', '/noflo/components/Merge.js');
loader.registerComponent('', 'Callback', '/noflo/components/Callback.js');
loader.registerComponent('', 'GetElement', '/noflo/components/GetElement.js');
};
77 changes: 77 additions & 0 deletions spec/GetElement.coffee
@@ -0,0 +1,77 @@
if typeof process is 'object' and process.title is 'node'
# TODO: Use jsdom to make DOM components work also on Node
return
else
getelement = require 'noflo/components/GetElement.js'
socket = require 'noflo/lib/InternalSocket.js'

describe 'GetElement component', ->
c = null
ins = null
selector = null
element = null
error = null
beforeEach ->
c = getelement.getComponent()
ins = socket.createSocket()
selector = socket.createSocket()
element = socket.createSocket()
error = socket.createSocket()
c.inPorts.in.attach ins
c.inPorts.selector.attach selector
c.outPorts.element.attach element

describe 'with non-matching query', ->
it 'should throw an error when ERROR port is not attached', ->
chai.expect(-> selector.send 'Foo').to.throw Error
it 'should transmit an Error when ERROR port is attached', (done) ->
error.once 'data', (data) ->
chai.expect(data).to.be.an.instanceof Error
done()
c.outPorts.error.attach error
selector.send 'Foo'

describe 'with invalid query', ->
it 'should throw an error when ERROR port is not attached', ->
chai.expect(-> ins.send {}).to.throw Error
it 'should transmit an Error when ERROR port is attached', (done) ->
error.once 'data', (data) ->
chai.expect(data).to.be.an.instanceof Error
done()
c.outPorts.error.attach error
ins.send {}

describe 'with invalid container', ->
it 'should throw an error when ERROR port is not attached', ->
chai.expect(-> ins.send {}).to.throw Error
it 'should transmit an Error when ERROR port is attached', (done) ->
error.once 'data', (data) ->
chai.expect(data).to.be.an.instanceof Error
done()
c.outPorts.error.attach error
ins.send {}

describe 'with matching query without container', ->
it 'should send the matched element to the ELEMENT port', (done) ->
query = '#fixtures .getelement'
el = document.querySelector query
element.once 'data', (data) ->
chai.expect(data.tagName).to.exist
chai.expect(data.tagName).to.equal 'DIV'
chai.expect(data.innerHTML).to.equal 'Foo'
chai.expect(data).to.equal el
done()
selector.send query

describe 'with matching query with container', ->
it 'should send the matched element to the ELEMENT port', (done) ->
container = document.querySelector '#fixtures'
el = document.querySelector '#fixtures .getelement'
element.once 'data', (data) ->
chai.expect(data.tagName).to.exist
chai.expect(data.tagName).to.equal 'DIV'
chai.expect(data.innerHTML).to.equal 'Foo'
chai.expect(data).to.equal el
done()
ins.send container
selector.send '.getelement'
9 changes: 9 additions & 0 deletions spec/runner.html
Expand Up @@ -4,9 +4,17 @@
<meta charset="utf-8">
<title>NoFlo in browser</title>
<link rel="stylesheet" href="../node_modules/mocha/mocha.css">
<style type="text/css">
#fixtures {
display: none;
}
</style>
</head>
<body>
<div id="mocha"></div>
<div id="fixtures">
<div class="getelement">Foo</div>
</div>
<script src="../browser/noflo.js"></script>
<script src="http://chaijs.com/chai.js"></script>
<script src="../node_modules/mocha/mocha.js"></script>
Expand All @@ -18,6 +26,7 @@
<script src="./ComponentLoader.js"></script>
<script src="./Network.js"></script>
<script src="./Callback.js"></script>
<script src="./GetElement.js"></script>
<script>
if (window.mochaPhantomJS) {
mochaPhantomJS.run();
Expand Down
45 changes: 45 additions & 0 deletions src/components/GetElement.coffee
@@ -0,0 +1,45 @@
if typeof process is 'object' and process.title is 'node'
noflo = require "../../lib/NoFlo"
else
noflo = require '/noflo'

class GetElement extends noflo.Component
description: 'Get a DOM element matching a query'
constructor: ->
@container = null

@inPorts =
in: new noflo.Port 'object'
selector: new noflo.Port 'string'
@outPorts =
element: new noflo.Port 'object'
error: new noflo.Port 'object'

@inPorts.in.on 'data', (data) =>
unless typeof data.querySelector is 'function'
@error 'Given container doesn\'t support querySelectors'
return
@container = data

@inPorts.selector.on 'data', (data) =>
@select data

select: (selector) ->
if @container
el = @container.querySelector selector
else
el = document.querySelector selector
unless el
@error "No element matching '#{selector}' found"
return
@outPorts.element.send el
@outPorts.element.disconnect()

error: (msg) ->
if @outPorts.error.isAttached()
@outPorts.error.send new Error msg
@outPorts.error.disconnect()
return
throw new Error msg

exports.getComponent = -> new GetElement

0 comments on commit 42b1d0f

Please sign in to comment.