init
[mdref/mdref] / public / index.js
1 function log() {
2 // console.log.apply(console, arguments);
3 }
4
5 function is_constant(s) {
6 s = s.replace(/v\d+(_\d+)?$/, "");
7 if (s.length < 2) {
8 return false;
9 }
10 return s.toUpperCase(s) === s;
11 }
12
13 function is_variable(s) {
14 return s.substring(0,1) === "$";
15 }
16
17 var is_in_string = false;
18
19 function type(s, nn) {
20 var i, j, t;
21 //log("type", s);
22 // nothing
23 if (!s.match(/[a-zA-Z]/)) {
24 return;
25 }
26
27 switch (s) {
28 // types
29 case "void":
30 case "bool":
31 case "int":
32 case "float":
33 case "string":
34 case "resource":
35 case "array":
36 case "object":
37 case "callable":
38 case "mixed":
39 // Zend/SPL
40 case "stdClass":
41 case "Exception":
42 case "ErrorException":
43 case "RuntimeException":
44 case "UnexpectedValueException":
45 case "DomainException":
46 case "InvalidArgumentException":
47 case "BadMethodCallException":
48 case "Closure":
49 case "Generator":
50 case "Countable":
51 case "Serializable":
52 case "Traversable":
53 case "Iterator":
54 case "IteratorAggregate":
55 case "ArrayAccess":
56 case "ArrayObject":
57 case "ArrayIterator":
58 case "RecursiveArrayIterator":
59 case "SplObserver":
60 case "SplSubject":
61 case "SplObjectStorage":
62 return "<code>";
63
64 // keywords
65 case "is":
66 if (nn !== "H1") {
67 return;
68 }
69 case "extends":
70 case "implements":
71 if (nn === "H1") {
72 return "<br>&nbsp;<em>";
73 }
74 case "class":
75 case "interface":
76 case "namespace":
77 case "public":
78 case "protected":
79 case "private":
80 case "static":
81 case "final":
82 case "abstract":
83 case "self":
84 case "parent":
85 // phrases
86 case "Optional":
87 case "optional":
88 return "<em>";
89 }
90
91 // class members
92 if (-1 !== (i = s.indexOf("::"))) {
93 t = s.substring(i+2);
94 if (!is_constant(t) && !is_variable(t)) {
95 // methods
96 return "<a href=\"" + s.replace(/::|\\/g, "/") + "\">";
97 }
98 }
99 if (-1 !== (j = s.indexOf("\\")) && s.substr(j+1,1) !== "n") {
100 return "<a href=\"" + s.replace(/\\/g, "/").replace(/::|$/, "#") + "\">";
101 }
102
103 switch (s.toLowerCase()) {
104 // variables
105 default:
106 if (!is_variable(s)) {
107 break;
108 }
109 // special constants
110 case "null":
111 case "true":
112 case "false":
113 return "<span class=\"var\">";
114 }
115
116 // constants
117 if (is_constant(s)) {
118 return "<span class=\"constant\">";
119 }
120 }
121
122 function node(s, nn) {
123 //log("node", s);
124
125 var t;
126
127 if ((t = type(s, nn))) {
128 return $(t).text(s);
129 }
130 return document.createTextNode(s);
131 }
132 function wrap(n, nn) {
133 var $n = $(n)
134 var a = [];
135
136 $n.text().split(/([^a-zA-Z0-9_\\\$:]+)/).forEach(function(v) {
137 a.push(node(v, nn));
138 });
139 $n.replaceWith(a);
140 }
141 function walk(i, e) {
142 log("walk", i, e);
143
144 $.each($.makeArray(e.childNodes), function(i, n) {
145 switch (n.nodeName) {
146 case "A":
147 case "BR":
148 case "HR":
149 break;
150 case "#text":
151 wrap(n, e.nodeName);
152 break;
153 default:
154 walk(-1, n);
155 break;
156 }
157 });
158 }
159
160 function blink(c) {
161 var $c = $(c);
162
163 $c.fadeOut("fast").queue(function(next) {
164 this.style.color = "red";
165 next();
166 }).fadeIn("fast").fadeOut("slow").queue(function(next) {
167 this.style.color = "";
168 next();
169 }).fadeIn("slow");
170 }
171
172 function hashchange() {
173 if (location.hash.length > 1) {
174 var hash = location.hash.substring(1);
175 var name = is_variable(hash) ? ".var" : ".constant";
176 var scrolled = false;
177
178 $(name).each(hash.substring(hash.length-1) === "_" ? function(i, c) {
179 if (c.textContent.substring(0, hash.length) === hash) {
180 if (!scrolled) {
181 $(window).scrollTop($(c).offset().top - 100);
182 scrolled = true;
183 }
184 blink(c);
185 }
186 } : function(i, c) {
187 if (c.textContent === hash) {
188 $(window).scrollTop($(c).offset().top - 100);
189 blink(c);
190 return false;
191 }
192 });
193 }
194 }
195
196 $(function() {
197 $("h1,h2,h3,h4,h5,h6,p,li,code").each(walk);
198 $(window).on("hashchange", hashchange);
199 hashchange();
200 });