PageSourceSearch

https://www.cpib.ac.uk/htmlwidgets-1.6.2/htmlwidgets.js

js cpib.ac.uk collected 2026-09-25 14:58:41 UTC 33,190 bytes, 901 lines download raw bytes

1(function() {
2  // If window.HTMLWidgets is already defined, then use it; otherwise create a
3  // new object. This allows preceding code to set options that affect the
4  // initialization process (though none currently exist).
5  window.HTMLWidgets = window.HTMLWidgets || {};
6
7  // See if we're running in a viewer pane. If not, we're in a web browser.
8  var viewerMode = window.HTMLWidgets.viewerMode =
9      /\bviewer_pane=1\b/.test(window.location);
10
11  // See if we're running in Shiny mode. If not, it's a static document.
12  // Note that static widgets can appear in both Shiny and static modes, but
13  // obviously, Shiny widgets can only appear in Shiny apps/documents.
14  var shinyMode = window.HTMLWidgets.shinyMode =
15      typeof(window.Shiny) !== "undefined" && !!window.Shiny.outputBindings;
16
17  // We can't count on jQuery being available, so we implement our own
18  // version if necessary.
19  function querySelectorAll(scope, selector) {
20    if (typeof(jQuery) !== "undefined" && scope instanceof jQuery) {
21      return scope.find(selector);
22    }
23    if (scope.querySelectorAll) {
24      return scope.querySelectorAll(selector);
25    }
26  }
27
28  function asArray(value) {
29    if (value === null)
30      return [];
31    if ($.isArray(value))
32      return value;
33    return [value];
34  }
35
36  // Implement jQuery's extend
37  function extend(target /*, ... */) {
38    if (arguments.length == 1) {
39      return target;
40    }
41    for (var i = 1; i < arguments.length; i++) {
42      var source = arguments[i];
43      for (var prop in source) {
44        if (source.hasOwnProperty(prop)) {
45          target[prop] = source[prop];
46        }
47      }
48    }
49    return target;
50  }
51
52  // IE8 doesn't support Array.forEach.
53  function forEach(values, callback, thisArg) {
54    if (values.forEach) {
55      values.forEach(callback, thisArg);
56    } else {
57      for (var i = 0; i < values.length; i++) {
58        callback.call(thisArg, values[i], i, values);
59      }
60    }
61  }
62
63  // Replaces the specified method with the return value of funcSource.
64  //
65  // Note that funcSource should not BE the new method, it should be a function
66  // that RETURNS the new method. funcSource receives a single argument that is
67  // the overridden method, it can be called from the new method. The overridden
68  // method can be called like a regular function, it has the target permanently
69  // bound to it so "this" will work correctly.
70  function overrideMethod(target, methodName, funcSource) {
71    var superFunc = target[methodName] || function() {};
72    var superFuncBound = function() {
73      return superFunc.apply(target, arguments);
74    };
75    target[methodName] = funcSource(superFuncBound);
76  }
77
78  // Add a method to delegator that, when invoked, calls
79  // delegatee.methodName. If there is no such method on
80  // the delegatee, but there was one on delegator before
81  // delegateMethod was called, then the original version
82  // is invoked instead.
83  // For example:
84  //
85  // var a = {
86  //   method1: function() { console.log('a1'); }
87  //   method2: function() { console.log('a2'); }
88  // };
89  // var b = {
90  //   method1: function() { console.log('b1'); }
91  // };
92  // delegateMethod(a, b, "method1");
93  // delegateMethod(a, b, "method2");
94  // a.method1();
95  // a.method2();
96  //
97  // The output would be "b1", "a2".
98  function delegateMethod(delegator, delegatee, methodName) {
99    var inherited = delegator[methodName];
100    delegator[methodName] = function() {
101      var target = delegatee;
102      var method = delegatee[methodName];
103
104      // The method doesn't exist on the delegatee. Instead,
105      // call the method on the delegator, if it exists.
106      if (!method) {
107        target = delegator;
108        method = inherited;
109      }
110
111      if (method) {
112        return method.apply(target, arguments);
113      }
114    };
115  }
116
117  // Implement a vague facsimilie of jQuery's data method
118  function elementData(el, name, value) {
119    if (arguments.length == 2) {
120      return el["htmlwidget_data_" + name];
121    } else if (arguments.length == 3) {
122      el["htmlwidget_data_" + name] = value;
123      return el;
124    } else {
125      throw new Error("Wrong number of arguments for elementData: " +
126        arguments.length);
127    }
128  }
129
130  // http://stackoverflow.com/questions/3446170/escape-string-for-use-in-javascript-regex
131  function escapeRegExp(str) {
132    return str.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, "\\$&");
133  }
134
135  function hasClass(el, className) {
136    var re = new RegExp("\\b" + escapeRegExp(className) + "\\b");
137    return re.test(el.className);
138  }
139
140  // elements - array (or array-like object) of HTML elements
141  // className - class name to test for
142  // include - if true, only return elements with given className;
143  //   if false, only return elements *without* given className
144  function filterByClass(elements, className, include) {
145    var results = [];
146    for (var i = 0; i < elements.length; i++) {
147      if (hasClass(elements[i], className) == include)
148        results.push(elements[i]);
149    }
150    return results;
151  }
152
153  function on(obj, eventName, func) {
154    if (obj.addEventListener) {
155      obj.addEventListener(eventName, func, false);
156    } else if (obj.attachEvent) {
157      obj.attachEvent(eventName, func);
158    }
159  }
160
161  function off(obj, eventName, func) {
162    if (obj.removeEventListener)
163      obj.removeEventListener(eventName, func, false);
164    else if (obj.detachEvent) {
165      obj.detachEvent(eventName, func);
166    }
167  }
168
169  // Translate array of values to top/right/bottom/left, as usual with
170  // the "padding" CSS property
171  // https://developer.mozilla.org/en-US/docs/Web/CSS/padding
172  function unpackPadding(value) {
173    if (typeof(value) === "number")
174      value = [value];
175    if (value.length === 1) {
176      return {top: value[0], right: value[0], bottom: value[0], left: value[0]};
177    }
178    if (value.length === 2) {
179      return {top: value[0], right: value[1], bottom: value[0], left: value[1]};
180    }
181    if (value.length === 3) {
182      return {top: value[0], right: value[1], bottom: value[2], left: value[1]};
183    }
184    if (value.length === 4) {
185      return {top: value[0], right: value[1], bottom: value[2], left: value[3]};
186    }
187  }
188
189  // Convert an unpacked padding object to a CSS value
190  function paddingToCss(paddingObj) {
191    return paddingObj.top + "px " + paddingObj.right + "px " + paddingObj.bottom + "px " + paddingObj.left + "px";
192  }
193
194  // Makes a number suitable for CSS
195  function px(x) {
196    if (typeof(x) === "number")
197      return x + "px";
198    else
199      return x;
200  }
201
202  // Retrieves runtime widget sizing information for an element.
203  // The return value is either null, or an object with fill, padding,
204  // defaultWidth, defaultHeight fields.
205  function sizingPolicy(el) {
206    var sizingEl = document.querySelector("script[data-for='" + el.id + "'][type='application/htmlwidget-sizing']");
207    if (!sizingEl)
208      return null;
209    var sp = JSON.parse(sizingEl.textContent || sizingEl.text || "{}");
210    if (viewerMode) {
211      return sp.viewer;
212    } else {
213      return sp.browser;
214    }
215  }
216
217  // @param tasks Array of strings (or falsy value, in which case no-op).
218  //   Each element must be a valid JavaScript expression that yields a
219  //   function. Or, can be an array of objects with "code" and "data"
220  //   properties; in this case, the "code" property should be a string
221  //   of JS that's an expr that yields a function, and "data" should be
222  //   an object that will be added as an additional argument when that
223  //   function is called.
224  // @param target The object that will be "this" for each function
225  //   execution.
226  // @param args Array of arguments to be passed to the functions. (The
227  //   same arguments will be passed to all functions.)
228  function evalAndRun(tasks, target, args) {
229    if (tasks) {
230      forEach(tasks, function(task) {
231        var theseArgs = args;
232        if (typeof(task) === "object") {
233          theseArgs = theseArgs.concat([task.data]);
234          task = task.code;
235        }
236        var taskFunc = tryEval(task);
237        if (typeof(taskFunc) !== "function") {
238          throw new Error("Task must be a function! Source:\n" + task);
239        }
240        taskFunc.apply(target, theseArgs);
241      });
242    }
243  }
244
245  // Attempt eval() both with and without enclosing in parentheses.
246  // Note that enclosing coerces a function declaration into
247  // an expression that eval() can parse
248  // (otherwise, a SyntaxError is thrown)
249  function tryEval(code) {
250    var result = null;
251    try {
252      result = eval("(" + code + ")");
253    } catch(error) {
254      if (!(error instanceof SyntaxError)) {
255        throw error;
256      }
257      try {
258        result = eval(code);
259      } catch(e) {
260        if (e instanceof SyntaxError) {
261          throw error;
262        } else {
263          throw e;
264        }
265      }
266    }
267    return result;
268  }
269
270  function initSizing(el) {
271    var sizing = sizingPolicy(el);
272    if (!sizing)
273      return;
274
275    var cel = document.getElementById("htmlwidget_container");
276    if (!cel)
277      return;
278
279    if (typeof(sizing.padding) !== "undefined") {
280      document.body.style.margin = "0";
281      document.body.style.padding = paddingToCss(unpackPadding(sizing.padding));
282    }
283
284    if (sizing.fill) {
285      document.body.style.overflow = "hidden";
286      document.body.style.width = "100%";
287      document.body.style.height = "100%";
288      document.documentElement.style.width = "100%";
289      document.documentElement.style.height = "100%";
290      cel.style.position = "absolute";
291      var pad = unpackPadding(sizing.padding);
292      cel.style.top = pad.top + "px";
293      cel.style.right = pad.right + "px";
294      cel.style.bottom = pad.bottom + "px";
295      cel.style.left = pad.left + "px";
296      el.style.width = "100%";
297      el.style.height = "100%";
298
299      return {
300        getWidth: function() { return cel.getBoundingClientRect().width; },
301        getHeight: function() { return cel.getBoundingClientRect().height; }
302      };
303
304    } else {
305      el.style.width = px(sizing.width);
306      el.style.height = px(sizing.height);
307
308      return {
309        getWidth: function() { return cel.getBoundingClientRect().width; },
310        getHeight: function() { return cel.getBoundingClientRect().height; }
311      };
312    }
313  }
314
315  // Default implementations for methods
316  var defaults = {
317    find: function(scope) {
318      return querySelectorAll(scope, "." + this.name);
319    },
320    renderError: function(el, err) {
321      var $el = $(el);
322
323      this.clearError(el);
324
325      // Add all these error classes, as Shiny does
326      var errClass = "shiny-output-error";
327      if (err.type !== null) {
328        // use the classes of the error condition as CSS class names
329        errClass = errClass + " " + $.map(asArray(err.type), function(type) {
330          return errClass + "-" + type;
331        }).join(" ");
332      }
333      errClass = errClass + " htmlwidgets-error";
334
335      // Is el inline or block? If inline or inline-block, just display:none it
336      // and add an inline error.
337      var display = $el.css("display");
338      $el.data("restore-display-mode", display);
339
340      if (display === "inline" || display === "inline-block") {
341        $el.hide();
342        if (err.message !== "") {
343          var errorSpan = $("<span>").addClass(errClass);
344          errorSpan.text(err.message);
345          $el.after(errorSpan);
346        }
347      } else if (display === "block") {
348        // If block, add an error just after the el, set visibility:none on the
349        // el, and position the error to be on top of the el.
350        // Mark it with a unique ID and CSS class so we can remove it later.
351        $el.css("visibility", "hidden");
352        if (err.message !== "") {
353          var errorDiv = $("<div>").addClass(errClass).css("position", "absolute")
354            .css("top", el.offsetTop)
355            .css("left", el.offsetLeft)
356            // setting width can push out the page size, forcing otherwise
357            // unnecessary scrollbars to appear and making it impossible for
358            // the element to shrink; so use max-width instead
359            .css("maxWidth", el.offsetWidth)
360            .css("height", el.offsetHeight);
361          errorDiv.text(err.message);
362          $el.after(errorDiv);
363
364          // Really dumb way to keep the size/position of the error in sync with
365          // the parent element as the window is resized or whatever.
366          var intId = setInterval(function() {
367            if (!errorDiv[0].parentElement) {
368              clearInterval(intId);
369              return;
370            }
371            errorDiv
372              .css("top", el.offsetTop)
373              .css("left", el.offsetLeft)
374              .css("maxWidth", el.offsetWidth)
375              .css("height", el.offsetHeight);
376          }, 500);
377        }
378      }
379    },
380    clearError: function(el) {
381      var $el = $(el);
382      var display = $el.data("restore-display-mode");
383      $el.data("restore-display-mode", null);
384
385      if (display === "inline" || display === "inline-block") {
386        if (display)
387          $el.css("display", display);
388        $(el.nextSibling).filter(".htmlwidgets-error").remove();
389      } else if (display === "block"){
390        $el.css("visibility", "inherit");
391        $(el.nextSibling).filter(".htmlwidgets-error").remove();
392      }
393    },
394    sizing: {}
395  };
396
397  // Called by widget bindings to register a new type of widget. The definition
398  // object can contain the following properties:
399  // - name (required) - A string indicating the binding name, which will be
400  //   used by default as the CSS classname to look for.
401  // - initialize (optional) - A function(el) that will be called once per
402  //   widget element; if a value is returned, it will be passed as the third
403  //   value to renderValue.
404  // - renderValue (required) - A function(el, data, initValue) that will be
405  //   called with data. Static contexts will cause this to be called once per
406  //   element; Shiny apps will cause this to be called multiple times per
407  //   element, as the data changes.
408  window.HTMLWidgets.widget = function(definition) {
409    if (!definition.name) {
410      throw new Error("Widget must have a name");
411    }
412    if (!definition.type) {
413      throw new Error("Widget must have a type");
414    }
415    // Currently we only support output widgets
416    if (definition.type !== "output") {
417      throw new Error("Unrecognized widget type '" + definition.type + "'");
418    }
419    // TODO: Verify that .name is a valid CSS classname
420
421    // Support new-style instance-bound definitions. Old-style class-bound
422    // definitions have one widget "object" per widget per type/class of
423    // widget; the renderValue and resize methods on such widget objects
424    // take el and instance arguments, because the widget object can't
425    // store them. New-style instance-bound definitions have one widget
426    // object per widget instance; the definition that's passed in doesn't
427    // provide renderValue or resize methods at all, just the single method
428    //   factory(el, width, height)
429    // which returns an object that has renderValue(x) and resize(w, h).
430    // This enables a far more natural programming style for the widget
431    // author, who can store per-instance state using either OO-style
432    // instance fields or functional-style closure variables (I guess this
433    // is in contrast to what can only be called C-style pseudo-OO which is
434    // what we required before).
435    if (definition.factory) {
436      definition = createLegacyDefinitionAdapter(definition);
437    }
438
439    if (!definition.renderValue) {
440      throw new Error("Widget must have a renderValue function");
441    }
442
443    // For static rendering (non-Shiny), use a simple widget registration
444    // scheme. We also use this scheme for Shiny apps/documents that also
445    // contain static widgets.
446    window.HTMLWidgets.widgets = window.HTMLWidgets.widgets || [];
447    // Merge defaults into the definition; don't mutate the original definition.
448    var staticBinding = extend({}, defaults, definition);
449    overrideMethod(staticBinding, "find", function(superfunc) {
450      return function(scope) {
451        var results = superfunc(scope);
452        // Filter out Shiny outputs, we only want the static kind
453        return filterByClass(results, "html-widget-output", false);
454      };
455    });
456    window.HTMLWidgets.widgets.push(staticBinding);
457
458    if (shinyMode) {
459      // Shiny is running. Register the definition with an output binding.
460      // The definition itself will not be the output binding, instead
461      // we will make an output binding object that delegates to the
462      // definition. This is because we foolishly used the same method
463      // name (renderValue) for htmlwidgets definition and Shiny bindings
464      // but they actually have quite different semantics (the Shiny
465      // bindings receive data that includes lots of metadata that it
466      // strips off before calling htmlwidgets renderValue). We can't
467      // just ignore the difference because in some widgets it's helpful
468      // to call this.renderValue() from inside of resize(), and if
469      // we're not delegating, then that call will go to the Shiny
470      // version instead of the htmlwidgets version.
471
472      // Merge defaults with definition, without mutating either.
473      var bindingDef = extend({}, defaults, definition);
474
475      // This object will be our actual Shiny binding.
476      var shinyBinding = new Shiny.OutputBinding();
477
478      // With a few exceptions, we'll want to simply use the bindingDef's
479      // version of methods if they are available, otherwise fall back to
480      // Shiny's defaults. NOTE: If Shiny's output bindings gain additional
481      // methods in the future, and we want them to be overrideable by
482      // HTMLWidget binding definitions, then we'll need to add them to this
483      // list.
484      delegateMethod(shinyBinding, bindingDef, "getId");
485      delegateMethod(shinyBinding, bindingDef, "onValueChange");
486      delegateMethod(shinyBinding, bindingDef, "onValueError");
487      delegateMethod(shinyBinding, bindingDef, "renderError");
488      delegateMethod(shinyBinding, bindingDef, "clearError");
489      delegateMethod(shinyBinding, bindingDef, "showProgress");
490
491      // The find, renderValue, and resize are handled differently, because we
492      // want to actually decorate the behavior of the bindingDef methods.
493
494      shinyBinding.find = function(scope) {
495        var results = bindingDef.find(scope);
496
497        // Only return elements that are Shiny outputs, not static ones
498        var dynamicResults = results.filter(".html-widget-output");
499
500        // It's possible that whatever caused Shiny to think there might be
501        // new dynamic outputs, also caused there to be new static outputs.
502        // Since there might be lots of different htmlwidgets bindings, we
503        // schedule execution for later--no need to staticRender multiple
504        // times.
505        if (results.length !== dynamicResults.length)
506          scheduleStaticRender();
507
508        return dynamicResults;
509      };
510
511      // Wrap renderValue to handle initialization, which unfortunately isn't
512      // supported natively by Shiny at the time of this writing.
513
514      shinyBinding.renderValue = function(el, data) {
515        Shiny.renderDependencies(data.deps);
516        // Resolve strings marked as javascript literals to objects
517        if (!(data.evals instanceof Array)) data.evals = [data.evals];
518        for (var i = 0; data.evals && i < data.evals.length; i++) {
519          window.HTMLWidgets.evaluateStringMember(data.x, data.evals[i]);
520        }
521        if (!bindingDef.renderOnNullValue) {
522          if (data.x === null) {
523            el.style.visibility = "hidden";
524            return;
525          } else {
526            el.style.visibility = "inherit";
527          }
528        }
529        if (!elementData(el, "initialized")) {
530          initSizing(el);
531
532          elementData(el, "initialized", true);
533          if (bindingDef.initialize) {
534            var rect = el.getBoundingClientRect();
535            var result = bindingDef.initialize(el, rect.width, rect.height);
536            elementData(el, "init_result", result);
537          }
538        }
539        bindingDef.renderValue(el, data.x, elementData(el, "init_result"));
540        evalAndRun(data.jsHooks.render, elementData(el, "init_result"), [el, data.x]);
541      };
542
543      // Only override resize if bindingDef implements it
544      if (bindingDef.resize) {
545        shinyBinding.resize = function(el, width, height) {
546          // Shiny can call resize before initialize/renderValue have been
547          // called, which doesn't make sense for widgets.
548          if (elementData(el, "initialized")) {
549            bindingDef.resize(el, width, height, elementData(el, "init_result"));
550          }
551        };
552      }
553
554      Shiny.outputBindings.register(shinyBinding, bindingDef.name);
555    }
556  };
557
558  var scheduleStaticRenderTimerId = null;
559  function scheduleStaticRender() {
560    if (!scheduleStaticRenderTimerId) {
561      scheduleStaticRenderTimerId = setTimeout(function() {
562        scheduleStaticRenderTimerId = null;
563        window.HTMLWidgets.staticRender();
564      }, 1);
565    }
566  }
567
568  // Render static widgets after the document finishes loading
569  // Statically render all elements that are of this widget's class
570  window.HTMLWidgets.staticRender = function() {
571    var bindings = window.HTMLWidgets.widgets || [];
572    forEach(bindings, function(binding) {
573      var matches = binding.find(document.documentElement);
574      forEach(matches, function(el) {
575        var sizeObj = initSizing(el, binding);
576
577        var getSize = function(el) {
578          if (sizeObj) {
579            return {w: sizeObj.getWidth(), h: sizeObj.getHeight()}
580          } else {
581            var rect = el.getBoundingClientRect();
582            return {w: rect.width, h: rect.height}
583          }
584        };
585
586        if (hasClass(el, "html-widget-static-bound"))
587          return;
588        el.className = el.className + " html-widget-static-bound";
589
590        var initResult;
591        if (binding.initialize) {
592          var size = getSize(el);
593          initResult = binding.initialize(el, size.w, size.h);
594          elementData(el, "init_result", initResult);
595        }
596
597        if (binding.resize) {
598          var lastSize = getSize(el);
599          var resizeHandler = function(e) {
600            var size = getSize(el);
601            if (size.w === 0 && size.h === 0)
602              return;
603            if (size.w === lastSize.w && size.h === lastSize.h)
604              return;
605            lastSize = size;
606            binding.resize(el, size.w, size.h, initResult);
607          };
608
609          on(window, "resize", resizeHandler);
610
611          // This is needed for cases where we're running in a Shiny
612          // app, but the widget itself is not a Shiny output, but
613          // rather a simple static widget. One example of this is
614          // an rmarkdown document that has runtime:shiny and widget
615          // that isn't in a render function. Shiny only knows to
616          // call resize handlers for Shiny outputs, not for static
617          // widgets, so we do it ourselves.
618          if (window.jQuery) {
619            window.jQuery(document).on(
620              "shown.htmlwidgets shown.bs.tab.htmlwidgets shown.bs.collapse.htmlwidgets",
621              resizeHandler
622            );
623            window.jQuery(document).on(
624              "hidden.htmlwidgets hidden.bs.tab.htmlwidgets hidden.bs.collapse.htmlwidgets",
625              resizeHandler
626            );
627          }
628
629          // This is needed for the specific case of ioslides, which
630          // flips slides between display:none and display:block.
631          // Ideally we would not have to have ioslide-specific code
632          // here, but rather have ioslides raise a generic event,
633          // but the rmarkdown package just went to CRAN so the
634          // window to getting that fixed may be long.
635          if (window.addEventListener) {
636            // It's OK to limit this to window.addEventListener
637            // browsers because ioslides itself only supports
638            // such browsers.
639            on(document, "slideenter", resizeHandler);
640            on(document, "slideleave", resizeHandler);
641          }
642        }
643
644        var scriptData = document.querySelector("script[data-for='" + el.id + "'][type='application/json']");
645        if (scriptData) {
646          var data = JSON.parse(scriptData.textContent || scriptData.text);
647          // Resolve strings marked as javascript literals to objects
648          if (!(data.evals instanceof Array)) data.evals = [data.evals];
649          for (var k = 0; data.evals && k < data.evals.length; k++) {
650            window.HTMLWidgets.evaluateStringMember(data.x, data.evals[k]);
651          }
652          binding.renderValue(el, data.x, initResult);
653          evalAndRun(data.jsHooks.render, initResult, [el, data.x]);
654        }
655      });
656    });
657
658    invokePostRenderHandlers();
659  }
660
661
662  function has_jQuery3() {
663    if (!window.jQuery) {
664      return false;
665    }
666    var $version = window.jQuery.fn.jquery;
667    var $major_version = parseInt($version.split(".")[0]);
668    return $major_version >= 3;
669  }
670
671  /*
672  / Shiny 1.4 bumped jQuery from 1.x to 3.x which means jQuery's
673  / on-ready handler (i.e., $(fn)) is now asyncronous (i.e., it now
674  / really means $(setTimeout(fn)).
675  / https://jquery.com/upgrade-guide/3.0/#breaking-change-document-ready-handlers-are-now-asynchronous
676  /
677  / Since Shiny uses $() to schedule initShiny, shiny>=1.4 calls initShiny
678  / one tick later than it did before, which means staticRender() is
679  / called renderValue() earlier than (advanced) widget authors might be expecting.
680  / https://github.com/rstudio/shiny/issues/2630
681  /
682  / For a concrete example, leaflet has some methods (e.g., updateBounds)
683  / which reference Shiny methods registered in initShiny (e.g., setInputValue).
684  / Since leaflet is privy to this life-cycle, it knows to use setTimeout() to
685  / delay execution of those methods (until Shiny methods are ready)
686  / https://github.com/rstudio/leaflet/blob/18ec981/javascript/src/index.js#L266-L268
687  /
688  / Ideally widget authors wouldn't need to use this setTimeout() hack that
689  / leaflet uses to call Shiny methods on a staticRender(). In the long run,
690  / the logic initShiny should be broken up so that method registration happens
691  / right away, but binding happens later.
692  */
693  function maybeStaticRenderLater() {
694    if (shinyMode && has_jQuery3()) {
695      window.jQuery(window.HTMLWidgets.staticRender);
696    } else {
697      window.HTMLWidgets.staticRender();
698    }
699  }
700
701  if (document.addEventListener) {
702    document.addEventListener("DOMContentLoaded", function() {
703      document.removeEventListener("DOMContentLoaded", arguments.callee, false);
704      maybeStaticRenderLater();
705    }, false);
706  } else if (document.attachEvent) {
707    document.attachEvent("onreadystatechange", function() {
708      if (document.readyState === "complete") {
709        document.detachEvent("onreadystatechange", arguments.callee);
710        maybeStaticRenderLater();
711      }
712    });
713  }
714
715
716  window.HTMLWidgets.getAttachmentUrl = function(depname, key) {
717    // If no key, default to the first item
718    if (typeof(key) === "undefined")
719      key = 1;
720
721    var link = document.getElementById(depname + "-" + key + "-attachment");
722    if (!link) {
723      throw new Error("Attachment " + depname + "/" + key + " not found in document");
724    }
725    return link.getAttribute("href");
726  };
727
728  window.HTMLWidgets.dataframeToD3 = function(df) {
729    var names = [];
730    var length;
731    for (var name in df) {
732        if (df.hasOwnProperty(name))
733            names.push(name);
734        if (typeof(df[name]) !== "object" || typeof(df[name].length) === "undefined") {
735            throw new Error("All fields must be arrays");
736        } else if (typeof(length) !== "undefined" && length !== df[name].length) {
737            throw new Error("All fields must be arrays of the same length");
738        }
739        length = df[name].length;
740    }
741    var results = [];
742    var item;
743    for (var row = 0; row < length; row++) {
744        item = {};
745        for (var col = 0; col < names.length; col++) {
746            item[names[col]] = df[names[col]][row];
747        }
748        results.push(item);
749    }
750    return results;
751  };
752
753  window.HTMLWidgets.transposeArray2D = function(array) {
754      if (array.length === 0) return array;
755      var newArray = array[0].map(function(col, i) {
756          return array.map(function(row) {
757              return row[i]
758          })
759      });
760      return newArray;
761  };
762  // Split value at splitChar, but allow splitChar to be escaped
763  // using escapeChar. Any other characters escaped by escapeChar
764  // will be included as usual (including escapeChar itself).
765  function splitWithEscape(value, splitChar, escapeChar) {
766    var results = [];
767    var escapeMode = false;
768    var currentResult = "";
769    for (var pos = 0; pos < value.length; pos++) {
770      if (!escapeMode) {
771        if (value[pos] === splitChar) {
772          results.push(currentResult);
773          currentResult = "";
774        } else if (value[pos] === escapeChar) {
775          escapeMode = true;
776        } else {
777          currentResult += value[pos];
778        }
779      } else {
780        currentResult += value[pos];
781        escapeMode = false;
782      }
783    }
784    if (currentResult !== "") {
785      results.push(currentResult);
786    }
787    return results;
788  }
789  // Function authored by Yihui/JJ Allaire
790  window.HTMLWidgets.evaluateStringMember = function(o, member) {
791    var parts = splitWithEscape(member, '.', '\\');
792    for (var i = 0, l = parts.length; i < l; i++) {
793      var part = parts[i];
794      // part may be a character or 'numeric' member name
795      if (o !== null && typeof o === "object" && part in o) {
796        if (i == (l - 1)) { // if we are at the end of the line then evalulate
797          if (typeof o[part] === "string")
798            o[part] = tryEval(o[part]);
799        } else { // otherwise continue to next embedded object
800          o = o[part];
801        }
802      }
803    }
804  };
805
806  // Retrieve the HTMLWidget instance (i.e. the return value of an
807  // HTMLWidget binding's initialize() or factory() function)
808  // associated with an element, or null if none.
809  window.HTMLWidgets.getInstance = function(el) {
810    return elementData(el, "init_result");
811  };
812
813  // Finds the first element in the scope that matches the selector,
814  // and returns the HTMLWidget instance (i.e. the return value of
815  // an HTMLWidget binding's initialize() or factory() function)
816  // associated with that element, if any. If no element matches the
817  // selector, or the first matching element has no HTMLWidget
818  // instance associated with it, then null is returned.
819  //
820  // The scope argument is optional, and defaults to window.document.
821  window.HTMLWidgets.find = function(scope, selector) {
822    if (arguments.length == 1) {
823      selector = scope;
824      scope = document;
825    }
826
827    var el = scope.querySelector(selector);
828    if (el === null) {
829      return null;
830    } else {
831      return window.HTMLWidgets.getInstance(el);
832    }
833  };
834
835  // Finds all elements in the scope that match the selector, and
836  // returns the HTMLWidget instances (i.e. the return values of
837  // an HTMLWidget binding's initialize() or factory() function)
838  // associated with the elements, in an array. If elements that
839  // match the selector don't have an associated HTMLWidget
840  // instance, the returned array will contain nulls.
841  //
842  // The scope argument is optional, and defaults to window.document.
843  window.HTMLWidgets.findAll = function(scope, selector) {
844    if (arguments.length == 1) {
845      selector = scope;
846      scope = document;
847    }
848
849    var nodes = scope.querySelectorAll(selector);
850    var results = [];
851    for (var i = 0; i < nodes.length; i++) {
852      results.push(window.HTMLWidgets.getInstance(nodes[i]));
853    }
854    return results;
855  };
856
857  var postRenderHandlers = [];
858  function invokePostRenderHandlers() {
859    while (postRenderHandlers.length) {
860      var handler = postRenderHandlers.shift();
861      if (handler) {
862        handler();
863      }
864    }
865  }
866
867  // Register the given callback function to be invoked after the
868  // next time static widgets are rendered.
869  window.HTMLWidgets.addPostRenderHandler = function(callback) {
870    postRenderHandlers.push(callback);
871  };
872
873  // Takes a new-style instance-bound definition, and returns an
874  // old-style class-bound definition. This saves us from having
875  // to rewrite all the logic in this file to accomodate both
876  // types of definitions.
877  function createLegacyDefinitionAdapter(defn) {
878    var result = {
879      name: defn.name,
880      type: defn.type,
881      initialize: function(el, width, height) {
882        return defn.factory(el, width, height);
883      },
884      renderValue: function(el, x, instance) {
885        return instance.renderValue(x);
886      },
887      resize: function(el, width, height, instance) {
888        return instance.resize(width, height);
889      }
890    };
891
892    if (defn.find)
893      result.find = defn.find;
894    if (defn.renderError)
895      result.renderError = defn.renderError;
896    if (defn.clearError)
897      result.clearError = defn.clearError;
898
899    return result;
900  }
901})();

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.