PageSourceSearch

https://te4.org/misc/drupal.js?8

js te4.org collected 2026-10-04 00:28:29 UTC 13,958 bytes, 421 lines download raw bytes

1
2/**
3 * Override jQuery.fn.init to guard against XSS attacks.
4 *
5 * See http://bugs.jquery.com/ticket/9521
6 */
7(function () {
8  var jquery_init = jQuery.fn.init;
9  jQuery.fn.init = function (selector, context, rootjQuery) {
10    // If the string contains a "#" before a "<", treat it as invalid HTML.
11    if (selector && typeof selector === 'string') {
12      var hash_position = selector.indexOf('#');
13      if (hash_position >= 0) {
14        var bracket_position = selector.indexOf('<');
15        if (bracket_position > hash_position) {
16          throw 'Syntax error, unrecognized expression: ' + selector;
17        }
18      }
19    }
20    return jquery_init.call(this, selector, context, rootjQuery);
21  };
22  jQuery.fn.init.prototype = jquery_init.prototype;
23
24  /**
25   * Pre-filter Ajax requests to guard against XSS attacks.
26   *
27   * See https://github.com/jquery/jquery/issues/2432
28   */
29  if ($.ajaxPrefilter) {
30    // For newer versions of jQuery, use an Ajax prefilter to prevent
31    // auto-executing script tags from untrusted domains. This is similar to the
32    // fix that is built in to jQuery 3.0 and higher.
33    $.ajaxPrefilter(function (s) {
34      if (s.crossDomain) {
35        s.contents.script = false;
36      }
37    });
38  }
39  else if ($.httpData) {
40    // For the version of jQuery that ships with Drupal core, override
41    // jQuery.httpData to prevent auto-detecting "script" data types from
42    // untrusted domains.
43    var jquery_httpData = $.httpData;
44    $.httpData = function (xhr, type, s) {
45      // @todo Consider backporting code from newer jQuery versions to check for
46      //   a cross-domain request here, rather than using Drupal.urlIsLocal() to
47      //   block scripts from all URLs that are not on the same site.
48      if (!type && (!s || !Drupal.urlIsLocal(s.url))) {
49        var content_type = xhr.getResponseHeader('content-type') || '';
50        if (content_type.indexOf('javascript') >= 0) {
51          // Default to a safe data type.
52          type = 'text';
53        }
54      }
55      return jquery_httpData.call(this, xhr, type, s);
56    };
57    $.httpData.prototype = jquery_httpData.prototype;
58  }
59})();
60
61var Drupal = Drupal || { 'settings': {}, 'behaviors': {}, 'themes': {}, 'locale': {} };
62
63/**
64 * Set the variable that indicates if JavaScript behaviors should be applied
65 */
66Drupal.jsEnabled = document.getElementsByTagName && document.createElement && document.createTextNode && document.documentElement && document.getElementById;
67
68/**
69 * Attach all registered behaviors to a page element.
70 *
71 * Behaviors are event-triggered actions that attach to page elements, enhancing
72 * default non-Javascript UIs. Behaviors are registered in the Drupal.behaviors
73 * object as follows:
74 * @code
75 *    Drupal.behaviors.behaviorName = function () {
76 *      ...
77 *    };
78 * @endcode
79 *
80 * Drupal.attachBehaviors is added below to the jQuery ready event and so
81 * runs on initial page load. Developers implementing AHAH/AJAX in their
82 * solutions should also call this function after new page content has been
83 * loaded, feeding in an element to be processed, in order to attach all
84 * behaviors to the new content.
85 *
86 * Behaviors should use a class in the form behaviorName-processed to ensure
87 * the behavior is attached only once to a given element. (Doing so enables
88 * the reprocessing of given elements, which may be needed on occasion despite
89 * the ability to limit behavior attachment to a particular element.)
90 *
91 * @param context
92 *   An element to attach behaviors to. If none is given, the document element
93 *   is used.
94 */
95Drupal.attachBehaviors = function(context) {
96  context = context || document;
97  if (Drupal.jsEnabled) {
98    // Execute all of them.
99    jQuery.each(Drupal.behaviors, function() {
100      this(context);
101    });
102  }
103};
104
105/**
106 * Encode special characters in a plain-text string for display as HTML.
107 */
108Drupal.checkPlain = function(str) {
109  str = String(str);
110  var replace = { '&': '&amp;', "'": '&#39;', '"': '&quot;', '<': '&lt;', '>': '&gt;' };
111  for (var character in replace) {
112    var regex = new RegExp(character, 'g');
113    str = str.replace(regex, replace[character]);
114  }
115  return str;
116};
117
118/**
119 * Translate strings to the page language or a given language.
120 *
121 * See the documentation of the server-side t() function for further details.
122 *
123 * @param str
124 *   A string containing the English string to translate.
125 * @param args
126 *   An object of replacements pairs to make after translation. Incidences
127 *   of any key in this array are replaced with the corresponding value.
128 *   Based on the first character of the key, the value is escaped and/or themed:
129 *    - !variable: inserted as is
130 *    - @variable: escape plain text to HTML (Drupal.checkPlain)
131 *    - %variable: escape text and theme as a placeholder for user-submitted
132 *      content (checkPlain + Drupal.theme('placeholder'))
133 * @return
134 *   The translated string.
135 */
136Drupal.t = function(str, args) {
137  // Fetch the localized version of the string.
138  if (Drupal.locale.strings && Drupal.locale.strings[str]) {
139    str = Drupal.locale.strings[str];
140  }
141
142  if (args) {
143    // Transform arguments before inserting them
144    for (var key in args) {
145      switch (key.charAt(0)) {
146        // Escaped only
147        case '@':
148          args[key] = Drupal.checkPlain(args[key]);
149        break;
150        // Pass-through
151        case '!':
152          break;
153        // Escaped and placeholder
154        case '%':
155        default:
156          args[key] = Drupal.theme('placeholder', args[key]);
157          break;
158      }
159      str = str.replace(key, args[key]);
160    }
161  }
162  return str;
163};
164
165/**
166 * Format a string containing a count of items.
167 *
168 * This function ensures that the string is pluralized correctly. Since Drupal.t() is
169 * called by this function, make sure not to pass already-localized strings to it.
170 *
171 * See the documentation of the server-side format_plural() function for further details.
172 *
173 * @param count
174 *   The item count to display.
175 * @param singular
176 *   The string for the singular case. Please make sure it is clear this is
177 *   singular, to ease translation (e.g. use "1 new comment" instead of "1 new").
178 *   Do not use @count in the singular string.
179 * @param plural
180 *   The string for the plural case. Please make sure it is clear this is plural,
181 *   to ease translation. Use @count in place of the item count, as in "@count
182 *   new comments".
183 * @param args
184 *   An object of replacements pairs to make after translation. Incidences
185 *   of any key in this array are replaced with the corresponding value.
186 *   Based on the first character of the key, the value is escaped and/or themed:
187 *    - !variable: inserted as is
188 *    - @variable: escape plain text to HTML (Drupal.checkPlain)
189 *    - %variable: escape text and theme as a placeholder for user-submitted
190 *      content (checkPlain + Drupal.theme('placeholder'))
191 *   Note that you do not need to include @count in this array.
192 *   This replacement is done automatically for the plural case.
193 * @return
194 *   A translated string.
195 */
196Drupal.formatPlural = function(count, singular, plural, args) {
197  var args = args || {};
198  args['@count'] = count;
199  // Determine the index of the plural form.
200  var index = Drupal.locale.pluralFormula ? Drupal.locale.pluralFormula(args['@count']) : ((args['@count'] == 1) ? 0 : 1);
201
202  if (index == 0) {
203    return Drupal.t(singular, args);
204  }
205  else if (index == 1) {
206    return Drupal.t(plural, args);
207  }
208  else {
209    args['@count['+ index +']'] = args['@count'];
210    delete args['@count'];
211    return Drupal.t(plural.replace('@count', '@count['+ index +']'), args);
212  }
213};
214
215/**
216 * Returns the passed in URL as an absolute URL.
217 *
218 * @param url
219 *   The URL string to be normalized to an absolute URL.
220 *
221 * @return
222 *   The normalized, absolute URL.
223 *
224 * @see https://github.com/angular/angular.js/blob/v1.4.4/src/ng/urlUtils.js
225 * @see https://grack.com/blog/2009/11/17/absolutizing-url-in-javascript
226 * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L53
227 */
228Drupal.absoluteUrl = function (url) {
229  var urlParsingNode = document.createElement('a');
230
231  // Decode the URL first; this is required by IE <= 6. Decoding non-UTF-8
232  // strings may throw an exception.
233  try {
234    url = decodeURIComponent(url);
235  } catch (e) {}
236
237  urlParsingNode.setAttribute('href', url);
238
239  // IE <= 7 normalizes the URL when assigned to the anchor node similar to
240  // the other browsers.
241  return urlParsingNode.cloneNode(false).href;
242};
243
244/**
245 * Returns true if the URL is within Drupal's base path.
246 *
247 * @param url
248 *   The URL string to be tested.
249 *
250 * @return
251 *   Boolean true if local.
252 *
253 * @see https://github.com/jquery/jquery-ui/blob/1.11.4/ui/tabs.js#L58
254 */
255Drupal.urlIsLocal = function (url) {
256  // Always use browser-derived absolute URLs in the comparison, to avoid
257  // attempts to break out of the base path using directory traversal.
258  var absoluteUrl = Drupal.absoluteUrl(url);
259  var protocol = location.protocol;
260
261  // Consider URLs that match this site's base URL but use HTTPS instead of HTTP
262  // as local as well.
263  if (protocol === 'http:' && absoluteUrl.indexOf('https:') === 0) {
264    protocol = 'https:';
265  }
266  var baseUrl = protocol + '//' + location.host + Drupal.settings.basePath.slice(0, -1);
267
268  // Decoding non-UTF-8 strings may throw an exception.
269  try {
270    absoluteUrl = decodeURIComponent(absoluteUrl);
271  } catch (e) {}
272  try {
273    baseUrl = decodeURIComponent(baseUrl);
274  } catch (e) {}
275
276  // The given URL matches the site's base URL, or has a path under the site's
277  // base URL.
278  return absoluteUrl === baseUrl || absoluteUrl.indexOf(baseUrl + '/') === 0;
279};
280
281/**
282 * Generate the themed representation of a Drupal object.
283 *
284 * All requests for themed output must go through this function. It examines
285 * the request and routes it to the appropriate theme function. If the current
286 * theme does not provide an override function, the generic theme function is
287 * called.
288 *
289 * For example, to retrieve the HTML that is output by theme_placeholder(text),
290 * call Drupal.theme('placeholder', text).
291 *
292 * @param func
293 *   The name of the theme function to call.
294 * @param ...
295 *   Additional arguments to pass along to the theme function.
296 * @return
297 *   Any data the theme function returns. This could be a plain HTML string,
298 *   but also a complex object.
299 */
300Drupal.theme = function(func) {
301  for (var i = 1, args = []; i < arguments.length; i++) {
302    args.push(arguments[i]);
303  }
304
305  return (Drupal.theme[func] || Drupal.theme.prototype[func]).apply(this, args);
306};
307
308/**
309 * Parse a JSON response.
310 *
311 * The result is either the JSON object, or an object with 'status' 0 and 'data' an error message.
312 */
313Drupal.parseJson = function (data) {
314  if ((data.substring(0, 1) != '{') && (data.substring(0, 1) != '[')) {
315    return { status: 0, data: data.length ? data : Drupal.t('Unspecified error') };
316  }
317  return eval('(' + data + ');');
318};
319
320/**
321 * Freeze the current body height (as minimum height). Used to prevent
322 * unnecessary upwards scrolling when doing DOM manipulations.
323 */
324Drupal.freezeHeight = function () {
325  Drupal.unfreezeHeight();
326  var div = document.createElement('div');
327  $(div).css({
328    position: 'absolute',
329    top: '0px',
330    left: '0px',
331    width: '1px',
332    height: $('body').css('height')
333  }).attr('id', 'freeze-height');
334  $('body').append(div);
335};
336
337/**
338 * Unfreeze the body height
339 */
340Drupal.unfreezeHeight = function () {
341  $('#freeze-height').remove();
342};
343
344/**
345 * Wrapper around encodeURIComponent() which avoids Apache quirks (equivalent of
346 * drupal_urlencode() in PHP). This function should only be used on paths, not
347 * on query string arguments.
348 */
349Drupal.encodeURIComponent = function (item, uri) {
350  uri = uri || location.href;
351  item = encodeURIComponent(item).replace(/%2F/g, '/');
352  return (uri.indexOf('?q=') != -1) ? item : item.replace(/%26/g, '%2526').replace(/%23/g, '%2523').replace(/\/\//g, '/%252F');
353};
354
355/**
356 * Get the text selection in a textarea.
357 */
358Drupal.getSelection = function (element) {
359  if (typeof(element.selectionStart) != 'number' && document.selection) {
360    // The current selection
361    var range1 = document.selection.createRange();
362    var range2 = range1.duplicate();
363    // Select all text.
364    range2.moveToElementText(element);
365    // Now move 'dummy' end point to end point of original range.
366    range2.setEndPoint('EndToEnd', range1);
367    // Now we can calculate start and end points.
368    var start = range2.text.length - range1.text.length;
369    var end = start + range1.text.length;
370    return { 'start': start, 'end': end };
371  }
372  return { 'start': element.selectionStart, 'end': element.selectionEnd };
373};
374
375/**
376 * Build an error message from ahah response.
377 */
378Drupal.ahahError = function(xmlhttp, uri) {
379  if (xmlhttp.status == 200) {
380    if (jQuery.trim($(xmlhttp.responseText).text())) {
381      var message = Drupal.t("An error occurred. \n@uri\n@text", {'@uri': uri, '@text': xmlhttp.responseText });
382    }
383    else {
384      var message = Drupal.t("An error occurred. \n@uri\n(no information available).", {'@uri': uri, '@text': xmlhttp.responseText });
385    }
386  }
387  else {
388    var message = Drupal.t("An HTTP error @status occurred. \n@uri", {'@uri': uri, '@status': xmlhttp.status });
389  }
390  return message;
391}
392
393// Global Killswitch on the <html> element
394if (Drupal.jsEnabled) {
395  // Global Killswitch on the <html> element
396  $(document.documentElement).addClass('js');
397  // 'js enabled' cookie
398  document.cookie = 'has_js=1; path=/';
399  // Attach all behaviors.
400  $(document).ready(function() {
401    Drupal.attachBehaviors(this);
402  });
403}
404
405/**
406 * The default themes.
407 */
408Drupal.theme.prototype = {
409
410  /**
411   * Formats text for emphasized display in a placeholder inside a sentence.
412   *
413   * @param str
414   *   The text to format (plain-text).
415   * @return
416   *   The formatted text (html).
417   */
418  placeholder: function(str) {
419    return '<em>' + Drupal.checkPlain(str) + '</em>';
420  }
421};

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.