|
8 | 8 | * Requires jQuery 1.4+
|
9 | 9 | */
|
10 | 10 |
|
11 |
| -(function ($) { |
| 11 | +(function($) { |
12 | 12 |
|
13 | 13 | "use strict";
|
14 | 14 |
|
15 |
| - var |
16 |
| - |
17 | 15 | // Regex to break the main string into parts
|
18 | 16 | // example " getTag(p, 6).world[placeholder=some text] {myvar} yeah"
|
19 | 17 | // matches
|
|
22 | 20 | // 3: parentheses "(p, 6)"
|
23 | 21 | // 4: method args "p, 6"
|
24 | 22 | // 5: everything else ".world[placeholder=some text] {myvar} yeah"
|
25 |
| - rparse = /^(\s*)([\w-]*)(\((.*)\))?(.*)$/, |
| 23 | + var rline = /^(\s*)([\w-]*)(\((.*)\))?(.*)$/; |
26 | 24 |
|
27 | 25 | // Regex for explicitly stated attributes ( the stuff in square brackets )
|
28 | 26 | // matches
|
29 | 27 | // 1: attribute name "placeholder"
|
30 | 28 | // 2: value "some text"
|
31 |
| - rattrs = /\[([\w-]+)=?([^\]]*)\]/g, |
| 29 | + var rattrs = /\[([\w-]+)=?([^\]]*)\]/g; |
32 | 30 |
|
33 | 31 | // Regex for the modifiers ( class, id, cache )
|
34 | 32 | // matches
|
35 | 33 | // 1: type flag ".", "#", "$"
|
36 | 34 | // 2: value from the example above "world"
|
37 |
| - rmods = /([.#$])([\w-]+)/g, |
| 35 | + var rmods = /([.#$])([\w-]+)/g; |
38 | 36 |
|
39 | 37 | // Regex for the handlebar type variable syntax in text
|
40 | 38 | // matches
|
41 | 39 | // 1: start or leading character, check comments in varReplacer() for why
|
42 | 40 | // 2: variable key
|
43 |
| - rvariables = /(^|[^\\])\{(.*?[^\\])\}/g, |
| 41 | + var rvariables = /(^|[^\\])\{(.*?[^\\])\}/g; |
44 | 42 |
|
45 |
| - // set the value property instead of innerhtml for these tags |
46 |
| - setValuesFor = ["input", "textarea"], |
| 43 | + // set the `value` property instead of `innerHTML` for these tags |
| 44 | + var setValuesFor = ["input", "textarea"]; |
47 | 45 |
|
48 | 46 | // just for compression
|
49 |
| - isFunction = $.isFunction, |
| 47 | + var isFunction = $.isFunction; |
50 | 48 |
|
51 | 49 | // Turn dot notation in a string into object reference
|
52 | 50 | // example "a.b.c" on a = {b:{c:variable}} will return variable
|
53 |
| - dotToRef = function (notation, object) { |
| 51 | + var dotToRef = function (notation, object) { |
54 | 52 | return notation.split(".")
|
55 | 53 | .reduce(function (current, i) {
|
56 | 54 | return current[i];
|
57 | 55 | }, object);
|
58 |
| - }, |
| 56 | + }; |
| 57 | + |
| 58 | + // scratch vars |
| 59 | + var lastEl; |
| 60 | + var parentEl; |
| 61 | + var indexOfSpace; |
| 62 | + var textVal; |
| 63 | + var modVal; |
59 | 64 |
|
60 | 65 | // The actual plugin function
|
61 |
| - tmpl = function (template, data) { |
| 66 | + var tmpl = function(template, data) { |
62 | 67 |
|
63 |
| - if (!$.isArray(template)) |
| 68 | + if (!$.isArray(template)) { |
64 | 69 | template = [];
|
| 70 | + } |
65 | 71 |
|
66 | 72 | data = data || {};
|
67 | 73 |
|
68 |
| - var ret = $(), |
69 |
| - itemIndex, |
70 |
| - parent, |
71 |
| - lastEl, |
72 |
| - lastDepth = 0, |
73 |
| - objCache = {}, |
74 |
| - |
75 |
| - // Replace variables in strings |
76 |
| - varReplacer = function (match, lead, key) { |
77 |
| - var val = dotToRef(key, data); |
78 |
| - |
79 |
| - if (isFunction(val)) |
80 |
| - val = val.call(data); |
81 |
| - |
82 |
| - if (null == val) |
83 |
| - val = ""; |
84 |
| - |
85 |
| - // In order to have escapeable opening curly brackets, |
86 |
| - // we have to capture the character before the bracket |
87 |
| - // then append it back in. |
88 |
| - // Without lookbehinds in js, is there a better way to do this? |
89 |
| - return lead + val; |
90 |
| - }; |
91 |
| - |
92 |
| - for (itemIndex in template) { |
93 |
| - |
94 |
| - var matches = rparse.exec(template[itemIndex]), |
95 |
| - tag = matches[2], |
96 |
| - postTag = matches[5], |
97 |
| - el = 0, |
98 |
| - $el = 0, |
99 |
| - indexOfSpace, textVal, modVal, |
100 |
| - classes = [], |
101 |
| - |
102 |
| - // The amount of white space that starts the string |
103 |
| - // defines its depth in the DOM tree |
104 |
| - // Four spaces to a level, add one to compensate for |
105 |
| - // the quote character then floor the value |
106 |
| - // examples |
107 |
| - // "tag" : 0 spaces = 0 |
108 |
| - // " tag" : 3 spaces = 1 |
109 |
| - // " tag" : 7 spaces = 2 |
110 |
| - depth = ((matches[1].length + 1) / 4) | 0; |
| 74 | + var ret = $(); |
| 75 | + var templateIndex = 0; |
| 76 | + var templateLength = template.length; |
| 77 | + var lastDepth = 0; |
| 78 | + var objCache = {}; |
| 79 | + |
| 80 | + // Replace variables in strings |
| 81 | + var varReplacer = function(match, lead, key) { |
| 82 | + var val = dotToRef(key, data); |
| 83 | + |
| 84 | + if (isFunction(val)) { |
| 85 | + val = val.call(data); |
| 86 | + } |
| 87 | + |
| 88 | + if (!val && 0 !== val) { |
| 89 | + val = ""; |
| 90 | + } |
| 91 | + |
| 92 | + // In order to have escapable opening curly brackets, |
| 93 | + // we have to capture the character before the bracket |
| 94 | + // then append it back in. |
| 95 | + // Without lookbehinds in js, is there a better way to do this? |
| 96 | + return lead + val; |
| 97 | + }; |
| 98 | + |
| 99 | + while (templateIndex < templateLength) { |
| 100 | + |
| 101 | + var matches = rline.exec(template[templateIndex++]); |
| 102 | + var tag = matches[2]; |
| 103 | + var postTag = matches[5]; |
| 104 | + var el = false; |
| 105 | + var $el = false; |
| 106 | + var classes = []; |
| 107 | + |
| 108 | + // The amount of white space that starts the string |
| 109 | + // defines its depth in the DOM tree |
| 110 | + // Four spaces to a level, add one to compensate for |
| 111 | + // the quote character then floor the value |
| 112 | + // examples |
| 113 | + // "tag" : 0 spaces = 0 |
| 114 | + // " tag" : 3 spaces = 1 |
| 115 | + // " tag" : 7 spaces = 2 |
| 116 | + var depth = ((matches[1].length + 1) / 4) | 0; |
111 | 117 |
|
112 | 118 | // Make sure there is at least a tag or postTag declared
|
113 | 119 | // basically, skip empty lines
|
114 |
| - if (!tag && !postTag) |
| 120 | + if (!tag && !postTag) { |
115 | 121 | continue;
|
| 122 | + } |
116 | 123 |
|
117 | 124 | // matches[3] is truthy if parentheses were provided after the tag name
|
118 | 125 | // so we consider it a fn call
|
|
134 | 141 | el = document.createElement(tag || "div");
|
135 | 142 | }
|
136 | 143 |
|
137 |
| - if (depth && parent) { |
138 |
| - if (depth > lastDepth) // nest in last element |
139 |
| - parent = lastEl; |
| 144 | + if (depth && parentEl) { |
| 145 | + if (depth > lastDepth) { // nest in last element |
| 146 | + parentEl = lastEl; |
| 147 | + } |
140 | 148 |
|
141 |
| - while (depth < lastDepth--) // traverse up |
142 |
| - parent = parent.parentNode; |
| 149 | + while (depth < lastDepth--) { // traverse up |
| 150 | + parentEl = parentEl.parentNode; |
| 151 | + } |
143 | 152 |
|
144 |
| - parent.appendChild(el); |
| 153 | + parentEl.appendChild(el); |
145 | 154 | } else {
|
146 |
| - ret.push(parent = el); |
| 155 | + ret.push(parentEl = el); |
147 | 156 | }
|
148 | 157 |
|
149 | 158 | lastDepth = depth;
|
150 | 159 | lastEl = el;
|
151 | 160 |
|
152 | 161 | // Don't bother with the rest if there's no mods or text
|
153 |
| - if (!postTag) |
| 162 | + if (!postTag) { |
154 | 163 | continue;
|
| 164 | + } |
155 | 165 |
|
156 | 166 | // Search for attributes
|
157 | 167 | // Attach them to the element and remove the characters
|
158 | 168 | // from the postTag string, this allows us to have spaces in the attr values
|
159 | 169 | //
|
160 | 170 | // [placeholder=Hello World] -> placeholder="Hello World"
|
161 | 171 | // [disabled] -> disabled="disabled"
|
162 |
| - postTag = postTag.replace(rattrs, function (match, attr, val) { |
| 172 | + postTag = postTag.replace(rattrs, function(match, attr, val) { |
163 | 173 | el.setAttribute(attr, val || attr);
|
164 | 174 | return "";
|
165 | 175 | });
|
|
178 | 188 |
|
179 | 189 | // Set the value for the tags we want to,
|
180 | 190 | // otherwise set innerHTML
|
181 |
| - if ($.inArray(el.tagName.toLowerCase(), setValuesFor) < 0) |
| 191 | + if ($.inArray(el.tagName.toLowerCase(), setValuesFor) < 0) { |
182 | 192 | el.innerHTML = textVal;
|
183 |
| - else |
| 193 | + } else { |
184 | 194 | el.value = textVal;
|
| 195 | + } |
185 | 196 | }
|
186 | 197 |
|
187 | 198 | // Loop the mods
|
188 | 199 | while ((matches = rmods.exec(postTag))) {
|
189 | 200 | modVal = matches[2];
|
190 | 201 |
|
191 | 202 | switch (matches[1]) {
|
192 |
| - case ".": // Add class |
193 |
| - classes.push(modVal); |
194 |
| - break; |
| 203 | + case ".": // Add class |
| 204 | + classes.push(modVal); |
| 205 | + break; |
195 | 206 |
|
196 |
| - case "#": // Set id |
197 |
| - el.id = modVal; |
198 |
| - break; |
| 207 | + case "#": // Set id |
| 208 | + el.id = modVal; |
| 209 | + break; |
199 | 210 |
|
200 |
| - case "$": // cache jQueryized element for later |
201 |
| - objCache[modVal] = $el || $(el); |
| 211 | + case "$": // cache jQueryized element for later |
| 212 | + objCache[modVal] = $el || $(el); |
202 | 213 | }
|
203 | 214 | }
|
204 | 215 |
|
|
0 commit comments