PageSourceSearch

https://www.tulln.at/typo3conf/ext/tulln/Resources/Public/JavaScript/shims.js?1712149715

js tulln.at collected 2026-10-02 06:58:13 UTC 7,670 bytes, 197 lines download raw bytes

1'use strict';
2
3// js2016-10-25
4
5/**
6 * Part 1:
7 * Enable proper operation of <details> tags in unsupportive browsers (IE/Edge)
8
9 * based on details-shim.js from (c) 2013 Tyler Uebele, under the MIT license
10 */
11
12var dbgShim={
13      details: true
14    };
15
16// utils ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
17
18function _tagname (e) { return e.tagName.toLowerCase(); }
19
20function _ins_css (id, stylestr)
21{ //var stylesheet=document.styleSheets[0];
22  var stylesheet=document.getElementById(id);
23  if (!stylesheet)
24  { stylesheet=document.createElement('style');
25    stylesheet.id=id;
26    stylesheet.type='text/css';
27    // stylesheet.appendChild(document.createTextNode(stylestr));
28    document.head.appendChild(stylesheet);
29  }
30  if (dbgShim.details) console.log(document.styleSheets);
31  if (dbgShim.details) console.log(stylesheet, stylestr);
32  //stylesheet.insertRule(stylestr, 0/*stylesheet.cssRules.length*/);
33  stylesheet.innerHTML=stylestr;
34}
35
36function _add_event (el,evname,fun, xtra)
37{ var args = Array.prototype.slice.call(arguments, 1);
38  el.addEventListener ? el.addEventListener.apply(el,args)
39                      : el.attachEvent && el.attachEvent('on' + evname, fun)
40}
41
42function _foreach (es, fun) { return Array.prototype.forEach.call(es,fun) }
43
44// forward for namespace ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
45
46/**
47 * Enable proper operation of <details> tags in unsupportive browsers
48 *
49 * @param Details details element to shim
50 * @returns {boolean} false on error
51 */
52function details_shim (Details) { return details_shim.shim(Details); }
53
54// helper ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
55
56details_shim.test_native = function (e) // _test_native_support
57{ if ('boolean' == typeof details_shim.native_support) return details_shim.native_support;
58  var details=e || document.createElement('details');
59  details_shim.native_support = 'boolean' == typeof details.open;
60  if (dbgShim.details) //console.log('details_shim.test_native:', details, details_shim.native_support);
61  return details_shim.native_support;
62}
63
64details_shim.ins_css = function ()
65{ _ins_css('detailshim',
66  'details { display: block; }\
67   details[data-shim] > summary { display: block; } /* list-item dont interfere */\
68   details[data-shim="closed"] > * { display: none;}\
69   details[data-shim="closed"] > summary { display: block; }\
70   details[data-shim="open"]   > summary { display: block; }\
71   details[data-shim] > summary::before { display: inline-block; padding: 0; }\
72   details[data-shim="closed"] > summary::before\
73       { content: "\\25b6"; padding: 0 0.1em; margin-right: 0.4em; font-size: 0.9em;}\
74   details[data-shim="open"]   > summary::before { content: "\\25bc"; margin-right: 0.35em;}');
75}
76
77// details shim ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
78
79details_shim.shim = function (Details)
80{
81    // For backward compatibility, if no DOM Element is sent, call init()
82    if (!Details || !('nodeType' in Details) || !('tagName' in Details))
83        return details_shim.init();
84
85    var Summary;
86    // If we were passed a details tag, find its summary tag
87    if ('details' == _tagname(Details)) {
88        // Assume first found summary tag is the corresponding summary tag
89        Summary = Details.getElementsByTagName('summary')[0];
90
91    // If we were passed a summary tag, find its details tag
92    } else if (!!Details.parentNode && 'summary' == _tagname(Details)) {
93        Summary = Details;
94        Details = Summary.parentNode;
95    } else {
96        // An invalid parameter was passed for Details
97        return false;
98    }
99
100    // If the details tag is natively supported or already shimmed
101    if (details_shim.test_native(Details)
102        || Details.getAttribute('data-shim') // ???
103       ) return false;
104
105    // Set initial class according to `open` attribute
106    var state = Details.outerHTML;
107        // OR older firefox doesn't have .outerHTML
108        // || new XMLSerializer().serializeToString(Details);
109    state = state.substring(0, state.indexOf('>'));
110    // Read: There is an open attribute, and it's not explicitly empty
111    state = (-1 != state.indexOf('open') && -1 == state.indexOf('open=""'))
112            ? 'open' : 'closed';
113
114    Details.setAttribute('data-shim', state); // TODO: last?
115
116    // make it focusable
117    if (!Summary.getAttribute('tabindex')) Summary.setAttribute('tabindex',0);
118
119    // Add onclick handler to toggle visibility class
120    _add_event(Summary,'click', function () { details_shim.toggle(Details); });
121    _add_event(Summary,'keydown',function (ev) {
122       if (dbgShim.details) console.log('detailshim key-event:',ev);
123       if (ev.key=='Enter' || ev.keyCode==13 || ev.key==' ' || ev.charCode==32) 
124          { details_shim.toggle(Details); ev.preventDefault(); }
125    });
126
127    Object.defineProperty(Details, 'open', {
128        get: function() {
129            return 'open' == this.getAttribute('data-shim');
130        },
131        set: function(state) {
132            details_shim.toggle(this, state);
133        }
134    });
135
136    // wrap text nodes in span to expose them to css
137    _foreach(Details.childNodes, function (n) {
138       if (n.nodeType == 3 && /[^\s]/.test(n.data)) // non-empty textnode
139       { var span = document.createElement('span');
140         Details.insertBefore(span, n);
141         Details.removeChild(n);
142         span.appendChild(n);
143       }
144    });
145} // end of details_shim()
146
147/**
148 * Toggle the open state of specified <details> tag
149 * @param Details The <details> tag to toggle
150 * @param state   Optional override state
151 */
152details_shim.toggle = function(Details, state) {
153    var oldstate = Details.getAttribute('data-shim');
154    // If state was not passed, seek current state
155    if ('undefined' === typeof state) {
156        // new state
157        state = oldstate=='open' ? 'closed' : 'open';
158    } else {
159        // Sanitize the input, expect boolean, force string
160        // Expecting boolean means even 'closed' will result in an open
161        // This is the behavior of the natively supportive browsers
162        state = !!state ? 'open' : 'closed';
163    }
164
165    // replace previous open/close state
166    if (state != oldstate) // 1st defense line against recurrent recall
167    { Details.setAttribute('data-shim', state);
168      try {
169        var ie8=!document.addEventListener; // 2nd defense line, more specific
170        if (state == 'open')
171             ie8 ? Details.setAttribute('OPEN', state, 1) : Details.setAttribute('open', state);
172        else ie8 ? Details.removeAttribute('OPEN', 1)     : Details.removeAttribute('open');
173      } catch (x) {}
174   }
175   if (dbgShim.details) console.log('details_shim.toggle: ', Details, state);
176   // TODO: Allow Links inside <summary>
177};
178
179/**
180 * Run details_shim() on each details tag
181 */
182details_shim.init = function() {
183    // untrue: Because <details> must include a <summary>,
184    //      collecting <summary> tags collects *valid* <details> tags
185    // but: for our purpose we just assume every <details> has
186    //      exactly one <summary>.
187    // also we ignore "future content",
188    //      the possibility to inject DOM per JavaScript
189    if (details_shim.test_native()) return;
190    var Summaries = document.getElementsByTagName('summary');
191    if (Summaries.length == 0) return;
192    details_shim.ins_css();
193    for (var i=0; i<Summaries.length; ++i) { details_shim.shim(Summaries[i]); }
194};
195
196// Run details_shim.init() when the page loads
197_add_event(window,'load',details_shim.init, false);

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.