mirror of
https://github.com/meteor/meteor.git
synced 2026-05-02 03:01:46 -04:00
clean up the demo
This commit is contained in:
@@ -152,7 +152,7 @@ Commands.push({
|
||||
|
||||
var example_dir = path.join(__dirname, '../../examples');
|
||||
var examples = _.reject(fs.readdirSync(example_dir), function (e) {
|
||||
return (e === 'unfinished');
|
||||
return (e === 'unfinished' || e === 'other');
|
||||
});
|
||||
|
||||
if (argv._.length === 1) {
|
||||
|
||||
@@ -1,20 +0,0 @@
|
||||
/* CSS declarations go here */
|
||||
|
||||
@-webkit-keyframes spinForward {
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spinBackward {
|
||||
from {-webkit-transform: rotate(360deg);}
|
||||
to {-webkit-transform: rotate(0deg);}
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 100px;
|
||||
border: 2px solid black;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background: white;
|
||||
}
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
<head>
|
||||
<title>landmark-demo</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<h1>Spark demo</h1>
|
||||
{{> redrawButtons }}
|
||||
{{> preserveDemo }}
|
||||
{{> constantDemo }}
|
||||
{{> stateDemo }}
|
||||
{{> d3Demo }}
|
||||
</body>
|
||||
|
||||
<template name="redrawButtons">
|
||||
<input type="button" value="X++" class="x">
|
||||
<input type="button" value="Y++" class="y">
|
||||
<input type="button" value="Z++" class="z">
|
||||
<br>
|
||||
</template>
|
||||
|
||||
<template name="preserveDemo">
|
||||
<h2>Simple element preservation</h2>
|
||||
X={{x}}<br>
|
||||
<div class="spinner" style="-webkit-animation: {{spinAnim}} 2s infinite linear">
|
||||
X={{x}}
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" class="spinforward" {{spinForwardChecked}}>
|
||||
Spin Forward
|
||||
</div>
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="constantDemo">
|
||||
<h2>Constant regions</h2>
|
||||
X={{x}}<br>
|
||||
{{#constant}}
|
||||
<div style="float: left; padding-right: 20px;">
|
||||
<iframe width="200" height="200" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=140+10th+Street,+San+Francisco,+CA&aq=0&oq=140+10th+s&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=140+10th+St,+San+Francisco,+California+94103&t=m&ll=37.774921,-122.415419&spn=0.013569,0.017252&z=14&iwloc=A&output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=140+10th+Street,+San+Francisco,+CA&aq=0&oq=140+10th+s&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=140+10th+St,+San+Francisco,+California+94103&t=m&ll=37.774921,-122.415419&spn=0.013569,0.017252&z=14&iwloc=A" style="color:#0000FF;text-align:left">View Larger Map</a></small>
|
||||
</div>
|
||||
{{/constant}}
|
||||
{{#constant}}
|
||||
<div>
|
||||
<iframe width="200" height="200" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=880+Harrison+Street,+San+Francisco,+CA&aq=0&oq=880+harrison&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=880+Harrison+St,+San+Francisco,+California+94107&t=m&ll=37.779534,-122.411213&spn=0.013568,0.01708&z=14&iwloc=A&output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=880+Harrison+Street,+San+Francisco,+CA&aq=0&oq=880+harrison&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=880+Harrison+St,+San+Francisco,+California+94107&t=m&ll=37.779534,-122.411213&spn=0.013568,0.01708&z=14&iwloc=A" style="color:#0000FF;text-align:left">View Larger Map</a></small>
|
||||
</div>
|
||||
{{/constant}}
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="stateDemo">
|
||||
<h2>Template callbacks</h2>
|
||||
X={{x}}<br>
|
||||
<input type="button" value="Create a timer" class="create"><br>
|
||||
{{#each timers}}
|
||||
<div>
|
||||
{{> timer}}
|
||||
Y={{y}}
|
||||
</div>
|
||||
{{/each}}
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="timer">
|
||||
<span class="elapsed"></span>
|
||||
<input type="button" value="Reset" class="reset">
|
||||
<input type="button" value="Delete" class="delete">
|
||||
Z={{z}}
|
||||
</template>
|
||||
|
||||
<template name="d3Demo">
|
||||
<h2>Simple d3.js integration</h2>
|
||||
{{> circles left}}
|
||||
{{> circles right}}
|
||||
</template>
|
||||
|
||||
<template name="circles">
|
||||
<div style="float: left; padding-right: 20px;">
|
||||
{{#constant}}
|
||||
<svg width="200" height="200" class="xyzzy"></svg>
|
||||
{{/constant}}
|
||||
<br>
|
||||
{{count}} circles<br>
|
||||
<input type="button" value="Add" class="add">
|
||||
<input type="button" value="Remove" class="remove" {{{disabled}}}>
|
||||
<input type="button" value="Scram" class="scram">
|
||||
</div>
|
||||
</template>
|
||||
44
examples/other/template-demo/client/template-demo.css
Normal file
44
examples/other/template-demo/client/template-demo.css
Normal file
@@ -0,0 +1,44 @@
|
||||
body {
|
||||
font-family: 'Helvetica Neue', Helvetica, Arial, san-serif;
|
||||
width: 600px;
|
||||
margin: auto;
|
||||
padding: 25px 50px;
|
||||
border: 5px dashed #ccc;
|
||||
border-style: none dashed;
|
||||
}
|
||||
|
||||
h2 {
|
||||
margin-top: 50px;
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
.clearboth {
|
||||
clear: both;
|
||||
}
|
||||
|
||||
@-webkit-keyframes spinForward {
|
||||
from {-webkit-transform: rotate(0deg);}
|
||||
to {-webkit-transform: rotate(360deg);}
|
||||
}
|
||||
|
||||
@-webkit-keyframes spinBackward {
|
||||
from {-webkit-transform: rotate(360deg);}
|
||||
to {-webkit-transform: rotate(0deg);}
|
||||
}
|
||||
|
||||
.spinner {
|
||||
width: 100px;
|
||||
border: 2px solid black;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
background: white;
|
||||
}
|
||||
|
||||
.circles {
|
||||
float: left;
|
||||
padding-right: 20px;
|
||||
}
|
||||
|
||||
.circles svg {
|
||||
border: 2px solid #333;
|
||||
}
|
||||
182
examples/other/template-demo/client/template-demo.html
Normal file
182
examples/other/template-demo/client/template-demo.html
Normal file
@@ -0,0 +1,182 @@
|
||||
<head>
|
||||
<title>Advanced Template Demo</title>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
{{> page}}
|
||||
</body>
|
||||
|
||||
<template name="page">
|
||||
<h1>Advanced Template Demo</h1>
|
||||
<p>
|
||||
This demo shows off the advanced features of Meteor's optional
|
||||
Spark-based templating system, including constant regions, node
|
||||
preservation, per-template state, and template lifecycle
|
||||
callbacks.
|
||||
</p>
|
||||
|
||||
{{> preserveDemo }}
|
||||
{{> constantDemo }}
|
||||
{{> stateDemo }}
|
||||
{{> d3Demo }}
|
||||
</template>
|
||||
|
||||
<template name="preserveDemo">
|
||||
<h2>Element preservation</h2>
|
||||
|
||||
<input type="button" value="X++" class="x">
|
||||
|
||||
<p>
|
||||
Elements can be <em>preserved</em>, meaning that they will not be
|
||||
disturbed even as their attributes, children, or siblings
|
||||
change. In this example, when you press the X++ button, the CSS
|
||||
animation continues uninterrupted.
|
||||
</p>
|
||||
|
||||
|
||||
X={{x}}<br>
|
||||
<div class="spinner" style="-webkit-animation: {{spinAnim}} 2s infinite linear">
|
||||
X={{x}}
|
||||
</div>
|
||||
<div>
|
||||
<input type="checkbox" class="spinforward" {{spinForwardChecked}}>
|
||||
Spin Forward
|
||||
</div>
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="constantDemo">
|
||||
<h2>Constant regions</h2>
|
||||
|
||||
<div>
|
||||
<input type="button" value="X++" class="x"> <br>
|
||||
<input type="checkbox" class="remove" which="1" {{checked 1}}>
|
||||
Remove map 1<br>
|
||||
<input type="checkbox" class="remove" which="2" {{checked 2}}>
|
||||
Remove map 2
|
||||
</div>
|
||||
<br>
|
||||
|
||||
<p>
|
||||
Parts of a template can be marked as <em>constant</em>, meaning
|
||||
that Meteor will leave the entire region alone (even as its
|
||||
siblings change.) This is great for embedding non-Meteor
|
||||
widgets. Try scrolling the two Google Maps embeds below. When you
|
||||
press X++, the maps stay where they are.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
Try using the checkboxes to remove either or both of the
|
||||
maps. When you remove a map, Spark tracks the <em>identity</em> of
|
||||
the constant regions so that it knows which DOM nodes to keep and
|
||||
which DOM nodes to throw away. In the case of the Handlebars
|
||||
package, the identity is based on the actual template call stack
|
||||
that rendered the constant region.
|
||||
</p>
|
||||
|
||||
X={{x}}<br>
|
||||
|
||||
{{#if show 1}}
|
||||
{{#constant}}
|
||||
<div style="float: left; padding-right: 20px;">
|
||||
<iframe width="290" height="290" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=140+10th+Street,+San+Francisco,+CA&aq=0&oq=140+10th+s&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=140+10th+St,+San+Francisco,+California+94103&t=m&ll=37.774921,-122.415419&spn=0.013569,0.017252&z=14&iwloc=A&output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=140+10th+Street,+San+Francisco,+CA&aq=0&oq=140+10th+s&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=140+10th+St,+San+Francisco,+California+94103&t=m&ll=37.774921,-122.415419&spn=0.013569,0.017252&z=14&iwloc=A" style="color:#0000FF;text-align:left">View Larger Map</a></small>
|
||||
</div>
|
||||
{{/constant}}
|
||||
{{/if}}
|
||||
|
||||
{{#if show 2}}
|
||||
{{#constant}}
|
||||
<div>
|
||||
<iframe width="290" height="290" frameborder="0" scrolling="no" marginheight="0" marginwidth="0" src="https://maps.google.com/maps?f=q&source=s_q&hl=en&geocode=&q=880+Harrison+Street,+San+Francisco,+CA&aq=0&oq=880+harrison&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=880+Harrison+St,+San+Francisco,+California+94107&t=m&ll=37.779534,-122.411213&spn=0.013568,0.01708&z=14&iwloc=A&output=embed"></iframe><br /><small><a href="https://maps.google.com/maps?f=q&source=embed&hl=en&geocode=&q=880+Harrison+Street,+San+Francisco,+CA&aq=0&oq=880+harrison&sll=37.7577,-122.4376&sspn=0.166931,0.329247&ie=UTF8&hq=&hnear=880+Harrison+St,+San+Francisco,+California+94107&t=m&ll=37.779534,-122.411213&spn=0.013568,0.01708&z=14&iwloc=A" style="color:#0000FF;text-align:left">View Larger Map</a></small>
|
||||
</div>
|
||||
{{/constant}}
|
||||
{{/if}}
|
||||
|
||||
<div class="clearboth"> </div>
|
||||
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="stateDemo">
|
||||
<h2>Template callbacks</h2>
|
||||
|
||||
<p>
|
||||
<input type="button" value="X++" class="x">
|
||||
<input type="button" value="Y++" class="y">
|
||||
<input type="button" value="Z++" class="z">
|
||||
</p>
|
||||
|
||||
<p>
|
||||
You can get a <em>create</em> callback when a template is
|
||||
initially rendered; a <em>render</em> when a template is placed on
|
||||
the screen and when any part of the template is redrawn; and
|
||||
a <em>destroy</em> callback when a template is taken across the
|
||||
screen. All of these callbacks receive a common <em>template state
|
||||
object</em> in 'this' which allows you to attach data to each
|
||||
particular instance of a template.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
In this case, <em>create</em> is used to create a new JavaScript
|
||||
timer that updates the text of a <span> element every
|
||||
second. <em>render</em> is used to find the <span> when it
|
||||
appears on the screen, and update the pointer when the
|
||||
<span> is redraw (say, when you press Y++ — since it
|
||||
is not marked to be preserved.) <em>destroy</em> is used to cancel
|
||||
the timer when the template goes off the screen.
|
||||
</p>
|
||||
|
||||
<p>
|
||||
The template state is used to hold the current time count and a
|
||||
reference to the <span> object to update. That's why there
|
||||
can be multiple copies of the same template, each with a different
|
||||
value for the counter.
|
||||
</p>
|
||||
|
||||
X={{x}}<br>
|
||||
<input type="button" value="Create a timer" class="create"><br>
|
||||
{{#each timers}}
|
||||
<div>
|
||||
{{> timer}}
|
||||
Z={{z}}
|
||||
</div>
|
||||
{{/each}}
|
||||
X={{x}}
|
||||
</template>
|
||||
|
||||
<template name="timer">
|
||||
<span class="elapsed"></span>
|
||||
<input type="button" value="Reset" class="reset">
|
||||
<input type="button" value="Delete" class="delete">
|
||||
Y={{y}}
|
||||
</template>
|
||||
|
||||
<template name="d3Demo">
|
||||
<h2>Simple d3.js integration</h2>
|
||||
<p>
|
||||
Meteor fits naturally with the popular d3.js data visualization
|
||||
library by Michael Bostock. Just set up d3 from your
|
||||
template's <em>render</em> callback. With Meteor, you can pass
|
||||
data directly out of a Mongo query into d3, and your d3
|
||||
visualization will update in realtime, with no extra code! Try
|
||||
opening this page in two browser windows.
|
||||
</p>
|
||||
|
||||
{{> circles left}}
|
||||
{{> circles right}}
|
||||
<div class="clearboth"> </div>
|
||||
|
||||
</template>
|
||||
|
||||
<template name="circles">
|
||||
<div class="circles">
|
||||
{{#constant}}
|
||||
<svg width="200" height="200" class="xyzzy"></svg>
|
||||
{{/constant}}
|
||||
<br>
|
||||
{{count}} circles<br>
|
||||
<input type="button" value="Add" class="add">
|
||||
<input type="button" value="Remove" class="remove" {{{disabled}}}>
|
||||
<input type="button" value="Scram" class="scram">
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,5 +1,7 @@
|
||||
Timers = new Meteor.Collection(null);
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (! Session.get("x")) {
|
||||
Session.set("x", 1);
|
||||
}
|
||||
@@ -12,11 +14,23 @@ if (! Session.get("z")) {
|
||||
Session.set("z", 1);
|
||||
}
|
||||
|
||||
if (typeof Session.get("spinForward") !== 'boolean') {
|
||||
Session.set("spinForward", true);
|
||||
}
|
||||
Template.preserveDemo.x =
|
||||
Template.constantDemo.x =
|
||||
Template.stateDemo.x =
|
||||
function () {
|
||||
return Session.get("x");
|
||||
};
|
||||
|
||||
Template.redrawButtons.events = {
|
||||
Template.timer.y = function () {
|
||||
return Session.get("y");
|
||||
};
|
||||
|
||||
Template.stateDemo.z =
|
||||
function () {
|
||||
return Session.get("z");
|
||||
};
|
||||
|
||||
Template.page.events = {
|
||||
'click input.x': function () {
|
||||
Session.set("x", Session.get("x") + 1);
|
||||
},
|
||||
@@ -30,6 +44,12 @@ Template.redrawButtons.events = {
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
if (typeof Session.get("spinForward") !== 'boolean') {
|
||||
Session.set("spinForward", true);
|
||||
}
|
||||
|
||||
Template.preserveDemo.preserve([ '.spinner', '.spinforward' ]);
|
||||
|
||||
Template.preserveDemo.spinForwardChecked = function () {
|
||||
@@ -46,18 +66,24 @@ Template.preserveDemo.events = {
|
||||
}
|
||||
};
|
||||
|
||||
Template.preserveDemo.x =
|
||||
Template.constantDemo.x =
|
||||
Template.stateDemo.x =
|
||||
function () {
|
||||
return Session.get("x");
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Template.constantDemo.checked = function (which) {
|
||||
return Session.get('mapchecked' + which) ? 'checked="checked"' : '';
|
||||
};
|
||||
|
||||
Template.stateDemo.y =
|
||||
function () {
|
||||
return Session.get("y");
|
||||
Template.constantDemo.show = function (which) {
|
||||
return ! Session.get('mapchecked' + which);
|
||||
};
|
||||
|
||||
Template.constantDemo.events = {
|
||||
'change .remove' : function (event) {
|
||||
var tgt = event.currentTarget;
|
||||
Session.set('mapchecked' + tgt.getAttribute("which"), tgt.checked);
|
||||
}
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Template.stateDemo.events = {
|
||||
'click .create': function () {
|
||||
@@ -79,10 +105,6 @@ Template.timer.events = {
|
||||
}
|
||||
};
|
||||
|
||||
Template.timer.z = function () {
|
||||
return Session.get("z");
|
||||
};
|
||||
|
||||
var updateTimer = function (timer) {
|
||||
timer.node.innerHTML = timer.elapsed + " second" +
|
||||
((timer.elapsed === 1) ? "" : "s");
|
||||
@@ -90,14 +112,12 @@ var updateTimer = function (timer) {
|
||||
|
||||
Template.timer.create = function () {
|
||||
var self = this;
|
||||
console.log("timer create");
|
||||
self.elapsed = 0;
|
||||
self.node = null;
|
||||
};
|
||||
|
||||
Template.timer.render = function () {
|
||||
var self = this;
|
||||
console.log("timer render");
|
||||
self.node = this.find(".elapsed");
|
||||
updateTimer(self);
|
||||
|
||||
@@ -111,16 +131,19 @@ Template.timer.render = function () {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
Template.timer.destroy = function () {
|
||||
console.log("timer destroy");
|
||||
clearInterval(this.timer);
|
||||
};
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// XXX move to Meteor.autorun?
|
||||
// (what else does it need to replace Meteor.autosubscribe?)
|
||||
// Run f(). Record its dependencies. Rerun it whenever the
|
||||
// dependencies change.
|
||||
//
|
||||
// Returns an object with a stop() method. Call stop() to stop the
|
||||
// rerunning.
|
||||
//
|
||||
// XXX this should go into Meteor core as Meteor.autorun
|
||||
var autorun = function (f) {
|
||||
var ctx;
|
||||
var slain = false;
|
||||
@@ -149,10 +172,7 @@ Template.d3Demo.right = function () {
|
||||
};
|
||||
|
||||
Template.circles.events = {
|
||||
'click circle': function (evt, template) {
|
||||
// XXX actually want to create a ReactiveVar on the template!
|
||||
// (but how will it be preserved across migration?)
|
||||
// (maybe template.get, template.set?? rather than form??)
|
||||
'mousedown circle': function (evt, template) {
|
||||
Session.set("selectedCircle:" + this.group, evt.currentTarget.id);
|
||||
},
|
||||
'click .add': function () {
|
||||
@@ -184,9 +204,6 @@ Template.circles.events = {
|
||||
}
|
||||
};
|
||||
|
||||
Template.circles.create = function () {
|
||||
};
|
||||
|
||||
var colorToString = function (color) {
|
||||
var f = function (x) { return Math.floor(x * 256); };
|
||||
return "rgb(" + f(color.r) + "," +
|
||||
@@ -202,6 +219,9 @@ Template.circles.disabled = function () {
|
||||
'' : 'disabled="disabled"';
|
||||
};
|
||||
|
||||
Template.circles.create = function () {
|
||||
};
|
||||
|
||||
Template.circles.render = function () {
|
||||
var self = this;
|
||||
self.node = self.find("svg");
|
||||
@@ -209,9 +229,6 @@ Template.circles.render = function () {
|
||||
var data = self.data;
|
||||
|
||||
if (! self.handle) {
|
||||
// XXX template.firstRender would be handy here
|
||||
// (except that node's inside a constant region, so it's unnecessary)
|
||||
|
||||
d3.select(self.node).append("rect");
|
||||
self.handle = autorun(function () {
|
||||
var circle = d3.select(self.node).selectAll("circle")
|
||||
@@ -256,7 +273,6 @@ Template.circles.render = function () {
|
||||
.attr("r", 0)
|
||||
.remove();
|
||||
|
||||
// XXX this doesn't animate as I'd hoped when you press Scram
|
||||
var selectionId = Session.get("selectedCircle:" + data.group);
|
||||
var s = selectionId && Circles.findOne(selectionId);
|
||||
var rect = d3.select(self.node).select("rect");
|
||||
Reference in New Issue
Block a user