├── README.md
├── spec
├── lib
│ ├── jasmine.extensions.css
│ ├── jasmine.extensions.js
│ ├── jasmine.css
│ ├── jasmine-html.js
│ ├── knockout-3.0.0.js
│ └── jasmine.js
├── runner.html
└── repeatBinding.js
├── index.html
└── knockout-repeat.js
/README.md:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/mbest/knockout-repeat/HEAD/README.md
--------------------------------------------------------------------------------
/spec/lib/jasmine.extensions.css:
--------------------------------------------------------------------------------
1 | #HTMLReporter {
2 | position: absolute;
3 | background: #EEE;
4 | }
5 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | mbest/knockout-repeat @ GitHub
6 |
7 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | Repeat binding for Knockout
39 |
40 |
41 |
Download
42 |
knockout-repeat.js
43 |
44 |
Dependencies
45 |
Knockout
46 |
47 |
License
48 |
MIT (http://www.opensource.org/licenses/mit-license.php)
49 |
50 |
Author
51 |
Michael Best
52 |
53 |
56 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/spec/runner.html:
--------------------------------------------------------------------------------
1 |
3 |
4 |
5 | Knockout-repeat test runner
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/spec/lib/jasmine.extensions.js:
--------------------------------------------------------------------------------
1 | jasmine.Spec.prototype.restoreAfter = function(object, propertyName) {
2 | var originalValue = object[propertyName];
3 | this.after(function() {
4 | object[propertyName] = originalValue;
5 | });
6 | };
7 |
8 | jasmine.Matchers.prototype.toEqualOneOf = function (expectedPossibilities) {
9 | for (var i = 0; i < expectedPossibilities.length; i++) {
10 | if (this.env.equals_(this.actual, expectedPossibilities[i])) {
11 | return true;
12 | }
13 | }
14 | return false;
15 | };
16 |
17 | jasmine.Matchers.prototype.toContainHtml = function (expectedHtml) {
18 | var cleanedHtml = this.actual.innerHTML.toLowerCase().replace(/\r\n/g, "");
19 | // IE < 9 strips whitespace immediately following comment nodes. Normalize by doing the same on all browsers.
20 | cleanedHtml = cleanedHtml.replace(/()\s*/g, "$1");
21 | expectedHtml = expectedHtml.replace(/()\s*/g, "$1");
22 | // Also remove __ko__ expando properties (for DOM data) - most browsers hide these anyway but IE < 9 includes them in innerHTML
23 | cleanedHtml = cleanedHtml.replace(/ __ko__\d+=\"(ko\d+|null)\"/g, "");
24 | this.actual = cleanedHtml; // Fix explanatory message
25 | return cleanedHtml === expectedHtml;
26 | };
27 |
28 | jasmine.nodeText = function(node) {
29 | return 'textContent' in node ? node.textContent : node.innerText;
30 | }
31 |
32 | jasmine.Matchers.prototype.toContainText = function (expectedText) {
33 | var actualText = jasmine.nodeText(this.actual);
34 | var cleanedActualText = actualText.replace(/\r\n/g, "\n");
35 | this.actual = cleanedActualText; // Fix explanatory message
36 | return cleanedActualText === expectedText;
37 | };
38 |
39 | jasmine.Matchers.prototype.toHaveOwnProperties = function (expectedProperties) {
40 | var ownProperties = [];
41 | for (var prop in this.actual) {
42 | if (this.actual.hasOwnProperty(prop)) {
43 | ownProperties.push(prop);
44 | }
45 | }
46 | return this.env.equals_(ownProperties, expectedProperties);
47 | };
48 |
49 | jasmine.Matchers.prototype.toHaveTexts = function (expectedTexts) {
50 | var texts = ko.utils.arrayMap(this.actual.childNodes, jasmine.nodeText);
51 | this.actual = texts; // Fix explanatory message
52 | return this.env.equals_(texts, expectedTexts);
53 | };
54 |
55 | jasmine.Matchers.prototype.toHaveValues = function (expectedValues) {
56 | var values = ko.utils.arrayMap(this.actual.childNodes, function (node) { return node.value; });
57 | this.actual = values; // Fix explanatory message
58 | return this.env.equals_(values, expectedValues);
59 | };
60 |
61 | jasmine.Matchers.prototype.toHaveSelectedValues = function (expectedValues) {
62 | var selectedNodes = ko.utils.arrayFilter(this.actual.childNodes, function (node) { return node.selected; }),
63 | selectedValues = ko.utils.arrayMap(selectedNodes, function (node) { return ko.selectExtensions.readValue(node); });
64 | this.actual = selectedValues; // Fix explanatory message
65 | return this.env.equals_(selectedValues, expectedValues);
66 | };
67 |
68 | jasmine.prepareTestNode = function() {
69 | // The bindings specs make frequent use of this utility function to set up
70 | // a clean new DOM node they can execute code against
71 | var existingNode = document.getElementById("testNode");
72 | if (existingNode != null)
73 | existingNode.parentNode.removeChild(existingNode);
74 | testNode = document.createElement("div");
75 | testNode.id = "testNode";
76 | document.body.appendChild(testNode);
77 | };
78 |
--------------------------------------------------------------------------------
/spec/lib/jasmine.css:
--------------------------------------------------------------------------------
1 | body { background-color: #eeeeee; padding: 0; margin: 5px; overflow-y: scroll; }
2 |
3 | #HTMLReporter { font-size: 11px; font-family: Monaco, "Lucida Console", monospace; line-height: 14px; color: #333333; }
4 | #HTMLReporter a { text-decoration: none; }
5 | #HTMLReporter a:hover { text-decoration: underline; }
6 | #HTMLReporter p, #HTMLReporter h1, #HTMLReporter h2, #HTMLReporter h3, #HTMLReporter h4, #HTMLReporter h5, #HTMLReporter h6 { margin: 0; line-height: 14px; }
7 | #HTMLReporter .banner, #HTMLReporter .symbolSummary, #HTMLReporter .summary, #HTMLReporter .resultMessage, #HTMLReporter .specDetail .description, #HTMLReporter .alert .bar, #HTMLReporter .stackTrace { padding-left: 9px; padding-right: 9px; }
8 | #HTMLReporter #jasmine_content { position: fixed; right: 100%; }
9 | #HTMLReporter .version { color: #aaaaaa; }
10 | #HTMLReporter .banner { margin-top: 14px; }
11 | #HTMLReporter .duration { color: #aaaaaa; float: right; }
12 | #HTMLReporter .symbolSummary { overflow: hidden; *zoom: 1; margin: 14px 0; }
13 | #HTMLReporter .symbolSummary li { display: block; float: left; height: 7px; width: 14px; margin-bottom: 7px; font-size: 16px; }
14 | #HTMLReporter .symbolSummary li.passed { font-size: 14px; }
15 | #HTMLReporter .symbolSummary li.passed:before { color: #5e7d00; content: "\02022"; }
16 | #HTMLReporter .symbolSummary li.failed { line-height: 9px; }
17 | #HTMLReporter .symbolSummary li.failed:before { color: #b03911; content: "x"; font-weight: bold; margin-left: -1px; }
18 | #HTMLReporter .symbolSummary li.skipped { font-size: 14px; }
19 | #HTMLReporter .symbolSummary li.skipped:before { color: #bababa; content: "\02022"; }
20 | #HTMLReporter .symbolSummary li.pending { line-height: 11px; }
21 | #HTMLReporter .symbolSummary li.pending:before { color: #aaaaaa; content: "-"; }
22 | #HTMLReporter .exceptions { color: #fff; float: right; margin-top: 5px; margin-right: 5px; }
23 | #HTMLReporter .bar { line-height: 28px; font-size: 14px; display: block; color: #eee; }
24 | #HTMLReporter .runningAlert { background-color: #666666; }
25 | #HTMLReporter .skippedAlert { background-color: #aaaaaa; }
26 | #HTMLReporter .skippedAlert:first-child { background-color: #333333; }
27 | #HTMLReporter .skippedAlert:hover { text-decoration: none; color: white; text-decoration: underline; }
28 | #HTMLReporter .passingAlert { background-color: #a6b779; }
29 | #HTMLReporter .passingAlert:first-child { background-color: #5e7d00; }
30 | #HTMLReporter .failingAlert { background-color: #cf867e; }
31 | #HTMLReporter .failingAlert:first-child { background-color: #b03911; }
32 | #HTMLReporter .results { margin-top: 14px; }
33 | #HTMLReporter #details { display: none; }
34 | #HTMLReporter .resultsMenu, #HTMLReporter .resultsMenu a { background-color: #fff; color: #333333; }
35 | #HTMLReporter.showDetails .summaryMenuItem { font-weight: normal; text-decoration: inherit; }
36 | #HTMLReporter.showDetails .summaryMenuItem:hover { text-decoration: underline; }
37 | #HTMLReporter.showDetails .detailsMenuItem { font-weight: bold; text-decoration: underline; }
38 | #HTMLReporter.showDetails .summary { display: none; }
39 | #HTMLReporter.showDetails #details { display: block; }
40 | #HTMLReporter .summaryMenuItem { font-weight: bold; text-decoration: underline; }
41 | #HTMLReporter .summary { margin-top: 14px; }
42 | #HTMLReporter .summary .suite .suite, #HTMLReporter .summary .specSummary { margin-left: 14px; }
43 | #HTMLReporter .summary .specSummary.passed a { color: #5e7d00; }
44 | #HTMLReporter .summary .specSummary.failed a { color: #b03911; }
45 | #HTMLReporter .description + .suite { margin-top: 0; }
46 | #HTMLReporter .suite { margin-top: 14px; }
47 | #HTMLReporter .suite a { color: #333333; }
48 | #HTMLReporter #details .specDetail { margin-bottom: 28px; }
49 | #HTMLReporter #details .specDetail .description { display: block; color: white; background-color: #b03911; }
50 | #HTMLReporter .resultMessage { padding-top: 14px; color: #333333; }
51 | #HTMLReporter .resultMessage span.result { display: block; }
52 | #HTMLReporter .stackTrace { margin: 5px 0 0 0; max-height: 224px; overflow: auto; line-height: 18px; color: #666666; border: 1px solid #ddd; background: white; white-space: pre; }
53 |
54 | #TrivialReporter { padding: 8px 13px; position: absolute; top: 0; bottom: 0; left: 0; right: 0; overflow-y: scroll; background-color: white; font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ }
55 | #TrivialReporter a:visited, #TrivialReporter a { color: #303; }
56 | #TrivialReporter a:hover, #TrivialReporter a:active { color: blue; }
57 | #TrivialReporter .run_spec { float: right; padding-right: 5px; font-size: .8em; text-decoration: none; }
58 | #TrivialReporter .banner { color: #303; background-color: #fef; padding: 5px; }
59 | #TrivialReporter .logo { float: left; font-size: 1.1em; padding-left: 5px; }
60 | #TrivialReporter .logo .version { font-size: .6em; padding-left: 1em; }
61 | #TrivialReporter .runner.running { background-color: yellow; }
62 | #TrivialReporter .options { text-align: right; font-size: .8em; }
63 | #TrivialReporter .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; }
64 | #TrivialReporter .suite .suite { margin: 5px; }
65 | #TrivialReporter .suite.passed { background-color: #dfd; }
66 | #TrivialReporter .suite.failed { background-color: #fdd; }
67 | #TrivialReporter .spec { margin: 5px; padding-left: 1em; clear: both; }
68 | #TrivialReporter .spec.failed, #TrivialReporter .spec.passed, #TrivialReporter .spec.skipped { padding-bottom: 5px; border: 1px solid gray; }
69 | #TrivialReporter .spec.failed { background-color: #fbb; border-color: red; }
70 | #TrivialReporter .spec.passed { background-color: #bfb; border-color: green; }
71 | #TrivialReporter .spec.skipped { background-color: #bbb; }
72 | #TrivialReporter .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; }
73 | #TrivialReporter .passed { background-color: #cfc; display: none; }
74 | #TrivialReporter .failed { background-color: #fbb; }
75 | #TrivialReporter .skipped { color: #777; background-color: #eee; display: none; }
76 | #TrivialReporter .resultMessage span.result { display: block; line-height: 2em; color: black; }
77 | #TrivialReporter .resultMessage .mismatch { color: black; }
78 | #TrivialReporter .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; }
79 | #TrivialReporter .finished-at { padding-left: 1em; font-size: .6em; }
80 | #TrivialReporter.show-passed .passed, #TrivialReporter.show-skipped .skipped { display: block; }
81 | #TrivialReporter #jasmine_content { position: fixed; right: 100%; }
82 | #TrivialReporter .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; }
83 |
--------------------------------------------------------------------------------
/knockout-repeat.js:
--------------------------------------------------------------------------------
1 | // REPEAT binding for Knockout http://knockoutjs.com/
2 | // (c) Michael Best
3 | // License: MIT (http://www.opensource.org/licenses/mit-license.php)
4 | // Version 2.1.0
5 |
6 | (function(factory) {
7 | if (typeof define === 'function' && define.amd) {
8 | // [1] AMD anonymous module
9 | define(['knockout'], factory);
10 | } else if (typeof exports === 'object') {
11 | // [2] commonJS
12 | factory(require('knockout'));
13 | } else {
14 | // [3] No module loader (plain