-
88 |
├── examples ├── 1 │ └── index.html ├── 2 │ └── index.html ├── 3 │ └── index.html ├── 4 │ └── index.html ├── 5 │ └── index.html ├── 6 │ └── index.html ├── todomvc │ ├── css │ │ └── app.css │ ├── node_modules │ │ ├── todomvc-common │ │ │ ├── base.css │ │ │ └── base.js │ │ └── todomvc-app-css │ │ │ └── index.css │ ├── js │ │ ├── z_handlers.js │ │ └── z.js │ └── index.html ├── index.html └── css │ └── main.css ├── LICENSE ├── CHANGELOG.md └── src ├── ext └── z_handlers.js └── core └── z.js /examples/todomvc/css/app.css: -------------------------------------------------------------------------------- 1 | [filter="active"] li.completed, 2 | [filter="completed"] li:not(.completed), 3 | .all-active .clear-completed 4 | { 5 | display: none; 6 | } 7 | .todo-list li label 8 | { 9 | white-space: initial; 10 | } -------------------------------------------------------------------------------- /examples/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 |
4 |
20 |
<p>
29 | <!--
30 | Устанавливаем z-обработчик тегу <p>
31 | По событию "makeTextRed" необходимо вызвать "addClass"
32 | и в качестве параметра передать имя класса "red"
33 | -->
34 | <e on="makeTextRed" do="addClass">red</e>
35 | Этот текст должен быть красным
36 | </p>
37 | <!-- После загрузки страницы выполняем операции -->
38 | <exec>
39 | <!--
40 | Запускаем событие "makeTextRed"
41 | начиная от родительского элемена тега <exec>
42 | -->
43 | <dispatch e="makeTextRed"></dispatch>
44 | </exec>
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | Версия 0.8.5
2 |
3 | * Косметические изменения в коде
4 |
5 | Версия 0.8.4
6 |
7 | * Исправлена ошибка с циклическими запусками директивы `exec`
8 | * Добавлена возможность не блокировать DOM-события (`stopPropagation` и `preventDefault`)
9 | * Добавлена возможность не запускать события, если на странице выделен контент
10 | * Можно указывать `target` для `
20 |
<p>
34 | <!--
35 | Устанавливаем z-обработчик тегу <p>
36 | По событию "makeTextRed" необходимо вызвать "addClass"
37 | и в качестве параметра передать имя класса "red"
38 | -->
39 | <e on="makeTextRed" do="addClass">red</e>
40 | Этот текст должен стать красным после нажатия на ссылку
41 | </p>
42 | <p>
43 | <a href="#">
44 | <!-- Тегу <a> устанавливаем DOM-обработчик "click" -->
45 | <handler on="click">
46 | <!--
47 | Запускаем событие "makeTextRed"
48 | начиная от <body> (f[rom]="body")
49 | (иначе событие распространялость бы от тега <a>)
50 | -->
51 | <dispatch e="makeTextRed" f="body"></dispatch>
52 | </handler>
53 | Сделать текст красным
54 | </a>
55 | </p>
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/examples/todomvc/node_modules/todomvc-common/base.css:
--------------------------------------------------------------------------------
1 | hr {
2 | margin: 20px 0;
3 | border: 0;
4 | border-top: 1px dashed #c5c5c5;
5 | border-bottom: 1px dashed #f7f7f7;
6 | }
7 |
8 | .learn a {
9 | font-weight: normal;
10 | text-decoration: none;
11 | color: #b83f45;
12 | }
13 |
14 | .learn a:hover {
15 | text-decoration: underline;
16 | color: #787e7e;
17 | }
18 |
19 | .learn h3,
20 | .learn h4,
21 | .learn h5 {
22 | margin: 10px 0;
23 | font-weight: 500;
24 | line-height: 1.2;
25 | color: #000;
26 | }
27 |
28 | .learn h3 {
29 | font-size: 24px;
30 | }
31 |
32 | .learn h4 {
33 | font-size: 18px;
34 | }
35 |
36 | .learn h5 {
37 | margin-bottom: 0;
38 | font-size: 14px;
39 | }
40 |
41 | .learn ul {
42 | padding: 0;
43 | margin: 0 0 30px 25px;
44 | }
45 |
46 | .learn li {
47 | line-height: 20px;
48 | }
49 |
50 | .learn p {
51 | font-size: 15px;
52 | font-weight: 300;
53 | line-height: 1.3;
54 | margin-top: 0;
55 | margin-bottom: 0;
56 | }
57 |
58 | #issue-count {
59 | display: none;
60 | }
61 |
62 | .quote {
63 | border: none;
64 | margin: 20px 0 60px 0;
65 | }
66 |
67 | .quote p {
68 | font-style: italic;
69 | }
70 |
71 | .quote p:before {
72 | content: '“';
73 | font-size: 50px;
74 | opacity: .15;
75 | position: absolute;
76 | top: -20px;
77 | left: 3px;
78 | }
79 |
80 | .quote p:after {
81 | content: '”';
82 | font-size: 50px;
83 | opacity: .15;
84 | position: absolute;
85 | bottom: -42px;
86 | right: 3px;
87 | }
88 |
89 | .quote footer {
90 | position: absolute;
91 | bottom: -40px;
92 | right: 0;
93 | }
94 |
95 | .quote footer img {
96 | border-radius: 3px;
97 | }
98 |
99 | .quote footer a {
100 | margin-left: 5px;
101 | vertical-align: middle;
102 | }
103 |
104 | .speech-bubble {
105 | position: relative;
106 | padding: 10px;
107 | background: rgba(0, 0, 0, .04);
108 | border-radius: 5px;
109 | }
110 |
111 | .speech-bubble:after {
112 | content: '';
113 | position: absolute;
114 | top: 100%;
115 | right: 30px;
116 | border: 13px solid transparent;
117 | border-top-color: rgba(0, 0, 0, .04);
118 | }
119 |
120 | .learn-bar > .learn {
121 | position: absolute;
122 | width: 272px;
123 | top: 8px;
124 | left: -300px;
125 | padding: 10px;
126 | border-radius: 5px;
127 | background-color: rgba(255, 255, 255, .6);
128 | transition-property: left;
129 | transition-duration: 500ms;
130 | }
131 |
132 | @media (min-width: 899px) {
133 | .learn-bar {
134 | width: auto;
135 | padding-left: 300px;
136 | }
137 |
138 | .learn-bar > .learn {
139 | left: 8px;
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/examples/css/main.css:
--------------------------------------------------------------------------------
1 | body
2 | {
3 | background: #2c3e50;
4 | color: #ecf0f1;
5 | font: normal 12pt Arial;
6 | padding: 30px 40px;
7 | }
8 | body::after
9 | {
10 | content: "z";
11 | position: fixed;
12 | left: 0px;
13 | top: 0px;
14 | font-size: 200px;
15 | z-index: -1;
16 | color: rgba(255,255,255,0.1);
17 | line-height: 85px;
18 | }
19 | h1
20 | {
21 | font-weight: normal;
22 | }
23 | h1::before
24 | {
25 | content: "";
26 | padding: 0.2em 0.75em;
27 | margin-right: 0.5em;
28 | width: 0px;
29 | height: 0px;
30 | background: #1abc9c;
31 | border-radius: 10em;
32 | }
33 | a
34 | {
35 | color: #1abc9c;
36 | text-decoration: none;
37 | }
38 | a:hover, a:active
39 | {
40 | text-decoration: underline;
41 | }
42 | a:visited
43 | {
44 | color: #16a085;
45 | }
46 | .content
47 | {
48 | padding-left: 65px;
49 | }
50 | .backLink:link, .backLink:visited
51 | {
52 | font: normal 20pt Arial;
53 | position: absolute;
54 | color: #ecf0f1;
55 | text-decoration: none;
56 | padding: 0.3em 0.65em;
57 | margin: 0.55em 0px;
58 | }
59 | li
60 | {
61 | margin: 10px 0px;
62 | }
63 | code
64 | {
65 | display: block;
66 | white-space: pre;
67 | margin: 40px 20px 20px 65px;
68 | padding: 20px;
69 | background: #34495e;
70 | overflow: auto;
71 | }
72 | code.html::before
73 | {
74 | font-family: Arial;
75 | content: "HTML";
76 | display: block;
77 | background: #7f8c8d;
78 | padding: 8px 20px;
79 | margin: -20px -20px 20px;
80 | position: relative;
81 | }
82 | code .tag
83 | {
84 | color: #d35400;
85 | }
86 | code .zTag
87 | {
88 | color: #3498db;
89 | }
90 | code .txt
91 | {
92 | color: #ecf0f1;
93 | }
94 | code .attrVal
95 | {
96 | color: #1abc9c;
97 | }
98 | code .comment
99 | {
100 | color: #7f8c8d;
101 | }
102 | code .zHandler
103 | {
104 | color: #000;
105 | }
106 | code .dispatcher
107 | {
108 | color: #fff;
109 | text-shadow: 2px 1px 0px rgba(0,0,0,0.2);
110 | }
111 | code .hl
112 | {
113 | background: #000;
114 | border-radius: 5px;
115 | padding: 0px 5px;
116 | margin: 0px -5px;
117 | }
118 | code .global
119 | {
120 | color: #f1c40f;
121 | }
122 | code .zTag:hover .hoverUS
123 | {
124 | border-bottom: 1px dotted #7f8c8d;
125 | cursor: pointer;
126 | }
127 | code .hoverUS:hover
128 | {
129 | color: #f1c40f;
130 | }
131 |
132 | .pMarker::before,
133 | .bMarker::before,
134 | .liMarker::before
135 | {
136 | content: "#";
137 | display: inline-block;
138 | color: #2980b9;
139 | background: #34495e;
140 | border-radius: 3px;
141 | font: normal 9pt monospace;
142 | padding: 2px;
143 | vertical-align: top;
144 | }
145 | .pMarker::before { content: "" }
146 | .bMarker::before { content: "" }
147 | .liMarker::before { content: "
20 |
30 |
62 | Раскрасить
63 |
64 | Извините, тут пусто. Данный пример показывает, как оперировать контейнером начала распространения события и зонами видимости Диспатчеры интерактивные, можно смело тыкать в них палочкойФормы множеств
16 |
17 |
58 |
71 |
72 | <div class="content">
87 | <!-- Темплейтируем данные -->
88 | <e on="init" do="template">listTpl</e>
89 | <exec>
90 | <dispatch e="init">
91 | {
92 | "kids":
93 | [
94 | {
95 | "name": "Маша",
96 | "sex": 0,
97 | "eats":
98 | {
99 | "apples": 11
100 | }
101 | },
102 | {
103 | "name": "Настя",
104 | "sex": 0,
105 | "eats":
106 | {
107 | "apples": 5,
108 | "bananas": 2
109 | }
110 | },
111 | {
112 | "name": "Тарас",
113 | "sex": 1,
114 | "eats":
115 | {
116 | "borsch": 1
117 | }
118 | }
119 | ]
120 | }
121 | </dispatch>
122 | </exec>
123 | </div>
124 | <template id="zTemplates">
125 | <template id="listTpl">
126 | <ul>
127 | <!-- Перебираем элементы массива "kids"-->
128 | <foreach from="kids" item="kid">
129 | <li>
130 | <!-- Выводим имя -->
131 | <value>kid.name</value>
132 | <!--
133 | Тут мы хитрим. Мы будем использовать формы множеств
134 | английского языка для определения подходящего глагола
135 | для разных полов.
136 | Первый параметр ("eats") будет ключом в таблице форм
137 | множеств, второй - количеством, третий указывает на
138 | правило, которое будет использовано для нахождения
139 | нужной формы множеств.
140 | -->
141 | <value>"eats"^kid.sex^1</value>
142 | <!-- Перебираем массив "eats" -->
143 | <foreach from="kid.eats" item="amount" key="food">
144 | <!--
145 | Запоминаем контент в переменную "txt".
146 | Эта переменная локальна исключительно для тега <li>
147 | -->
148 | <capture to="txt">
149 | <!--
150 | Выводим количество и правильную форму множеств.
151 | Ключи форм множеств берутся из названия ключа объекта
152 | с данными
153 | -->
154 | <span class="hl"><value>amount</value></span> <value>food^amount^7</value>
155 | </capture>
156 | </foreach>
157 | <!-- Вставляем контент, который мы запоминали раннее -->
158 | <flush>txt.join(", ")</flush>
159 | </li>
160 | </foreach>
161 | </ul>
162 | </template>
163 | <!--
164 | Описываем ключи и значения для обычного контента
165 | -->
166 | <plurals rule="7">
167 | {
168 | "apples": [ "яблоко", "яблока", "яблок" ],
169 | "bananas": [ "банан", "банана", "бананов" ],
170 | "borsch": [ "тарелку борща", "тарелки борща", "тарелок борща" ]
171 | }
172 | </plurals>
173 | <!--
174 | и для хитрого варианта с определением пола
175 | -->
176 | <plurals rule="1">
177 | {
178 | "eats": [ "съел", "съела" ]
179 | }
180 | </plurals>
181 | </template>
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/examples/3/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Локализация распространения событий
17 |
18 |
40 |
61 | <p>
94 | <!--
95 | Устанавливаем 2 z-обработчика
96 | По событию "makeTextRed" установим элементу класс "red"
97 | а по "clear" - удалим его
98 | -->
99 | <e on="makeTextRed" do="addClass">red</e>
100 | <e on="clear" do="removeClass">red</e>
101 | Параграф
102 | <b>
103 | <!-- Z-обработчики для всех тегов будут одинаковыми -->
104 | <e on="makeTextRed" do="addClass">red</e>
105 | <e on="clear" do="removeClass">red</e>
106 | 1
107 | </b>
108 | </p>
109 | <p>
110 | <e on="makeTextRed" do="addClass">red</e>
111 | <e on="clear" do="removeClass">red</e>
112 | Параграф
113 | <b>
114 | <e on="makeTextRed" do="addClass">red</e>
115 | <e on="clear" do="removeClass">red</e>
116 | 2
117 | </b>
118 | </p>
119 | <ul>
120 | <li>
121 | <e on="makeTextRed" do="addClass">red</e>
122 | <e on="clear" do="removeClass">red</e>
123 | Элемент списка
124 | <b>
125 | <e on="makeTextRed" do="addClass">red</e>
126 | <e on="clear" do="removeClass">red</e>
127 | 1
128 | </b>
129 | </li>
130 | <li>
131 | <e on="makeTextRed" do="addClass">red</e>
132 | <e on="clear" do="removeClass">red</e>
133 | Элемент списка
134 | <b>
135 | <e on="makeTextRed" do="addClass">red</e>
136 | <e on="clear" do="removeClass">red</e>
137 | 2
138 | </b>
139 | </li>
140 | </ul>
141 | <p>
142 | Раскрасить
143 | <a href="#">
144 | <handler on="click">
145 | <!--
146 | Запускаем событие "makeTextRed"
147 | начиная от <body>
148 | и распространяем его только на <b>
149 | -->
150 | <dispatch e="makeTextRed" f="body" p="b"></dispatch>
151 | </handler>
152 | <b>
153 | </a>
154 | или
155 | <a href="#">
156 | <handler on="click">
157 | <!-- Распространяем событие только на <li> -->
158 | <dispatch e="makeTextRed" f="body" p="li"></dispatch>
159 | </handler>
160 | <li>
161 | </a>
162 | или
163 | <a href="#">
164 | <handler on="click">
165 | <!-- И только на <p> -->
166 | <dispatch e="makeTextRed" f="body" p="p"></dispatch>
167 | </handler>
168 | <p>
169 | </a>
170 | или
171 | <a href="#">
172 | <handler on="click">
173 | <!--
174 | Запускаем событие очистки "clear"
175 | для всех элементов сразу
176 | -->
177 | <dispatch e="clear" f="body"></dispatch>
178 | </handler>
179 | отменить раскраску
180 | </a>
181 | </p>
182 |
183 |
184 |
185 |
--------------------------------------------------------------------------------
/examples/todomvc/node_modules/todomvc-common/base.js:
--------------------------------------------------------------------------------
1 | /* global _ */
2 | (function () {
3 | 'use strict';
4 |
5 | /* jshint ignore:start */
6 | // Underscore's Template Module
7 | // Courtesy of underscorejs.org
8 | var _ = (function (_) {
9 | _.defaults = function (object) {
10 | if (!object) {
11 | return object;
12 | }
13 | for (var argsIndex = 1, argsLength = arguments.length; argsIndex < argsLength; argsIndex++) {
14 | var iterable = arguments[argsIndex];
15 | if (iterable) {
16 | for (var key in iterable) {
17 | if (object[key] == null) {
18 | object[key] = iterable[key];
19 | }
20 | }
21 | }
22 | }
23 | return object;
24 | }
25 |
26 | // By default, Underscore uses ERB-style template delimiters, change the
27 | // following template settings to use alternative delimiters.
28 | _.templateSettings = {
29 | evaluate : /<%([\s\S]+?)%>/g,
30 | interpolate : /<%=([\s\S]+?)%>/g,
31 | escape : /<%-([\s\S]+?)%>/g
32 | };
33 |
34 | // When customizing `templateSettings`, if you don't want to define an
35 | // interpolation, evaluation or escaping regex, we need one that is
36 | // guaranteed not to match.
37 | var noMatch = /(.)^/;
38 |
39 | // Certain characters need to be escaped so that they can be put into a
40 | // string literal.
41 | var escapes = {
42 | "'": "'",
43 | '\\': '\\',
44 | '\r': 'r',
45 | '\n': 'n',
46 | '\t': 't',
47 | '\u2028': 'u2028',
48 | '\u2029': 'u2029'
49 | };
50 |
51 | var escaper = /\\|'|\r|\n|\t|\u2028|\u2029/g;
52 |
53 | // JavaScript micro-templating, similar to John Resig's implementation.
54 | // Underscore templating handles arbitrary delimiters, preserves whitespace,
55 | // and correctly escapes quotes within interpolated code.
56 | _.template = function(text, data, settings) {
57 | var render;
58 | settings = _.defaults({}, settings, _.templateSettings);
59 |
60 | // Combine delimiters into one regular expression via alternation.
61 | var matcher = new RegExp([
62 | (settings.escape || noMatch).source,
63 | (settings.interpolate || noMatch).source,
64 | (settings.evaluate || noMatch).source
65 | ].join('|') + '|$', 'g');
66 |
67 | // Compile the template source, escaping string literals appropriately.
68 | var index = 0;
69 | var source = "__p+='";
70 | text.replace(matcher, function(match, escape, interpolate, evaluate, offset) {
71 | source += text.slice(index, offset)
72 | .replace(escaper, function(match) { return '\\' + escapes[match]; });
73 |
74 | if (escape) {
75 | source += "'+\n((__t=(" + escape + "))==null?'':_.escape(__t))+\n'";
76 | }
77 | if (interpolate) {
78 | source += "'+\n((__t=(" + interpolate + "))==null?'':__t)+\n'";
79 | }
80 | if (evaluate) {
81 | source += "';\n" + evaluate + "\n__p+='";
82 | }
83 | index = offset + match.length;
84 | return match;
85 | });
86 | source += "';\n";
87 |
88 | // If a variable is not specified, place data values in local scope.
89 | if (!settings.variable) source = 'with(obj||{}){\n' + source + '}\n';
90 |
91 | source = "var __t,__p='',__j=Array.prototype.join," +
92 | "print=function(){__p+=__j.call(arguments,'');};\n" +
93 | source + "return __p;\n";
94 |
95 | try {
96 | render = new Function(settings.variable || 'obj', '_', source);
97 | } catch (e) {
98 | e.source = source;
99 | throw e;
100 | }
101 |
102 | if (data) return render(data, _);
103 | var template = function(data) {
104 | return render.call(this, data, _);
105 | };
106 |
107 | // Provide the compiled function source as a convenience for precompilation.
108 | template.source = 'function(' + (settings.variable || 'obj') + '){\n' + source + '}';
109 |
110 | return template;
111 | };
112 |
113 | return _;
114 | })({});
115 |
116 | if (location.hostname === 'todomvc.com') {
117 | (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
118 | (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
119 | m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
120 | })(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
121 | ga('create', 'UA-31081062-1', 'auto');
122 | ga('send', 'pageview');
123 | }
124 | /* jshint ignore:end */
125 |
126 | function redirect() {
127 | if (location.hostname === 'tastejs.github.io') {
128 | location.href = location.href.replace('tastejs.github.io/todomvc', 'todomvc.com');
129 | }
130 | }
131 |
132 | function findRoot() {
133 | var base = location.href.indexOf('examples/');
134 | return location.href.substr(0, base);
135 | }
136 |
137 | function getFile(file, callback) {
138 | if (!location.host) {
139 | return console.info('Miss the info bar? Run TodoMVC from a server to avoid a cross-origin error.');
140 | }
141 |
142 | var xhr = new XMLHttpRequest();
143 |
144 | xhr.open('GET', findRoot() + file, true);
145 | xhr.send();
146 |
147 | xhr.onload = function () {
148 | if (xhr.status === 200 && callback) {
149 | callback(xhr.responseText);
150 | }
151 | };
152 | }
153 |
154 | function Learn(learnJSON, config) {
155 | if (!(this instanceof Learn)) {
156 | return new Learn(learnJSON, config);
157 | }
158 |
159 | var template, framework;
160 |
161 | if (typeof learnJSON !== 'object') {
162 | try {
163 | learnJSON = JSON.parse(learnJSON);
164 | } catch (e) {
165 | return;
166 | }
167 | }
168 |
169 | if (config) {
170 | template = config.template;
171 | framework = config.framework;
172 | }
173 |
174 | if (!template && learnJSON.templates) {
175 | template = learnJSON.templates.todomvc;
176 | }
177 |
178 | if (!framework && document.querySelector('[data-framework]')) {
179 | framework = document.querySelector('[data-framework]').dataset.framework;
180 | }
181 |
182 | this.template = template;
183 |
184 | if (learnJSON.backend) {
185 | this.frameworkJSON = learnJSON.backend;
186 | this.frameworkJSON.issueLabel = framework;
187 | this.append({
188 | backend: true
189 | });
190 | } else if (learnJSON[framework]) {
191 | this.frameworkJSON = learnJSON[framework];
192 | this.frameworkJSON.issueLabel = framework;
193 | this.append();
194 | }
195 |
196 | this.fetchIssueCount();
197 | }
198 |
199 | Learn.prototype.append = function (opts) {
200 | var aside = document.createElement('aside');
201 | aside.innerHTML = _.template(this.template, this.frameworkJSON);
202 | aside.className = 'learn';
203 |
204 | if (opts && opts.backend) {
205 | // Remove demo link
206 | var sourceLinks = aside.querySelector('.source-links');
207 | var heading = sourceLinks.firstElementChild;
208 | var sourceLink = sourceLinks.lastElementChild;
209 | // Correct link path
210 | var href = sourceLink.getAttribute('href');
211 | sourceLink.setAttribute('href', href.substr(href.lastIndexOf('http')));
212 | sourceLinks.innerHTML = heading.outerHTML + sourceLink.outerHTML;
213 | } else {
214 | // Localize demo links
215 | var demoLinks = aside.querySelectorAll('.demo-link');
216 | Array.prototype.forEach.call(demoLinks, function (demoLink) {
217 | if (demoLink.getAttribute('href').substr(0, 4) !== 'http') {
218 | demoLink.setAttribute('href', findRoot() + demoLink.getAttribute('href'));
219 | }
220 | });
221 | }
222 |
223 | document.body.className = (document.body.className + ' learn-bar').trim();
224 | document.body.insertAdjacentHTML('afterBegin', aside.outerHTML);
225 | };
226 |
227 | Learn.prototype.fetchIssueCount = function () {
228 | var issueLink = document.getElementById('issue-count-link');
229 | if (issueLink) {
230 | var url = issueLink.href.replace('https://github.com', 'https://api.github.com/repos');
231 | var xhr = new XMLHttpRequest();
232 | xhr.open('GET', url, true);
233 | xhr.onload = function (e) {
234 | var parsedResponse = JSON.parse(e.target.responseText);
235 | if (parsedResponse instanceof Array) {
236 | var count = parsedResponse.length;
237 | if (count !== 0) {
238 | issueLink.innerHTML = 'This app has ' + count + ' open issues';
239 | document.getElementById('issue-count').style.display = 'inline';
240 | }
241 | }
242 | };
243 | xhr.send();
244 | }
245 | };
246 |
247 | redirect();
248 | getFile('learn.json', Learn);
249 | })();
250 |
--------------------------------------------------------------------------------
/examples/todomvc/node_modules/todomvc-app-css/index.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
7 | button {
8 | margin: 0;
9 | padding: 0;
10 | border: 0;
11 | background: none;
12 | font-size: 100%;
13 | vertical-align: baseline;
14 | font-family: inherit;
15 | font-weight: inherit;
16 | color: inherit;
17 | -webkit-appearance: none;
18 | appearance: none;
19 | -webkit-font-smoothing: antialiased;
20 | -moz-font-smoothing: antialiased;
21 | font-smoothing: antialiased;
22 | }
23 |
24 | body {
25 | font: 14px 'Helvetica Neue', Helvetica, Arial, sans-serif;
26 | line-height: 1.4em;
27 | background: #f5f5f5;
28 | color: #4d4d4d;
29 | min-width: 230px;
30 | max-width: 550px;
31 | margin: 0 auto;
32 | -webkit-font-smoothing: antialiased;
33 | -moz-font-smoothing: antialiased;
34 | font-smoothing: antialiased;
35 | font-weight: 300;
36 | }
37 |
38 | button,
39 | input[type="checkbox"] {
40 | outline: none;
41 | }
42 |
43 | .hidden {
44 | display: none;
45 | }
46 |
47 | .todoapp {
48 | background: #fff;
49 | margin: 130px 0 40px 0;
50 | position: relative;
51 | box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.2),
52 | 0 25px 50px 0 rgba(0, 0, 0, 0.1);
53 | }
54 |
55 | .todoapp input::-webkit-input-placeholder {
56 | font-style: italic;
57 | font-weight: 300;
58 | color: #e6e6e6;
59 | }
60 |
61 | .todoapp input::-moz-placeholder {
62 | font-style: italic;
63 | font-weight: 300;
64 | color: #e6e6e6;
65 | }
66 |
67 | .todoapp input::input-placeholder {
68 | font-style: italic;
69 | font-weight: 300;
70 | color: #e6e6e6;
71 | }
72 |
73 | .todoapp h1 {
74 | position: absolute;
75 | top: -155px;
76 | width: 100%;
77 | font-size: 100px;
78 | font-weight: 100;
79 | text-align: center;
80 | color: rgba(175, 47, 47, 0.15);
81 | -webkit-text-rendering: optimizeLegibility;
82 | -moz-text-rendering: optimizeLegibility;
83 | text-rendering: optimizeLegibility;
84 | }
85 |
86 | .new-todo,
87 | .edit {
88 | position: relative;
89 | margin: 0;
90 | width: 100%;
91 | font-size: 24px;
92 | font-family: inherit;
93 | font-weight: inherit;
94 | line-height: 1.4em;
95 | border: 0;
96 | outline: none;
97 | color: inherit;
98 | padding: 6px;
99 | border: 1px solid #999;
100 | box-shadow: inset 0 -1px 5px 0 rgba(0, 0, 0, 0.2);
101 | box-sizing: border-box;
102 | -webkit-font-smoothing: antialiased;
103 | -moz-font-smoothing: antialiased;
104 | font-smoothing: antialiased;
105 | }
106 |
107 | .new-todo {
108 | padding: 16px 16px 16px 60px;
109 | border: none;
110 | background: rgba(0, 0, 0, 0.003);
111 | box-shadow: inset 0 -2px 1px rgba(0,0,0,0.03);
112 | }
113 |
114 | .main {
115 | position: relative;
116 | z-index: 2;
117 | border-top: 1px solid #e6e6e6;
118 | }
119 |
120 | label[for='toggle-all'] {
121 | display: none;
122 | }
123 |
124 | .toggle-all {
125 | position: absolute;
126 | top: -55px;
127 | left: -12px;
128 | width: 60px;
129 | height: 34px;
130 | text-align: center;
131 | border: none; /* Mobile Safari */
132 | }
133 |
134 | .toggle-all:before {
135 | content: '❯';
136 | font-size: 22px;
137 | color: #e6e6e6;
138 | padding: 10px 27px 10px 27px;
139 | }
140 |
141 | .toggle-all:checked:before {
142 | color: #737373;
143 | }
144 |
145 | .todo-list {
146 | margin: 0;
147 | padding: 0;
148 | list-style: none;
149 | }
150 |
151 | .todo-list li {
152 | position: relative;
153 | font-size: 24px;
154 | border-bottom: 1px solid #ededed;
155 | }
156 |
157 | .todo-list li:last-child {
158 | border-bottom: none;
159 | }
160 |
161 | .todo-list li.editing {
162 | border-bottom: none;
163 | padding: 0;
164 | }
165 |
166 | .todo-list li.editing .edit {
167 | display: block;
168 | width: 506px;
169 | padding: 13px 17px 12px 17px;
170 | margin: 0 0 0 43px;
171 | }
172 |
173 | .todo-list li.editing .view {
174 | display: none;
175 | }
176 |
177 | .todo-list li .toggle {
178 | text-align: center;
179 | width: 40px;
180 | /* auto, since non-WebKit browsers doesn't support input styling */
181 | height: auto;
182 | position: absolute;
183 | top: 0;
184 | bottom: 0;
185 | margin: auto 0;
186 | border: none; /* Mobile Safari */
187 | -webkit-appearance: none;
188 | appearance: none;
189 | }
190 |
191 | .todo-list li .toggle:after {
192 | content: url('data:image/svg+xml;utf8,');
193 | }
194 |
195 | .todo-list li .toggle:checked:after {
196 | content: url('data:image/svg+xml;utf8,');
197 | }
198 |
199 | .todo-list li label {
200 | white-space: pre-line;
201 | word-break: break-all;
202 | padding: 15px 60px 15px 15px;
203 | margin-left: 45px;
204 | display: block;
205 | line-height: 1.2;
206 | transition: color 0.4s;
207 | }
208 |
209 | .todo-list li.completed label {
210 | color: #d9d9d9;
211 | text-decoration: line-through;
212 | }
213 |
214 | .todo-list li .destroy {
215 | display: none;
216 | position: absolute;
217 | top: 0;
218 | right: 10px;
219 | bottom: 0;
220 | width: 40px;
221 | height: 40px;
222 | margin: auto 0;
223 | font-size: 30px;
224 | color: #cc9a9a;
225 | margin-bottom: 11px;
226 | transition: color 0.2s ease-out;
227 | }
228 |
229 | .todo-list li .destroy:hover {
230 | color: #af5b5e;
231 | }
232 |
233 | .todo-list li .destroy:after {
234 | content: '×';
235 | }
236 |
237 | .todo-list li:hover .destroy {
238 | display: block;
239 | }
240 |
241 | .todo-list li .edit {
242 | display: none;
243 | }
244 |
245 | .todo-list li.editing:last-child {
246 | margin-bottom: -1px;
247 | }
248 |
249 | .footer {
250 | color: #777;
251 | padding: 10px 15px;
252 | height: 20px;
253 | text-align: center;
254 | border-top: 1px solid #e6e6e6;
255 | }
256 |
257 | .footer:before {
258 | content: '';
259 | position: absolute;
260 | right: 0;
261 | bottom: 0;
262 | left: 0;
263 | height: 50px;
264 | overflow: hidden;
265 | box-shadow: 0 1px 1px rgba(0, 0, 0, 0.2),
266 | 0 8px 0 -3px #f6f6f6,
267 | 0 9px 1px -3px rgba(0, 0, 0, 0.2),
268 | 0 16px 0 -6px #f6f6f6,
269 | 0 17px 2px -6px rgba(0, 0, 0, 0.2);
270 | }
271 |
272 | .todo-count {
273 | float: left;
274 | text-align: left;
275 | }
276 |
277 | .todo-count strong {
278 | font-weight: 300;
279 | }
280 |
281 | .filters {
282 | margin: 0;
283 | padding: 0;
284 | list-style: none;
285 | position: absolute;
286 | right: 0;
287 | left: 0;
288 | }
289 |
290 | .filters li {
291 | display: inline;
292 | }
293 |
294 | .filters li a {
295 | color: inherit;
296 | margin: 3px;
297 | padding: 3px 7px;
298 | text-decoration: none;
299 | border: 1px solid transparent;
300 | border-radius: 3px;
301 | }
302 |
303 | .filters li a.selected,
304 | .filters li a:hover {
305 | border-color: rgba(175, 47, 47, 0.1);
306 | }
307 |
308 | .filters li a.selected {
309 | border-color: rgba(175, 47, 47, 0.2);
310 | }
311 |
312 | .clear-completed,
313 | html .clear-completed:active {
314 | float: right;
315 | position: relative;
316 | line-height: 20px;
317 | text-decoration: none;
318 | cursor: pointer;
319 | position: relative;
320 | }
321 |
322 | .clear-completed:hover {
323 | text-decoration: underline;
324 | }
325 |
326 | .info {
327 | margin: 65px auto 0;
328 | color: #bfbfbf;
329 | font-size: 10px;
330 | text-shadow: 0 1px 0 rgba(255, 255, 255, 0.5);
331 | text-align: center;
332 | }
333 |
334 | .info p {
335 | line-height: 1;
336 | }
337 |
338 | .info a {
339 | color: inherit;
340 | text-decoration: none;
341 | font-weight: 400;
342 | }
343 |
344 | .info a:hover {
345 | text-decoration: underline;
346 | }
347 |
348 | /*
349 | Hack to remove background from Mobile Safari.
350 | Can't use it globally since it destroys checkboxes in Firefox
351 | */
352 | @media screen and (-webkit-min-device-pixel-ratio:0) {
353 | .toggle-all,
354 | .todo-list li .toggle {
355 | background: none;
356 | }
357 |
358 | .todo-list li .toggle {
359 | height: 40px;
360 | }
361 |
362 | .toggle-all {
363 | -webkit-transform: rotate(90deg);
364 | transform: rotate(90deg);
365 | -webkit-appearance: none;
366 | appearance: none;
367 | }
368 | }
369 |
370 | @media (max-width: 430px) {
371 | .footer {
372 | height: 50px;
373 | }
374 |
375 | .filters {
376 | bottom: 10px;
377 | }
378 | }
379 |
--------------------------------------------------------------------------------
/examples/todomvc/js/z_handlers.js:
--------------------------------------------------------------------------------
1 | /* Code is available under the Piblic Domain (Unlicense) */
2 |
3 | z.addHandler( "debug", function ( e, data ) {
4 |
5 | console.log(this, e, data);
6 |
7 | });
8 |
9 | z.addHandler( "addClass", function ( e, data ) {
10 | if ( data[0] ) this.classList.add( data[0] );
11 | });
12 | z.addHandler( "removeClass", function ( e, data ) {
13 | if ( data[0] ) this.classList.remove( data[0] );
14 | });
15 | z.addHandler( "swapClass", function ( e, data ) {
16 | if ( data[0] ) this.classList.toggle( data[0] );
17 | });
18 |
19 | z.addHandler( "clearValue", function ( e, data ) {
20 | this.value = "";
21 | });
22 |
23 | z.addHandler( "smartClassProcess", function ( e, data ) {
24 | var
25 | eData = e.data,
26 | reverse = !(data[0] == "add" || data[0] == "addOnly"),
27 | oneWay = (data[0].indexOf("Only") !== -1),
28 | className = data[1],
29 | expressions = data.slice(2),
30 | res = false,
31 | thisNode = this
32 | ;
33 | for ( var i=expressions.length; i-->0; ) {
34 | var
35 | exprArr = expressions[i].split("="),
36 | existCheck = false
37 | ;
38 | expr = exprArr.map( function (e) {
39 | if ( e.indexOf("$") == 0 ) return eData[e.slice(1)];
40 | if ( e.indexOf("@") == 0 ) return thisNode.getAttribute(e.slice(1));
41 | if ( e.indexOf("?") == 0 ) {
42 | existCheck = true;
43 | try { return !!(eData[e.slice(1)].length) } catch (e) { return false };
44 | }
45 | return e
46 | })
47 |
48 | if ( existCheck ) {
49 | if (expr[0]) res = true;
50 | }
51 | else
52 | {
53 | if ( expr[0] == expr[1] ) res = true;
54 | if ( exprArr[1] === undefined && expr[0] ) res = true;
55 | }
56 | };
57 |
58 | var
59 | aRes = (reverse)? !res : res,
60 | action = (aRes)? "add" : "remove"
61 | ;
62 |
63 | if (data[0] == "toggle" && res) {
64 | var hasClass = this.classList.contains(className);
65 | if (aRes && hasClass) action = "remove";
66 | if (!aRes && !hasClass) action = "add";
67 | }
68 |
69 | if (oneWay && !res) return;
70 |
71 | this.classList[action]( className );
72 | });
73 |
74 | z.addHandler( "setAttr", function ( e, data ) {
75 |
76 | var
77 | eData = e.data,
78 | attrName = data[0],
79 | defaultValue = data[1] || 1,
80 | propertyName = data[2] || attrName,
81 | attrValue = (eData[propertyName] !== undefined)? eData[propertyName] : defaultValue
82 | ;
83 |
84 | if ( !attrName ) return;
85 |
86 | this.setAttribute( attrName, attrValue );
87 |
88 | });
89 |
90 | z.addHandler( "checkIf", function ( e, data ) {
91 |
92 | var
93 | eData = e.data,
94 | expressions = data,
95 | res = false,
96 | thisNode = this
97 | ;
98 |
99 | for ( var i=expressions.length; i-->0; ) {
100 | var exprArr = expressions[i].split("=");
101 | expr = exprArr.map( function (e) {
102 | if ( e.indexOf("$") == 0 ) return eData[e.slice(1)];
103 | if ( e.indexOf("@") == 0 ) return thisNode.getAttribute(e.slice(1));
104 | return e
105 | })
106 |
107 | if ( expr[0] == expr[1] ) res = true;
108 | }
109 |
110 | this.checked = res;
111 |
112 | });
113 |
114 | z.addHandler( "collectData", function ( e, data ) {
115 |
116 | var
117 | name = this.name || this.id || data[0],
118 | mode = data[1] || "replace",
119 | nodeName = this.nodeName,
120 | value = "",
121 | eData = e.data,
122 | keyExists = false
123 | ;
124 |
125 | if ( name === undefined ) return;
126 |
127 | if ( eData.hasOwnProperty(name) ) keyExists = true;
128 | if ( keyExists && mode == "once" ) return;
129 |
130 | switch ( nodeName ) {
131 | case "SELECT":
132 | if ( this.multiple ) {
133 | value = [];
134 | for ( var i=this.options.length; i--; ) {
135 | var option = this.options[i];
136 | if ( option.selected ) value.unshift( option.value );
137 | }
138 | }
139 | else
140 | {
141 | value = this.value;
142 | }
143 |
144 | break;
145 | case "INPUT":
146 | if ( this.type === "checkbox" ) {
147 | if ( mode == "simple" ) {
148 | value = (this.checked);
149 | }
150 | else
151 | {
152 | value = ( eData[name] instanceof Array )? eData[name] : [];
153 | value.unshift( (this.checked)? this.value : "" );
154 | }
155 | }
156 | else
157 | {
158 | if ( this.type === "radio" && !this.checked ) return;
159 | value = this.value;
160 | }
161 | break;
162 | case "TEXTAREA":
163 | {
164 | value = this.value;
165 | break;
166 | }
167 |
168 | default:
169 | value = this.textContent.trim();
170 | }
171 |
172 | eData[name] = value;
173 |
174 | });
175 |
176 | z.addHandler( "removeChildAndDispatch", function ( e, data ) {
177 |
178 | var
179 | parentNode = this.parentNode,
180 | eData = e.data,
181 | execArr = eData.dispatch || [],
182 | that = this,
183 | execArr = execArr.map(function(d){
184 | d.f = ( d.f )? z.getParentNode( that, d.f ) : parentNode;
185 | d.data = eData;
186 | return d;
187 | })
188 | ;
189 |
190 | parentNode.removeChild(this);
191 |
192 | for ( var i=0, l=execArr.length; itodos
48 |
88 |
97 | Темплейтирование
50 |
51 |
104 |
108 | <div class="content">
117 | <!--
118 | Устанавливаем контейнеру обработчик события "init".
119 | Он будет темплейтировать данные, которые придут
120 | вместе с событием
121 | В качестве шаблона будет взят template#tabContentTpl
122 | -->
123 | <e on="init" do="template">tabContentTpl</e>
124 | <!-- Делаем вызов инструкций -->
125 | <exec>
126 | <!--
127 | Запускаем событие "init", которому устанавливаем
128 | JSON-объект в качестве данных
129 | -->
130 | <dispatch e="init">
131 | {
132 | "tabs":
133 | [
134 | {
135 | "id": "fruit",
136 | "name": "Фрукты",
137 | "values": [ "Яблоки", "Сливы", "Апельсины" ]
138 | },
139 | {
140 | "id": "vegetables",
141 | "name": "Овощи",
142 | "values": [ "Капуста", "Горох", "Морковь", "Тыква" ]
143 | },
144 | {
145 | "id": "something",
146 | "name": "Нечто"
147 | }
148 | ]
149 | }
150 | </dispatch>
151 | </exec>
152 | </div>
153 | <!-- Все темплейты должны находиться в данном контейнере -->
154 | <template id="zTemplates">
155 | <!-- Темплейт для отображения табов -->
156 | <template id="tabContentTpl">
157 | <div class="tabContainer">
158 | <!--
159 | Этот диспатчер будет запускать событие "tabActivate",
160 | которое будет распростаняться от контейнера div.tabContainer
161 | только на прямых потомков
162 | -->
163 | <dispatch id="tabActivator" e="tabActivate" p="childNodes"></dispatch>
164 | <!-- Итерируем пришедшие с событием "init" данные.-->
165 | <foreach from="tabs" item="tab">
166 | <a href="#" class="tab">
167 | <!--
168 | Устанавливаем тегу <a> обработчик события "tabActivate"
169 | по которому будем устанавливать класс "active"
170 | если в пришедших с событием данных
171 | будет присутствовать ключ, название которого
172 | будет совпадать со значением атрибута "data-id"
173 | -->
174 | <e on="tabActivate" do="addClassIfAttrMatch">active,data-id</e>
175 | <!--
176 | Устанавливаем тегу <a> атрибут "data-id"
177 | который равен "tab.id"
178 | -->
179 | <attr name="data-id"><value>tab.id</value></attr>
180 | <!--
181 | Устанавливаем тегу <a> обработчик
182 | DOM-события "click"
183 | -->
184 | <handler on="click">
185 | <!--
186 | По которому будем запускать диспатчер с id
187 | равным "tabActivator" (описан выше),
188 | а в качестве параметров передадим JSON-объект
189 | -->
190 | <dispatch use="tabActivator">{ "<value>tab.id</value>": 1 }</dispatch>
191 | </handler>
192 | <!-- Выводим название таба -->
193 | <value>tab.name</value>
194 | </a>
195 | <div class="tabContent">
196 | <!--
197 | Подключаем темплейт template#listTpl,
198 | в который передадим данные таба
199 | -->
200 | <include tpl="listTpl"><value>JSON.stringify(tab)</value></include>
201 | </div>
202 | </foreach>
203 | <exec>
204 | <!--
205 | Активируем таб путем запуска события "tabActivator",
206 | которому передадим в качестве параметра id первого таба
207 | -->
208 | <dispatch use="tabActivator">{ "<value>tabs[0].id</value>": 1 }</dispatch>
209 | </exec>
210 | </div>
211 | </template>
212 | <template id="listTpl">
213 | <!-- Если массив "values" не пустой -->
214 | <if expr="values.length">
215 | <!-- выводим его значения -->
216 | <then>
217 | <ul>
218 | <foreach from="values" item="item">
219 | <li><value>item</value></li>
220 | </foreach>
221 | </ul>
222 | </then>
223 | <!-- иначе выводим сообщение -->
224 | <else>
225 | <p>Извините, тут пусто.</p>
226 | </else>
227 | </if>
228 | </template>
229 | </template>
230 |
231 |
232 |
233 |
--------------------------------------------------------------------------------
/examples/6/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Интерактивный пример
16 |
17 |
268 |
269 |
270 |
--------------------------------------------------------------------------------
/src/core/z.js:
--------------------------------------------------------------------------------
1 | /*
2 | Z (zet) framework, version 0.8.5
3 | Code is available under the Piblic Domain (Unlicense)
4 | */
5 |
6 | var z = (function(){
7 |
8 | var
9 | handlers = {},
10 | templates = document,
11 | globals = null,
12 | plurals = [],
13 | pluralFuncs = [
14 | /* 0: Chinese */ [1, function(n) { return 0 }],
15 | /* 1: English */ [2, function(n) { return (n!=1)?1:0 }],
16 | /* 2: French */ [2, function(n) { return (n>1)?1:0 }],
17 | /* 3: Latvian */ [3, function(n) { return (n%10==1&&n%100!=11)?1:(n!=0)?2:0 }],
18 | /* 4: Scottish Gaelic */ [4, function(n) { return (n==1||n==11)?0:(n==2||n==12)?1:(n>0&&n<20)?2:3 }],
19 | /* 5: Romanian */ [3, function(n) { return (n==1)?0:(n==0||n%100>0&&n%100<20)?1:2 }],
20 | /* 6: Lithuanian */ [3, function(n) { return (n%10==1&&n%100!=11)?0:(n%10>=2&&(n%100<10||n%100>=20))?2:1 }],
21 | /* 7: Ukrainian */ [3, function(n) { return (n%10==1&&n%100!=11)?0:(n%10>=2&&n%10<=4&&(n%100<10||n%100>=20))?1:2 }],
22 | /* 8: Slovak */ [3, function(n) { return (n==1)?0:(n>=2&&n<=4)?1:2 }],
23 | /* 9: Polish */ [3, function(n) { return (n==1)?0:(n%10>=2&&n%10<=4&&(n%100<10||n%100>=20))?1:2 }],
24 | /* 10: Slovenian */ [4, function(n) { return (n%100==1)?0:(n%100==2)?1:(n%100==3||n%100==4)?2:3 }],
25 | /* 11: Irish Gaeilge */ [5, function(n) { return (n==1)?0:(n==2)?1:(n>=3&&n<=6)?2:(n>=7&&n<=10)?3:4 }],
26 | /* 12: Arabic */ [6, function(n) { return (n==0)?5:(n==1)?0:(n==2)?1:(n%100>=3&&n%100<=10)?2:(n%100>=11&&n%100<=99)?3:4 }],
27 | /* 13: Maltese */ [4, function(n) { return (n==1)?0:(n==0||n%100>0&&n%100<=10)?1:(n%100>10&&n%100<20)?2:3 }],
28 | /* 14: Macedonian */ [3, function(n) { return (n%10==1)?0:(n%10==2)?1:2 }],
29 | /* 15: Icelandic */ [2, function(n) { return (n%10==1&&n%100!=11)?0:1 }],
30 | /* 16: Breton */ [5, function(n) { return (n%10==1&&n%100!=11&&n%100!=71&&n%100!=91)?0:(n%10==2&&n%100!=12&&n%100!=72&&n%100!=92)?1:((n%10==3||n%10==4||n%10==9)&&n%100!=13&&n%100!=14&&n%100!=19&&n%100!=73&&n%100!=74&&n%100!=79&&n%100!=93&&n%100!=94&&n%100!=99)?2:(n%1000000==0&&n!=0)?3:4 }]
31 | ]
32 | ;
33 |
34 | var init = function ( ) {
35 | try {
36 | addZStyles();
37 | detachTemplateContainer();
38 | addGlobalContainer();
39 | processAllNodes(document);
40 | } catch(e){}
41 | };
42 |
43 | var addZStyles = function( ) {
44 | var
45 | zElements = [ "template", "e", "dispatch", "exec", "hidden", "handler", "#zTemplates", "#zGlobal" ],
46 | styleNode = document.createElement('style'),
47 | styleSheet
48 | ;
49 | styleNode.appendChild(document.createTextNode(''));// Safari magic
50 |
51 | document.head.appendChild(styleNode);
52 |
53 | styleSheet = styleNode.sheet;
54 |
55 | styleSheet.insertRule( zElements.join(", ") + "{ display: none !important; }", 0 );
56 |
57 | };
58 |
59 | var detachTemplateContainer = function () {
60 |
61 | var tplNode = $("zTemplates");
62 | if ( tplNode ) {
63 | var
64 | tplNode = tplNode.parentNode.removeChild(tplNode),
65 | iFrameNode = document.createElement("iframe"),
66 | bodyNode = document.body
67 | ;
68 |
69 | iFrameNode.width = iFrameNode.height = 0;
70 | iFrameNode.id = "zTemplates";
71 | bodyNode.insertBefore(iFrameNode, bodyNode.firstChild);
72 |
73 | var iFrameDoc = iFrameNode.contentDocument;
74 |
75 | iFrameDoc.open();
76 | iFrameDoc.write("\n" + tplNode.innerHTML + "");
77 | iFrameDoc.close();
78 |
79 | templates = iFrameNode.contentDocument;
80 |
81 | }
82 |
83 | };
84 |
85 | var addGlobalContainer = function () {
86 |
87 | var
88 | bodyNode = document.body
89 | ;
90 |
91 | globals = document.createElement("global");
92 | globals.id = "zGlobal";
93 |
94 | bodyNode.insertBefore(globals, bodyNode.firstChild);
95 |
96 | };
97 |
98 | var processAllNodes = function ( container ) {
99 | processENodes(container);
100 | processHandlerNodes(container);
101 | processWrapperNodes(container);
102 | processPluralNodes();
103 | processExecNodes(container);
104 | };
105 |
106 | var processENodes = function ( container ) {
107 |
108 | var eList = container.getElementsByTagName( "e" );
109 |
110 | for ( var i=0, l=eList.length; i