Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like __TwigTemplate_8206467aa1869d2c5530cbed2cab9e3f45d7108d4175abc935bd2f89c2f421bf often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use __TwigTemplate_8206467aa1869d2c5530cbed2cab9e3f45d7108d4175abc935bd2f89c2f421bf, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
4 | class __TwigTemplate_8206467aa1869d2c5530cbed2cab9e3f45d7108d4175abc935bd2f89c2f421bf extends Twig_Template |
||
5 | { |
||
6 | public function __construct(Twig_Environment $env) |
||
7 | { |
||
8 | parent::__construct($env); |
||
9 | |||
10 | $this->parent = false; |
||
11 | |||
12 | $this->blocks = array( |
||
13 | 'search_index' => array($this, 'block_search_index'), |
||
14 | 'search_index_extra' => array($this, 'block_search_index_extra'), |
||
15 | 'treejs' => array($this, 'block_treejs'), |
||
16 | ); |
||
17 | } |
||
18 | |||
19 | protected function doDisplay(array $context, array $blocks = array()) |
||
20 | { |
||
21 | // line 1 |
||
22 | $context["__internal_8afc8a8ae1ba1195f1a5124fbe671ff7240f27c9ccc050ed7e120c7cdabb77b7"] = $this; |
||
23 | // line 2 |
||
24 | echo " |
||
25 | window.projectVersion = '"; |
||
26 | // line 3 |
||
27 | echo twig_escape_filter($this->env, twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["project"]) || array_key_exists("project", $context) ? $context["project"] : (function () { throw new Twig_Error_Runtime('Variable "project" does not exist.', 3, $this->getSourceContext()); })()), "version", array()), "html", null, true); |
||
28 | echo "'; |
||
29 | |||
30 | (function(root) { |
||
31 | |||
32 | var bhIndex = null; |
||
33 | var rootPath = ''; |
||
34 | var treeHtml = '"; |
||
35 | // line 9 |
||
36 | echo twig_replace_filter($context["__internal_8afc8a8ae1ba1195f1a5124fbe671ff7240f27c9ccc050ed7e120c7cdabb77b7"]->macro_element((isset($context["tree"]) || array_key_exists("tree", $context) ? $context["tree"] : (function () { throw new Twig_Error_Runtime('Variable "tree" does not exist.', 9, $this->getSourceContext()); })()), twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["project"]) || array_key_exists("project", $context) ? $context["project"] : (function () { throw new Twig_Error_Runtime('Variable "project" does not exist.', 9, $this->getSourceContext()); })()), "config", array(0 => "default_opened_level"), "method"), 0), array("'" => "\\'", " |
||
37 | " => "")); |
||
38 | echo "'; |
||
39 | |||
40 | var searchTypeClasses = { |
||
41 | 'Namespace': 'label-default', |
||
42 | 'Class': 'label-info', |
||
43 | 'Interface': 'label-primary', |
||
44 | 'Trait': 'label-success', |
||
45 | 'Method': 'label-danger', |
||
46 | '_': 'label-warning' |
||
47 | }; |
||
48 | |||
49 | var searchIndex = [ |
||
50 | "; |
||
51 | // line 21 |
||
52 | $this->displayBlock('search_index', $context, $blocks); |
||
53 | // line 41 |
||
54 | echo " // Fix trailing commas in the index |
||
55 | {} |
||
56 | ]; |
||
57 | |||
58 | /** Tokenizes strings by namespaces and functions */ |
||
59 | function tokenizer(term) { |
||
60 | if (!term) { |
||
61 | return []; |
||
62 | } |
||
63 | |||
64 | var tokens = [term]; |
||
65 | var meth = term.indexOf('::'); |
||
66 | |||
67 | // Split tokens into methods if \"::\" is found. |
||
68 | if (meth > -1) { |
||
69 | tokens.push(term.substr(meth + 2)); |
||
70 | term = term.substr(0, meth - 2); |
||
71 | } |
||
72 | |||
73 | // Split by namespace or fake namespace. |
||
74 | if (term.indexOf('\\\\') > -1) { |
||
75 | tokens = tokens.concat(term.split('\\\\')); |
||
76 | } else if (term.indexOf('_') > 0) { |
||
77 | tokens = tokens.concat(term.split('_')); |
||
78 | } |
||
79 | |||
80 | // Merge in splitting the string by case and return |
||
81 | tokens = tokens.concat(term.match(/(([A-Z]?[^A-Z]*)|([a-z]?[^a-z]*))/g).slice(0,-1)); |
||
82 | |||
83 | return tokens; |
||
84 | }; |
||
85 | |||
86 | root.Sami = { |
||
87 | /** |
||
88 | * Cleans the provided term. If no term is provided, then one is |
||
89 | * grabbed from the query string \"search\" parameter. |
||
90 | */ |
||
91 | cleanSearchTerm: function(term) { |
||
92 | // Grab from the query string |
||
93 | if (typeof term === 'undefined') { |
||
94 | var name = 'search'; |
||
95 | var regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\"); |
||
96 | var results = regex.exec(location.search); |
||
97 | if (results === null) { |
||
98 | return null; |
||
99 | } |
||
100 | term = decodeURIComponent(results[1].replace(/\\+/g, \" \")); |
||
101 | } |
||
102 | |||
103 | return term.replace(/<(?:.|\\n)*?>/gm, ''); |
||
104 | }, |
||
105 | |||
106 | /** Searches through the index for a given term */ |
||
107 | search: function(term) { |
||
108 | // Create a new search index if needed |
||
109 | if (!bhIndex) { |
||
110 | bhIndex = new Bloodhound({ |
||
111 | limit: 500, |
||
112 | local: searchIndex, |
||
113 | datumTokenizer: function (d) { |
||
114 | return tokenizer(d.name); |
||
115 | }, |
||
116 | queryTokenizer: Bloodhound.tokenizers.whitespace |
||
117 | }); |
||
118 | bhIndex.initialize(); |
||
119 | } |
||
120 | |||
121 | results = []; |
||
122 | bhIndex.get(term, function(matches) { |
||
123 | results = matches; |
||
124 | }); |
||
125 | |||
126 | if (!rootPath) { |
||
127 | return results; |
||
128 | } |
||
129 | |||
130 | // Fix the element links based on the current page depth. |
||
131 | return \$.map(results, function(ele) { |
||
132 | if (ele.link.indexOf('..') > -1) { |
||
133 | return ele; |
||
134 | } |
||
135 | ele.link = rootPath + ele.link; |
||
136 | if (ele.fromLink) { |
||
137 | ele.fromLink = rootPath + ele.fromLink; |
||
138 | } |
||
139 | return ele; |
||
140 | }); |
||
141 | }, |
||
142 | |||
143 | /** Get a search class for a specific type */ |
||
144 | getSearchClass: function(type) { |
||
145 | return searchTypeClasses[type] || searchTypeClasses['_']; |
||
146 | }, |
||
147 | |||
148 | /** Add the left-nav tree to the site */ |
||
149 | injectApiTree: function(ele) { |
||
150 | ele.html(treeHtml); |
||
151 | } |
||
152 | }; |
||
153 | |||
154 | \$(function() { |
||
155 | // Modify the HTML to work correctly based on the current depth |
||
156 | rootPath = \$('body').attr('data-root-path'); |
||
157 | treeHtml = treeHtml.replace(/href=\"/g, 'href=\"' + rootPath); |
||
158 | Sami.injectApiTree(\$('#api-tree')); |
||
159 | }); |
||
160 | |||
161 | return root.Sami; |
||
162 | })(window); |
||
163 | |||
164 | \$(function() { |
||
165 | |||
166 | // Enable the version switcher |
||
167 | \$('#version-switcher').change(function() { |
||
168 | window.location = \$(this).val() |
||
169 | }); |
||
170 | |||
171 | "; |
||
172 | // line 158 |
||
173 | $this->displayBlock('treejs', $context, $blocks); |
||
174 | // line 184 |
||
175 | echo " |
||
176 | "; |
||
177 | // line 212 |
||
178 | echo " |
||
179 | var form = \$('#search-form .typeahead'); |
||
180 | form.typeahead({ |
||
181 | hint: true, |
||
182 | highlight: true, |
||
183 | minLength: 1 |
||
184 | }, { |
||
185 | name: 'search', |
||
186 | displayKey: 'name', |
||
187 | source: function (q, cb) { |
||
188 | cb(Sami.search(q)); |
||
189 | } |
||
190 | }); |
||
191 | |||
192 | // The selection is direct-linked when the user selects a suggestion. |
||
193 | form.on('typeahead:selected', function(e, suggestion) { |
||
194 | window.location = suggestion.link; |
||
195 | }); |
||
196 | |||
197 | // The form is submitted when the user hits enter. |
||
198 | form.keypress(function (e) { |
||
199 | if (e.which == 13) { |
||
200 | \$('#search-form').submit(); |
||
201 | return true; |
||
202 | } |
||
203 | }); |
||
204 | |||
205 | "; |
||
206 | echo " |
||
207 | }); |
||
208 | |||
209 | "; |
||
210 | // line 224 |
||
211 | echo " |
||
212 | "; |
||
213 | } |
||
214 | |||
215 | // line 21 |
||
216 | public function block_search_index($context, array $blocks = array()) |
||
217 | { |
||
218 | // line 22 |
||
219 | echo " "; |
||
220 | $context["__internal_e00250934c7fb9cfd9a6e95672df28c1397bb383b1410781167bff5196387df3"] = $this; |
||
221 | // line 23 |
||
222 | echo " |
||
223 | "; |
||
224 | // line 24 |
||
225 | $context['_parent'] = $context; |
||
226 | $context['_seq'] = twig_ensure_traversable((isset($context["namespaces"]) || array_key_exists("namespaces", $context) ? $context["namespaces"] : (function () { throw new Twig_Error_Runtime('Variable "namespaces" does not exist.', 24, $this->getSourceContext()); })())); |
||
227 | foreach ($context['_seq'] as $context["_key"] => $context["ns"]) { |
||
228 | // line 25 |
||
229 | echo "{\"type\": \"Namespace\", \"link\": \""; |
||
230 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForNamespace($context, $context["ns"]); |
||
231 | echo "\", \"name\": \""; |
||
232 | echo twig_replace_filter($context["ns"], array("\\" => "\\\\")); |
||
233 | echo "\", \"doc\": \"Namespace "; |
||
234 | echo twig_replace_filter($context["ns"], array("\\" => "\\\\")); |
||
235 | echo "\"},"; |
||
236 | } |
||
237 | $_parent = $context['_parent']; |
||
238 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['ns'], $context['_parent'], $context['loop']); |
||
239 | $context = array_intersect_key($context, $_parent) + $_parent; |
||
240 | // line 27 |
||
241 | echo " |
||
242 | "; |
||
243 | // line 28 |
||
244 | $context['_parent'] = $context; |
||
245 | $context['_seq'] = twig_ensure_traversable((isset($context["interfaces"]) || array_key_exists("interfaces", $context) ? $context["interfaces"] : (function () { throw new Twig_Error_Runtime('Variable "interfaces" does not exist.', 28, $this->getSourceContext()); })())); |
||
246 | foreach ($context['_seq'] as $context["_key"] => $context["class"]) { |
||
247 | // line 29 |
||
248 | echo "{\"type\": \"Interface\", "; |
||
249 | if (twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array())) { |
||
250 | echo "\"fromName\": \""; |
||
251 | echo twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array()), array("\\" => "\\\\")); |
||
252 | echo "\", \"fromLink\": \""; |
||
253 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForNamespace($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array())); |
||
254 | echo "\","; |
||
255 | } |
||
256 | echo " \"link\": \""; |
||
257 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForClass($context, $context["class"]); |
||
258 | echo "\", \"name\": \""; |
||
259 | echo twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "name", array()), array("\\" => "\\\\")); |
||
260 | echo "\", \"doc\": \""; |
||
261 | echo twig_escape_filter($this->env, json_encode($this->env->getExtension('Sami\Renderer\TwigExtension')->parseDesc($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "shortdesc", array()), $context["class"])), "html", null, true); |
||
262 | echo "\"}, |
||
263 | "; |
||
264 | // line 30 |
||
265 | echo $context["__internal_e00250934c7fb9cfd9a6e95672df28c1397bb383b1410781167bff5196387df3"]->macro_add_class_methods_index($context["class"]); |
||
266 | echo " |
||
267 | "; |
||
268 | } |
||
269 | $_parent = $context['_parent']; |
||
270 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['class'], $context['_parent'], $context['loop']); |
||
271 | $context = array_intersect_key($context, $_parent) + $_parent; |
||
272 | // line 32 |
||
273 | echo " |
||
274 | "; |
||
275 | // line 33 |
||
276 | $context['_parent'] = $context; |
||
277 | $context['_seq'] = twig_ensure_traversable((isset($context["classes"]) || array_key_exists("classes", $context) ? $context["classes"] : (function () { throw new Twig_Error_Runtime('Variable "classes" does not exist.', 33, $this->getSourceContext()); })())); |
||
278 | foreach ($context['_seq'] as $context["_key"] => $context["class"]) { |
||
279 | // line 34 |
||
280 | echo "{\"type\": "; |
||
281 | if (twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "isTrait", array())) { |
||
282 | echo "\"Trait\""; |
||
283 | } else { |
||
284 | echo "\"Class\""; |
||
285 | } |
||
286 | echo ", "; |
||
287 | if (twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array())) { |
||
288 | echo "\"fromName\": \""; |
||
289 | echo twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array()), array("\\" => "\\\\")); |
||
290 | echo "\", \"fromLink\": \""; |
||
291 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForNamespace($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "namespace", array())); |
||
292 | echo "\","; |
||
293 | } |
||
294 | echo " \"link\": \""; |
||
295 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForClass($context, $context["class"]); |
||
296 | echo "\", \"name\": \""; |
||
297 | echo twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "name", array()), array("\\" => "\\\\")); |
||
298 | echo "\", \"doc\": \""; |
||
299 | echo twig_escape_filter($this->env, json_encode($this->env->getExtension('Sami\Renderer\TwigExtension')->parseDesc($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["class"], "shortdesc", array()), $context["class"])), "html", null, true); |
||
300 | echo "\"}, |
||
301 | "; |
||
302 | // line 35 |
||
303 | echo $context["__internal_e00250934c7fb9cfd9a6e95672df28c1397bb383b1410781167bff5196387df3"]->macro_add_class_methods_index($context["class"]); |
||
304 | echo " |
||
305 | "; |
||
306 | } |
||
307 | $_parent = $context['_parent']; |
||
308 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['class'], $context['_parent'], $context['loop']); |
||
309 | $context = array_intersect_key($context, $_parent) + $_parent; |
||
310 | // line 37 |
||
311 | echo " |
||
312 | "; |
||
313 | // line 39 |
||
314 | echo " "; |
||
315 | $this->displayBlock('search_index_extra', $context, $blocks); |
||
316 | // line 40 |
||
317 | echo " "; |
||
318 | } |
||
319 | |||
320 | // line 39 |
||
321 | public function block_search_index_extra($context, array $blocks = array()) |
||
322 | { |
||
323 | echo ""; |
||
324 | } |
||
325 | |||
326 | // line 158 |
||
327 | public function block_treejs($context, array $blocks = array()) |
||
328 | { |
||
329 | // line 159 |
||
330 | echo " |
||
331 | // Toggle left-nav divs on click |
||
332 | \$('#api-tree .hd span').click(function() { |
||
333 | \$(this).parent().parent().toggleClass('opened'); |
||
334 | }); |
||
335 | |||
336 | // Expand the parent namespaces of the current page. |
||
337 | var expected = \$('body').attr('data-name'); |
||
338 | |||
339 | if (expected) { |
||
340 | // Open the currently selected node and its parents. |
||
341 | var container = \$('#api-tree'); |
||
342 | var node = \$('#api-tree li[data-name=\"' + expected + '\"]'); |
||
343 | // Node might not be found when simulating namespaces |
||
344 | if (node.length > 0) { |
||
345 | node.addClass('active').addClass('opened'); |
||
346 | node.parents('li').addClass('opened'); |
||
347 | var scrollPos = node.offset().top - container.offset().top + container.scrollTop(); |
||
348 | // Position the item nearer to the top of the screen. |
||
349 | scrollPos -= 200; |
||
350 | container.scrollTop(scrollPos); |
||
351 | } |
||
352 | } |
||
353 | |||
354 | "; |
||
355 | } |
||
356 | |||
357 | // line 215 |
||
358 | public function macro_add_class_methods_index($__class__ = null, ...$__varargs__) |
||
359 | { |
||
360 | $context = $this->env->mergeGlobals(array( |
||
361 | "class" => $__class__, |
||
362 | "varargs" => $__varargs__, |
||
363 | )); |
||
364 | |||
365 | $blocks = array(); |
||
366 | |||
367 | ob_start(); |
||
368 | try { |
||
369 | // line 216 |
||
370 | echo " "; |
||
371 | if (twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["class"]) || array_key_exists("class", $context) ? $context["class"] : (function () { throw new Twig_Error_Runtime('Variable "class" does not exist.', 216, $this->getSourceContext()); })()), "methods", array())) { |
||
372 | // line 217 |
||
373 | echo " "; |
||
374 | $context["from_name"] = twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["class"]) || array_key_exists("class", $context) ? $context["class"] : (function () { throw new Twig_Error_Runtime('Variable "class" does not exist.', 217, $this->getSourceContext()); })()), "name", array()), array("\\" => "\\\\")); |
||
375 | // line 218 |
||
376 | echo " "; |
||
377 | $context["from_link"] = $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForClass($context, (isset($context["class"]) || array_key_exists("class", $context) ? $context["class"] : (function () { throw new Twig_Error_Runtime('Variable "class" does not exist.', 218, $this->getSourceContext()); })())); |
||
378 | // line 219 |
||
379 | echo " "; |
||
380 | $context['_parent'] = $context; |
||
381 | $context['_seq'] = twig_ensure_traversable(twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["class"]) || array_key_exists("class", $context) ? $context["class"] : (function () { throw new Twig_Error_Runtime('Variable "class" does not exist.', 219, $this->getSourceContext()); })()), "methods", array())); |
||
382 | foreach ($context['_seq'] as $context["_key"] => $context["meth"]) { |
||
383 | // line 220 |
||
384 | echo " {\"type\": \"Method\", \"fromName\": \""; |
||
385 | echo (isset($context["from_name"]) || array_key_exists("from_name", $context) ? $context["from_name"] : (function () { throw new Twig_Error_Runtime('Variable "from_name" does not exist.', 220, $this->getSourceContext()); })()); |
||
386 | echo "\", \"fromLink\": \""; |
||
387 | echo (isset($context["from_link"]) || array_key_exists("from_link", $context) ? $context["from_link"] : (function () { throw new Twig_Error_Runtime('Variable "from_link" does not exist.', 220, $this->getSourceContext()); })()); |
||
388 | echo "\", \"link\": \""; |
||
389 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForMethod($context, $context["meth"]); |
||
390 | echo "\", \"name\": \""; |
||
391 | echo twig_replace_filter($context["meth"], array("\\" => "\\\\")); |
||
392 | echo "\", \"doc\": \""; |
||
393 | echo twig_escape_filter($this->env, json_encode($this->env->getExtension('Sami\Renderer\TwigExtension')->parseDesc($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["meth"], "shortdesc", array()), (isset($context["class"]) || array_key_exists("class", $context) ? $context["class"] : (function () { throw new Twig_Error_Runtime('Variable "class" does not exist.', 220, $this->getSourceContext()); })()))), "html", null, true); |
||
394 | echo "\"}, |
||
395 | "; |
||
396 | } |
||
397 | $_parent = $context['_parent']; |
||
398 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['meth'], $context['_parent'], $context['loop']); |
||
399 | $context = array_intersect_key($context, $_parent) + $_parent; |
||
400 | // line 222 |
||
401 | echo " "; |
||
402 | } |
||
403 | |||
404 | return ('' === $tmp = ob_get_contents()) ? '' : new Twig_Markup($tmp, $this->env->getCharset()); |
||
405 | } finally { |
||
406 | ob_end_clean(); |
||
407 | } |
||
408 | } |
||
409 | |||
410 | // line 225 |
||
411 | public function macro_element($__tree__ = null, $__opened__ = null, $__depth__ = null, ...$__varargs__) |
||
412 | { |
||
413 | $context = $this->env->mergeGlobals(array( |
||
414 | "tree" => $__tree__, |
||
415 | "opened" => $__opened__, |
||
416 | "depth" => $__depth__, |
||
417 | "varargs" => $__varargs__, |
||
418 | )); |
||
419 | |||
420 | $blocks = array(); |
||
421 | |||
422 | ob_start(); |
||
423 | try { |
||
424 | // line 226 |
||
425 | echo " "; |
||
426 | $context["__internal_19673542bca73c75548fd07e0673770ce397b80422823d7d940f6382456d6a39"] = $this; |
||
427 | // line 227 |
||
428 | echo " |
||
429 | <ul>"; |
||
430 | // line 229 |
||
431 | $context['_parent'] = $context; |
||
432 | $context['_seq'] = twig_ensure_traversable((isset($context["tree"]) || array_key_exists("tree", $context) ? $context["tree"] : (function () { throw new Twig_Error_Runtime('Variable "tree" does not exist.', 229, $this->getSourceContext()); })())); |
||
433 | foreach ($context['_seq'] as $context["_key"] => $context["element"]) { |
||
434 | // line 230 |
||
435 | if (twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 2, array(), "array")) { |
||
436 | // line 231 |
||
437 | echo " <li data-name=\"namespace:"; |
||
438 | echo twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 1, array(), "array"), array("\\" => "_")); |
||
439 | echo "\" "; |
||
440 | if (((isset($context["depth"]) || array_key_exists("depth", $context) ? $context["depth"] : (function () { throw new Twig_Error_Runtime('Variable "depth" does not exist.', 231, $this->getSourceContext()); })()) < (isset($context["opened"]) || array_key_exists("opened", $context) ? $context["opened"] : (function () { throw new Twig_Error_Runtime('Variable "opened" does not exist.', 231, $this->getSourceContext()); })()))) { |
||
441 | echo "class=\"opened\""; |
||
442 | } |
||
443 | echo "> |
||
444 | <div style=\"padding-left:"; |
||
445 | // line 232 |
||
446 | echo ((isset($context["depth"]) || array_key_exists("depth", $context) ? $context["depth"] : (function () { throw new Twig_Error_Runtime('Variable "depth" does not exist.', 232, $this->getSourceContext()); })()) * 18); |
||
447 | echo "px\" class=\"hd\"> |
||
448 | <span class=\"glyphicon glyphicon-play\"></span>"; |
||
449 | // line 233 |
||
450 | if ( !twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["project"]) || array_key_exists("project", $context) ? $context["project"] : (function () { throw new Twig_Error_Runtime('Variable "project" does not exist.', 233, $this->getSourceContext()); })()), "config", array(0 => "simulate_namespaces"), "method")) { |
||
451 | echo "<a href=\""; |
||
452 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForNamespace($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 1, array(), "array")); |
||
453 | echo "\">"; |
||
454 | } |
||
455 | echo twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 0, array(), "array"); |
||
456 | if ( !twig_get_attribute($this->env, $this->getSourceContext(), (isset($context["project"]) || array_key_exists("project", $context) ? $context["project"] : (function () { throw new Twig_Error_Runtime('Variable "project" does not exist.', 233, $this->getSourceContext()); })()), "config", array(0 => "simulate_namespaces"), "method")) { |
||
457 | echo "</a>"; |
||
458 | } |
||
459 | // line 234 |
||
460 | echo " </div> |
||
461 | <div class=\"bd\"> |
||
462 | "; |
||
463 | // line 236 |
||
464 | echo $context["__internal_19673542bca73c75548fd07e0673770ce397b80422823d7d940f6382456d6a39"]->macro_element(twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 2, array(), "array"), (isset($context["opened"]) || array_key_exists("opened", $context) ? $context["opened"] : (function () { throw new Twig_Error_Runtime('Variable "opened" does not exist.', 236, $this->getSourceContext()); })()), ((isset($context["depth"]) || array_key_exists("depth", $context) ? $context["depth"] : (function () { throw new Twig_Error_Runtime('Variable "depth" does not exist.', 236, $this->getSourceContext()); })()) + 1)); |
||
465 | // line 237 |
||
466 | echo "</div> |
||
467 | </li> |
||
468 | "; |
||
469 | } else { |
||
470 | // line 240 |
||
471 | echo " <li data-name=\"class:"; |
||
472 | echo twig_escape_filter($this->env, twig_replace_filter(twig_get_attribute($this->env, $this->getSourceContext(), twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 1, array(), "array"), "name", array()), array("\\" => "_")), "html", null, true); |
||
473 | echo "\" "; |
||
474 | if (((isset($context["depth"]) || array_key_exists("depth", $context) ? $context["depth"] : (function () { throw new Twig_Error_Runtime('Variable "depth" does not exist.', 240, $this->getSourceContext()); })()) < (isset($context["opened"]) || array_key_exists("opened", $context) ? $context["opened"] : (function () { throw new Twig_Error_Runtime('Variable "opened" does not exist.', 240, $this->getSourceContext()); })()))) { |
||
475 | echo "class=\"opened\""; |
||
476 | } |
||
477 | echo "> |
||
478 | <div style=\"padding-left:"; |
||
479 | // line 241 |
||
480 | echo twig_escape_filter($this->env, (8 + ((isset($context["depth"]) || array_key_exists("depth", $context) ? $context["depth"] : (function () { throw new Twig_Error_Runtime('Variable "depth" does not exist.', 241, $this->getSourceContext()); })()) * 18)), "html", null, true); |
||
481 | echo "px\" class=\"hd leaf\"> |
||
482 | <a href=\""; |
||
483 | // line 242 |
||
484 | echo $this->env->getExtension('Sami\Renderer\TwigExtension')->pathForClass($context, twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 1, array(), "array")); |
||
485 | echo "\">"; |
||
486 | echo twig_escape_filter($this->env, twig_get_attribute($this->env, $this->getSourceContext(), $context["element"], 0, array(), "array"), "html", null, true); |
||
487 | echo "</a> |
||
488 | </div> |
||
489 | </li> |
||
490 | "; |
||
491 | } |
||
492 | } |
||
493 | $_parent = $context['_parent']; |
||
494 | unset($context['_seq'], $context['_iterated'], $context['_key'], $context['element'], $context['_parent'], $context['loop']); |
||
495 | $context = array_intersect_key($context, $_parent) + $_parent; |
||
496 | // line 247 |
||
497 | echo " </ul> |
||
498 | "; |
||
499 | |||
500 | return ('' === $tmp = ob_get_contents()) ? '' : new Twig_Markup($tmp, $this->env->getCharset()); |
||
501 | } finally { |
||
502 | ob_end_clean(); |
||
503 | } |
||
504 | } |
||
505 | |||
506 | public function getTemplateName() |
||
507 | { |
||
508 | return "sami.js.twig"; |
||
509 | } |
||
510 | |||
511 | public function isTraitable() |
||
512 | { |
||
513 | return false; |
||
514 | } |
||
515 | |||
516 | public function getDebugInfo() |
||
517 | { |
||
518 | return array ( 497 => 247, 484 => 242, 480 => 241, 471 => 240, 466 => 237, 464 => 236, 460 => 234, 450 => 233, 446 => 232, 437 => 231, 435 => 230, 431 => 229, 428 => 227, 425 => 226, 411 => 225, 401 => 222, 384 => 220, 379 => 219, 376 => 218, 373 => 217, 370 => 216, 358 => 215, 330 => 159, 327 => 158, 321 => 39, 317 => 40, 314 => 39, 311 => 37, 303 => 35, 280 => 34, 276 => 33, 273 => 32, 265 => 30, 248 => 29, 244 => 28, 241 => 27, 229 => 25, 225 => 24, 222 => 23, 219 => 22, 216 => 21, 211 => 224, 178 => 212, 175 => 184, 173 => 158, 54 => 41, 52 => 21, 36 => 9, 27 => 3, 24 => 2, 22 => 1,); |
||
519 | } |
||
520 | |||
521 | public function getSourceContext() |
||
522 | { |
||
523 | return new Twig_Source("{% from _self import element %} |
||
524 | |||
525 | window.projectVersion = '{{ project.version }}'; |
||
526 | |||
527 | (function(root) { |
||
528 | |||
529 | var bhIndex = null; |
||
530 | var rootPath = ''; |
||
531 | var treeHtml = '{{ element(tree, project.config('default_opened_level'), 0)|replace({\"'\": \"\\\\'\", \"\\n\": ''})|raw }}'; |
||
532 | |||
533 | var searchTypeClasses = { |
||
534 | 'Namespace': 'label-default', |
||
535 | 'Class': 'label-info', |
||
536 | 'Interface': 'label-primary', |
||
537 | 'Trait': 'label-success', |
||
538 | 'Method': 'label-danger', |
||
539 | '_': 'label-warning' |
||
540 | }; |
||
541 | |||
542 | var searchIndex = [ |
||
543 | {% block search_index %} |
||
544 | {% from _self import add_class_methods_index %} |
||
545 | |||
546 | {% for ns in namespaces -%} |
||
547 | {\"type\": \"Namespace\", \"link\": \"{{ namespace_path(ns) }}\", \"name\": \"{{ ns|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"doc\": \"Namespace {{ ns|replace({'\\\\': '\\\\\\\\'})|raw }}\"}, |
||
548 | {%- endfor %} |
||
549 | |||
550 | {% for class in interfaces -%} |
||
551 | {\"type\": \"Interface\", {% if class.namespace %}\"fromName\": \"{{ class.namespace|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"fromLink\": \"{{ namespace_path(class.namespace)|raw }}\",{% endif %} \"link\": \"{{ class_path(class) }}\", \"name\": \"{{ class.name|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"doc\": \"{{ class.shortdesc|desc(class)|json_encode }}\"}, |
||
552 | {{ add_class_methods_index(class) }} |
||
553 | {% endfor %} |
||
554 | |||
555 | {% for class in classes -%} |
||
556 | {\"type\": {% if class.isTrait %}\"Trait\"{% else %}\"Class\"{% endif %}, {% if class.namespace %}\"fromName\": \"{{ class.namespace|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"fromLink\": \"{{ namespace_path(class.namespace) }}\",{% endif %} \"link\": \"{{ class_path(class) }}\", \"name\": \"{{ class.name|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"doc\": \"{{ class.shortdesc|desc(class)|json_encode }}\"}, |
||
557 | {{ add_class_methods_index(class) }} |
||
558 | {% endfor %} |
||
559 | |||
560 | {# Override this block, search_index_extra, to add custom search entries! #} |
||
561 | {% block search_index_extra '' %} |
||
562 | {% endblock %} |
||
563 | // Fix trailing commas in the index |
||
564 | {} |
||
565 | ]; |
||
566 | |||
567 | /** Tokenizes strings by namespaces and functions */ |
||
568 | function tokenizer(term) { |
||
569 | if (!term) { |
||
570 | return []; |
||
571 | } |
||
572 | |||
573 | var tokens = [term]; |
||
574 | var meth = term.indexOf('::'); |
||
575 | |||
576 | // Split tokens into methods if \"::\" is found. |
||
577 | if (meth > -1) { |
||
578 | tokens.push(term.substr(meth + 2)); |
||
579 | term = term.substr(0, meth - 2); |
||
580 | } |
||
581 | |||
582 | // Split by namespace or fake namespace. |
||
583 | if (term.indexOf('\\\\') > -1) { |
||
584 | tokens = tokens.concat(term.split('\\\\')); |
||
585 | } else if (term.indexOf('_') > 0) { |
||
586 | tokens = tokens.concat(term.split('_')); |
||
587 | } |
||
588 | |||
589 | // Merge in splitting the string by case and return |
||
590 | tokens = tokens.concat(term.match(/(([A-Z]?[^A-Z]*)|([a-z]?[^a-z]*))/g).slice(0,-1)); |
||
591 | |||
592 | return tokens; |
||
593 | }; |
||
594 | |||
595 | root.Sami = { |
||
596 | /** |
||
597 | * Cleans the provided term. If no term is provided, then one is |
||
598 | * grabbed from the query string \"search\" parameter. |
||
599 | */ |
||
600 | cleanSearchTerm: function(term) { |
||
601 | // Grab from the query string |
||
602 | if (typeof term === 'undefined') { |
||
603 | var name = 'search'; |
||
604 | var regex = new RegExp(\"[\\\\?&]\" + name + \"=([^&#]*)\"); |
||
605 | var results = regex.exec(location.search); |
||
606 | if (results === null) { |
||
607 | return null; |
||
608 | } |
||
609 | term = decodeURIComponent(results[1].replace(/\\+/g, \" \")); |
||
610 | } |
||
611 | |||
612 | return term.replace(/<(?:.|\\n)*?>/gm, ''); |
||
613 | }, |
||
614 | |||
615 | /** Searches through the index for a given term */ |
||
616 | search: function(term) { |
||
617 | // Create a new search index if needed |
||
618 | if (!bhIndex) { |
||
619 | bhIndex = new Bloodhound({ |
||
620 | limit: 500, |
||
621 | local: searchIndex, |
||
622 | datumTokenizer: function (d) { |
||
623 | return tokenizer(d.name); |
||
624 | }, |
||
625 | queryTokenizer: Bloodhound.tokenizers.whitespace |
||
626 | }); |
||
627 | bhIndex.initialize(); |
||
628 | } |
||
629 | |||
630 | results = []; |
||
631 | bhIndex.get(term, function(matches) { |
||
632 | results = matches; |
||
633 | }); |
||
634 | |||
635 | if (!rootPath) { |
||
636 | return results; |
||
637 | } |
||
638 | |||
639 | // Fix the element links based on the current page depth. |
||
640 | return \$.map(results, function(ele) { |
||
641 | if (ele.link.indexOf('..') > -1) { |
||
642 | return ele; |
||
643 | } |
||
644 | ele.link = rootPath + ele.link; |
||
645 | if (ele.fromLink) { |
||
646 | ele.fromLink = rootPath + ele.fromLink; |
||
647 | } |
||
648 | return ele; |
||
649 | }); |
||
650 | }, |
||
651 | |||
652 | /** Get a search class for a specific type */ |
||
653 | getSearchClass: function(type) { |
||
654 | return searchTypeClasses[type] || searchTypeClasses['_']; |
||
655 | }, |
||
656 | |||
657 | /** Add the left-nav tree to the site */ |
||
658 | injectApiTree: function(ele) { |
||
659 | ele.html(treeHtml); |
||
660 | } |
||
661 | }; |
||
662 | |||
663 | \$(function() { |
||
664 | // Modify the HTML to work correctly based on the current depth |
||
665 | rootPath = \$('body').attr('data-root-path'); |
||
666 | treeHtml = treeHtml.replace(/href=\"/g, 'href=\"' + rootPath); |
||
667 | Sami.injectApiTree(\$('#api-tree')); |
||
668 | }); |
||
669 | |||
670 | return root.Sami; |
||
671 | })(window); |
||
672 | |||
673 | \$(function() { |
||
674 | |||
675 | // Enable the version switcher |
||
676 | \$('#version-switcher').change(function() { |
||
677 | window.location = \$(this).val() |
||
678 | }); |
||
679 | |||
680 | {% block treejs %} |
||
681 | |||
682 | // Toggle left-nav divs on click |
||
683 | \$('#api-tree .hd span').click(function() { |
||
684 | \$(this).parent().parent().toggleClass('opened'); |
||
685 | }); |
||
686 | |||
687 | // Expand the parent namespaces of the current page. |
||
688 | var expected = \$('body').attr('data-name'); |
||
689 | |||
690 | if (expected) { |
||
691 | // Open the currently selected node and its parents. |
||
692 | var container = \$('#api-tree'); |
||
693 | var node = \$('#api-tree li[data-name=\"' + expected + '\"]'); |
||
694 | // Node might not be found when simulating namespaces |
||
695 | if (node.length > 0) { |
||
696 | node.addClass('active').addClass('opened'); |
||
697 | node.parents('li').addClass('opened'); |
||
698 | var scrollPos = node.offset().top - container.offset().top + container.scrollTop(); |
||
699 | // Position the item nearer to the top of the screen. |
||
700 | scrollPos -= 200; |
||
701 | container.scrollTop(scrollPos); |
||
702 | } |
||
703 | } |
||
704 | |||
705 | {% endblock %} |
||
706 | |||
707 | {% verbatim %} |
||
708 | var form = \$('#search-form .typeahead'); |
||
709 | form.typeahead({ |
||
710 | hint: true, |
||
711 | highlight: true, |
||
712 | minLength: 1 |
||
713 | }, { |
||
714 | name: 'search', |
||
715 | displayKey: 'name', |
||
716 | source: function (q, cb) { |
||
717 | cb(Sami.search(q)); |
||
718 | } |
||
719 | }); |
||
720 | |||
721 | // The selection is direct-linked when the user selects a suggestion. |
||
722 | form.on('typeahead:selected', function(e, suggestion) { |
||
723 | window.location = suggestion.link; |
||
724 | }); |
||
725 | |||
726 | // The form is submitted when the user hits enter. |
||
727 | form.keypress(function (e) { |
||
728 | if (e.which == 13) { |
||
729 | \$('#search-form').submit(); |
||
730 | return true; |
||
731 | } |
||
732 | }); |
||
733 | |||
734 | {% endverbatim %} |
||
735 | }); |
||
736 | |||
737 | {% macro add_class_methods_index(class) %} |
||
738 | {% if class.methods %} |
||
739 | {% set from_name = class.name|replace({'\\\\': '\\\\\\\\'}) %} |
||
740 | {% set from_link = class_path(class) %} |
||
741 | {% for meth in class.methods %} |
||
742 | {\"type\": \"Method\", \"fromName\": \"{{ from_name|raw }}\", \"fromLink\": \"{{ from_link|raw }}\", \"link\": \"{{ method_path(meth) }}\", \"name\": \"{{ meth|replace({'\\\\': '\\\\\\\\'})|raw }}\", \"doc\": \"{{ meth.shortdesc|desc(class)|json_encode }}\"}, |
||
743 | {% endfor %} |
||
744 | {% endif %} |
||
745 | {% endmacro %} |
||
746 | |||
747 | {% macro element(tree, opened, depth) %} |
||
748 | {% from _self import element %} |
||
749 | |||
750 | <ul> |
||
751 | {%- for element in tree -%} |
||
752 | {% if element[2] %} |
||
753 | <li data-name=\"namespace:{{ element[1]|replace({'\\\\': '_'})|raw }}\" {% if depth < opened %}class=\"opened\"{% endif %}> |
||
754 | <div style=\"padding-left:{{ (depth * 18)|raw }}px\" class=\"hd\"> |
||
755 | <span class=\"glyphicon glyphicon-play\"></span>{% if not project.config('simulate_namespaces') %}<a href=\"{{ namespace_path(element[1]) }}\">{% endif %}{{ element[0]|raw }}{% if not project.config('simulate_namespaces') %}</a>{% endif %} |
||
756 | </div> |
||
757 | <div class=\"bd\"> |
||
758 | {{ element(element[2], opened, depth + 1) -}} |
||
759 | </div> |
||
760 | </li> |
||
761 | {% else %} |
||
762 | <li data-name=\"class:{{ (element[1].name)|replace({'\\\\': '_'}) }}\" {% if depth < opened %}class=\"opened\"{% endif %}> |
||
763 | <div style=\"padding-left:{{ 8 + (depth * 18) }}px\" class=\"hd leaf\"> |
||
764 | <a href=\"{{ class_path(element[1]) }}\">{{ element[0] }}</a> |
||
765 | </div> |
||
766 | </li> |
||
767 | {% endif %} |
||
768 | {%- endfor %} |
||
769 | </ul> |
||
770 | {% endmacro %} |
||
771 | ", "sami.js.twig", "phar:///Users/bobby/Dropbox/Sites/OpenSource/Slackify/sami.phar/Sami/Resources/themes/default/sami.js.twig"); |
||
772 | } |
||
773 | } |
||
774 |