• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1// Copyright 2014 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5/**
6 * @typedef {{afterHighlight: string,
7 *            beforeHighlight: string,
8 *            highlight: string,
9 *            title: string}}
10 */
11var ExtensionHighlight;
12
13cr.define('extensions', function() {
14  'use strict';
15
16  /**
17   * ExtensionCode is an element which displays code in a styled div, and is
18   * designed to highlight errors.
19   * @constructor
20   * @extends {HTMLDivElement}
21   */
22  function ExtensionCode(div) {
23    div.__proto__ = ExtensionCode.prototype;
24    return div;
25  }
26
27  ExtensionCode.prototype = {
28    __proto__: HTMLDivElement.prototype,
29
30    /**
31     * Populate the content area of the code div with the given code. This will
32     * highlight the erroneous section (if any).
33     * @param {ExtensionHighlight} code The 'highlight' strings represent the
34     *     three portions of the file's content to display - the portion which
35     *     is most relevant and should be emphasized (highlight), and the parts
36     *     both before and after this portion. The title is the error message,
37     *     which will be the mouseover hint for the highlighted region. These
38     *     may be empty.
39     *  @param {string} emptyMessage The message to display if the code
40     *     object is empty (e.g., 'could not load code').
41     */
42    populate: function(code, emptyMessage) {
43      // Clear any remnant content, so we don't have multiple code listed.
44      this.clear();
45
46      var sourceDiv = document.createElement('div');
47      sourceDiv.classList.add('extension-code-source');
48      this.appendChild(sourceDiv);
49
50      // If there's no code, then display an appropriate message.
51      if (!code ||
52          (!code.highlight && !code.beforeHighlight && !code.afterHighlight)) {
53        var span = document.createElement('span');
54        span.textContent = emptyMessage;
55        sourceDiv.appendChild(span);
56        return;
57      }
58
59      var lineCount = 0;
60      var createSpan = function(source, isHighlighted) {
61        lineCount += source.split('\n').length - 1;
62        var span = document.createElement('span');
63        span.className = isHighlighted ? 'extension-code-highlighted-source' :
64                                         'extension-code-normal-source';
65        span.textContent = source;
66        return span;
67      };
68
69      if (code.beforeHighlight)
70        sourceDiv.appendChild(createSpan(code.beforeHighlight, false));
71
72      if (code.highlight) {
73        var highlightSpan = createSpan(code.highlight, true);
74        highlightSpan.title = code.message;
75        sourceDiv.appendChild(highlightSpan);
76      }
77
78      if (code.afterHighlight)
79        sourceDiv.appendChild(createSpan(code.afterHighlight, false));
80
81      // Make the line numbers. This should be the number of line breaks + 1
82      // (the last line doesn't break, but should still be numbered).
83      var content = '';
84      for (var i = 1; i < lineCount + 1; ++i)
85        content += i + '\n';
86      var span = document.createElement('span');
87      span.textContent = content;
88
89      var linesDiv = document.createElement('div');
90      linesDiv.classList.add('extension-code-line-numbers');
91      linesDiv.appendChild(span);
92      this.insertBefore(linesDiv, this.firstChild);
93    },
94
95    /**
96     * Clears the content of the element.
97     */
98    clear: function() {
99      while (this.firstChild)
100        this.removeChild(this.firstChild);
101    },
102
103    /**
104     * Scrolls to the error, if there is one. This cannot be called when the
105     * div is hidden.
106     */
107    scrollToError: function() {
108      var errorSpan = this.querySelector('.extension-code-highlighted-source');
109      if (errorSpan)
110        this.scrollTop = errorSpan.offsetTop - this.clientHeight / 2;
111    }
112  };
113
114  // Export
115  return {
116    ExtensionCode: ExtensionCode
117  };
118});
119