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