├── .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 |
14 |
15 |
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 | Change name
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 | Change name
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 | Change name
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 |
24 |
25 |
26 |
27 |
Demos
28 |
29 |
32 |
See also the following links:
33 |
34 |
JsViews and JsRender Overview:
35 |
36 |
Source code:
37 |
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 |
45 |
46 |
47 | Other links:
48 |
49 |
56 |
57 | Tests :
58 |
59 |
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 | Change name
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 | Insert person
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 | Add people
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 | Title Languages
29 |
30 |
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 | Title Languages
31 |
32 |
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 | Title Languages
33 |
34 |
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 | show data
18 | delete last language
19 |
20 |
21 |
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 | Title Languages
29 |
30 |
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 | Data DayOff
22 |
23 |
24 |
25 | Convert and convertBack converters with data linking:
26 | data-link="{convert:dataPath:convertBack}"
27 |
28 | Data DayOff Choose day off
29 |
30 |
31 | To edit, enter part of the name, or the number, or click here: Change day
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 | Title Orginal order Reverse order
38 |
39 |
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 |
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 |
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 | add Movie
34 | remove last Movie
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 |
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 | Modify name, city, color and cars
19 | Modify city
20 |
21 |
22 |
23 |
24 |
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 |
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 |
26 |
27 |
28 |
29 | Todos: enter to add, double-click to edit...
30 |
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 | Insert person
20 | remove person
21 | remove people
22 | Swap people
23 |
24 | Add/Remove settings
25 | Swap team
26 | Swap with empty team
27 | Refresh people
28 |
29 | replace all
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 | insert action
18 | insert thing
19 | replace actions
20 | replace things
21 | remove first action
22 | replace
23 |
24 |
25 | View annotations are logged in the console.
26 | Sibling lists within element-only content:
27 |
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 | insert
17 | remove
18 | replace
19 |
20 |
21 |
22 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
--------------------------------------------------------------------------------