[ Index ]

PHP Cross Reference of Joomla 4.2.2 documentation

title

Body

[close]

/libraries/vendor/maximebf/debugbar/src/DebugBar/Resources/ -> widgets.js (source)

   1  if (typeof(PhpDebugBar) == 'undefined') {
   2      // namespace
   3      var PhpDebugBar = {};
   4      PhpDebugBar.$ = jQuery;
   5  }
   6  
   7  (function($) {
   8  
   9      /**
  10       * @namespace
  11       */
  12      PhpDebugBar.Widgets = {};
  13  
  14      var csscls = PhpDebugBar.utils.makecsscls('phpdebugbar-widgets-');
  15  
  16      /**
  17       * Replaces spaces with &nbsp; and line breaks with <br>
  18       *
  19       * @param {String} text
  20       * @return {String}
  21       */
  22      var htmlize = PhpDebugBar.Widgets.htmlize = function(text) {
  23          return text.replace(/\n/g, '<br>').replace(/\s/g, "&nbsp;")
  24      };
  25  
  26      /**
  27       * Returns a string representation of value, using JSON.stringify
  28       * if it's an object.
  29       *
  30       * @param {Object} value
  31       * @param {Boolean} prettify Uses htmlize() if true
  32       * @return {String}
  33       */
  34      var renderValue = PhpDebugBar.Widgets.renderValue = function(value, prettify) {
  35          if (typeof(value) !== 'string') {
  36              if (prettify) {
  37                  return htmlize(JSON.stringify(value, undefined, 2));
  38              }
  39              return JSON.stringify(value);
  40          }
  41          return value;
  42      };
  43  
  44      /**
  45       * Highlights a block of code
  46       *
  47       * @param  {String} code
  48       * @param  {String} lang
  49       * @return {String}
  50       */
  51      var highlight = PhpDebugBar.Widgets.highlight = function(code, lang) {
  52          if (typeof(code) === 'string') {
  53              if (typeof(hljs) === 'undefined') {
  54                  return htmlize(code);
  55              }
  56              if (lang) {
  57                  return hljs.highlight(lang, code).value;
  58              }
  59              return hljs.highlightAuto(code).value;
  60          }
  61  
  62          if (typeof(hljs) === 'object') {
  63              code.each(function(i, e) { hljs.highlightBlock(e); });
  64          }
  65          return code;
  66      };
  67  
  68      /**
  69       * Creates a <pre> element with a block of code
  70       *
  71       * @param  {String} code
  72       * @param  {String} lang
  73       * @param  {Number} [firstLineNumber] If provided, shows line numbers beginning with the given value.
  74       * @param  {Number} [highlightedLine] If provided, the given line number will be highlighted.
  75       * @return {String}
  76       */
  77      var createCodeBlock = PhpDebugBar.Widgets.createCodeBlock = function(code, lang, firstLineNumber, highlightedLine) {
  78          var pre = $('<pre />').addClass(csscls('code-block'));
  79          // Add a newline to prevent <code> element from vertically collapsing too far if the last
  80          // code line was empty: that creates problems with the horizontal scrollbar being
  81          // incorrectly positioned - most noticeable when line numbers are shown.
  82          var codeElement = $('<code />').text(code + '\n').appendTo(pre);
  83  
  84          // Add a span with a special class if we are supposed to highlight a line.  highlight.js will
  85          // still correctly format code even with existing markup in it.
  86          if ($.isNumeric(highlightedLine)) {
  87              if ($.isNumeric(firstLineNumber)) {
  88                  highlightedLine = highlightedLine - firstLineNumber + 1;
  89              }
  90              codeElement.html(function (index, html) {
  91                  var currentLine = 1;
  92                  return html.replace(/^.*$/gm, function(line) {
  93                      if (currentLine++ == highlightedLine) {
  94                          return '<span class="' + csscls('highlighted-line') + '">' + line + '</span>';
  95                      } else {
  96                          return line;
  97                      }
  98                  });
  99              });
 100          }
 101  
 102          // Format the code
 103          if (lang) {
 104              pre.addClass("language-" + lang);
 105          }
 106          highlight(pre);
 107  
 108          // Show line numbers in a list
 109          if ($.isNumeric(firstLineNumber)) {
 110              var lineCount = code.split('\n').length;
 111              var $lineNumbers = $('<ul />').prependTo(pre);
 112              pre.children().addClass(csscls('numbered-code'));
 113              for (var i = firstLineNumber; i < firstLineNumber + lineCount; i++) {
 114                  $('<li />').text(i).appendTo($lineNumbers);
 115              }
 116          }
 117  
 118          return pre;
 119      };
 120  
 121      // ------------------------------------------------------------------
 122      // Generic widgets
 123      // ------------------------------------------------------------------
 124  
 125      /**
 126       * Displays array element in a <ul> list
 127       *
 128       * Options:
 129       *  - data
 130       *  - itemRenderer: a function used to render list items (optional)
 131       */
 132      var ListWidget = PhpDebugBar.Widgets.ListWidget = PhpDebugBar.Widget.extend({
 133  
 134          tagName: 'ul',
 135  
 136          className: csscls('list'),
 137  
 138          initialize: function(options) {
 139              if (!options['itemRenderer']) {
 140                  options['itemRenderer'] = this.itemRenderer;
 141              }
 142              this.set(options);
 143          },
 144  
 145          render: function() {
 146              this.bindAttr(['itemRenderer', 'data'], function() {
 147                  this.$el.empty();
 148                  if (!this.has('data')) {
 149                      return;
 150                  }
 151  
 152                  var data = this.get('data');
 153                  for (var i = 0; i < data.length; i++) {
 154                      var li = $('<li />').addClass(csscls('list-item')).appendTo(this.$el);
 155                      this.get('itemRenderer')(li, data[i]);
 156                  }
 157              });
 158          },
 159  
 160          /**
 161           * Renders the content of a <li> element
 162           *
 163           * @param {jQuery} li The <li> element as a jQuery Object
 164           * @param {Object} value An item from the data array
 165           */
 166          itemRenderer: function(li, value) {
 167              li.html(renderValue(value));
 168          }
 169  
 170      });
 171  
 172      // ------------------------------------------------------------------
 173  
 174      /**
 175       * Displays object property/value paris in a <dl> list
 176       *
 177       * Options:
 178       *  - data
 179       *  - itemRenderer: a function used to render list items (optional)
 180       */
 181      var KVListWidget = PhpDebugBar.Widgets.KVListWidget = ListWidget.extend({
 182  
 183          tagName: 'dl',
 184  
 185          className: csscls('kvlist'),
 186  
 187          render: function() {
 188              this.bindAttr(['itemRenderer', 'data'], function() {
 189                  this.$el.empty();
 190                  if (!this.has('data')) {
 191                      return;
 192                  }
 193  
 194                  var self = this;
 195                  $.each(this.get('data'), function(key, value) {
 196                      var dt = $('<dt />').addClass(csscls('key')).appendTo(self.$el);
 197                      var dd = $('<dd />').addClass(csscls('value')).appendTo(self.$el);
 198                      self.get('itemRenderer')(dt, dd, key, value);
 199                  });
 200              });
 201          },
 202  
 203          /**
 204           * Renders the content of the <dt> and <dd> elements
 205           *
 206           * @param {jQuery} dt The <dt> element as a jQuery Object
 207           * @param {jQuery} dd The <dd> element as a jQuery Object
 208           * @param {String} key Property name
 209           * @param {Object} value Property value
 210           */
 211          itemRenderer: function(dt, dd, key, value) {
 212              dt.text(key);
 213              dd.html(htmlize(value));
 214          }
 215  
 216      });
 217  
 218      // ------------------------------------------------------------------
 219  
 220      /**
 221       * An extension of KVListWidget where the data represents a list
 222       * of variables
 223       *
 224       * Options:
 225       *  - data
 226       */
 227      var VariableListWidget = PhpDebugBar.Widgets.VariableListWidget = KVListWidget.extend({
 228  
 229          className: csscls('kvlist varlist'),
 230  
 231          itemRenderer: function(dt, dd, key, value) {
 232              $('<span />').attr('title', key).text(key).appendTo(dt);
 233  
 234              var v = value;
 235              if (v && v.length > 100) {
 236                  v = v.substr(0, 100) + "...";
 237              }
 238              var prettyVal = null;
 239              dd.text(v).click(function() {
 240                  if (dd.hasClass(csscls('pretty'))) {
 241                      dd.text(v).removeClass(csscls('pretty'));
 242                  } else {
 243                      prettyVal = prettyVal || createCodeBlock(value);
 244                      dd.addClass(csscls('pretty')).empty().append(prettyVal);
 245                  }
 246              });
 247          }
 248  
 249      });
 250  
 251      // ------------------------------------------------------------------
 252  
 253      /**
 254       * An extension of KVListWidget where the data represents a list
 255       * of variables whose contents are HTML; this is useful for showing
 256       * variable output from VarDumper's HtmlDumper.
 257       *
 258       * Options:
 259       *  - data
 260       */
 261      var HtmlVariableListWidget = PhpDebugBar.Widgets.HtmlVariableListWidget = KVListWidget.extend({
 262  
 263          className: csscls('kvlist htmlvarlist'),
 264  
 265          itemRenderer: function(dt, dd, key, value) {
 266              $('<span />').attr('title', key).text(key).appendTo(dt);
 267              dd.html(value);
 268          }
 269  
 270      });
 271  
 272      // ------------------------------------------------------------------
 273  
 274      /**
 275       * Iframe widget
 276       *
 277       * Options:
 278       *  - data
 279       */
 280      var IFrameWidget = PhpDebugBar.Widgets.IFrameWidget = PhpDebugBar.Widget.extend({
 281  
 282          tagName: 'iframe',
 283  
 284          className: csscls('iframe'),
 285  
 286          render: function() {
 287              this.$el.attr({
 288                  seamless: "seamless",
 289                  border: "0",
 290                  width: "100%",
 291                  height: "100%"
 292              });
 293              this.bindAttr('data', function(url) { this.$el.attr('src', url); });
 294          }
 295  
 296      });
 297  
 298  
 299      // ------------------------------------------------------------------
 300      // Collector specific widgets
 301      // ------------------------------------------------------------------
 302  
 303      /**
 304       * Widget for the MessagesCollector
 305       *
 306       * Uses ListWidget under the hood
 307       *
 308       * Options:
 309       *  - data
 310       */
 311      var MessagesWidget = PhpDebugBar.Widgets.MessagesWidget = PhpDebugBar.Widget.extend({
 312  
 313          className: csscls('messages'),
 314  
 315          render: function() {
 316              var self = this;
 317  
 318              this.$list = new ListWidget({ itemRenderer: function(li, value) {
 319                  if (value.message_html) {
 320                      var val = $('<span />').addClass(csscls('value')).html(value.message_html).appendTo(li);
 321                  } else {
 322                      var m = value.message;
 323                      if (m.length > 100) {
 324                          m = m.substr(0, 100) + "...";
 325                      }
 326  
 327                      var val = $('<span />').addClass(csscls('value')).text(m).appendTo(li);
 328                      if (!value.is_string || value.message.length > 100) {
 329                          var prettyVal = value.message;
 330                          if (!value.is_string) {
 331                              prettyVal = null;
 332                          }
 333                          li.css('cursor', 'pointer').click(function () {
 334                              if (val.hasClass(csscls('pretty'))) {
 335                                  val.text(m).removeClass(csscls('pretty'));
 336                              } else {
 337                                  prettyVal = prettyVal || createCodeBlock(value.message, 'php');
 338                                  val.addClass(csscls('pretty')).empty().append(prettyVal);
 339                              }
 340                          });
 341                      }
 342                  }
 343  
 344                  if (value.collector) {
 345                      $('<span />').addClass(csscls('collector')).text(value.collector).prependTo(li);
 346                  }
 347                  if (value.label) {
 348                      val.addClass(csscls(value.label));
 349                      $('<span />').addClass(csscls('label')).text(value.label).prependTo(li);
 350                  }
 351              }});
 352  
 353              this.$list.$el.appendTo(this.$el);
 354              this.$toolbar = $('<div><i class="phpdebugbar-fa phpdebugbar-fa-search"></i></div>').addClass(csscls('toolbar')).appendTo(this.$el);
 355  
 356              $('<input type="text" />')
 357                  .on('change', function() { self.set('search', this.value); })
 358                  .appendTo(this.$toolbar);
 359  
 360              this.bindAttr('data', function(data) {
 361                  this.set({ exclude: [], search: '' });
 362                  this.$toolbar.find(csscls('.filter')).remove();
 363  
 364                  var filters = [], self = this;
 365                  for (var i = 0; i < data.length; i++) {
 366                      if (!data[i].label || $.inArray(data[i].label, filters) > -1) {
 367                          continue;
 368                      }
 369                      filters.push(data[i].label);
 370                      $('<a />')
 371                          .addClass(csscls('filter'))
 372                          .text(data[i].label)
 373                          .attr('rel', data[i].label)
 374                          .on('click', function() { self.onFilterClick(this); })
 375                          .appendTo(this.$toolbar);
 376                  }
 377              });
 378  
 379              this.bindAttr(['exclude', 'search'], function() {
 380                  var data = this.get('data'),
 381                      exclude = this.get('exclude'),
 382                      search = this.get('search'),
 383                      caseless = false,
 384                      fdata = [];
 385  
 386                  if (search && search === search.toLowerCase()) {
 387                      caseless = true;
 388                  }
 389  
 390                  for (var i = 0; i < data.length; i++) {
 391                      var message = caseless ? data[i].message.toLowerCase() : data[i].message;
 392  
 393                      if ((!data[i].label || $.inArray(data[i].label, exclude) === -1) && (!search || message.indexOf(search) > -1)) {
 394                          fdata.push(data[i]);
 395                      }
 396                  }
 397  
 398                  this.$list.set('data', fdata);
 399              });
 400          },
 401  
 402          onFilterClick: function(el) {
 403              $(el).toggleClass(csscls('excluded'));
 404  
 405              var excludedLabels = [];
 406              this.$toolbar.find(csscls('.filter') + csscls('.excluded')).each(function() {
 407                  excludedLabels.push(this.rel);
 408              });
 409  
 410              this.set('exclude', excludedLabels);
 411          }
 412  
 413      });
 414  
 415      // ------------------------------------------------------------------
 416  
 417      /**
 418       * Widget for the TimeDataCollector
 419       *
 420       * Options:
 421       *  - data
 422       */
 423      var TimelineWidget = PhpDebugBar.Widgets.TimelineWidget = PhpDebugBar.Widget.extend({
 424  
 425          tagName: 'ul',
 426  
 427          className: csscls('timeline'),
 428  
 429          render: function() {
 430              this.bindAttr('data', function(data) {
 431  
 432                  // ported from php DataFormatter
 433                  var formatDuration = function(seconds) {
 434                      if (seconds < 0.001)
 435                          return (seconds * 1000000).toFixed() + 'μs';
 436                      else if (seconds < 1)
 437                          return (seconds * 1000).toFixed(2) + 'ms';
 438                      return (seconds).toFixed(2) +  's';
 439                  };
 440  
 441                  this.$el.empty();
 442                  if (data.measures) {
 443                      var aggregate = {};
 444  
 445                      for (var i = 0; i < data.measures.length; i++) {
 446                          var measure = data.measures[i];
 447  
 448                          if(!aggregate[measure.label])
 449                              aggregate[measure.label] = { count: 0, duration: 0 };
 450  
 451                          aggregate[measure.label]['count'] += 1;
 452                          aggregate[measure.label]['duration'] += measure.duration;
 453  
 454                          var m = $('<div />').addClass(csscls('measure')),
 455                              li = $('<li />'),
 456                              left = (measure.relative_start * 100 / data.duration).toFixed(2),
 457                              width = Math.min((measure.duration * 100 / data.duration).toFixed(2), 100 - left);
 458  
 459                          m.append($('<span />').addClass(csscls('value')).css({
 460                              left: left + "%",
 461                              width: width + "%"
 462                          }));
 463                          m.append($('<span />').addClass(csscls('label')).text(measure.label + " (" + measure.duration_str + ")"));
 464  
 465                          if (measure.collector) {
 466                              $('<span />').addClass(csscls('collector')).text(measure.collector).appendTo(m);
 467                          }
 468  
 469                          m.appendTo(li);
 470                          this.$el.append(li);
 471  
 472                          if (measure.params && !$.isEmptyObject(measure.params)) {
 473                              var table = $('<table><tr><th colspan="2">Params</th></tr></table>').addClass(csscls('params')).appendTo(li);
 474                              for (var key in measure.params) {
 475                                  if (typeof measure.params[key] !== 'function') {
 476                                      table.append('<tr><td class="' + csscls('name') + '">' + key + '</td><td class="' + csscls('value') +
 477                                      '"><pre><code>' + measure.params[key] + '</code></pre></td></tr>');
 478                                  }
 479                              }
 480                              li.css('cursor', 'pointer').click(function() {
 481                                  var table = $(this).find('table');
 482                                  if (table.is(':visible')) {
 483                                      table.hide();
 484                                  } else {
 485                                      table.show();
 486                                  }
 487                              });
 488                          }
 489                      }
 490  
 491                      // convert to array and sort by duration
 492                      aggregate = $.map(aggregate, function(data, label) {
 493                         return {
 494                             label: label,
 495                             data: data
 496                         }
 497                      }).sort(function(a, b) {
 498                          return b.data.duration - a.data.duration
 499                      });
 500  
 501                      // build table and add
 502                      var aggregateTable = $('<table style="display: table; border: 0; width: 99%"></table>').addClass(csscls('params'));
 503                      $.each(aggregate, function(i, aggregate) {
 504                          width = Math.min((aggregate.data.duration * 100 / data.duration).toFixed(2), 100);
 505  
 506                          aggregateTable.append('<tr><td class="' + csscls('name') + '">' + aggregate.data.count + ' x ' + aggregate.label + ' (' + width + '%)</td><td class="' + csscls('value') + '">' +
 507                              '<div class="' + csscls('measure') +'">' +
 508                                  '<span class="' + csscls('value') + '" style="width:' + width + '%"></span>' +
 509                                  '<span class="' + csscls('label') + '">' + formatDuration(aggregate.data.duration) + '</span>' +
 510                              '</div></td></tr>');
 511                      });
 512  
 513                      this.$el.append('<li/>').find('li:last').append(aggregateTable);
 514                  }
 515              });
 516          }
 517  
 518      });
 519  
 520      // ------------------------------------------------------------------
 521  
 522      /**
 523       * Widget for the displaying exceptions
 524       *
 525       * Options:
 526       *  - data
 527       */
 528      var ExceptionsWidget = PhpDebugBar.Widgets.ExceptionsWidget = PhpDebugBar.Widget.extend({
 529  
 530          className: csscls('exceptions'),
 531  
 532          render: function() {
 533              this.$list = new ListWidget({ itemRenderer: function(li, e) {
 534                  $('<span />').addClass(csscls('message')).text(e.message).appendTo(li);
 535                  if (e.file) {
 536                      var header = $('<span />').addClass(csscls('filename')).text(e.file + "#" + e.line);
 537                      if (e.xdebug_link) {
 538                          if (e.xdebug_link.ajax) {
 539                              $('<a title="' + e.xdebug_link.url + '"></a>').on('click', function () {
 540                                  $.ajax(e.xdebug_link.url);
 541                              }).addClass(csscls('editor-link')).appendTo(header);
 542                          } else {
 543                              $('<a href="' + e.xdebug_link.url + '"></a>').addClass(csscls('editor-link')).appendTo(header);
 544                          }
 545                      }
 546                      header.appendTo(li);
 547                  }
 548                  if (e.type) {
 549                      $('<span />').addClass(csscls('type')).text(e.type).appendTo(li);
 550                  }
 551                  if (e.surrounding_lines) {
 552                      var pre = createCodeBlock(e.surrounding_lines.join(""), 'php').addClass(csscls('file')).appendTo(li);
 553                      if (!e.stack_trace_html) {
 554                          // This click event makes the var-dumper hard to use.
 555                          li.click(function () {
 556                              if (pre.is(':visible')) {
 557                                  pre.hide();
 558                              } else {
 559                                  pre.show();
 560                              }
 561                          });
 562                      }
 563                  }
 564                  if (e.stack_trace_html) {
 565                      var $trace = $('<span />').addClass(csscls('filename')).html(e.stack_trace_html);
 566                      $trace.appendTo(li);
 567                  } else if (e.stack_trace) {
 568                      e.stack_trace.split("\n").forEach(function (trace) {
 569                          var $traceLine = $('<div />');
 570                          $('<span />').addClass(csscls('filename')).text(trace).appendTo($traceLine);
 571                          $traceLine.appendTo(li);
 572                      });
 573                  }
 574              }});
 575              this.$list.$el.appendTo(this.$el);
 576  
 577              this.bindAttr('data', function(data) {
 578                  this.$list.set('data', data);
 579                  if (data.length == 1) {
 580                      this.$list.$el.children().first().find(csscls('.file')).show();
 581                  }
 582              });
 583  
 584          }
 585  
 586      });
 587  
 588  
 589  })(PhpDebugBar.$);


Generated: Wed Sep 7 05:41:13 2022 Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer