├── .gitattributes ├── .gitignore ├── .npmignore ├── MIT-LICENSE.txt ├── README.md ├── bower.json ├── demos ├── demos.html ├── features │ └── observability │ │ ├── computed-data-prototype.html │ │ ├── computed-data.html │ │ ├── computed-helper.html │ │ └── observing-paths.html ├── index.html ├── jQueryConfDemosOct2011 │ ├── 01_render-template.html │ ├── 02_compiled-template.html │ ├── 03_named-template.html │ ├── 04_data-array.html │ ├── 05_input.html │ ├── 06_data-binding.html │ ├── 06_data-binding2.html │ ├── 07_observable.html │ ├── 07_observable2.html │ ├── 07_observable3.html │ ├── 08_for-tag.html │ ├── 09_for-composition.html │ ├── 10_if-else-tag.html │ ├── 11_editable-data.html │ ├── 12_helper-functions.html │ ├── 13_converters.html │ ├── 14_custom-tags.html │ └── index.html ├── resources │ ├── close.png │ ├── demos.css │ ├── masterdetail.css │ ├── masterdetail2.css │ ├── movielist.css │ ├── perf-compare.css │ ├── presentation.css │ ├── syntaxhighlighter.css │ ├── syntaxhighlighter.min.js │ └── todos.css └── step-by-step │ ├── 01_rendering-and-linking.html │ ├── 03_top-level-linking.html │ ├── 04_form-elements_if-binding.html │ ├── 06_accordion_switching-template.html │ └── 10_todos.html ├── gulpfile.js ├── jquery.observable.js ├── jquery.observable.min.js ├── jquery.observable.min.js.map ├── jquery.views.js ├── jquery.views.min.js ├── jquery.views.min.js.map ├── jsrender.js ├── jsrender.min.js ├── jsrender.min.js.map ├── jsviews.js ├── jsviews.min.js ├── jsviews.min.js.map ├── package-lock.json ├── package.json ├── test ├── browserify │ ├── 1-unit-tests.js │ ├── 10-errors-unit-tests.js │ ├── 11-errors-unit-tests.js │ ├── 12-nested-unit-tests.js │ ├── 2-unit-tests.js │ ├── 3-unit-tests.js │ ├── 4-unit-tests.js │ ├── 5-unit-tests.js │ ├── 6-unit-tests.js │ ├── 7-unit-tests.js │ ├── 8-unit-tests.js │ ├── 8B-unit-tests.js │ ├── 9-unit-tests.js │ ├── bundles │ │ ├── 1-bundle.js │ │ ├── 10-errors-bundle.js │ │ ├── 11-errors-bundle.js │ │ ├── 12-nested-bundle.js │ │ ├── 2-bundle.js │ │ ├── 3-bundle.js │ │ ├── 4-bundle.js │ │ ├── 5-bundle.js │ │ ├── 6-bundle.js │ │ ├── 7-bundle.js │ │ ├── 8-bundle.js │ │ ├── 8B-bundle.js │ │ ├── 9-bundle.js │ │ └── browserify-bundles-go-here.txt │ └── tests-browserify-completed.js ├── index.html ├── requirejs │ ├── require.js │ └── require.min.js ├── resources │ ├── close.png │ └── showviews.js ├── templates │ ├── file │ │ └── path.html │ ├── inner.html │ ├── name-template.htm │ ├── name-template.html │ ├── name-template.jsr │ ├── name-template.jsrender │ └── outer.html ├── test-amd-scriptloader-no-jquery.html ├── test-pages │ ├── for-else.html │ ├── index.html │ ├── sibling-collection-views.html │ └── view-hierarchy-refresh.html ├── test.min.map.html ├── unit-tests-all-jsviews.html ├── unit-tests-all-observable-render-views.html ├── unit-tests-all-render-observable-views.html ├── unit-tests-amd-scriptloader.html ├── unit-tests-browserify.html ├── unit-tests-jsobservable-no-jqueryviews.html ├── unit-tests-jsrender-no-jquery.html ├── unit-tests-jsrender-with-jquery.html ├── unit-tests-jsviews.html ├── unit-tests-multiple-loads.html └── unit-tests │ ├── requirejs-config.js │ ├── tests-jsobservable-withIE.js │ ├── tests-jsobservable.js │ ├── tests-jsrender-amd-scriptloader.js │ ├── tests-jsrender-no-jquery-withIE.js │ ├── tests-jsrender-no-jquery.js │ ├── tests-jsrender-with-jquery-withIE.js │ ├── tests-jsrender-with-jquery.js │ ├── tests-jsviews-amd-scriptloader.js │ ├── tests-jsviews-withIE.js │ └── tests-jsviews.js └── typescript └── jsviews ├── index.d.ts └── test ├── jsr-tests.ts ├── jsv-tests.ts ├── tests.html └── tsconfig.json /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # JS files must always use LF for tools to work 5 | *.js eol=lf 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | **/.* 2 | node_modules 3 | bower_components 4 | *.config 5 | desktop.ini 6 | built 7 | Scripts 8 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | **/.* 2 | 3 | /test/browserify/bundles/*.js 4 | *.config 5 | gulpfile.js 6 | desktop.ini 7 | /Scripts 8 | /node_modules 9 | /bower_components 10 | /demos 11 | /test 12 | /-* 13 | built -------------------------------------------------------------------------------- /MIT-LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright (c) 2025 Boris Moore https://github.com/BorisMoore/jsviews 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsviews", 3 | "main": "jsviews.js", 4 | "homepage": "http://www.jsviews.com/#jsviews", 5 | "authors": [ 6 | { 7 | "name": "Boris Moore", 8 | "email": "borismoore@gmail.com", 9 | "homepage": "https://github.com/borismoore" 10 | } 11 | ], 12 | "description": "Next-generation MVVM and MVP framework - built on top of JsRender templates. Bringing templates to life...", 13 | "moduleType": [ 14 | "amd", 15 | "globals", 16 | "node" 17 | ], 18 | "repository": { 19 | "type": "git", 20 | "url": "git://github.com/borismoore/jsviews.git" 21 | }, 22 | "keywords": [ 23 | "jsviews", 24 | "jsrender", 25 | "jquery", 26 | "mvvm", 27 | "mvp", 28 | "spa", 29 | "browserify", 30 | "templates", 31 | "template" 32 | ], 33 | "license": "MIT", 34 | "dependencies": { 35 | "jquery": ">=1.8" 36 | }, 37 | "ignore": [ 38 | "**/.*", 39 | "node_modules", 40 | "bower_components", 41 | "test", 42 | "demos", 43 | "*.md", 44 | "gulpfile.js", 45 | "package.json" 46 | ] 47 | } 48 | -------------------------------------------------------------------------------- /demos/demos.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JsViews: Step by step 5 | 6 | 7 | 8 | 9 |
10 |

The demos below have been superseded by the documentation 11 | and samples on jsviews.com, 12 | which are more up-to-date and complete

13 |
14 | 15 |
<< Index for JsViews and JsRender
16 | 17 |

JsViews: Demos

18 | 19 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /demos/features/observability/computed-data-prototype.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Computed data properties on prototype, using constructor

18 | 19 |

20 | 21 | 22 |
23 | 24 | 25 | 62 | 63 | 64 | 129 | 130 | 131 | 132 |

HTML:

133 |
134 | <!-- data-linking-->
135 | 
136 | <input data-link="fullName()" />
137 | ...
138 | <td data-link="fullName(true)" ></td>
139 | 
140 | <!-- data-bound tag-->
141 | 
142 | {^{:fullName(true)}}
143 | 
144 | 145 |

Script:

146 |
147 | //====================== Data ======================
148 | // Constructor
149 | var Person = function(first, last) {
150 |         this._firstName = first;
151 |         this.lastName = last;
152 |     },
153 | 
154 |     // Prototype
155 |     personProto = {
156 |         // Computed firstName
157 |         firstName: function() { ... },
158 |         // Computed fullName
159 |         fullName: fullName
160 |     };
161 | 
162 |     //Setter for firstName - for two-way binding
163 |     personProto.firstName.set = function(val) { ... }
164 | 
165 |     Person.prototype = personProto,
166 | 
167 |     person = new Person("Jeff", "Friedman");
168 | 
169 | // Parameterized computed observable
170 | function fullName(reversed) {
171 |     return reversed ? this.lastName + " " + this.firstName ...
172 | }
173 | 
174 | // Declare dependencies
175 | fullName.depends = ["firstName", "lastName"];
176 | 
177 | // For two-way binding of computed observables, provide a setter
178 | fullName.set = function(val) {
179 |     $.observable(this).setProperty({
180 |         lastName: ...,
181 |         firstName: ...
182 |     });
183 | 
184 | 185 | 186 | -------------------------------------------------------------------------------- /demos/features/observability/computed-data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Computed data properties (declared on instance)

18 | 19 |

20 | 21 | 22 |
23 | 24 | 25 | 62 | 63 | 64 | 111 | 112 | 113 | 114 |

HTML:

115 |
116 | <!-- data-linking-->
117 | 
118 | <input data-link="fullName()" />
119 | ...
120 | <td data-link="fullName(true)" ></td>
121 | 
122 | <!-- data-bound tag-->
123 | 
124 | {^{:fullName(true)}}
125 | 
126 | 127 |

Script:

128 |
129 | //====================== Data ======================
130 | var person = {
131 |     firstName: "Jeff",
132 |     lastName: "Friedman",
133 | 
134 |     // Computed fullName
135 |     fullName: fullName
136 | };
137 | 
138 | // Parameterized computed observable
139 | function fullName(reversed) { ... }
140 | 
141 | // Declare dependencies
142 | fullName.depends = ["firstName", "lastName"];
143 | 
144 | // For two-way binding of computed observables, provide a setter
145 | fullName.set = function(val) {
146 |     $.observable(this).setProperty({
147 |         lastName: ...,
148 |         firstName: ...
149 |     });
150 | 
151 | 152 | 153 | -------------------------------------------------------------------------------- /demos/features/observability/computed-helper.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |

Computed observables as helper functions (with declared dependencies, and optional setter)

18 | 19 |

20 | 21 | 22 |
23 | 24 | 25 | 62 | 63 | 64 | 130 | 131 | 132 | 133 |

HTML:

134 |
135 | <!-- data-linking-->
136 | 
137 | <input data-link="~fullName()" />
138 | ...
139 | <td data-link="~fullName(true)" ></td>
140 | 
141 | <!-- data-bound tag-->
142 | 
143 | {^{:~fullName(true)}}
144 | 
145 | 146 |

Script:

147 |
148 | //====================== Data ======================
149 | var person = {
150 |     firstName: "Jeff",
151 |     lastName: "Friedman"
152 | };
153 | 
154 | //====================== Helper ======================
155 | // Parameterized computed observable helper function
156 | function fullName(reversed) { ... }
157 | 
158 | // Declare dependencies
159 | fullName.depends = ["#data.firstName", "#data.lastName"];
160 | 
161 | // For two-way binding of computed observables, provide a setter
162 | fullName.set = function(val) {
163 |     // The this pointer is the view, so this.data is the current data item
164 |     $.observable(this.data).setProperty({
165 |         lastName: ...,
166 |         firstName: ...
167 |     });
168 | 
169 | //========== Register helper, or pass in as parameter ==========
170 | // Register helper ...
171 | $.views.helpers({
172 | 	fullName: fullName
173 | });
174 | 
175 | // ... or alternatively pass helper in as a computed template parameter:
176 | $.link.personTmpl( "#details", person, { fullName: fullName});
177 | 
178 | 
179 | 
180 | 181 | 182 | -------------------------------------------------------------------------------- /demos/features/observability/observing-paths.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

Data-linking to deep paths - observing changes higher up the path

15 | 16 |
By default, binding to a path such as app.selected.name.first will 'observe' changes at the leaf level only.
17 | To observe changes higher up the path, such as swapping the app.selected object (selected person), replace the '.' by '^' 18 | immediately after the highest-level item to be 'observed'. 19 |

For paths in which objects higher in the path may sometimes be null or undefined, 20 | add onError=null or onError='' in order to suppress error rendering and default to an empty string. 21 | 22 |

Example:
<div data-link="selected^name.first onError=null "></div>
23 | 24 | 25 |
26 |
Observing changes to object properties higher up the path
27 |
28 |
29 |
30 |
Data-bound tag — {^{>selected^name.first onError=null }}:
31 |
32 |
33 | 34 | 35 | 57 | 58 | 61 | 62 | 63 | 120 | 121 | 122 | 123 |

HTML:

124 |
125 | <!-- data-linking-->
126 | 
127 | <input data-link="selected^name.first onError=null " />
128 | 
129 | <!-- data-bound tag-->
130 | 
131 | {^{>selected^name.first onError=null }}
132 | 
133 | 134 | 135 | -------------------------------------------------------------------------------- /demos/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JsViews: Demos 5 | 6 | 7 | 8 | 9 |

JsViews: Next-generation jQuery Templates and Data Linking

10 | 11 |
JsViews:
12 | 13 |
14 |
JsViews builds on top of JsRender templates, 15 | and adds data-binding and observable data, to provide 16 | a fully-fledged MVVM platform for easily creating interactive data-driven single page apps and websites. 17 |
18 |
JsRender and JsViews together provide the next-generation implementation of both JQuery Templates, 19 | and JQuery Data Link - and supersede those libraries.
20 |
Documentation, samples 21 | and downloads 22 | are available on the www.jsviews.com website. 23 |
24 |
25 | 26 |
27 |

Demos

28 | 29 |
The primary location for JsViews 30 | or JsRender 31 | samples and demos is now on jsviews.com
32 |
See also the following links:
33 |
JsViews: Demos
34 |
JsViews and JsRender Overview:
35 |
Demo sequence from jQuery Conference October 2011
36 |
Source code:
37 |
https://github.com/BorisMoore/jsviews
38 |
39 | 40 |
See also on JsRender site:
41 | 42 |
43 |
JsRender templates are optimized for high-performance pure string-based rendering, without DOM or jQuery dependency
44 |
JsRender: Demos
45 |
46 | 47 |
Other links:
48 | 49 |
50 |
Slide deck: jQuery Conference October 2011
51 |
MSDN 'Client Insight' articles on JsRender part one and 52 | part two
53 |
Training course: JsRender Fundamentals 54 | from John Papa on Pluralsight (3 hours of video)
55 |
56 | 57 |
Tests:
58 | 59 |
60 |
Combined unit tests, JsViews and JsRender
61 |
Additional tests
62 |
63 | 64 | 65 | 66 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/01_render-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Declare template in script block, and render against data

15 | 16 | 17 |
18 | 19 | 20 | 25 | 26 | 27 | 39 | 40 | 41 | 42 |

HTML:

43 |
44 | 
45 | <script id="personTmpl" type="text/x-jsrender">
46 |     <tr>
47 |         <td>{{>firstName}}</td>
48 |     </tr>
49 | </script>
50 | 
51 | 
52 | <table><tbody id="details"></tbody></table>
53 | 54 |

Data:

55 |
56 | var person = {
57 |     firstName: "Jeff"
58 | };
59 | 
60 | 61 |

Script:

62 |
63 | // Render to string
64 | var html = $( "#personTmpl" ).render( person );
65 | 
66 | // Insert as HTML
67 | $( "#details" ).html( html );
68 | 
69 | 70 | 71 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/02_compiled-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Compile template object from string, and render against data

15 | 16 | 17 |
18 | 19 | 20 | 36 | 37 | 38 | 39 |

Data:

40 |
41 | var person = {
42 |     firstName: "Jeff"
43 | };
44 | 
45 | 46 |

Script:

47 |
48 | // Compile from string as template object
49 | var template = $.templates( "<tr><td>{{>firstName}}</td></tr>" );
50 | 
51 | // Render to string
52 | var html = template.render( person );
53 | 
54 | // Insert as HTML
55 | $( "#details" ).html( html );
56 | 
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/03_named-template.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Compile template from string, and register as named template

15 | 16 | 17 |
18 | 19 | 20 | 36 | 37 | 38 | 39 |

Data:

40 |
41 | var person = {
42 |     firstName: "Jeff"
43 | };
44 | 
45 | 46 |

Script:

47 |
48 | // Compile as named template
49 | $.templates( "detailsTmpl", "<tr><td>{{>firstName}}</td></tr>" );
50 | 
51 | // Render to string
52 | var html = $.render.detailsTmpl( person );
53 | 
54 | // Insert as HTML
55 | $( "#details" ).html( html );
56 | 
57 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/04_data-array.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Data Arrays

15 | 16 | 17 |
18 | 19 | 20 | 25 | 26 | 27 | 48 | 49 | 50 | 51 |

Data:

52 |
53 | var people = [
54 |     {
55 |         firstName: "Jeff"
56 |     },
57 |     {
58 |         firstName: "Rebecca"
59 |     }
60 | ];
61 | 
62 | 63 |

Script:

64 |
65 | // An array renders once for each item (concatenated)
66 | var html = $.render.personTmpl( people );
67 | 
68 | // Insert as HTML
69 | $( "#details" ).html( html );
70 | 
71 | 72 | 73 | 74 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/05_input.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Inputs (without data binding)

15 | 16 | 17 |
18 | 19 | 20 | 26 | 27 | 28 | 47 | 48 | 49 | 50 |

HTML:

51 |
<script id="personTmpl" type="text/x-jsrender">
52 |     <tr>
53 |         <td>{{>firstName}}</td>
54 |         <td>
55 |             <input value="{{>firstName}}" />
56 |         </td>
57 |     </tr>
58 | </script>
59 | 60 | 61 | 62 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/06_data-binding.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsViews: Data binding

17 | 18 | 19 |
20 | 21 | 22 | 30 | 31 | 32 | 53 | 54 | 55 | 56 |

HTML:

57 |
58 | 
59 | ...
60 |     <td data-link="firstName"></td>
61 |     <td>
62 |         <input data-link="firstName" />
63 |     </td>
64 | ...
65 | 
66 | 67 |

Script:

68 |
69 | // Get template object
70 | var template = $.templates( "#personTmpl" );
71 | 
72 | // Render and link: data-link people to the
73 | // details container, using the personTmpl template
74 | 
75 | template.link( "#details", people );
76 | 
77 | // Alternative syntax:
78 | //    $.link(template, "#details", people);
79 | 
80 | 81 | 82 |

Other possible data-binding paths:

83 |
84 | <input data-link="{convert:manager.firstName:convertBack} title{:manager.firstName + manager.lastName}" ... />
85 | 
86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/06_data-binding2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsViews: Data binding - compact linking API syntax

17 | 18 | 19 |
20 | 21 | 22 | 30 | 31 | 32 | 51 | 52 | 53 | 54 |

HTML:

55 |
56 | 
57 | ...
58 |     <td data-link="firstName"></td>
59 |     <td>
60 |         <input data-link="firstName" />
61 |     </td>
62 | ...
63 | 
64 | 65 |

Script:

66 |
67 | // Compile template
68 | 
69 | $.templates( "personTmpl", "#personTmpl" );
70 | 
71 | // Render and link (compact syntax): data-link people to the
72 | // details container, using the personTmpl template
73 | 
74 | $.link.personTmpl( "#details", people );
75 | 
76 | 77 | 78 | 79 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/07_observable.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsViews: Observable property changes

17 | 18 |

19 | 20 | 21 |
22 | 23 | 24 | 32 | 33 | 34 | 52 | 53 | 54 | 55 |

HTML:

56 |
57 | ...
58 |     <td data-link="firstName"></td>
59 |     <td>
60 |         <input data-link="firstName" />
61 |     </td>
62 | ...
63 | 
64 | 65 |

Script:

66 |
67 | // Data-link details container to person, using the personTmpl template
68 | $.link.personTmpl( "#details", person );
69 | 
70 | // Observable property change
71 | $( "#changeName" ).on( "click", function() {
72 |     $.observable( person ).setProperty( "firstName", person.firstName + "Plus" );
73 | });
74 | 
75 | 76 | 77 | 78 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/07_observable2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsViews: Observable collection changes

17 | 18 |

19 | 20 | 21 |
22 | 23 | 24 | 35 | 36 | 37 | 68 | 69 | 70 | 71 |

HTML:

72 |
73 | ...
74 |     <td data-link="firstName"></td>
75 |     <td>
76 |         <input data-link="firstName" />
77 |     </td>
78 | 
79 | 
80 | 81 |

Script:

82 |
83 | $.link.personTmpl( "#details", people );
84 | 
85 | // Observable array change: insert
86 | $( "#insertPerson" ).on( "click", function() {
87 |     $.observable( people ).insert( 0, { firstName: "NewPerson" + counter++ });
88 | });
89 | 
90 | // Observable array change: remove
91 | $( "#details" )
92 |     .on( "click", ".close", function() {
93 |         $.observable( people ).remove( $.view( this ).index );
94 |     });
95 | 
96 | 
97 | 98 | 99 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/07_observable3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsViews: Two containers data-linked to the same array

17 | 18 |

19 | 20 | 21 |
22 | 23 |
24 | 25 | 26 | 37 | 38 | 39 | 44 | 45 | 46 | 86 | 87 | 88 | 89 |

Script:

90 |
 91 | // Data-link people to the details container, using the personTmpl template
 92 | $.link.personTmpl1( "#details1", people );
 93 | $.link.personTmpl2( "#details2", people );
 94 | 
 95 | // Observable array change: insert two new people at index 1
 96 | $( "#insertPerson" ).on( "click", function() {
 97 |     $.observable( people ).insert(
 98 |         1,    // index 1
 99 |         [      // add two new people
100 |             { firstName: "NewPerson" },
101 |             { firstName: "NewPerson2" }
102 |         ]);
103 | });
104 | 
105 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/08_for-tag.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Using {{for}} to render hierarchical data - inline nested template

15 | 16 | 26 | 27 | 28 | 29 | 30 |
TitleLanguages
31 | 32 | 48 | 49 | 50 | 51 |

Data:

52 |
53 | var movie = {
54 |     title: "Eyes Wide Shut",
55 |     languages: [
56 |         { name: "French" },
57 |         { name: "Mandarin" },
58 |         { name: "Spanish" }
59 |     ]
60 | }
61 | 
62 | 63 |

HTML:

64 |
65 | <td>{{>title}}</td>
66 | <td>
67 |     {{for languages}}
68 |         <div>{{>name}}</div>
69 |     {{/for}}
70 | </td>
71 | 
72 | 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/09_for-composition.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Composing nested templates: {{for}} with external template

15 | 16 | 24 | 25 | 28 | 29 | 30 | 31 | 32 |
TitleLanguages
33 | 34 | 50 | 51 | 52 | 53 |

HTML:

54 |
55 | 
56 | ...
57 | <td>{{>title}}</td>
58 | <td>
59 |     {{for languages tmpl="#languageTmpl"/}}
60 | </td>
61 | ..
62 | 
63 | 
64 | <script id="languageTmpl" type="text/x-jsrender">
65 |     <div>{{>name}}</div>
66 | </script>
67 | 
68 | 69 | 70 | 71 | 72 | 73 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/10_if-else-tag.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Using {{if}} and {{else}} to render conditional sections

15 | 16 | 30 | 31 | 32 | 33 | 34 |
TitleLanguages
35 | 36 | 58 | 59 | 60 | 61 |

HTML:

62 |
63 | <td>
64 |     {{if languages}}
65 |         ...
66 |     {{else subtitles}}
67 |         ....
68 |     {{else}}
69 |         ...
70 |     {{/if}}
71 | </td>
72 | 
73 | 74 |

Data:

75 |
76 | var movies = [
77 |     {
78 |         title: "Meet Joe Black",
79 |         languages: "English and French",
80 |         subtitles: "English"
81 |     },
82 |     {
83 |         title: "Eyes Wide Shut",
84 |         subtitles: "French and Spanish"
85 |     },
86 |     ...
87 | ];
88 | 
89 | 90 | 91 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/11_editable-data.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsViews: Fully editable data: JsViews

15 | 16 |
17 | 18 | 19 |
20 | 21 |
Click to select and edit
22 | 23 |
24 | 25 | 60 | 61 | 146 | 147 | 148 | 149 | 150 | 151 | 154 | 155 |
156 |
157 | 158 | 164 | 165 | 166 | 167 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/12_helper-functions.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

JsRender: Custom helper functions for computed parameters

15 | 16 | 26 | 27 | 28 | 29 | 30 |
TitleLanguages
31 | 32 | 60 | 61 | 62 | 63 |

HTML:

64 |
65 | <td>
66 |     {{for languages}}
67 |         {{>name}}
68 |         {{if ~nextToLast()}}
69 |             and
70 |         {{else ~notLast()}}
71 |             ,
72 |         {{/if}}
73 |     {{/for}}
74 | </td>
75 | 
76 | 77 |

Script:

78 |
79 | $.views.helpers({
80 | 
81 |     nextToLast: function() {
82 |         var view = this;
83 |         return view.index === view.parent.data.length - 2;
84 |     },
85 | 
86 |     notLast: function() {
87 |         var view = this;
88 |         return view.index !== view.parent.data.length - 1;
89 |     }
90 | });
91 | 
92 | 93 | 94 | 95 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/13_converters.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsRender and JsViews: Use converters for custom encoding, data formatting, localization, etc.

17 | 18 |
Converter in tags - not linked:
19 | {{convert:dataPath}} 20 | 21 | 22 | 23 |
DataDayOff
24 | 25 |
Convert and convertBack converters with data linking:
26 | data-link="{convert:dataPath:convertBack}" 27 | 28 | 29 | 30 |
DataDayOffChoose day off
31 |
To edit, enter part of the name, or the number, or click here:
32 | 33 | 39 | 40 | 47 | 48 | 49 | 95 | 96 | 97 | 98 |

HTML:

99 |
100 |     <!-- RENDERING with tags -->
101 |     <!-- data value, no converter: -->
102 |     <td>{{>dayOff}}</td>
103 | 
104 |     <!-- render from data, convert to display name -->
105 |     <td>{{intToDay:dayOff}}</td>
106 | 
107 | 
108 |     <!-- DATA LINKING with data-link expressions -->
109 |     <!-- link from data value, no converter -->
110 |     <td data-link="dayOff"></td>
111 | 
112 |     <!-- link from data, converted to display name -->
113 |     <td data-link="{intToDay:dayOff}"></td>
114 | 
115 |     <!-- two-way data linking with convert and convertBack between data format (integer) and display name (text) -->
116 |     <!-- Also show data value as tooltip -->
117 |     <td><input data-link="{intToDay:dayOff:dayToInt} title{:dayOff}" /></td>
118 | 
119 | 120 |

Script:

121 |
122 | // Data
123 | var days = [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ],
124 | 
125 | // Convert and ConvertBack
126 | $.views.converters({
127 |     dayToInt: function(val) {
128 |         ...
129 |     },
130 |     intToDay: function(val) {
131 |         ...
132 |     }
133 | });
134 | 
135 | 136 | 137 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/14_custom-tags.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |

JsRender: Custom tags for rendering

17 | 18 | 31 | 32 | 35 | 36 | 37 | 38 | 39 |
TitleOrginal orderReverse order
40 |
41 | 83 | 84 | 85 | 86 |

HTML:

87 |
 88 | <td>
 89 |     {{sort languages reverse="true"}}
 90 |         <div>{{>name}}</div>
 91 |     {{/sort}}
 92 | </td>
 93 | 
94 | 95 |

Script:

96 |
 97 | $.views.tags({
 98 | 
 99 |     sort: function( array ){
100 |         ...
101 |         if ( this.tagCtx.props.reverse ) {
102 |             // Render in reverse order
103 |             for ( var l = array.length, i = l; i; i-- ) {
104 |                 ret += $.render( array[ i - 1 ], this.tmpl );
105 |             }
106 |         }
107 |         ...
108 |         return ret;
109 |     }
110 | 
111 | });
112 | 
113 | 114 | 115 | 116 | 117 | -------------------------------------------------------------------------------- /demos/jQueryConfDemosOct2011/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | JsViews: Step by step 5 | 6 | 7 | 8 | 9 |

Overview: JsRender to JsViews

10 |
<< Index for JsViews and JsRender
11 | 12 |

Samples from jQuery Conference, Boston, October 2011

13 | 14 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /demos/resources/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BorisMoore/jsviews/15f8234c06be47b73317b18f0598eacbfefb6ae6/demos/resources/close.png -------------------------------------------------------------------------------- /demos/resources/demos.css: -------------------------------------------------------------------------------- 1 | body { padding: 10px; font-family: Verdana; font-size: small; } 2 | 3 | h4 { font-size: inherit; font-variant: small-caps; } 4 | 5 | .height { width: 100%; margin-bottom: 10px; float: left; clear: both; } 6 | 7 | .bottom { height: 400px; width: 100%; margin-bottom: 10px; float: left; clear: both; } 8 | 9 | body > button { float: left; clear: right; margin: 3px; } 10 | 11 | .subhead { margin: 3px 0 5px 0; font-weight: bolder; color: #116; font-family: Arial; font-size: 10pt; } 12 | 13 | .subsubhead { margin: 3px 0 5px 0; font-weight: 600; padding-left: 9px; color: #5A5A78; font-style: italic; font-family: Arial; font-size: 10pt; } 14 | 15 | a { color: #55b; } 16 | 17 | pre { font-size: 10pt; font-weight: bold; border-left: 3px solid #aaa; padding: 10px; margin-bottom: 30px; } 18 | 19 | .inset { padding-left: 18px; } 20 | 21 | .box { border: 1px solid #777; padding: 10px; margin: 5px 0 30px; } 22 | 23 | .box div { margin: 3px 0 10px 0; } 24 | 25 | .box .label { margin: 0; padding: 10px 0 0 0; font-style: italic; color: #55b; } 26 | 27 | .box.label { font-style: italic; color: #55b; } 28 | 29 | .desc { font-style: italic; margin: 0 0 15px; color: #116; } 30 | 31 | .indexitems { list-style-type: none; padding-left: 10px; margin: 0 0 20px; } 32 | 33 | .indexitems li { margin-top: 14px; } 34 | 35 | .indexitems .inset { margin-top: 6px; } 36 | 37 | h3 { margin-bottom: 10px; font-size: 11pt; } 38 | 39 | select.full { margin-bottom: 15px; width: 200px; } 40 | 41 | select[size].full { margin-bottom: 0; width: 100%; } 42 | 43 | .two tr td { width: 50%; } 44 | -------------------------------------------------------------------------------- /demos/resources/masterdetail.css: -------------------------------------------------------------------------------- 1 | input { 2 | color: #1010c0; 3 | } 4 | 5 | .buttons, .comment { 6 | float: left; 7 | clear: both; 8 | margin-bottom: 10px; 9 | } 10 | 11 | .comment { 12 | font-style: italic; 13 | } 14 | 15 | table { 16 | border-collapse: collapse; 17 | float: left; 18 | clear: both; 19 | border: 2px solid #4242ae; 20 | width: 380px; 21 | margin: 4px 0 4px 0px; 22 | padding: 2px; 23 | background-color: #f8f8f8; 24 | } 25 | 26 | table tr { 27 | border: 1px solid #4242ae; 28 | color: #1010c0; 29 | height: 25px; 30 | } 31 | 32 | thead tr { 33 | color: #009; 34 | border-bottom: solid #77c 2px; 35 | background-color: #e0e0e8; 36 | } 37 | 38 | thead th { 39 | padding: 5px; 40 | } 41 | 42 | .hover { 43 | cursor: pointer; 44 | } 45 | 46 | .hover:hover { 47 | color: #AD0157; 48 | } 49 | 50 | #movieList tr td:first-child { 51 | width: 250px; 52 | } 53 | 54 | #movieDetail > div { 55 | border: 2px solid #4242ae; 56 | width: 280px; 57 | margin: 4px 0 4px 4px; 58 | padding: 2px 0 2px 2px; 59 | background-color: #f8f8f8; 60 | } 61 | 62 | table td { 63 | padding: 3px; 64 | margin: 3px; 65 | } 66 | 67 | #movieDetail div div { 68 | margin: 3px; 69 | } 70 | 71 | .selected { 72 | background-color: yellow; 73 | } 74 | 75 | #movieDetail input { 76 | float: left; 77 | padding: 2px; 78 | width: 245px; 79 | margin: 1px; 80 | border: 1px solid #4a4aff; 81 | } 82 | 83 | #movieDetail { 84 | float: left; 85 | margin-left: 10px; 86 | font-weight: bold; 87 | font-style: italic; 88 | color: #009; 89 | } 90 | 91 | #movieDetail div { 92 | float: left; 93 | clear: both; 94 | } 95 | 96 | #movieDetail .title { 97 | padding-top: 8px; 98 | } 99 | 100 | .close { 101 | float: right; 102 | cursor: pointer; 103 | padding: 6px; 104 | } 105 | 106 | #addLanguageBtn, #addMovieBtn { 107 | float: right; 108 | text-decoration: underline; 109 | font-style: italic; 110 | color: #1010c0; 111 | cursor: pointer; 112 | padding: 0 5px 0 15px; 113 | } 114 | 115 | table input { 116 | width: 95%; 117 | border: 1px solid #000; 118 | padding: 4px; 119 | } 120 | 121 | #console { 122 | float: left; 123 | clear: both; 124 | } 125 | -------------------------------------------------------------------------------- /demos/resources/masterdetail2.css: -------------------------------------------------------------------------------- 1 | input { 2 | color: #1010c0; 3 | } 4 | 5 | .buttons, .comment { 6 | float: left; 7 | clear: both; 8 | margin-bottom: 10px; 9 | } 10 | 11 | .comment { 12 | font-style: italic; 13 | } 14 | 15 | table { 16 | border-collapse: collapse; 17 | float: left; 18 | clear: both; 19 | border: 2px solid #4242ae; 20 | width: 380px; 21 | margin: 4px 0 4px 0px; 22 | padding: 2px; 23 | background-color: #f8f8f8; 24 | } 25 | 26 | table tr { 27 | border: 1px solid #4242ae; 28 | color: #1010c0; 29 | height: 25px; 30 | } 31 | 32 | thead tr { 33 | color: #009; 34 | border-bottom: solid #77c 2px; 35 | background-color: #e0e0e8; 36 | } 37 | 38 | thead th { 39 | padding: 5px; 40 | } 41 | 42 | .hover { 43 | cursor: pointer; 44 | } 45 | 46 | .hover:hover { 47 | color: #AD0157; 48 | } 49 | 50 | .movies tr td:first-child { 51 | width: 250px; 52 | } 53 | 54 | .detail > div { 55 | border: 2px solid #4242ae; 56 | width: 280px; 57 | margin: 4px 0 4px 4px; 58 | padding: 2px 0 2px 2px; 59 | background-color: #f8f8f8; 60 | } 61 | 62 | table td { 63 | padding: 3px; 64 | margin: 3px; 65 | } 66 | 67 | .detail div div { 68 | margin: 3px; 69 | } 70 | 71 | .selected { 72 | background-color: yellow; 73 | } 74 | 75 | .detail input { 76 | float: left; 77 | padding: 2px; 78 | width: 245px; 79 | margin: 1px; 80 | border: 1px solid #4a4aff; 81 | } 82 | 83 | .detail { 84 | float: left; 85 | margin-left: 10px; 86 | font-weight: bold; 87 | font-style: italic; 88 | color: #009; 89 | } 90 | 91 | .detail div { 92 | float: left; 93 | clear: both; 94 | } 95 | 96 | .detail > div > input { 97 | margin: 0 0 3px 3px; 98 | } 99 | 100 | .detail .title { 101 | padding-top: 8px; 102 | } 103 | 104 | .removeLanguage, .removeMovie { 105 | float: right; 106 | cursor: pointer; 107 | padding: 6px; 108 | } 109 | 110 | .detail .title .addLanguage { 111 | margin-bottom: 3px; 112 | display: inline-block; 113 | } 114 | 115 | .addLanguage, .addMovie { 116 | text-decoration: underline; 117 | font-style: italic; 118 | color: #1010c0; 119 | cursor: pointer; 120 | padding: 0 5px 0 15px; 121 | } 122 | 123 | table input { 124 | width: 95%; 125 | border: 1px solid #000; 126 | padding: 4px; 127 | } 128 | 129 | #console { 130 | float: left; 131 | clear: both; 132 | } 133 | -------------------------------------------------------------------------------- /demos/resources/movielist.css: -------------------------------------------------------------------------------- 1 | table tr { 2 | color: blue; 3 | height: 25px; 4 | } 5 | 6 | thead { 7 | color: #009; 8 | border-bottom: solid #77c 2px; 9 | background-color: #E8E8F7; 10 | } 11 | 12 | thead th { 13 | padding: 5px; 14 | border: 1px solid #77c; 15 | } 16 | 17 | #movieList tr td:first-child { 18 | width: 130px; 19 | } 20 | 21 | table { 22 | border-collapse: collapse; 23 | border: 2px solid blue; 24 | width: 480px; 25 | margin: 4px 0 24px 4px; 26 | padding: 2px; 27 | background-color: #f8f8f8; 28 | } 29 | 30 | table td { 31 | padding: 3px; 32 | margin: 3px; 33 | border: solid #77c 1px; 34 | } 35 | -------------------------------------------------------------------------------- /demos/resources/perf-compare.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | font-family: Verdana; 4 | font-size: small; 5 | } 6 | 7 | h4 { 8 | font-size: inherit; 9 | font-variant: small-caps; 10 | } 11 | 12 | .height { 13 | width: 100%; 14 | margin-bottom: 10px; 15 | float: left; 16 | clear: both; 17 | } 18 | 19 | .bottom { 20 | height: 400px; 21 | width: 100%; 22 | margin-bottom: 10px; 23 | float: left; 24 | clear: both; 25 | } 26 | 27 | body > button { 28 | float: left; 29 | clear: right; 30 | margin: 3px; 31 | } 32 | 33 | .subhead { 34 | margin: 15px 0 4px 0; 35 | font-weight: bolder; 36 | color: #116; 37 | font-family: Arial; 38 | font-size: 10pt; 39 | } 40 | 41 | a { 42 | color: #55b; 43 | } 44 | 45 | .result { 46 | text-align: right; 47 | } 48 | -------------------------------------------------------------------------------- /demos/resources/presentation.css: -------------------------------------------------------------------------------- 1 | body { 2 | padding: 10px; 3 | font-family: Verdana; 4 | font-size: small; 5 | } 6 | 7 | h4 { 8 | font-size: inherit; 9 | font-variant: small-caps; 10 | } 11 | 12 | .height { 13 | width: 100%; 14 | margin-bottom: 10px; 15 | float: left; 16 | clear: both; 17 | } 18 | 19 | .bottom { 20 | height: 400px; 21 | width: 100%; 22 | margin-bottom: 10px; 23 | float: left; 24 | clear: both; 25 | } 26 | 27 | body > button { 28 | float: left; 29 | clear: right; 30 | margin: 3px; 31 | } 32 | 33 | .subhead { 34 | margin: 15px 0 10px 0; 35 | font-weight: bolder; 36 | color: #116; 37 | font-family: Arial; 38 | font-size: 10pt; 39 | font-style: italic; 40 | } 41 | 42 | a { 43 | color: #55b; 44 | } 45 | 46 | pre { 47 | font-size: 10pt; 48 | font-weight: bold; 49 | } 50 | 51 | table tr { 52 | color: blue; 53 | height: 25px; 54 | } 55 | 56 | table { 57 | border-collapse: collapse; 58 | border: 2px solid blue; 59 | width: 480px; 60 | margin: 6px 0 24px; 61 | padding: 2px; 62 | background-color: #f8f8f8; 63 | } 64 | 65 | thead tr { 66 | color: #009; 67 | border-bottom: solid #77c 2px; 68 | background-color: #E8E8F7; 69 | } 70 | 71 | thead th { 72 | padding: 5px; 73 | border: 1px solid #77c; 74 | } 75 | 76 | table td { 77 | width: 50%; 78 | padding: 3px; 79 | margin: 3px; 80 | border: solid #77c 1px; 81 | border: solid #77C 1px; 82 | } 83 | 84 | table input { 85 | width: 96%; 86 | border: 1px solid #000; 87 | padding: 4px; 88 | } 89 | 90 | #movieList tr td:first-child { 91 | width: 130px; 92 | } 93 | 94 | table.three td { 95 | width: 33%; 96 | padding: 3px; 97 | margin: 3px; 98 | border: solid #77c 1px; 99 | } 100 | 101 | table.three input { 102 | width: auto; 103 | border: 1px solid #000; 104 | padding: 4px; 105 | } 106 | 107 | .close { 108 | float: right; 109 | cursor: pointer; 110 | padding: 3px; 111 | } 112 | -------------------------------------------------------------------------------- /demos/resources/syntaxhighlighter.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SyntaxHighlighter 3 | * http://alexgorbatchev.com/ 4 | * 5 | * SyntaxHighlighter is donationware. If you are using it, please donate. 6 | * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate 7 | * 8 | * @version 9 | * 2.0.296 (March 01 2009) 10 | * 11 | * @copyright 12 | * Copyright (C) 2004-2009 Alex Gorbatchev. 13 | * 14 | * @license 15 | * This file is part of SyntaxHighlighter. 16 | * 17 | * SyntaxHighlighter is free software: you can redistribute it and/or modify 18 | * it under the terms of the GNU General Public License as published by 19 | * the Free Software Foundation, either version 3 of the License, or 20 | * (at your option) any later version. 21 | * 22 | * SyntaxHighlighter is distributed in the hope that it will be useful, 23 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 24 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 25 | * GNU General Public License for more details. 26 | * 27 | * You should have received a copy of the GNU General Public License 28 | * along with SyntaxHighlighter. If not, see . 29 | */ 30 | .syntaxhighlighter, 31 | .syntaxhighlighter div, 32 | .syntaxhighlighter code, 33 | .syntaxhighlighter span 34 | { 35 | margin: 0 !important; 36 | padding: 0 !important; 37 | border: 0 !important; 38 | outline: 0 !important; 39 | background: none !important; 40 | text-align: left !important; 41 | float: none !important; 42 | vertical-align: baseline !important; 43 | position: static !important; 44 | left: auto !important; 45 | top: auto !important; 46 | right: auto !important; 47 | bottom: auto !important; 48 | height: auto !important; 49 | width: auto !important; 50 | line-height: 1.1em !important; 51 | font-family: "Consolas", "Monaco", "Bitstream Vera Sans Mono", "Courier New", Courier, monospace !important; 52 | font-weight: normal !important; 53 | font-style: normal !important; 54 | font-size: 1em !important; 55 | } 56 | 57 | .syntaxhighlighter 58 | { 59 | width: 100% !important; 60 | margin: 1em 0 1em 0 !important; 61 | padding: 1px !important; /* adds a little border on top and bottom */ 62 | position: relative !important; 63 | } 64 | 65 | .syntaxhighlighter .bold { 66 | font-weight: bold !important; 67 | } 68 | 69 | .syntaxhighlighter .italic { 70 | font-style: italic !important; 71 | } 72 | 73 | .syntaxhighlighter .line .number 74 | { 75 | float: left !important; 76 | width: 3em !important; 77 | padding-right: .3em !important; 78 | text-align: right !important; 79 | display: block !important; 80 | } 81 | 82 | /* Disable numbers when no gutter option is set */ 83 | .syntaxhighlighter.nogutter .line .number 84 | { 85 | display: none !important; 86 | } 87 | 88 | .syntaxhighlighter .line .content 89 | { 90 | margin-left: 3.3em !important; 91 | padding-left: .5em !important; 92 | display: block !important; 93 | } 94 | 95 | .syntaxhighlighter .line .content .block 96 | { 97 | display: block !important; 98 | padding-left: 1.5em !important; 99 | text-indent: -1.5em !important; 100 | } 101 | 102 | .syntaxhighlighter .line .content .spaces 103 | { 104 | display: none !important; 105 | } 106 | 107 | /* Disable border and margin on the lines when no gutter option is set */ 108 | .syntaxhighlighter.nogutter .line .content 109 | { 110 | margin-left: 0 !important; 111 | border-left: none !important; 112 | } 113 | 114 | .syntaxhighlighter .bar 115 | { 116 | } 117 | 118 | .syntaxhighlighter.collapsed .bar 119 | { 120 | 121 | } 122 | 123 | .syntaxhighlighter.nogutter .ruler 124 | { 125 | margin-left: 0 !important; 126 | padding-left: 0 !important; 127 | } 128 | 129 | .syntaxhighlighter .ruler 130 | { 131 | padding: 0 0 .5em .5em !important; 132 | margin-left: 3.3em !important; 133 | overflow: hidden !important; 134 | } 135 | 136 | /* Adjust some properties when collapsed */ 137 | 138 | .syntaxhighlighter.collapsed .lines, 139 | .syntaxhighlighter.collapsed .ruler 140 | { 141 | display: none !important; 142 | } 143 | 144 | /* Styles for the toolbar */ 145 | 146 | .syntaxhighlighter .toolbar 147 | { 148 | position: absolute !important; 149 | right: 0px !important; 150 | top: 0px !important; 151 | font-size: 1px !important; 152 | padding: 8px 8px 8px 0 !important; /* in px because images don't scale with ems */ 153 | } 154 | 155 | .syntaxhighlighter.collapsed .toolbar 156 | { 157 | font-size: 80% !important; 158 | padding: .2em 0 .5em .5em !important; 159 | position: static !important; 160 | } 161 | 162 | .syntaxhighlighter .toolbar a.item, 163 | .syntaxhighlighter .toolbar .item 164 | { 165 | display: block !important; 166 | float: left !important; 167 | margin-left: 8px !important; 168 | background-repeat: no-repeat !important; 169 | overflow: hidden !important; 170 | text-indent: -5000px !important; 171 | } 172 | 173 | .syntaxhighlighter.collapsed .toolbar .item 174 | { 175 | display: none !important; 176 | } 177 | 178 | .syntaxhighlighter.collapsed .toolbar .item.expandSource 179 | { 180 | background-image: url(magnifier.png) !important; 181 | display: inline !important; 182 | text-indent: 0 !important; 183 | width: auto !important; 184 | float: none !important; 185 | height: 16px !important; 186 | padding-left: 20px !important; 187 | } 188 | 189 | .syntaxhighlighter .toolbar .item.viewSource 190 | { 191 | background-image: url(page_white_code.png) !important; 192 | } 193 | 194 | .syntaxhighlighter .toolbar .item.printSource 195 | { 196 | background-image: url(printer.png) !important; 197 | } 198 | 199 | .syntaxhighlighter .toolbar .item.copyToClipboard 200 | { 201 | text-indent: 0 !important; 202 | background: none !important; 203 | overflow: visible !important; 204 | } 205 | 206 | .syntaxhighlighter .toolbar .item.about 207 | { 208 | background-image: url(help.png) !important; 209 | } 210 | 211 | /** 212 | * Print view. 213 | * Colors are based on the default theme without background. 214 | */ 215 | 216 | .syntaxhighlighter.printing, 217 | .syntaxhighlighter.printing .line.alt1 .content, 218 | .syntaxhighlighter.printing .line.alt2 .content, 219 | .syntaxhighlighter.printing .line.highlighted .number, 220 | .syntaxhighlighter.printing .line.highlighted.alt1 .content, 221 | .syntaxhighlighter.printing .line.highlighted.alt2 .content, 222 | .syntaxhighlighter.printing .line .content .block 223 | { 224 | background: none !important; 225 | } 226 | 227 | /* Gutter line numbers */ 228 | .syntaxhighlighter.printing .line .number 229 | { 230 | color: #bbb !important; 231 | } 232 | 233 | /* Add border to the lines */ 234 | .syntaxhighlighter.printing .line .content 235 | { 236 | color: #000 !important; 237 | } 238 | 239 | /* Toolbar when visible */ 240 | .syntaxhighlighter.printing .toolbar, 241 | .syntaxhighlighter.printing .ruler 242 | { 243 | display: none !important; 244 | } 245 | 246 | .syntaxhighlighter.printing a 247 | { 248 | text-decoration: none !important; 249 | } 250 | 251 | .syntaxhighlighter.printing .plain, 252 | .syntaxhighlighter.printing .plain a 253 | { 254 | color: #000 !important; 255 | } 256 | 257 | .syntaxhighlighter.printing .comments, 258 | .syntaxhighlighter.printing .comments a 259 | { 260 | color: #008200 !important; 261 | } 262 | 263 | .syntaxhighlighter.printing .string, 264 | .syntaxhighlighter.printing .string a 265 | { 266 | color: blue !important; 267 | } 268 | 269 | .syntaxhighlighter.printing .keyword 270 | { 271 | color: #069 !important; 272 | font-weight: bold !important; 273 | } 274 | 275 | .syntaxhighlighter.printing .preprocessor 276 | { 277 | color: gray !important; 278 | } 279 | 280 | .syntaxhighlighter.printing .variable 281 | { 282 | color: #a70 !important; 283 | } 284 | 285 | .syntaxhighlighter.printing .value 286 | { 287 | color: #090 !important; 288 | } 289 | 290 | .syntaxhighlighter.printing .functions 291 | { 292 | color: #ff1493 !important; 293 | } 294 | 295 | .syntaxhighlighter.printing .constants 296 | { 297 | color: #0066CC !important; 298 | } 299 | 300 | .syntaxhighlighter.printing .script 301 | { 302 | font-weight: bold !important; 303 | } 304 | 305 | .syntaxhighlighter.printing .color1, 306 | .syntaxhighlighter.printing .color1 a 307 | { 308 | color: #808080 !important; 309 | } 310 | 311 | .syntaxhighlighter.printing .color2, 312 | .syntaxhighlighter.printing .color2 a 313 | { 314 | color: #ff1493 !important; 315 | } 316 | 317 | .syntaxhighlighter.printing .color3, 318 | .syntaxhighlighter.printing .color3 a 319 | { 320 | color: red !important; 321 | } 322 | 323 | /** 324 | * SyntaxHighlighter 325 | * http://alexgorbatchev.com/ 326 | * 327 | * SyntaxHighlighter is donationware. If you are using it, please donate. 328 | * http://alexgorbatchev.com/wiki/SyntaxHighlighter:Donate 329 | * 330 | * @version 331 | * 2.0.296 (March 01 2009) 332 | * 333 | * @copyright 334 | * Copyright (C) 2004-2009 Alex Gorbatchev. 335 | * 336 | * @license 337 | * This file is part of SyntaxHighlighter. 338 | * 339 | * SyntaxHighlighter is free software: you can redistribute it and/or modify 340 | * it under the terms of the GNU General Public License as published by 341 | * the Free Software Foundation, either version 3 of the License, or 342 | * (at your option) any later version. 343 | * 344 | * SyntaxHighlighter is distributed in the hope that it will be useful, 345 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 346 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 347 | * GNU General Public License for more details. 348 | * 349 | * You should have received a copy of the GNU General Public License 350 | * along with SyntaxHighlighter. If not, see . 351 | */ 352 | /************************************ 353 | * Default Syntax Highlighter theme. 354 | * 355 | * Interface elements. 356 | ************************************/ 357 | 358 | .syntaxhighlighter 359 | { 360 | background-color: #E7E5DC !important; 361 | } 362 | 363 | /* Highlighed line number */ 364 | .syntaxhighlighter .line.highlighted .number 365 | { 366 | background-color: #6CE26C !important; 367 | color: black !important; 368 | } 369 | 370 | /* Highlighed line */ 371 | .syntaxhighlighter .line.highlighted.alt1 .content, 372 | .syntaxhighlighter .line.highlighted.alt2 .content 373 | { 374 | background-color: #6CE26C !important; 375 | } 376 | 377 | /* Gutter line numbers */ 378 | .syntaxhighlighter .line .number 379 | { 380 | color: #5C5C5C !important; 381 | } 382 | 383 | /* Add border to the lines */ 384 | .syntaxhighlighter .line .content 385 | { 386 | border-left: 3px solid #6CE26C !important; 387 | color: #000 !important; 388 | } 389 | 390 | .syntaxhighlighter.printing .line .content 391 | { 392 | border: 0 !important; 393 | } 394 | 395 | /* First line */ 396 | .syntaxhighlighter .line.alt1 .content 397 | { 398 | background-color: #fff !important; 399 | } 400 | 401 | /* Second line */ 402 | .syntaxhighlighter .line.alt2 .content 403 | { 404 | background-color: #F8F8F8 !important; 405 | } 406 | 407 | .syntaxhighlighter .ruler 408 | { 409 | color: silver !important; 410 | background-color: #F8F8F8 !important; 411 | border-left: 3px solid #6CE26C !important; 412 | } 413 | 414 | .syntaxhighlighter.nogutter .ruler 415 | { 416 | border: 0 !important; 417 | } 418 | 419 | .syntaxhighlighter .toolbar 420 | { 421 | background-color: #F8F8F8 !important; 422 | border: #E7E5DC solid 1px !important; 423 | } 424 | 425 | .syntaxhighlighter .toolbar a 426 | { 427 | color: #a0a0a0 !important; 428 | } 429 | 430 | .syntaxhighlighter .toolbar a:hover 431 | { 432 | color: red !important; 433 | } 434 | 435 | /************************************ 436 | * Actual syntax highlighter colors. 437 | ************************************/ 438 | .syntaxhighlighter .plain, 439 | .syntaxhighlighter .plain a 440 | { 441 | color: #000 !important; 442 | } 443 | 444 | .syntaxhighlighter .comments, 445 | .syntaxhighlighter .comments a 446 | { 447 | color: #008200 !important; 448 | } 449 | 450 | .syntaxhighlighter .string, 451 | .syntaxhighlighter .string a 452 | { 453 | color: blue !important; 454 | } 455 | 456 | .syntaxhighlighter .keyword 457 | { 458 | color: #069 !important; 459 | font-weight: bold !important; 460 | } 461 | 462 | .syntaxhighlighter .preprocessor 463 | { 464 | color: gray !important; 465 | } 466 | 467 | .syntaxhighlighter .variable 468 | { 469 | color: #a70 !important; 470 | } 471 | 472 | .syntaxhighlighter .value 473 | { 474 | color: #090 !important; 475 | } 476 | 477 | .syntaxhighlighter .functions 478 | { 479 | color: #ff1493 !important; 480 | } 481 | 482 | .syntaxhighlighter .constants 483 | { 484 | color: #0066CC !important; 485 | } 486 | 487 | .syntaxhighlighter .script 488 | { 489 | background-color: yellow !important; 490 | } 491 | 492 | .syntaxhighlighter .color1, 493 | .syntaxhighlighter .color1 a 494 | { 495 | color: #808080 !important; 496 | } 497 | 498 | .syntaxhighlighter .color2, 499 | .syntaxhighlighter .color2 a 500 | { 501 | color: #ff1493 !important; 502 | } 503 | 504 | .syntaxhighlighter .color3, 505 | .syntaxhighlighter .color3 a 506 | { 507 | color: red !important; 508 | } -------------------------------------------------------------------------------- /demos/resources/todos.css: -------------------------------------------------------------------------------- 1 | /* Sample inspired by Backbone Todos sample: http://documentcloud.github.com/backbone/examples/todos/index.html */ 2 | html, body, div, span, applet, object, iframe, 3 | h1, h2, h3, h4, h5, h6, p, blockquote, pre, 4 | a, abbr, acronym, address, big, cite, code, 5 | del, dfn, em, font, img, ins, kbd, q, s, samp, 6 | small, strike, strong, sub, sup, tt, var, 7 | dl, dt, dd, ol, ul, li, 8 | fieldset, form, label, legend, 9 | table, caption, tbody, tfoot, thead, tr, th, td { 10 | margin: 0; 11 | padding: 0; 12 | border: 0; 13 | outline: 0; 14 | font-weight: inherit; 15 | font-style: inherit; 16 | font-size: 100%; 17 | font-family: inherit; 18 | vertical-align: baseline; 19 | } 20 | 21 | body { 22 | line-height: 1; 23 | color: black; 24 | background: white; 25 | } 26 | 27 | ol, ul { 28 | list-style: none; 29 | } 30 | 31 | a img { 32 | border: none; 33 | } 34 | 35 | html { 36 | background: #eeeeee; 37 | } 38 | 39 | body { 40 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 41 | font-size: 14px; 42 | line-height: 1.4em; 43 | background: #eeeeee; 44 | color: #333333; 45 | } 46 | 47 | #todoapp { 48 | width: 480px; 49 | margin: 0 auto 40px; 50 | background: white; 51 | padding: 20px; 52 | -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0; 53 | -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0; 54 | -o-box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0; 55 | box-shadow: rgba(0, 0, 0, 0.2) 0 5px 6px 0; 56 | } 57 | 58 | #todoapp h1 { 59 | font-size: 36px; 60 | font-weight: bold; 61 | text-align: center; 62 | padding: 20px 0 30px 0; 63 | line-height: 1; 64 | } 65 | 66 | #new-todo { 67 | position: relative; 68 | width: 466px; 69 | font-size: 24px; 70 | font-family: inherit; 71 | line-height: 1.4em; 72 | border: 0; 73 | outline: none; 74 | padding: 6px; 75 | border: 1px solid #999999; 76 | -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 77 | -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 78 | -o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 79 | box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 80 | } 81 | 82 | #create-todo input::-webkit-input-placeholder { 83 | font-style: italic; 84 | } 85 | 86 | #create-todo span { 87 | position: absolute; 88 | z-index: 999; 89 | width: 170px; 90 | left: 50%; 91 | margin-left: -85px; 92 | } 93 | 94 | #todo-list { 95 | margin-top: 10px; 96 | } 97 | 98 | #todo-list li { 99 | padding: 12px 20px 11px 0; 100 | position: relative; 101 | font-size: 24px; 102 | line-height: 1.1em; 103 | border-bottom: 1px solid #cccccc; 104 | } 105 | 106 | #todo-list li:after { 107 | content: "\0020"; 108 | display: block; 109 | height: 0; 110 | clear: both; 111 | overflow: hidden; 112 | visibility: hidden; 113 | } 114 | 115 | #todo-list .editing { 116 | padding: 0; 117 | border-bottom: 0; 118 | } 119 | 120 | #todo-list .editing input { 121 | width: 444px; 122 | font-size: 24px; 123 | font-family: inherit; 124 | margin: 0; 125 | line-height: 1.6em; 126 | border: 0; 127 | outline: none; 128 | padding: 10px 7px 0px 27px; 129 | border: 1px solid #999999; 130 | -moz-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 131 | -webkit-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 132 | -o-box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 133 | box-shadow: rgba(0, 0, 0, 0.2) 0 1px 2px 0 inset; 134 | } 135 | 136 | #todo-list input[type=checkbox] { 137 | position: relative; 138 | top: 9px; 139 | margin: 0 10px 0 7px; 140 | float: left; 141 | } 142 | 143 | #todo-list .done .todo-content { 144 | text-decoration: line-through; 145 | color: #777777; 146 | } 147 | 148 | #todo-list .todo-destroy { 149 | position: absolute; 150 | right: 5px; 151 | top: 14px; 152 | display: none; 153 | cursor: pointer; 154 | width: 20px; 155 | height: 20px; 156 | background: url(http://documentcloud.github.com/backbone/examples/todos/destroy.png) no-repeat 0 0; 157 | } 158 | 159 | #todo-list li:hover .todo-destroy { 160 | display: block; 161 | } 162 | 163 | #todo-list .todo-destroy:hover { 164 | background-position: 0 -20px; 165 | } 166 | 167 | #todo-stats { 168 | *zoom: 1; 169 | margin-top: 10px; 170 | color: #777777; 171 | } 172 | 173 | #todo-stats:after { 174 | content: "\0020"; 175 | display: block; 176 | height: 0; 177 | clear: both; 178 | overflow: hidden; 179 | visibility: hidden; 180 | } 181 | 182 | #todo-stats .todo-count { 183 | float: left; 184 | } 185 | 186 | #todo-stats .todo-count .number { 187 | font-weight: bold; 188 | color: #333333; 189 | } 190 | 191 | #todo-stats .todo-clear { 192 | float: right; 193 | } 194 | 195 | #todo-stats .todo-clear a { 196 | color: #777777; 197 | font-size: 12px; 198 | } 199 | 200 | #todo-stats .todo-clear a:visited { 201 | color: #777777; 202 | } 203 | 204 | #todo-stats .todo-clear a:hover { 205 | color: #336699; 206 | } 207 | 208 | #instructions { 209 | width: 520px; 210 | margin: 10px auto; 211 | color: #777777; 212 | -webkit-text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0; 213 | text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0; 214 | text-align: center; 215 | } 216 | 217 | #instructions a { 218 | color: #336699; 219 | } 220 | 221 | #credits { 222 | width: 520px; 223 | margin: 30px auto; 224 | color: #999; 225 | -webkit-text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0; 226 | text-shadow: rgba(255, 255, 255, 0.8) 0 1px 0; 227 | text-align: center; 228 | } 229 | 230 | #credits a { 231 | color: #888; 232 | } 233 | 234 | 235 | /* 236 | * François 'cahnory' Germain 237 | */ 238 | .ui-tooltip, .ui-tooltip-top, .ui-tooltip-right, .ui-tooltip-bottom, .ui-tooltip-left { 239 | color: #ffffff; 240 | cursor: default; 241 | display: -moz-inline-stack; 242 | display: inline-block; 243 | font-size: 12px; 244 | font-family: arial; 245 | padding: .5em 1em; 246 | position: relative; 247 | text-align: center; 248 | -webkit-text-shadow: 0 -1px 1px #111111; 249 | text-shadow: 0 -1px 1px #111111; 250 | -webkit-border-top-left-radius: 4px; 251 | -webkit-border-top-right-radius: 4px; 252 | -webkit-border-bottom-right-radius: 4px; 253 | -webkit-border-bottom-left-radius: 4px; 254 | -khtml-border-top-left-radius: 4px; 255 | -khtml-border-top-right-radius: 4px; 256 | -khtml-border-bottom-right-radius: 4px; 257 | -khtml-border-bottom-left-radius: 4px; 258 | -moz-border-radius-topleft: 4px; 259 | -moz-border-radius-topright: 4px; 260 | -moz-border-radius-bottomright: 4px; 261 | -moz-border-radius-bottomleft: 4px; 262 | border-top-left-radius: 4px; 263 | border-top-right-radius: 4px; 264 | border-bottom-right-radius: 4px; 265 | border-bottom-left-radius: 4px; 266 | -o-box-shadow: 0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444; 267 | -moz-box-shadow: 0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444; 268 | -khtml-box-shadow: 0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444; 269 | -webkit-box-shadow: 0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444; 270 | box-shadow: 0 1px 2px #000000, inset 0 0 0 1px #222222, inset 0 2px #666666, inset 0 -2px 2px #444444; 271 | background-color: #3b3b3b; 272 | background-image: -moz-linear-gradient(top,#555555,#222222); 273 | background-image: -webkit-gradient(linear,left top,left bottom,color-stop(0,#555555),color-stop(1,#222222)); 274 | filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222); 275 | -ms-filter: progid:DXImageTransform.Microsoft.gradient(startColorStr=#555555,EndColorStr=#222222); 276 | } 277 | 278 | .ui-tooltip:after, .ui-tooltip-top:after, .ui-tooltip-right:after, .ui-tooltip-bottom:after, .ui-tooltip-left:after { 279 | content: "\25B8"; 280 | display: block; 281 | font-size: 2em; 282 | height: 0; 283 | line-height: 0; 284 | position: absolute; 285 | } 286 | 287 | .ui-tooltip:after, .ui-tooltip-bottom:after { 288 | color: #2a2a2a; 289 | bottom: 0; 290 | left: 1px; 291 | text-align: center; 292 | -webkit-text-shadow: 1px 0 2px #000000; 293 | text-shadow: 1px 0 2px #000000; 294 | -o-transform: rotate(90deg); 295 | -moz-transform: rotate(90deg); 296 | -khtml-transform: rotate(90deg); 297 | -webkit-transform: rotate(90deg); 298 | -ms-transform: rotate(90deg); 299 | transform: rotate(90deg); 300 | width: 100%; 301 | } 302 | 303 | .ui-tooltip-top:after { 304 | bottom: auto; 305 | color: #4f4f4f; 306 | left: -2px; 307 | top: 0; 308 | text-align: center; 309 | -webkit-text-shadow: none; 310 | text-shadow: none; 311 | -o-transform: rotate(-90deg); 312 | -moz-transform: rotate(-90deg); 313 | -khtml-transform: rotate(-90deg); 314 | -webkit-transform: rotate(-90deg); 315 | -ms-transform: rotate(-90deg); 316 | transform: rotate(-90deg); 317 | width: 100%; 318 | } 319 | 320 | .ui-tooltip-right:after { 321 | color: #222222; 322 | right: -0.375em; 323 | top: 50%; 324 | margin-top: -.05em; 325 | -webkit-text-shadow: 0 1px 2px #000000; 326 | text-shadow: 0 1px 2px #000000; 327 | -o-transform: rotate(0); 328 | -moz-transform: rotate(0); 329 | -khtml-transform: rotate(0); 330 | -webkit-transform: rotate(0); 331 | -ms-transform: rotate(0); 332 | transform: rotate(0); 333 | } 334 | 335 | .ui-tooltip-left:after { 336 | color: #222222; 337 | left: -0.375em; 338 | top: 50%; 339 | margin-top: .1em; 340 | -webkit-text-shadow: 0 -1px 2px #000000; 341 | text-shadow: 0 -1px 2px #000000; 342 | -o-transform: rotate(180deg); 343 | -moz-transform: rotate(180deg); 344 | -khtml-transform: rotate(180deg); 345 | -webkit-transform: rotate(180deg); 346 | -ms-transform: rotate(180deg); 347 | transform: rotate(180deg); 348 | } 349 | 350 | .date-input { 351 | width: 200px; 352 | } 353 | -------------------------------------------------------------------------------- /demos/step-by-step/01_rendering-and-linking.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 18 | 19 | 20 | 23 | 24 |

Rendering templates, and linking to changes in data:

25 | 26 |
Insert HTML from a rendered template, as innerHTML under a container element. (Uses only JsRender.)
27 |
28 |
    29 |
    30 | 31 |
    Insert HTML from a rendered template between other content, and then data-link the content, for live updates. (Uses JsViews for data-linking.)
    32 |

    33 | 34 | 35 |

    36 | 37 |
    Binding content to data by rendering a template, inserted between text nodes:
    38 |
    39 | Preceding text - Following text 40 |
    41 | 42 |
    Binding content to data by rendering a template, inserted between elements:
    43 |
    44 | Preceding element - Following element 45 |
    46 | 47 |
    Binding content to data by rendering a template, inserted as content of an HTML container element:
    48 |
    49 |
      50 |
      51 | 52 | 91 | 92 | 93 | -------------------------------------------------------------------------------- /demos/step-by-step/03_top-level-linking.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

      Data-Linking to static content in the page

      16 | 17 |
      18 | 19 | 20 |
      21 | 22 |
      23 | 24 |
      25 | 26 |
      Linking to data values and expressions
      27 | 28 |

      29 | Name: 30 |

      31 | 32 |

      33 | 34 | 35 | 36 | 37 |

      38 | 39 |

      Cars: 40 | Quantity 41 | Price 42 | Total Value: 43 |

      44 | 45 |

      46 | 47 |

      48 |
      49 | 50 | 98 | 99 | 100 | -------------------------------------------------------------------------------- /demos/step-by-step/04_form-elements_if-binding.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

      Data Linking to Form Elements

      15 |
      Dynamic content blocks use {^{if}} binding
      16 | 17 |

      Purchase a movie ticket

      18 | 19 |
      20 | 21 | 71 | 72 | 124 | 125 | 126 | -------------------------------------------------------------------------------- /demos/step-by-step/06_accordion_switching-template.html: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 17 | 18 | 19 |

      Accordion: Using dynamic switching of templates

      20 | 21 | 26 | 27 | 39 | 40 | Click for details: 41 |
      42 |
      43 |
      44 | 45 | 113 | 114 | 115 | -------------------------------------------------------------------------------- /demos/step-by-step/10_todos.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | JsViews Demo: Todos 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |
      15 | 16 |

      Todos

      17 | 18 | 19 | 20 |
        21 | 22 |
        23 | 24 | 25 |
        26 |
        27 | 28 | 31 | 32 | 33 | 41 | 42 | 47 | 48 | 153 | 154 | 155 | 156 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require('gulp'), 2 | browserify = require('browserify'), 3 | fs = require('fs'); 4 | 5 | //================================= BUNDLE - Run Browserify - create client bundles for test cases =================================// 6 | // See https://github.com/gulpjs/gulp/blob/master/docs/recipes/browserify-with-globs.md 7 | 8 | // Task to create Browserify client-side bundle scripts for Browserify test cases. 9 | gulp.task('bundle', function() { 10 | var tmplify = require('jsrender/tmplify'); 11 | var gs = require('glob-stream'); 12 | 13 | return gs('./test/browserify/*-unit-tests.js') 14 | .on('data', function(file) { 15 | // file has path, base, and cwd attrs 16 | var fileName = file.path.slice(file.base.length, -14); 17 | browserify(file.path, {debug:true}) 18 | .transform(tmplify) 19 | .bundle() 20 | .pipe(fs.createWriteStream('./test/browserify/bundles/' + fileName + "-bundle.js")) 21 | .on('error', function(err) { 22 | // Make sure failed tests cause gulp to exit non-zero 23 | throw err; 24 | }); 25 | }); 26 | }); 27 | -------------------------------------------------------------------------------- /jquery.observable.min.js: -------------------------------------------------------------------------------- 1 | /*! JsObservable v1.0.16: http://jsviews.com/#jsobservable */ 2 | !function(t,e){var n=e.jQuery;"object"==typeof exports?module.exports=n?t(e,n):function(n){return t(e,n)}:"function"==typeof define&&define.amd?define(["jquery"],function(n){return t(e,n)}):t(e,!1)}(function(t,e){"use strict";var n=e===!1;if(e=e||t.jQuery,!e||!e.fn)throw"jquery.observable.js requires jQuery";var r,i,o="v1.0.16",s=e.views=e.views||n&&t.jsrender&&jsrender.views||{jsviews:o,sub:{settings:{}},settings:{advanced:function(t){return f=c.advanced=c.advanced||{_jsv:!0},t?("_jsv"in t&&(f._jsv=t._jsv),a.advSet(),s.settings):f}}},a=s.sub,c=a.settings,f=c.advanced,l=function(t){return"function"==typeof t},p=Array.isArray,u=e.expando,d="string",h="object";if(s.jsviews!==o)throw"jquery.observable.js requires jsrender.js "+o;if(!e.observe){var v=e.event.special,_=[].slice,g=[].splice,b=[].concat,y=parseInt,m=/\S+/g,I=/^[^.[]*$/,w=a.propChng=a.propChng||"propertyChange",j=a.arrChng=a.arrChng||"arrayChange",x={},A=w+".observe",k=1,C=1,P=1,F=e.data,S={},T=[],V=function(t){return t?t._cId=t._cId||".obs"+C++:""},q=function(t,e){return this._data=e,this._ns=t,this},D=function(t,e){return this._data=e,this._ns=t,this},O=function(t){return p(t)?[t]:t},H=function(t,e,n){t=t?p(t)?t:[t]:[];var r,i,o,s,a=o=e,c=t&&t.length,f=[];for(r=0;c>r;r++)i=t[r],l(i)?(s=e.tagName?e.linkCtx.data:e,f=f.concat(H(i.call(e,s,n),s,n))):typeof i===d?(a!==o&&f.push(o=a),f.push(i)):(e=a=i=void 0===i?null:i,a!==o&&f.push(o=a));return f.length&&(f.unshift({_ar:1}),f.push({_ar:-1})),f},Q=function(t,e){function n(t){return typeof t===h&&(d[0]||!u&&p(t))}if(!t.data||!t.data.off){var r,i,o,s=e.oldValue,a=e.value,c=t.data,f=c.observeAll,l=c.cb,u=c._arOk?0:1,d=c.paths,v=c.ns;t.type===j?(l.array||l).call(c,t,e):(c.prop===e.path||"*"===c.prop)&&(f?(r=f._path+"."+e.path,i=f.filter,o=[t.target].concat(f.parents()),n(s)&&M(void 0,v,[s],d,l,!0,i,[o],r),n(a)&&M(void 0,v,[a],d,l,void 0,i,[o],r)):(n(s)&&M(u,v,[s],d,l,!0),n(a)&&M(u,v,[a],d,l)),c.cb(t,e))}},M=function(){var t=b.apply([],arguments);return r.apply(t.shift(),t)},B=function(t,e,n){$(this._ns,this._data,t,e,[],"root",n)},N=function(t,e){B.call(this,t,e,!0)},$=function(t,n,o,s,a,c,f,l){function d(t,e){for(g=t.length,y=c+"[]";g--;)v(t,g,e,1)}function v(e,n,r,a){var c,f;n!==u&&(c=i._fltr(y,e[n],m,s))&&(f=m.slice(),a&&I&&f[0]!==I&&f.unshift(I),$(t,c,o,s||(a?void 0:0),f,y,r,l))}function _(t,e){switch(c=t.data.observeAll._path,I=t.target,e.change){case"insert":d(e.items);break;case"remove":d(e.items,!0);break;case"set":y=c+"."+e.path,v(e,"oldValue",!0),v(e,"value")}I=void 0,o.apply(this,arguments)}_._wrp=1;var g,b,y,m,I,w,j=!l||l.un||!f;if(n&&typeof n===h){if(m=[n].concat(a),b=p(n)?"":"*",l&&j&&e.hasData(n)&&l[w=F(n).obId])return void l[w]++;if(l||(l={un:f}),o){if(b||0!==s)if(_._cId=V(o),j)r(t,n,b,_,f,s,m,c),w=F(n).obId,l[w]=(l[w]||0)+1;else{if(--l[F(n).obId])return;r(t,n,b,_,f,s,m,c)}}else l&&(l[F(n).obId]=1),r(t,n,b,void 0,f,s,m,c);if(b)for(g in n)y=c+"."+g,v(n,g,f);else d(n,f)}},z=function(t){return I.test(t)},E=function(){return[].push.call(arguments,!0),r.apply(void 0,arguments)},G=function(t){var e,n=this.slice();for(this.length=0,this._go=0;e=n.shift();)e.skip||e[0]._trigger(e[1],e[2],!0);this.paths={}};r=function(){function t(){function s(t,e){var n;for(q in e)n=e[q],p(n)?f(t,n,I,I):c(t,n,void 0,W,"")}function c(t,r,i,s,a,c,f){var l,p,u,d=O(r),h=$,v=z;if(s=n?s+"."+n:s,!I&&(f||c))for(R=e._data(r).events,R=R&&R[c?j:w],U=R&&R.length;U--;)if(q=R[U]&&R[U].data,q&&(f&&q.ns!==n||!f&&q.ns===n&&q.cb&&q.cb._cId===t._cId&&q.cb._inId===t._inId&&(!t._wrp||q.cb._wrp)))return;I||f?e(d).off(s,Q):(p=c?{}:{fullPath:i,paths:a?[a]:[],prop:L,_arOk:o},p.ns=n,p.cb=t,z&&(p.observeAll={_path:v,path:function(){return l=h.length,v.replace(/[[.]/g,function(t){return l--,"["===t?"["+e.inArray(h[l-1],h[l]):"."})},parents:function(){return h},filter:E}),e(d).on(s,null,p,Q),B&&(u=F(r),u=u.obId||(u.obId=k++),B[u]=B[u]||(B.len++,r)))}function f(t,e,n,r,s){if(o){var a,f=z;a=e,s&&(a=e[s],z=z?z+"."+s:z),(r||p(a))&&(E&&a&&(a=i._fltr(z,a,$,E)),a&&c(t,a,void 0,j+".observe"+V(t),void 0,!0,n)),z=f}}function v(i){function s(i,_,g,m){function x(e){return e.ob=m(e),e.cb=function(n,r){var i=e.ob,s=e.sb,a=m(e);a!==i&&(typeof i===h&&(f(g,i,!0),(s||o&&p(i))&&t([i],s,g,m,!0)),e.ob=a,typeof a===h&&(f(g,a),(s||o&&p(a))&&t([a],s,g,m))),g(n,r)}}function A(t,i){function a(t,e){var n;if("insert"===e.change||(I="remove"===e.change)){for(n=e.items.length;n--;)A(e.items[n],i.slice());I=!1}}g&&(a._cId=V(g),a._inId=".arIn"+P++);var _,y,x,k,S,T,D,O=t;if(t&&t._cxp)return s(t[0],[t[1]],g,m);for(;void 0!==(L=i.shift())&&"__proto__"!==L;){if(O&&typeof O===h&&typeof L===d){if(""===L)continue;if("()"===L.slice(-2)&&(L=L.slice(0,-2),D=!0),i.lengthk;k++)if(C=_[k],""!==C)if(C&&C._ar)o+=C._ar;else if(typeof C===d)if(y=C.split("^"),y[1]&&(F=y[0].split(".").length,C=y.join("."),F=C.split(".").length-F),m&&(M=m(C,F))){if(M.length){var T=M[0],D=M[1];if(T&&T._cxp&&(D=T[1],T=T[0],"view"===T._is)){s(T,[D],g);continue}typeof D===d?A(T,D.split(".")):s(M.shift(),M,g,m)}}else A(i,C.split("."));else!l(C)&&C&&C._cpfn&&(N=I?C.cb||(C.cb=g):x(C),N._cId=g._cId,N._inId=N._inId||".obIn"+P++,(C.bnd||C.prm&&C.prm.length||!C.sb)&&t([i],C.path,C.prm.length?[C.root||i]:[],C.prm,N,m,I),C.sb&&(C.sb.prm&&(C.sb.root=i),s(C.ob,[C.sb],g,m)))}for(var _,g=[],m=i.length;m--;)_=i[m],typeof _===d||_&&(_._ar||_._cpfn)?g.unshift(_):(s(_,g,C,D),g=[])}var g,y,I,C,S,T,q,D,M,B,N,$,z,E,G,J,K,L,R,U,W=A,X=1!=this?b.apply([],arguments):_.call(arguments),Y=X.pop()||!1,Z=X.length;if(typeof Y===d&&(z=Y,$=X.pop(),E=X.pop(),Y=!!X.pop(),Z-=3),Y===!!Y&&(I=Y,Y=X[Z-1],Y=!Z||typeof Y===d||Y&&!l(Y)?void 0:(Z--,X.pop()),I&&!Z&&l(X[0])&&(Y=X.shift())),C=Y,Z&&l(X[Z-1])&&(D=C,Y=C=X.pop(),Z--),!I||!C||C._cId){for(W+=C?(T=C._inId||"",I?C._cId+T:(S=V(C))+T):"",S&&!I&&(B=x[S]=x[S]||{len:0}),G=n&&n.match(m)||[""],J=G.length;J--;){if(n=G[J],I&&arguments.length<3)if(C)s(C,x[C._cId]);else if(!X[0])for(g in x)s(C,x[g]);v(X)}return S&&!B.len&&delete x[S],{cbId:S,bnd:B,s:x}}}var n,o=1==this?0:1,s=_.call(arguments),c=s[0];return typeof c===d&&(n=c,s.shift()),t.apply(1,s)},T.wait=function(){var t=this;t._go=1,setTimeout(function(){t.trigger(!0),t._go=0,t.paths={}})},i=function(t,e,n){typeof t!==d&&(n=e,e=t,t=""),n=void 0===n?f.asyncObserve:n;var r=p(e)?new D(t,e):new q(t,e);return n&&(n===!0&&(r.async=!0,n=T),n.trigger||(p(n)?(n.trigger=G,n.paths={}):n=void 0),r._batch=n),r},e.observable=i,i._fltr=function(t,e,n,r){return(r&&l(r)&&(typeof e===h||l(e))?r(t,e,n):!0)?(e=l(e)?e.set&&e.call(n[0]):e,typeof e===h&&e):void 0},i.Object=q,i.Array=D,e.observe=i.observe=r,e.unobserve=i.unobserve=E,i._apply=M,q.prototype={_data:null,observeAll:B,unobserveAll:N,data:function(){return this._data},setProperty:function(t,e,n,r){t=t||"";var i,o,s,a,c=typeof t!==d,f=this,l=f._data,h=f._batch;if(l)if(c)if(n=e,p(t))for(i=t.length;i--;)o=t[i],f.setProperty(o.name,o.value,void 0===n||n);else{h||(f._batch=a=[],a.trigger=G,a.paths={});for(i in t)f.setProperty(i,t[i],n);a&&(f._batch.trigger(),f._batch=void 0)}else if(t!==u){for(s=t.split(/[.^]/);l&&s.length>1;)i=s.shift(),l="__proto__"!==i?l[i]:void 0;l&&f._setProperty(l,s[0],e,n,r)}return f},removeProperty:function(t){return this.setProperty(t,S),this},_setProperty:function(t,e,n,r,i){var o,s,a,c,f,p=e?t[e]:t;if(l(p)&&!l(n)){if(i&&!p.set)return;p.set&&(f=t._vw||t,s=p,o=s.set===!0?s:s.set,p=s.call(f))}(p!==n||r&&p!=n)&&(!(p instanceof Date&&n instanceof Date)||p>n||n>p)&&(o?(o.call(f,n),n=s.call(f)):(a=n===S)?void 0!==p?(delete t[e],n=void 0):e=void 0:e&&(t[e]=n),e&&(c={change:"set",path:e,value:n,oldValue:p,remove:a},t._ocp&&(c.ctxPrm=t._key),this._trigger(t,c)))},_trigger:function(t,n,r){c._cchCt++;var i,o,s,a=this;e.hasData(t)&&(!r&&(o=a._batch)?(a.async&&!o._go&&o.wait(),o.push([a,t,n]),i=F(t).obId+n.path,(s=o.paths[i])&&(o[s-1].skip=1),o.paths[i]=o.length):(e(t).triggerHandler(w+(this._ns?"."+/^\S+/.exec(this._ns)[0]:""),n),n.oldValue=null))}},D.prototype={_data:null,observeAll:B,unobserveAll:N,data:function(){return this._data},insert:function(t,e){var n=this._data;return 1===arguments.length&&(e=t,t=n.length),t=y(t),t>-1&&(e=p(e)?e:[e],e.length&&this._insert(t,e)),this},_insert:function(t,e){var n=this._data,r=n.length;t>r&&(t=r),g.apply(n,[t,0].concat(e)),this._trigger({change:"insert",index:t,items:e},r)},remove:function(t,e){var n,r=this._data;return void 0===t&&(t=r.length-1),t=y(t),e=e?y(e):0===e?0:1,e>0&&t>-1&&(n=r.slice(t,t+e),(e=n.length)&&this._remove(t,e,n)),this},_remove:function(t,e,n){var r=this._data,i=r.length;r.splice(t,e),this._trigger({change:"remove",index:t,items:n},i)},move:function(t,e,n){return n=n?y(n):0===n?0:1,t=y(t),e=y(e),n>0&&t>-1&&e>-1&&t!==e&&this._move(t,e,n),this},_move:function(t,e,n){var r,i=this._data,o=i.length,s=t+n-o;s>0&&(n-=s),n&&(r=i.splice(t,n),e>i.length&&(e=i.length),g.apply(i,[e,0].concat(r)),e!==t&&this._trigger({change:"move",oldIndex:t,index:e,items:r},o))},refresh:function(t){function e(){i&&(a.insert(r-i,c),u+=i,n+=i,i=0,c=[])}var n,r,i,o,s,a=this,c=[],f=a._data,l=f.slice(),p=f.length,u=p,d=t.length;for(a._srt=!0,r=i=0;d>r;r++)if((o=t[r])===f[r-i])e();else{for(n=r-i;u>n&&o!==f[n];n++);if(u>n){for(e(),s=0;s++r&&a.remove(r,u-r),a._srt=void 0,(p||d)&&a._trigger({change:"refresh",oldItems:l},p),a},_trigger:function(t,n,r){c._cchCt++;var i,o,s,a=this;e.hasData(o=a._data)&&(!r&&(s=a._batch)?(t._dly=!0,s.push([a,t,n]),a.async&&!s._go&&s.wait()):(i=o.length,o=e([o]),a._srt?t.refresh=!0:i!==n&&o.triggerHandler(w,{change:"set",path:"length",value:i,oldValue:n}),o.triggerHandler(j+(a._ns?"."+/^\S+/.exec(a._ns)[0]:""),t)))}},v[w]=v[j]={remove:function(t){var n,r,i,o,s,a=t.data;if(a&&(a.off=!0,a=a.cb)&&(n=x[a._cId])){for(i=e._data(this).events[t.type],o=i.length;o--&&!r;)r=(s=i[o].data)&&s.cb&&s.cb._cId===a._cId;r||(--n.len?delete n[F(this).obId]:delete x[a._cId])}}},s.map=function(t){function n(e,n,r,o){var s,a,c=this;c.src&&c.unmap(),n&&(n.map=c),(typeof e===h||l(e))&&(c.src=e,o?c.tgt=t.getTgt(e,n):(r&&(c.tgt=r.tgt||p(r)&&r),c.tgt=c.tgt||[],c.options=n||c.options,(a=c.update())?c=a:(t.obsSrc&&i(c.src).observeAll(c.obs=function(e,n){s||n.refresh||(s=!0,t.obsSrc(c,e,n),s=void 0)},c.srcFlt),t.obsTgt&&i(c.tgt).observeAll(c.obt=function(e,n){s||c.tgt._updt||(s=!0,t.obsTgt(c,e,n),s=void 0)},c.tgtFlt))))}return l(t)&&(t={getTgt:t}),t.baseMap&&(t=e.extend({},t.baseMap,t)),t.map=function(t,e,r,i){return new n(t,e,r,i)},(n.prototype={srcFlt:t.srcFlt||z,tgtFlt:t.tgtFlt||z,update:function(e){var n,r,o=this,s=o.tgt;return!s._updt&&(s._updt=!0,n=o.options&&o.options.map,i(s).refresh(t.getTgt(o.src,o.options=e||o.options)),s._updt=!1,r=o.options&&o.options.map,r&&n!==r)?r:void 0},observe:function(t,n){var r=this,o=r.options;r.obmp&&E(r.obmp),r.obmp=function(){var t=n.fn(n.data,n.view,a)[o.index];e.extend(o.props,t.props),o.args=t.args,r.update()},i._apply(1,n.data,H(t,n.tag,r.obmp),r.obmp,n._ctxCb)},unmap:function(){var t=this;t.src&&t.obs&&i(t.src).unobserveAll(t.obs,t.srcFlt),t.tgt&&t.obt&&i(t.tgt).unobserveAll(t.obt,t.tgtFlt),t.obmp&&E(t.obmp),t.src=void 0},map:n,_def:t}).constructor=n,t},a.advSet=function(){a=this,f=c.advanced,t._jsv=f._jsv?{cbBindings:x}:void 0},a._dp=H,a._gck=V,a._obs=r,c._cchCt=0,f=c.advanced=f||{useViews:!1,_jsv:!1}}return e},window); 3 | //# sourceMappingURL=jquery.observable.min.js.map 4 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jsviews", 3 | "version": "v1.0.16", 4 | "description": "Next-generation MVVM and MVP framework - built on top of JsRender templates. Bringing templates to life...", 5 | "main": "./jsviews.js", 6 | "author": { 7 | "name": "Boris Moore", 8 | "url": "https://github.com/borismoore" 9 | }, 10 | "homepage": "http://www.jsviews.com/#jsviews", 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/borismoore/jsviews.git" 14 | }, 15 | "license": "MIT", 16 | "bugs": { 17 | "url": "https://github.com/borismoore/jsviews/issues" 18 | }, 19 | "types": "./typescript/jsviews/index.d.ts", 20 | "keywords": [ 21 | "jsviews", 22 | "jsrender", 23 | "jquery", 24 | "mvvm", 25 | "mvp", 26 | "spa", 27 | "browserify", 28 | "templates", 29 | "template", 30 | "jquery-plugin", 31 | "ecosystem:jquery" 32 | ], 33 | "devDependencies": { 34 | "@types/jquery": "^3.3.31", 35 | "browserify": "^17.0.0", 36 | "glob-stream": "^8.0.2", 37 | "gulp": "^5.0.0", 38 | "jsrender": "^1.0.16", 39 | "qunit": "^2.21.0" 40 | }, 41 | "dependencies": { 42 | "jquery": "^3.4.1" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/browserify/1-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.one = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jsrender')()", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var jsrender = require('jsrender')(); // Not passing in jQuery, so returns the jsrender namespace 23 | 24 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 25 | var tmpl = require('../templates/name-template.html')(jsrender); // Provide jsrender 26 | 27 | var result = tmpl(data); 28 | 29 | result += " " + (jsrender !== jQuery); 30 | 31 | // ............................... Assert ................................. 32 | assert.equal(result, "Name: Jo (name-template.html) true", "result: No jQuery global: require('jsrender')()"); 33 | 34 | // ............................... Reset ................................. 35 | global.jQuery = jQuery; // Replace QUnit global jQuery 36 | global.jsrender = jsr; // Replace any previous global jsrender 37 | }); 38 | 39 | } 40 | })(); 41 | -------------------------------------------------------------------------------- /test/browserify/10-errors-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.ten = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test('Error cases for require() for JsRender, JsViews, JsObservable, JsRender templates', function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | var $jq, $jsr, tmpl, result; 19 | // ................................ Act .................................. 20 | 21 | try { 22 | // Server template in bundle, thanks to Browserify jsrender/tmplify transform 23 | tmpl = require('../templates/name-template.html')(); // Should provide $ with $.templates defined (jsrender or jQuery namespace) 24 | } 25 | catch(e) { 26 | result = e; 27 | } 28 | 29 | // ............................... Assert ................................. 30 | assert.equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")() throws "Requires jsrender/jQuery"'); 31 | 32 | // ................................ Act .................................. 33 | 34 | try { 35 | tmpl = require('../templates/name-template.html')(22); // Should provide $ with $.templates defined (jsrender or jQuery namespace) 36 | } 37 | catch(e) { 38 | result = e; 39 | } 40 | 41 | // ............................... Assert ................................. 42 | assert.equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")(22) throws "Requires jsrender/jQuery"'); 43 | 44 | // ................................ Act .................................. 45 | 46 | $jq = require("jQuery"); 47 | try { 48 | tmpl = require('../templates/name-template.html')($jq); // Should provide $ with $.templates defined (jsrender or jQuery namespace) 49 | } 50 | catch(e) { 51 | result = e; 52 | } 53 | 54 | // ............................... Assert ................................. 55 | assert.equal(result, "Requires jsrender/jQuery", 'require("../templates/name-template.html")(jq) ($ without jsrender) throws "Requires jsrender/jQuery"'); 56 | 57 | // ................................ Act .................................. 58 | 59 | try { 60 | $jsr = require('jsrender')({}); // Should provide null, or jQuery 61 | } 62 | catch(e) { 63 | result = e; 64 | } 65 | 66 | // ............................... Assert ................................. 67 | assert.equal(result, "Provide jQuery or null", 'require("jsrender")({}) throws "Provide jQuery or null"'); 68 | 69 | // ................................ Act .................................. 70 | 71 | try { 72 | $jsr = require('../../jquery.observable')(); // Should provide jQuery 73 | 74 | } 75 | catch(e) { 76 | result = e; 77 | } 78 | 79 | // ............................... Assert ................................. 80 | assert.equal(result, "jquery.observable.js requires jQuery", 'require("jquery.observable")() throws "jquery.observable.js requires requires jQuery"'); 81 | 82 | // ................................ Act .................................. 83 | 84 | try { 85 | $jsr = require('../../jquery.observable')("a"); // Should provide jQuery 86 | } 87 | catch(e) { 88 | result = e; 89 | } 90 | 91 | // ............................... Assert ................................. 92 | assert.equal(result, "jquery.observable.js requires jQuery", 'require("jquery.observable")("a") throws "jquery.observable.js requires jQuery"'); 93 | 94 | // ................................ Act .................................. 95 | 96 | try { 97 | $jsr = require('../../jquery.views')(); // Should provide jQuery with JsRender, JsObservable 98 | 99 | } 100 | catch(e) { 101 | result = e; 102 | } 103 | 104 | // ............................... Assert ................................. 105 | assert.equal(result, "jquery.views.js requires jQuery", 'require("jquery.views")() throws "jquery.views.js requires jQuery"'); 106 | 107 | // ................................ Act .................................. 108 | 109 | try { 110 | $jsr = require('../../jquery.views')("a"); // Should provide jQuery with JsRender, JsObservable 111 | } 112 | catch(e) { 113 | result = e; 114 | } 115 | 116 | // ............................... Assert ................................. 117 | assert.equal(result, "jquery.views.js requires jQuery", 'require("jquery.views")("a") throws "jquery.views.js requires jQuery"'); 118 | 119 | // ................................ Act .................................. 120 | 121 | $jq = require("jQuery"); 122 | 123 | try { 124 | $jsr = require('../../jquery.views')($jq); // Should provide jQuery with JsRender, JsObservable 125 | } 126 | catch(e) { 127 | result = e; 128 | } 129 | 130 | // ............................... Assert ................................. 131 | assert.equal(result, "jquery.views.js requires jsrender.js", 'require("jquery.views")(jQuery) throws "jquery.views.js requires jsrender.js"'); 132 | 133 | // ................................ Act .................................. 134 | 135 | $jsr = require('jsrender'); 136 | 137 | try { 138 | $jsr = require('../../jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable 139 | } 140 | catch(e) { 141 | result = e; 142 | } 143 | 144 | // ............................... Assert ................................. 145 | assert.equal(result, "jquery.views.js requires jQuery", 'require("jquery.views")(jsrender) throws "jquery.views.js requires jQuery"'); 146 | 147 | // ................................ Act .................................. 148 | 149 | $jsr = require('jsrender')(require("jQuery")); 150 | 151 | try { 152 | $jsr = require('../../jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable 153 | } 154 | catch(e) { 155 | result = e; 156 | } 157 | 158 | // ............................... Assert ................................. 159 | assert.equal(result, "jquery.views.js requires jquery.observable.js", 'require("jquery.views")($jsr) throws "jquery.views.js requires jquery.observable "'); 160 | 161 | // ............................... Reset ................................. 162 | global.jQuery = jQuery; // Replace QUnit global jQuery 163 | global.jsrender = jsr; // Replace any previous global jsrender 164 | }); 165 | } 166 | })(); 167 | -------------------------------------------------------------------------------- /test/browserify/11-errors-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.eleven = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test('More Errors for require() for JsRender, JsViews, JsObservable, JsRender templates', function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | var $jq, $jsr, tmpl, result; 19 | 20 | // ................................ Act .................................. 21 | 22 | $jsr = require("jsrender")(require("jQuery")); 23 | 24 | try { 25 | $jsr = require('../../jquery.views')($jsr); // Should provide jQuery with JsRender, JsObservable 26 | } 27 | catch(e) { 28 | result = e; 29 | } 30 | 31 | // ............................... Assert ................................. 32 | assert.equal(result, "jquery.views.js requires jquery.observable.js", 'require("jquery.views")($jsr) throws "jquery.views.js requires jquery.observable.js"'); 33 | 34 | // ................................ Act .................................. 35 | 36 | $jsr = require("jsrender")(require("jQuery")); 37 | 38 | try { 39 | $jsr = require('../../')(); // Should provide jQuery 40 | } 41 | catch(e) { 42 | result = e; 43 | } 44 | 45 | // ............................... Assert ................................. 46 | assert.equal(result, "JsViews requires jQuery", 'require("jsviews")($) throws "JsViews requires jQuery"'); 47 | 48 | // ................................ Act .................................. 49 | 50 | try { 51 | $jsr = require('../../')("a"); // Should provide jQuery 52 | } 53 | catch(e) { 54 | result = e; 55 | } 56 | 57 | // ............................... Assert ................................. 58 | assert.equal(result, "JsViews requires jQuery", 'require("jsviews")("a") throws "JsViews requires jQuery"'); 59 | 60 | // ................................ Act .................................. 61 | 62 | $jsr = require("jsrender"); 63 | 64 | try { 65 | $jsr = require('../../')($jsr); // Should provide jQuery 66 | } 67 | catch(e) { 68 | result = e; 69 | } 70 | 71 | // ............................... Assert ................................. 72 | assert.equal(result, "JsViews requires jQuery", 'require("jsviews")(jQuery) throws "JsViews requires jQuery"'); 73 | 74 | // ............................... Reset ................................. 75 | global.jQuery = jQuery; // Replace QUnit global jQuery 76 | global.jsrender = jsr; // Replace any previous global jsrender 77 | }); 78 | } 79 | })(); 80 | -------------------------------------------------------------------------------- /test/browserify/12-nested-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.twelve = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jsrender')() nested template", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var jsrender = require('jsrender')(); // Not passing in jQuery, so returns the jsrender namespace 23 | 24 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 25 | var tmpl = require('../templates/outer.html')(jsrender); // Provide jsrender 26 | 27 | var result = tmpl(data); 28 | 29 | result += " " + (jsrender !== jQuery); 30 | 31 | // ............................... Assert ................................. 32 | assert.equal(result, "Name: Jo (outer.html) Name: Jo (inner.html) true", "result: No jQuery global: require('jsrender')(), nested templates"); 33 | 34 | // ............................... Reset ................................. 35 | global.jQuery = jQuery; // Replace QUnit global jQuery 36 | global.jsrender = jsr; // Replace any previous global jsrender 37 | }); 38 | } 39 | })(); 40 | -------------------------------------------------------------------------------- /test/browserify/2-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.two = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jsrender')($)", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var $jq = require('jquery'); 23 | var $jsr = require('jsrender')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace 24 | 25 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 26 | var tmpl = require('../templates/name-template.html')($jsr); // Provide jsrender 27 | 28 | var result = tmpl(data); 29 | 30 | result += " " + ($jsr !== jQuery); 31 | 32 | // ............................... Assert ................................. 33 | assert.equal(result, "Name: Jo (name-template.html) true", "result: No jQuery global: require('jsrender')($)"); 34 | 35 | // ............................... Reset ................................. 36 | global.jQuery = jQuery; // Replace QUnit global jQuery 37 | global.jsrender = jsr; // Replace any previous global jsrender 38 | }); 39 | } 40 | })(); 41 | -------------------------------------------------------------------------------- /test/browserify/3-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.three = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("jQuery global: require('jsrender')", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | global.jQuery = require('jquery'); 23 | var $jsr = require('jsrender'); // Uses global jQuery, so $jsr === global.jQuery is global jQuery namespace 24 | 25 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 26 | var tmpl = require('../templates/name-template.html'); // Uses jsrender attached to global jQuery 27 | 28 | var result = tmpl(data); 29 | 30 | result += " " + ($jsr !== jQuery) + " " + ($jsr === global.jQuery); 31 | 32 | // ............................... Assert ................................. 33 | assert.equal(result, "Name: Jo (name-template.html) true true", "result: jQuery global: require('jsrender')"); 34 | 35 | // ............................... Reset ................................. 36 | global.jQuery = jQuery; // Replace QUnit global jQuery 37 | global.jsrender = jsr; // Replace any previous global jsrender 38 | }); 39 | } 40 | })(); 41 | -------------------------------------------------------------------------------- /test/browserify/4-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.four = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jquery.observable')", function(assert) { 14 | // ............................... Hide QUnit global jQuery ................................. 15 | var jQuery = global.jQuery; 16 | global.jQuery = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var $jq = require('jquery'); 23 | var $jsr = require('../../jquery.observable')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace && !$jsr.templates 24 | 25 | var result = ""; 26 | 27 | $jsr.observe(data, "name", function(ev, eventArgs) { 28 | result += " " + eventArgs.value; 29 | }) 30 | 31 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 32 | 33 | result += " " + ($jsr !== jQuery && $jsr === $jq); 34 | 35 | // ............................... Assert ................................. 36 | assert.equal(result, " new name true", "result: No jQuery global: require('jquery.observable')"); 37 | 38 | // ............................... Reset ................................. 39 | global.jQuery = jQuery; // Replace QUnit global jQuery 40 | }); 41 | } 42 | })(); 43 | -------------------------------------------------------------------------------- /test/browserify/5-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.five = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("jQuery global: require('jquery.observable')", function(assert) { 14 | // ............................... Hide QUnit global jQuery ................................. 15 | var jQuery = global.jQuery; 16 | global.jQuery = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | global.jQuery = require('jquery'); 23 | var $jsr = require('../../jquery.observable'); // Uses global jQuery, so $jsr === global.jQuery is global jQuery namespace 24 | var result = ""; 25 | 26 | $jsr.observe(data, "name", function(ev, eventArgs) { 27 | result += " " + eventArgs.value; 28 | }) 29 | 30 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 31 | 32 | result += " " + ($jsr === global.jQuery); 33 | 34 | // ............................... Assert ................................. 35 | assert.equal(result, " new name true", "result: jQuery global: require('jquery.observable')"); 36 | 37 | // ............................... Reset ................................. 38 | global.jQuery = jQuery; // Replace QUnit global jQuery 39 | }); 40 | } 41 | })(); 42 | -------------------------------------------------------------------------------- /test/browserify/6-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.six = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jquery.views')", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var $jq = require('jquery'); 23 | var $jsr = require('jsrender')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace // Else JsViews requires JsRender 24 | $jsr = require('../../jquery.observable.js')($jsr); // Provide $jsr === $jq // Else JsViews requires JsObservable 25 | $jsr = require('../../jquery.views.js')($jsr); // Provide $jsr === $jq 26 | 27 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 28 | var tmpl = require('../templates/name-template.html')($jsr); // Provide $jsr === $jq 29 | 30 | var result = tmpl(data); 31 | 32 | $jsr.observe(data, "name", function(ev, eventArgs) { 33 | result += " " + eventArgs.value; 34 | }) 35 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 36 | 37 | result += " " + ($jsr !== jQuery && $jsr === $jq); 38 | 39 | // ............................... Assert ................................. 40 | assert.equal(result, "Name: Jo (name-template.html) new name true", "result: No jQuery global: require('jquery.views')"); 41 | 42 | // ............................... Reset ................................. 43 | global.jQuery = jQuery; // Replace QUnit global jQuery 44 | global.jsrender = jsr; // Replace any previous global jsrender 45 | }); 46 | } 47 | })(); 48 | -------------------------------------------------------------------------------- /test/browserify/7-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.seven = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("jQuery global: require('jquery.views')", function(assert) { 14 | // ............................... Hide QUnit global jQuery ................................. 15 | var jQuery = global.jQuery; 16 | global.jQuery = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | global.jQuery = require('jquery'); 23 | 24 | var $jsr = require('jsrender'); // Uses global jQuery, so $jsr === global.jQuery is global jQuery namespace // Else JsViews requires JsRender 25 | $jsr = require('../../jquery.observable.js'); // $jsr === global.jQuery // Else JsViews requires JsObservable 26 | $jsr = require('../../jquery.views'); // $jsr === global.jQuery 27 | 28 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 29 | var tmpl = require('../templates/name-template.html'); // Uses jsrender attached to global jQuery 30 | 31 | var result = tmpl(data); 32 | 33 | $jsr.observe(data, "name", function(ev, eventArgs) { 34 | result += " " + eventArgs.value; 35 | }) 36 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 37 | 38 | result += " " + ($jsr === global.jQuery); 39 | 40 | // ............................... Assert ................................. 41 | assert.equal(result, "Name: Jo (name-template.html) new name true", "result: jQuery global: require('jquery.views')"); 42 | 43 | // ............................... Reset ................................. 44 | global.jQuery = jQuery; // Replace QUnit global jQuery 45 | }); 46 | } 47 | })(); 48 | -------------------------------------------------------------------------------- /test/browserify/8-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.eight = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jsviews')", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var $jq = require('jquery'); 23 | 24 | var $jsr = require('../../')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace 25 | 26 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 27 | var tmpl = require('../templates/name-template.html')($jsr); // Provide $jsr 28 | 29 | var result = tmpl(data); 30 | 31 | $jsr.observe(data, "name", function(ev, eventArgs) { 32 | result += " " + eventArgs.value; 33 | }) 34 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 35 | 36 | result += " " + ($jsr !== jQuery && $jsr === $jq); 37 | 38 | // ............................... Assert ................................. 39 | assert.equal(result, "Name: Jo (name-template.html) new name true", "result: No jQuery global: require('jsviews')"); 40 | 41 | // ............................... Reset ................................. 42 | global.jQuery = jQuery; // Replace QUnit global jQuery 43 | global.jsrender = jsr; // Replace any previous global jsrender 44 | }); 45 | } 46 | })(); 47 | -------------------------------------------------------------------------------- /test/browserify/8B-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.eightB = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("No jQuery global: require('jsrender') require('jsviews')", function(assert) { 14 | // ............................... Hide QUnit global jQuery and any previous global jsrender................................. 15 | var jQuery = global.jQuery, jsr = global.jsrender; 16 | global.jQuery = global.jsrender = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | var $jq = require('jquery'); 23 | var $jsr = require('jsrender')($jq); // Unnecessary loading of additional jsrender instance (Test case) 24 | $jsr = require('../../')($jq); // Provide jQuery, so $jsr === $jq is local jQuery namespace 25 | 26 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 27 | var tmpl = require('../templates/name-template.html')($jsr); // Provide $jsr 28 | 29 | var result = tmpl(data); 30 | 31 | $jsr.observe(data, "name", function(ev, eventArgs) { 32 | result += " " + eventArgs.value; 33 | }) 34 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 35 | 36 | result += " " + ($jsr !== jQuery && $jsr === $jq); 37 | 38 | // ............................... Assert ................................. 39 | assert.equal(result, "Name: Jo (name-template.html) new name true", "result: No jQuery global: require('jsviews')"); 40 | 41 | // ............................... Reset ................................. 42 | global.jQuery = jQuery; // Replace QUnit global jQuery 43 | global.jsrender = jsr; // Replace any previous global jsrender 44 | }); 45 | } 46 | })(); 47 | -------------------------------------------------------------------------------- /test/browserify/9-unit-tests.js: -------------------------------------------------------------------------------- 1 | /*global QUnit, test, equal, ok*/ 2 | (function(undefined) { 3 | "use strict"; 4 | 5 | browserify.done.nine = true; 6 | 7 | QUnit.module("Browserify - client code"); 8 | 9 | var isIE8 = window.attachEvent && !window.addEventListener; 10 | 11 | if (!isIE8) { 12 | 13 | QUnit.test("jQuery global: require('jsviews')", function(assert) { 14 | // ............................... Hide QUnit global jQuery ................................. 15 | var jQuery = global.jQuery; 16 | global.jQuery = undefined; 17 | 18 | // =============================== Arrange =============================== 19 | var data = {name: "Jo"}; 20 | 21 | // ................................ Act .................................. 22 | global.jQuery = require('jquery'); 23 | 24 | var $jsr = require('../../'); // Uses global jQuery, so $jsr === global.jQuery is global jQuery namespace 25 | 26 | // Use require to get server template, thanks to Browserify bundle that used jsrender/tmplify transform 27 | var tmpl = require('../templates/name-template.html'); // Uses jsrender attached to global jQuery 28 | 29 | var result = tmpl(data); 30 | 31 | $jsr.observe(data, "name", function(ev, eventArgs) { 32 | result += " " + eventArgs.value; 33 | }) 34 | $jsr.observable(data).setProperty("name", "new name"); // result === "new name" 35 | 36 | result += " " + ($jsr === global.jQuery); 37 | 38 | // ............................... Assert ................................. 39 | assert.equal(result, "Name: Jo (name-template.html) new name true", "result: jQuery global: require('jsviews')"); 40 | 41 | // ............................... Reset ................................. 42 | global.jQuery = jQuery; // Replace QUnit global jQuery 43 | }); 44 | } 45 | })(); 46 | -------------------------------------------------------------------------------- /test/browserify/bundles/browserify-bundles-go-here.txt: -------------------------------------------------------------------------------- 1 | Run 2 | $ gulp bundle 3 | to generate browserify client bundles used in the unit tests: test/unit-tests-browserify.html 4 | -------------------------------------------------------------------------------- /test/browserify/tests-browserify-completed.js: -------------------------------------------------------------------------------- 1 | /*global test, equal, module, ok*/ 2 | (function(global, $, undefined) { 3 | "use strict"; 4 | 5 | QUnit.module("browserify"); 6 | 7 | var isIE8 = window.attachEvent && !window.addEventListener; 8 | 9 | if (!isIE8) { 10 | 11 | QUnit.test("browserify tests all run", function(assert) { 12 | assert.equal(JSON.stringify(browserify.done), 13 | '{"one":true,"two":true,"three":true,"four":true,"five":true,"six":true,"seven":true,"eight":true,"eightB":true,"nine":true,"ten":true,"eleven":true,"twelve":true}' 14 | , "Browserify tests succeeded"); 15 | }); 16 | } 17 | })(this, this.jQuery); 18 | -------------------------------------------------------------------------------- /test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test pages for JsViews 5 | 6 | 11 | 12 | 13 | 14 | 15 |

        Unit tests for JsViews and JsRender

        16 | 30 | 31 | 32 | -------------------------------------------------------------------------------- /test/resources/close.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/BorisMoore/jsviews/15f8234c06be47b73317b18f0598eacbfefb6ae6/test/resources/close.png -------------------------------------------------------------------------------- /test/resources/showviews.js: -------------------------------------------------------------------------------- 1 | function viewsAndBindings() { 2 | var key, 3 | topView = _jsv.views[0], 4 | res = "", 5 | topViews = "", 6 | bindings = ""; 7 | 8 | for (key in _jsv.views) { 9 | if (_jsv.views[key]) { 10 | res += key + " "; 11 | } 12 | } 13 | 14 | res = res.slice(2); // Remove view 0 15 | 16 | res = res ? "Bound Views: " + res + "\n" : ""; 17 | 18 | for (key in topView.views) { 19 | if (topView.views[key]) { 20 | topViews += key + " "; 21 | } 22 | } 23 | 24 | res = res + (topViews ? "Top Views: " + topViews : ""); 25 | 26 | for (var key in _jsv.bindings) { 27 | if (_jsv.bindings[key]) { 28 | bindings += key + " "; 29 | } 30 | } 31 | 32 | res = res + (bindings ? "Bindings: " + bindings : ""); 33 | 34 | $("#views").html(res); 35 | return res; 36 | } 37 | -------------------------------------------------------------------------------- /test/templates/file/path.html: -------------------------------------------------------------------------------- 1 | ServerRenderedTemplate_{{:name}}_B -------------------------------------------------------------------------------- /test/templates/inner.html: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (inner.html) -------------------------------------------------------------------------------- /test/templates/name-template.htm: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (name-template.htm) -------------------------------------------------------------------------------- /test/templates/name-template.html: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (name-template.html) -------------------------------------------------------------------------------- /test/templates/name-template.jsr: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (name-template.jsr) -------------------------------------------------------------------------------- /test/templates/name-template.jsrender: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (name-template.jsrender) -------------------------------------------------------------------------------- /test/templates/outer.html: -------------------------------------------------------------------------------- 1 | Name: {{:name}} (outer.html) {{include tmpl="./test/templates/inner.html"/}} -------------------------------------------------------------------------------- /test/test-amd-scriptloader-no-jquery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /test/test-pages/for-else.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |

        Test Page for array data-binding

        16 |

        {^{for}}...{{else}}...{{/for}} and data-link="{for ...}"

        17 | 18 |

        19 | 20 | 21 | 22 | 23 |
        24 | 25 | 26 | 27 | 28 |
        29 | 30 |

        31 | 32 | 33 |
        34 | 35 | 36 | 106 | 107 | 110 | 111 | 114 | 115 | 203 | 204 | 205 | 206 | 207 | -------------------------------------------------------------------------------- /test/test-pages/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Test pages for JsViews 5 | 6 | 7 | 8 | 9 | 10 |

        Additional test pages for JsViews and JsRender

        11 | 12 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /test/test-pages/sibling-collection-views.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 |

        Test page for data-linking annotations and correct management of views and positional insertion

        15 | 16 |

        17 | 18 | 19 | 20 | 21 | 22 | 23 |

        24 | 25 | View annotations are logged in the console. 26 |

        Sibling lists within element-only content:

        27 | 28 | 29 |
        30 |

        Sibling lists within regular content:

        31 | 32 |
        33 | 56 | 57 | 82 | 83 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /test/test-pages/view-hierarchy-refresh.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |

        Test page for refresh behavior of view hierarchies

        14 | 15 |

        16 | 17 | 18 | 19 |

        20 | 21 | 22 | 23 | 24 |
        25 | 26 | 67 | 68 | 123 | 124 | 125 | -------------------------------------------------------------------------------- /test/test.min.map.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | Got to F12 debug and see if you have an error: 15 |

        DevTools failed to load SourceMap: Could not parse content for ... 16 |

        17 |
        18 | 19 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /test/unit-tests-all-jsviews.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 |
        47 |

        JsViews QUnit Tests

        48 |

        49 |
        50 |

        51 |
          52 | 53 | 54 | -------------------------------------------------------------------------------- /test/unit-tests-all-observable-render-views.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
          36 |

          JsViews QUnit Tests

          37 |

          38 |
          39 |

          40 |
            41 | 42 | 43 | -------------------------------------------------------------------------------- /test/unit-tests-all-render-observable-views.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 15 | 16 | 17 | 18 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 |
            46 |

            JsViews QUnit Tests

            47 |

            48 |
            49 |

            50 |
              51 | 52 | 53 | -------------------------------------------------------------------------------- /test/unit-tests-amd-scriptloader.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
              16 |

              JsViews AMD QUnit Tests

              17 |

              18 |
              19 |

              20 |
                21 | 22 | 23 | -------------------------------------------------------------------------------- /test/unit-tests-browserify.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

                Note: Run $ gulp bundle before running these tests

                11 |
                12 |

                JsViews QUnit Tests

                13 |

                14 |
                15 |

                16 |
                  17 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /test/unit-tests-jsobservable-no-jqueryviews.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
                  16 |

                  JsObservable QUnit Tests

                  17 |

                  18 |
                  19 |

                  20 |
                    21 | 22 | 23 | -------------------------------------------------------------------------------- /test/unit-tests-jsrender-no-jquery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
                    18 |

                    JsRender QUnit Tests

                    19 |

                    20 |
                    21 |

                    22 |
                      23 | 24 | 25 | -------------------------------------------------------------------------------- /test/unit-tests-jsrender-with-jquery.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
                      20 |

                      JsRender QUnit Tests

                      21 |

                      22 |
                      23 |

                      24 |
                        25 | 26 | 27 | -------------------------------------------------------------------------------- /test/unit-tests-jsviews.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 |
                        20 |

                        JsViews QUnit Tests

                        21 |

                        22 |
                        23 |

                        24 |
                          25 | 26 | 27 | -------------------------------------------------------------------------------- /test/unit-tests-multiple-loads.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 |
                          55 |

                          JsViews QUnit Tests

                          56 |

                          57 |
                          58 |

                          59 |
                            60 | 61 | 62 | -------------------------------------------------------------------------------- /test/unit-tests/requirejs-config.js: -------------------------------------------------------------------------------- 1 | // Configure loading modules from the download directory, 2 | requirejs.config({ 3 | "baseUrl": "//www.jsviews.com/download", // Or point to correct local path on your system: "baseUrl": "/download", 4 | // "baseUrl": "../../download", // Or point to correct local path on your system: "baseUrl": "/download", 5 | "paths": { 6 | "jquery": "//code.jquery.com/jquery-3.7.1", 7 | "jsrender": "./jsrender", 8 | "jquery.observable": "./jquery.observable", 9 | "jquery.views": "./jquery.views", 10 | "jsviews": "./jsviews" 11 | } 12 | }); 13 | -------------------------------------------------------------------------------- /test/unit-tests/tests-jsrender-amd-scriptloader.js: -------------------------------------------------------------------------------- 1 | /*global test, equal, module, ok*/ 2 | (function(global, jQuery, undefined) { 3 | "use strict"; 4 | 5 | function undefine() { // Undefine registered modules from previously run tests. 6 | require.undef("jsrender"); 7 | require.undef("jquery"); 8 | delete window.jQuery; 9 | } 10 | 11 | if (!window.attachEvent || window.addEventListener) { // Running RequireJS in qunit async test seems to fail in IE8 12 | 13 | QUnit.module("AMD Script Loader"); 14 | 15 | QUnit.test("Loading JsRender, without jQuery, using RequireJS", function(assert) { 16 | var done; 17 | if (assert.async) { done = assert.async() } else { stop() } 18 | var jq = window.jQuery; 19 | undefine(); 20 | 21 | require(["//www.jsviews.com/download/jsrender.js"], function($) { // Or point to correct local path for jsrender.js on your system 22 | // require(["../../download/jsrender.js"], function($) { // Or point to correct local path for jsrender.js on your system 23 | // Here $ is the global jQuery object, (jq - loaded by script block in page header, for QUnit) 24 | // If there was no global jQuery it would be the jsviews object - but no global would be created. 25 | 26 | var result = $.templates("Name: {{:name}}").render({name: "Jo"}) + " " + (!!$.jsrender); 27 | assert.equal(result, "Name: Jo true", "JsRender Loaded"); 28 | if (assert.async) { done() } else { start() } 29 | }); 30 | }); 31 | 32 | QUnit.test("Loading JsRender and jQuery, without forcing load order, using RequireJS", function(assert) { 33 | var done; 34 | if (assert.async) { done = assert.async() } else { stop() } 35 | var jq = window.jQuery; 36 | undefine(); 37 | 38 | // Note JsRender does not require jQuery - so its AMD definition does not specify jQuery dependency. 39 | 40 | require(["./unit-tests/requirejs-config"], function() { 41 | require(["jquery", "jsrender"], function($jq, $) { 42 | // Note: $ is either the jQuery loaded by RequireJS, or the window.jsrender object, depending on load order 43 | // Either way, it is the jQuery instance that has a $.views, $.templates etc. 44 | 45 | var result = $.templates("Name: {{:name}}").render({name: "Jo"}) + " " + ($ === $jq || !!$.jsrender); 46 | assert.equal(result, "Name: Jo true", "JsRender Loaded"); 47 | if (assert.async) { done() } else { start() } 48 | }); 49 | }); 50 | }); 51 | 52 | QUnit.test("Loading JsRender with jQuery, and force jQuery to load before JsRender, using RequireJS", function(assert) { 53 | var done; 54 | if (assert.async) { done = assert.async() } else { stop() } 55 | var jq = window.jQuery; 56 | undefine(); 57 | 58 | // Note JsRender does not require jQuery - so its AMD definition does not specify jQuery dependency. 59 | // So we will force loading order here by nesting require call for JsRender inside require call for jQuery. 60 | // This is not optimized for loading speed. 61 | 62 | require(["./unit-tests/requirejs-config"], function() { 63 | require(["jquery"], function($jq) { 64 | require(["jsrender"], function($) { 65 | // Note: $ is a new instance of jQuery (=== $jq) loaded by RequireJS, not the instance loaded by script block in page header, for QUnit. 66 | 67 | var result = $.templates("Name: {{:name}}").render({name: "Jo"}) + " " + (jq !== $ && $ === window.jQuery && $ === $jq); 68 | assert.equal(result, "Name: Jo true", "JsRender LoadedX"); 69 | if (assert.async) { done() } else { start() } 70 | }); 71 | }); 72 | }); 73 | }); 74 | 75 | } 76 | })(this, this.jQuery); 77 | -------------------------------------------------------------------------------- /test/unit-tests/tests-jsviews-amd-scriptloader.js: -------------------------------------------------------------------------------- 1 | /*global test, equal, module, ok*/ 2 | (function(global, jQuery, undefined) { 3 | "use strict"; 4 | 5 | function undefine() { // Undefine registered modules from previously run tests. 6 | require.undef("jsviews"); 7 | require.undef("jquery.views"); 8 | require.undef("jquery.observable"); 9 | require.undef("jsrender"); 10 | require.undef("jquery"); 11 | delete window.jQuery; 12 | } 13 | 14 | if (!window.attachEvent || window.addEventListener) { // Running RequireJS in qunit async test seems to fail in IE8 15 | 16 | QUnit.module("AMD Script Loader"); 17 | 18 | QUnit.test("Loading jquery.observable.js using RequireJS", function(assert) { 19 | var done; 20 | if (assert.async) { done = assert.async() } else { stop() } 21 | var jq = window.jQuery; 22 | undefine(); 23 | 24 | require(["./unit-tests/requirejs-config"], function() { 25 | require(["jquery.observable"], function($) { 26 | // Note: $ is a new instance of jQuery loaded by RequireJS, not the instance loaded by script block in page header, for QUnit. 27 | var data = {name: "Jo"}; 28 | $.observable(data).setProperty("name", "Jo updated!"); 29 | 30 | var result = data.name + " " + (jq !== $ && $ === window.jQuery); 31 | assert.equal(result, "Jo updated! true", "jsviews.js loaded"); 32 | if (assert.async) { done() } else { start() } 33 | }); 34 | }); 35 | }); 36 | 37 | QUnit.test("Loading jquery.views.js, plus dependencies, using RequireJS", function(assert) { 38 | var done; 39 | if (assert.async) { done = assert.async() } else { stop() } 40 | var jq = window.jQuery; 41 | undefine(); 42 | 43 | require(["./unit-tests/requirejs-config"], function() { 44 | require(["jquery.views"], function($) { 45 | // Note: $ is a new instance of jQuery loaded by RequireJS, not the instance loaded by script block in page header, for QUnit. 46 | var data = {name: "Jo"}; 47 | $.templates("Name: {^{:name}}").link("#result", data); 48 | $.observable(data).setProperty("name", "Jo updated!"); 49 | 50 | var result = $("#result").text() + " " + (jq !== $ && $ === window.jQuery); 51 | assert.equal(result, "Name: Jo updated! true", "jquery.views.js loaded"); 52 | if (assert.async) { done() } else { start() } 53 | }); 54 | }); 55 | }); 56 | 57 | QUnit.test("Loading jsviews.js using RequireJS", function(assert) { 58 | var done; 59 | if (assert.async) { done = assert.async() } else { stop() } 60 | var jq = window.jQuery; 61 | undefine(); 62 | 63 | require(["./unit-tests/requirejs-config"], function() { 64 | require(["jsviews"], function($) { 65 | // Note: $ is a new instance of jQuery loaded by RequireJS, not the instance loaded by script block in page header, for QUnit. 66 | var data = {name: "Jo"}; 67 | $.templates("Name: {^{:name}}").link("#result", data); 68 | $.observable(data).setProperty("name", "Jo updated!"); 69 | 70 | var result = $("#result").text() + " " + (jq !== $ && $ === window.jQuery); 71 | assert.equal(result, "Name: Jo updated! true", "jsviews.js loaded"); 72 | if (assert.async) { done() } else { start() } 73 | }); 74 | }); 75 | }); 76 | 77 | } 78 | })(this, this.jQuery); 79 | -------------------------------------------------------------------------------- /typescript/jsviews/test/tests.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /typescript/jsviews/test/tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "lib": [ 5 | "es6", 6 | "dom" 7 | ], 8 | "noImplicitAny": true, 9 | "noImplicitThis": true, 10 | "strictNullChecks": false, 11 | "strictFunctionTypes": true, 12 | "outDir": "./built/", 13 | "sourceMap": true, 14 | "typeRoots": ["../../"], 15 | "types": ["jsviews"] 16 | }, 17 | "include": ["jsr-tests.ts", "jsv-tests.ts"], 18 | "noImplicitAny": true 19 | } 20 | --------------------------------------------------------------------------------