mirror of
https://github.com/meteor/meteor.git
synced 2026-01-09 07:38:15 -05:00
Document Blaze.Var, check in doctool.js
This commit is contained in:
@@ -1,9 +1,87 @@
|
||||
// `[new] Blaze.Var(initializer[, equalsFunc])`
|
||||
//
|
||||
// A Var is a reactive mutable variable which may be initialized with a
|
||||
// value or a with a reactive function. If the initializer is a reactive
|
||||
// function, a Deps Computation is kicked off from the constructor
|
||||
// that updates the reactive variable.
|
||||
/**
|
||||
* ## [new] Blaze.Var(initializer[, equalsFunc])
|
||||
*
|
||||
* A reactive mutable variable which may be initialized with a value
|
||||
* or with a function to immediately autorun.
|
||||
*
|
||||
* * `initializer` - A function or a non-function value to use to
|
||||
* initialize the Var. If a function is given, it is called in
|
||||
* a `Deps.autorun` nested within the current Deps computation.
|
||||
*
|
||||
* * `equalsFunc` - A comparator function that takes two arguments
|
||||
* and returns a boolean. The value of the Var is only considered
|
||||
* to have changed (for the purpose of invalidating Computations)
|
||||
* if `equalsFunc(newValue, oldValue)` is truthy. If `equalsFunc`
|
||||
* is not given, `===` is used.
|
||||
*
|
||||
* Blaze.Var holds a single reactive value, providing `get` and `set`
|
||||
* methods that obey the usual reactive contract of a Deps data
|
||||
* source. (Namely, calling `get` causes the current Computation to
|
||||
* depend on the value, and calling `set` invalidates any dependent
|
||||
* Computations if it changes the value.)
|
||||
*
|
||||
* If a function is provided as an initializer, it is called to set
|
||||
* the initial value of the Var, and a Computation is started that
|
||||
* sets the value of the Var each time it re-runs. Because this new
|
||||
* (inner) Computation is nested in the current (outer) Computation,
|
||||
* when the outer Computation is invalidated, the inner Computation
|
||||
* is stopped. A Var whose Computation is stopped continues to be
|
||||
* reactively gettable and settable in the usual way.
|
||||
*
|
||||
* To avoid runaway Vars, an outer Computation is required to create a
|
||||
* Var with a function as initializer. As long as the outer Computation
|
||||
* is eventually invalidated or stopped, the Var will eventually
|
||||
* stop recomputing its value.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
var a = Blaze.Var(1);
|
||||
var b = Blaze.Var(1);
|
||||
|
||||
Deps.autorun(function () {
|
||||
console.log('LOG:', a.get() + b.get());
|
||||
});
|
||||
// => LOG: 2
|
||||
|
||||
// These statements are assumed to be typed one at a time
|
||||
// at the console, giving the autorun a chance to re-run
|
||||
// between them.
|
||||
b.set(2); // => LOG: 3
|
||||
a.set(2); // => LOG: 4
|
||||
a.set(10), b.set(10); // => LOG: 20 (printed once)
|
||||
* ```
|
||||
*
|
||||
* To use a Var with an initializer function, an outer autorun is necessary
|
||||
* and is used to stop the recomputation.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* ```
|
||||
var a = Blaze.Var(1);
|
||||
var b = Blaze.Var(1);
|
||||
|
||||
var handle = Deps.autorun(function () {
|
||||
var c = Blaze.Var(function () {
|
||||
return a.get() + b.get();
|
||||
});
|
||||
|
||||
Deps.autorun(function () {
|
||||
console.log('LOG:', c.get());
|
||||
});
|
||||
});
|
||||
// => LOG: 2
|
||||
|
||||
// These statements are assumed to be typed one at a time
|
||||
// at the console.
|
||||
b.set(2); // => LOG: 3
|
||||
a.set(2); // => LOG: 4
|
||||
a.set(10), b.set(10); // => LOG: 20 (printed once)
|
||||
handle.stop();
|
||||
a.set(1); // nothing printed
|
||||
* ```
|
||||
*/
|
||||
|
||||
Blaze.Var = function (initializer, equalsFunc) {
|
||||
var self = this;
|
||||
|
||||
@@ -35,12 +113,24 @@ Blaze.Var = function (initializer, equalsFunc) {
|
||||
};
|
||||
|
||||
_.extend(Blaze.Var.prototype, {
|
||||
/**
|
||||
* ## Blaze.Var#get()
|
||||
*
|
||||
* Returns the current value of the Var, causing the current
|
||||
* Deps Computation (if any) to depend on the value.
|
||||
*/
|
||||
get: function () {
|
||||
if (Deps.active)
|
||||
this.dep.depend();
|
||||
|
||||
return this.curValue;
|
||||
},
|
||||
/**
|
||||
* ## Blaze.Var#set(newValue)
|
||||
*
|
||||
* Sets the current value of the Var, causing any dependent
|
||||
* Computations to be invalidated.
|
||||
*/
|
||||
set: function (newValue) {
|
||||
var equals = this.equalsFunc;
|
||||
var oldValue = this.curValue;
|
||||
@@ -55,6 +145,12 @@ _.extend(Blaze.Var.prototype, {
|
||||
this.curValue = newValue;
|
||||
this.dep.changed();
|
||||
},
|
||||
/**
|
||||
* ## Blaze.Var#toString()
|
||||
*
|
||||
* Returns a String representation of the Var, which
|
||||
* includes the string form of its value.
|
||||
*/
|
||||
toString: function () {
|
||||
return 'Var{' + this.get() + '}';
|
||||
}
|
||||
|
||||
102
packages/blaze/var.md
Normal file
102
packages/blaze/var.md
Normal file
@@ -0,0 +1,102 @@
|
||||
*This file is automatically generated from [`var.js`](var.js).*
|
||||
|
||||
## [new] Blaze.Var(initializer[, equalsFunc])
|
||||
|
||||
A reactive mutable variable which may be initialized with a value
|
||||
or with a function to immediately autorun.
|
||||
|
||||
* `initializer` - A function or a non-function value to use to
|
||||
initialize the Var. If a function is given, it is called in
|
||||
a `Deps.autorun` nested within the current Deps computation.
|
||||
|
||||
* `equalsFunc` - A comparator function that takes two arguments
|
||||
and returns a boolean. The value of the Var is only considered
|
||||
to have changed (for the purpose of invalidating Computations)
|
||||
if `equalsFunc(newValue, oldValue)` is truthy. If `equalsFunc`
|
||||
is not given, `===` is used.
|
||||
|
||||
Blaze.Var holds a single reactive value, providing `get` and `set`
|
||||
methods that obey the usual reactive contract of a Deps data
|
||||
source. (Namely, calling `get` causes the current Computation to
|
||||
depend on the value, and calling `set` invalidates any dependent
|
||||
Computations if it changes the value.)
|
||||
|
||||
If a function is provided as an initializer, it is called to set
|
||||
the initial value of the Var, and a Computation is started that
|
||||
sets the value of the Var each time it re-runs. Because this new
|
||||
(inner) Computation is nested in the current (outer) Computation,
|
||||
when the outer Computation is invalidated, the inner Computation
|
||||
is stopped. A Var whose Computation is stopped continues to be
|
||||
reactively gettable and settable in the usual way.
|
||||
|
||||
To avoid runaway Vars, an outer Computation is required to create a
|
||||
Var with a function as initializer. As long as the outer Computation
|
||||
is eventually invalidated or stopped, the Var will eventually
|
||||
stop recomputing its value.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
var a = Blaze.Var(1);
|
||||
var b = Blaze.Var(1);
|
||||
|
||||
Deps.autorun(function () {
|
||||
console.log('LOG:', a.get() + b.get());
|
||||
});
|
||||
// => LOG: 2
|
||||
|
||||
// These statements are assumed to be typed one at a time
|
||||
// at the console, giving the autorun a chance to re-run
|
||||
// between them.
|
||||
b.set(2); // => LOG: 3
|
||||
a.set(2); // => LOG: 4
|
||||
a.set(10), b.set(10); // => LOG: 20 (printed once)
|
||||
```
|
||||
|
||||
To use a Var with an initializer function, an outer autorun is necessary
|
||||
and is used to stop the recomputation.
|
||||
|
||||
Example:
|
||||
|
||||
```
|
||||
var a = Blaze.Var(1);
|
||||
var b = Blaze.Var(1);
|
||||
|
||||
var handle = Deps.autorun(function () {
|
||||
var c = Blaze.Var(function () {
|
||||
return a.get() + b.get();
|
||||
});
|
||||
|
||||
Deps.autorun(function () {
|
||||
console.log('LOG:', c.get());
|
||||
});
|
||||
});
|
||||
// => LOG: 2
|
||||
|
||||
// These statements are assumed to be typed one at a time
|
||||
// at the console.
|
||||
b.set(2); // => LOG: 3
|
||||
a.set(2); // => LOG: 4
|
||||
a.set(10), b.set(10); // => LOG: 20 (printed once)
|
||||
handle.stop();
|
||||
a.set(1); // nothing printed
|
||||
```
|
||||
|
||||
|
||||
## Blaze.Var#get()
|
||||
|
||||
Returns the current value of the Var, causing the current
|
||||
Deps Computation (if any) to depend on the value.
|
||||
|
||||
|
||||
## Blaze.Var#set(newValue)
|
||||
|
||||
Sets the current value of the Var, causing any dependent
|
||||
Computations to be invalidated.
|
||||
|
||||
|
||||
## Blaze.Var#toString()
|
||||
|
||||
Returns a String representation of the Var, which
|
||||
includes the string form of its value.
|
||||
|
||||
@@ -10,15 +10,15 @@ templates during compilation.
|
||||
var UL = HTML.UL, LI = HTML.LI, B = HTML.B;
|
||||
|
||||
HTML.toHTML(
|
||||
UL({id: 'mylist'},
|
||||
LI({'class': 'item'}, "Hello ", B("world"), "!"),
|
||||
LI({'class': 'item'}, "Goodbye, world")))
|
||||
UL({id: 'mylist'},
|
||||
LI({'class': 'item'}, "Hello ", B("world"), "!"),
|
||||
LI({'class': 'item'}, "Goodbye, world")))
|
||||
```
|
||||
|
||||
```
|
||||
<ul id="mylist">
|
||||
<li class="item">Hello <b>world</b>!</li>
|
||||
<li class="item">Goodbye, world</li>
|
||||
<li class="item">Hello <b>world</b>!</li>
|
||||
<li class="item">Goodbye, world</li>
|
||||
</ul>
|
||||
```
|
||||
|
||||
|
||||
154
scripts/doctool.js
Executable file
154
scripts/doctool.js
Executable file
@@ -0,0 +1,154 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/// # doctool.js
|
||||
///
|
||||
/// Usage: `doctool.js ...jsfiles...`
|
||||
///
|
||||
/// Reads each `.js` file and writes a `.md` file in the same directory.
|
||||
/// The output file consists of the concatenation of the "doc comments"
|
||||
/// in the input file, which are assumed to contain Markdown content,
|
||||
/// including any section headings necessary to organize the file.
|
||||
///
|
||||
/// A "doc comment" must begin at the start of a line or after
|
||||
/// whitespace. There are two kinds of doc comments: `/** ... */`
|
||||
/// (block) comments and `/// ...` (triple-slash) comments.
|
||||
///
|
||||
/// If a file begins with the magic string "///!README", the output
|
||||
/// filename is changed to `README.md`.
|
||||
///
|
||||
/// Examples:
|
||||
///
|
||||
/// ```
|
||||
/// /**
|
||||
/// * This is a block comment. The parser strips the sequence,
|
||||
/// * [optional whitespace, `*`, optional single space] from
|
||||
/// * every line that has it.
|
||||
/// *
|
||||
/// For lines that don't, no big deal.
|
||||
///
|
||||
/// Leading whitspace will be preserved here.
|
||||
///
|
||||
/// * We can create a bullet list in here:
|
||||
/// *
|
||||
/// * * This is a bullet
|
||||
/// */
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// /** Single-line block comments are also ok. */
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// /**
|
||||
/// A block comment whose first line doesn't have a `*` receives
|
||||
/// no stripping of `*` characters on any line.
|
||||
///
|
||||
/// * This is a bullet
|
||||
///
|
||||
/// */
|
||||
/// ```
|
||||
///
|
||||
/// ```
|
||||
/// /// A triple-slash comment starts with `///` followed by an
|
||||
/// /// optional space (i.e. one space is removed if present).
|
||||
/// /// Multiple consecutive lines that start with `///` are
|
||||
/// /// treated together as a single doc comment.
|
||||
/// /** Separate doc comments get separate paragraphs. */
|
||||
/// ```
|
||||
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
|
||||
process.argv.slice(2).forEach(function (fileName) {
|
||||
var text = fs.readFileSync(fileName, "utf8");
|
||||
|
||||
var outFileName = fileName.replace(/\.js$/, '') + '.md';
|
||||
if (text.slice(0, 10) === '///!README') {
|
||||
outFileName = path.join(path.dirname(fileName), 'README.md');
|
||||
text = text.slice(10);
|
||||
}
|
||||
|
||||
var docComments = [];
|
||||
for (;;) {
|
||||
// This regex breaks down as follows:
|
||||
//
|
||||
// 1. Start of line
|
||||
// 2. Optional whitespace (not newline!)
|
||||
// 3. `///` (capturing group 1) or `/**` (group 2)
|
||||
// 4. Looking ahead, NOT `/` or `*`
|
||||
var nextOpener = /^[ \t]*(?:(\/\/\/)|(\/\*\*))(?![\/\*])/m.exec(text);
|
||||
if (! nextOpener)
|
||||
break;
|
||||
text = text.slice(nextOpener.index + nextOpener[0].length);
|
||||
if (nextOpener[1]) {
|
||||
// triple-slash
|
||||
text = text.replace(/^[ \t]/, ''); // optional space
|
||||
var comment = text.match(/^[^\n]*/)[0];
|
||||
text = text.slice(comment.length);
|
||||
var match;
|
||||
while ((match = /^\n[ \t]*\/\/\/[ \t]?/.exec(text))) {
|
||||
// multiple lines in a row become one comment
|
||||
text = text.slice(match[0].length);
|
||||
var restOfLine = text.match(/^[^\n]*/)[0];
|
||||
text = text.slice(restOfLine.length);
|
||||
comment += '\n' + restOfLine;
|
||||
}
|
||||
if (comment.trim())
|
||||
docComments.push(['///', comment]);
|
||||
} else if (nextOpener[2]) {
|
||||
// block comment
|
||||
var rawComment = text.match(/^[\s\S]*?\*\//);
|
||||
if ((! rawComment) || (! rawComment[0]))
|
||||
continue;
|
||||
rawComment = rawComment[0];
|
||||
text = text.slice(rawComment.length);
|
||||
rawComment = rawComment.slice(0, -2); // remove final `*/`
|
||||
if (rawComment.slice(-1) === ' ')
|
||||
// make that ' */' for the benefit of single-line blocks
|
||||
rawComment = rawComment.slice(0, -1);
|
||||
|
||||
var lines = rawComment.split('\n');
|
||||
|
||||
var stripStars = false;
|
||||
if (lines[0].trim().length === 0) {
|
||||
// The comment has a newline after the `/**` (with possible whitespace
|
||||
// between). This is like most comments, though occasionally people
|
||||
// may write `/** foo */` on one line. Skip the blank line.
|
||||
lines.splice(0, 1);
|
||||
if (! lines.length)
|
||||
continue;
|
||||
// Now we determine whether this is block comment with a column of
|
||||
// asterisks running down the left side, so we can strip them.
|
||||
stripStars = /^[ \t]*\*/.test(lines[1]);
|
||||
} else {
|
||||
// Trim beginning of line after `/**`
|
||||
lines[0] = lines[0].replace(/^\s*/, '');
|
||||
}
|
||||
|
||||
lines = lines.map(function (s) {
|
||||
// Strip either up to an asterisk and then an optional space,
|
||||
// or just an optional space, depending on `stripStars`.
|
||||
if (stripStars)
|
||||
return s.replace(/^[ \t]*\* ?/, '');
|
||||
else
|
||||
return s;
|
||||
});
|
||||
|
||||
var result = lines.join('\n');
|
||||
|
||||
if (result.trim())
|
||||
docComments.push(['/**', result]);
|
||||
}
|
||||
}
|
||||
|
||||
if (docComments.length) {
|
||||
var output = docComments.map(function (x) { return x[1]; }).join('\n\n');
|
||||
var fileShortName = path.basename(fileName);
|
||||
output = '*This file is automatically generated from [`' +
|
||||
fileShortName + '`](' + fileShortName + ').*\n\n' + output;
|
||||
fs.writeFileSync(outFileName, output, 'utf8');
|
||||
console.log("Wrote " + docComments.length + " comments to " + outFileName);
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
57
scripts/doctool.md
Normal file
57
scripts/doctool.md
Normal file
@@ -0,0 +1,57 @@
|
||||
*This file is automatically generated from [`doctool.js`](doctool.js).*
|
||||
|
||||
# doctool.js
|
||||
|
||||
Usage: `doctool.js ...jsfiles...`
|
||||
|
||||
Reads each `.js` file and writes a `.md` file in the same directory.
|
||||
The output file consists of the concatenation of the "doc comments"
|
||||
in the input file, which are assumed to contain Markdown content,
|
||||
including any section headings necessary to organize the file.
|
||||
|
||||
A "doc comment" must begin at the start of a line or after
|
||||
whitespace. There are two kinds of doc comments: `/** ... */`
|
||||
(block) comments and `/// ...` (triple-slash) comments.
|
||||
|
||||
If a file begins with the magic string "///!README", the output
|
||||
filename is changed to `README.md`.
|
||||
|
||||
Examples:
|
||||
|
||||
```
|
||||
/**
|
||||
* This is a block comment. The parser strips the sequence,
|
||||
* [optional whitespace, `*`, optional single space] from
|
||||
* every line that has it.
|
||||
*
|
||||
For lines that don't, no big deal.
|
||||
|
||||
Leading whitspace will be preserved here.
|
||||
|
||||
* We can create a bullet list in here:
|
||||
*
|
||||
* * This is a bullet
|
||||
*/
|
||||
```
|
||||
|
||||
```
|
||||
/** Single-line block comments are also ok. */
|
||||
```
|
||||
|
||||
```
|
||||
/**
|
||||
A block comment whose first line doesn't have a `*` receives
|
||||
no stripping of `*` characters on any line.
|
||||
|
||||
* This is a bullet
|
||||
|
||||
*/
|
||||
```
|
||||
|
||||
```
|
||||
/// A triple-slash comment starts with `///` followed by an
|
||||
/// optional space (i.e. one space is removed if present).
|
||||
/// Multiple consecutive lines that start with `///` are
|
||||
/// treated together as a single doc comment.
|
||||
/** Separate doc comments get separate paragraphs. */
|
||||
```
|
||||
30
scripts/doctool.md.md
Normal file
30
scripts/doctool.md.md
Normal file
@@ -0,0 +1,30 @@
|
||||
*This file is automatically generated from [`doctool.md`](doctool.md).*
|
||||
|
||||
This is a block comment. The parser strips the sequence,
|
||||
[optional whitespace, `*`, optional single space] from
|
||||
every line that has it.
|
||||
|
||||
For lines that don't, no big deal.
|
||||
|
||||
Leading whitspace will be preserved here.
|
||||
|
||||
We can create a bullet list in here:
|
||||
|
||||
* This is a bullet
|
||||
|
||||
|
||||
Single-line block comments are also ok.
|
||||
|
||||
A block comment whose first line doesn't have a `*` receives
|
||||
no stripping of `*` characters on any line.
|
||||
|
||||
* This is a bullet
|
||||
|
||||
|
||||
|
||||
A triple-slash comment starts with `///` followed by an
|
||||
optional space (i.e. one space is removed if present).
|
||||
Multiple consecutive lines that start with `///` are
|
||||
treated together as a single doc comment.
|
||||
|
||||
Separate doc comments get separate paragraphs.
|
||||
Reference in New Issue
Block a user