Verzeichnisstruktur phpBB-3.2.0
- Veröffentlicht
- 06.01.2017
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
render.js
001 var MSXML = (typeof DOMParser === 'undefined' || typeof XSLTProcessor === 'undefined');
002 var xslt = {
003 /**
004 * @param {!string} xsl
005 */
006 init: function(xsl)
007 {
008 var stylesheet = xslt.loadXML(xsl, 'MSXML2.FreeThreadedDOMDocument.6.0');
009 if (MSXML)
010 {
011 var generator = new ActiveXObject("MSXML2.XSLTemplate.6.0");
012 generator['stylesheet'] = stylesheet;
013 xslt.proc = generator['createProcessor']();
014 }
015 else
016 {
017 xslt.proc = new XSLTProcessor;
018 xslt.proc['importStylesheet'](stylesheet);
019 }
020 },
021
022 /**
023 * @param {!string} xml
024 * @param {string} type
025 */
026 loadXML: function(xml, type)
027 {
028 if (MSXML)
029 {
030 var dom = new ActiveXObject(type);
031 dom['async'] = false;
032 dom['validateOnParse'] = false;
033 dom['loadXML'](xml);
034
035 return dom;
036 }
037
038 return (new DOMParser).parseFromString(xml, 'text/xml');
039 },
040
041 /**
042 * @param {!string} paramName Parameter name
043 * @param {!string} paramValue Parameter's value
044 */
045 setParameter: function(paramName, paramValue)
046 {
047 if (MSXML)
048 {
049 xslt.proc['addParameter'](paramName, paramValue, '');
050 }
051 else
052 {
053 xslt.proc['setParameter'](null, paramName, paramValue);
054 }
055 },
056
057 /**
058 * @param {!string} xml
059 * @param {!HTMLDocument} targetDoc
060 */
061 transformToFragment: function(xml, targetDoc)
062 {
063 if (MSXML)
064 {
065 var div = targetDoc.createElement('div'),
066 fragment = targetDoc.createDocumentFragment();
067
068 xslt.proc['input'] = xslt.loadXML(xml, 'MSXML2.DOMDocument.6.0');
069 xslt.proc['transform']();
070 div.innerHTML = xslt.proc['output'];
071 while (div.firstChild)
072 {
073 fragment.appendChild(div.removeChild(div.firstChild));
074 }
075
076 return fragment;
077 }
078
079 // NOTE: importNode() is used because of https://code.google.com/p/chromium/issues/detail?id=266305
080 return targetDoc.importNode(xslt.proc['transformToFragment'](xslt.loadXML(xml), targetDoc), true);
081 }
082 }
083 xslt.init(xsl);
084
085 var postProcessFunctions = {};
086
087 /**
088 * Parse a given text and render it into given HTML element
089 *
090 * @param {!string} text
091 * @param {!HTMLElement} target
092 */
093 function preview(text, target)
094 {
095 var targetDoc = target.ownerDocument,
096 resultFragment = xslt.transformToFragment(parse(text), targetDoc);
097
098 // Apply post-processing
099 if (HINT.postProcessing)
100 {
101 var nodes = resultFragment['querySelectorAll']('[data-s9e-livepreview-postprocess]'),
102 i = nodes.length;
103 while (--i >= 0)
104 {
105 /** @type {!string} */
106 var code = nodes[i]['getAttribute']('data-s9e-livepreview-postprocess');
107
108 if (!postProcessFunctions[code])
109 {
110 postProcessFunctions[code] = new Function(code);
111 }
112
113 postProcessFunctions[code]['call'](nodes[i]);
114 }
115 }
116
117 /**
118 * Update the content of given element oldEl to match element newEl
119 *
120 * @param {!HTMLElement} oldEl
121 * @param {!HTMLElement} newEl
122 */
123 function refreshElementContent(oldEl, newEl)
124 {
125 var oldNodes = oldEl.childNodes,
126 newNodes = newEl.childNodes,
127 oldCnt = oldNodes.length,
128 newCnt = newNodes.length,
129 oldNode,
130 newNode,
131 left = 0,
132 right = 0;
133
134 // Skip the leftmost matching nodes
135 while (left < oldCnt && left < newCnt)
136 {
137 oldNode = oldNodes[left];
138 newNode = newNodes[left];
139
140 if (!refreshNode(oldNode, newNode))
141 {
142 break;
143 }
144
145 ++left;
146 }
147
148 // Skip the rightmost matching nodes
149 var maxRight = Math.min(oldCnt - left, newCnt - left);
150
151 while (right < maxRight)
152 {
153 oldNode = oldNodes[oldCnt - (right + 1)];
154 newNode = newNodes[newCnt - (right + 1)];
155
156 if (!refreshNode(oldNode, newNode))
157 {
158 break;
159 }
160
161 ++right;
162 }
163
164 // Clone the new nodes
165 var newNodesFragment = targetDoc.createDocumentFragment(),
166 i = left;
167
168 while (i < (newCnt - right))
169 {
170 newNode = newNodes[i].cloneNode(true);
171
172 newNodesFragment.appendChild(newNode);
173 ++i;
174 }
175
176 // Remove the old dirty nodes in the middle of the tree
177 i = oldCnt - right;
178 while (--i >= left)
179 {
180 oldEl.removeChild(oldNodes[i]);
181 }
182
183 // If we haven't skipped any nodes to the right, we can just append the fragment
184 if (!right)
185 {
186 oldEl.appendChild(newNodesFragment);
187 }
188 else
189 {
190 oldEl.insertBefore(newNodesFragment, oldEl.childNodes[left]);
191 }
192 }
193
194 /**
195 * Update given node oldNode to make it match newNode
196 *
197 * @param {!HTMLElement} oldNode
198 * @param {!HTMLElement} newNode
199 * @return boolean Whether the node can be skipped
200 */
201 function refreshNode(oldNode, newNode)
202 {
203 if (oldNode.nodeName !== newNode.nodeName
204 || oldNode.nodeType !== newNode.nodeType)
205 {
206 return false;
207 }
208
209 // Node.TEXT_NODE || Node.COMMENT_NODE
210 if (oldNode.nodeType === 3 || oldNode.nodeType === 8)
211 {
212 if (oldNode.nodeValue !== newNode.nodeValue)
213 {
214 oldNode.nodeValue = newNode.nodeValue;
215 }
216
217 return true;
218 }
219
220 if (oldNode.isEqualNode && oldNode.isEqualNode(newNode))
221 {
222 return true;
223 }
224
225 syncElementAttributes(oldNode, newNode);
226 refreshElementContent(oldNode, newNode);
227
228 return true;
229 }
230
231 /**
232 * Make the set of attributes of given element oldEl match newEl's
233 *
234 * @param {!HTMLElement} oldEl
235 * @param {!HTMLElement} newEl
236 */
237 function syncElementAttributes(oldEl, newEl)
238 {
239 var oldAttributes = oldEl['attributes'],
240 newAttributes = newEl['attributes'],
241 oldCnt = oldAttributes.length,
242 newCnt = newAttributes.length,
243 i = oldCnt;
244
245 while (--i >= 0)
246 {
247 var oldAttr = oldAttributes[i],
248 namespaceURI = oldAttr['namespaceURI'],
249 attrName = oldAttr['name'];
250
251 if (!newEl.hasAttributeNS(namespaceURI, attrName))
252 {
253 oldEl.removeAttributeNS(namespaceURI, attrName);
254 }
255 }
256
257 i = newCnt;
258 while (--i >= 0)
259 {
260 var newAttr = newAttributes[i],
261 namespaceURI = newAttr['namespaceURI'],
262 attrName = newAttr['name'],
263 attrValue = newAttr['value'];
264
265 if (attrValue !== oldEl.getAttributeNS(namespaceURI, attrName))
266 {
267 oldEl.setAttributeNS(namespaceURI, attrName, attrValue);
268 }
269 }
270 }
271
272 refreshElementContent(target, resultFragment);
273 }
274
275 /**
276 * Set the value of a stylesheet parameter
277 *
278 * @param {!string} paramName Parameter name
279 * @param {!string} paramValue Parameter's value
280 */
281 function setParameter(paramName, paramValue)
282 {
283 xslt.setParameter(paramName, paramValue);
284 }