Skip to content

Instantly share code, notes, and snippets.

@Saminou24
Created October 3, 2013 16:46
Show Gist options
  • Save Saminou24/6813009 to your computer and use it in GitHub Desktop.
Save Saminou24/6813009 to your computer and use it in GitHub Desktop.
A Pen by Harris Novick.
<!--
Copyright (C) 2006, 2007, 2008 Apple Inc. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
its contributors may be used to endorse or promote products derived
from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<link rel="stylesheet" type="text/css" href="devTools.css">
<script type="text/javascript" src="DevTools.js"></script>
</head>
<body class="detached" id="webkit-web-inspector">
<div class="outer">
<div id="toolbar">
<div class="toolbar-item close-left"><button id="close-button-left"></button></div>
<div id="toolbar-controls">
<div class="toolbar-item"><button id="toolbar-dropdown-arrow" class="toolbar-label">&raquo;</button></div>
<div class="toolbar-item close-right"><button id="close-button-right"></button></div>
</div>
</div>
<div id="main">
<div id="floating-status-bar-container" class="status-bar"><div id="floating-status-bar-resizer"></div></div>
</div>
<div id="drawer"></div>
<div id="main-status-bar" class="status-bar">
<div id="bottom-status-bar-container">
<div id="panel-status-bar"></div>
</div>
<div id="error-warning-count" class="hidden"></div>
</div>
</div>
</body>
</html>
This file has been truncated, but you can view the full file.
Object.isEmpty = function(obj)
{
for (var i in obj)
return false;
return true;
}
Object.values = function(obj)
{
var keys = Object.keys(obj);
var result = [];
for (var i = 0; i < keys.length; ++i)
result.push(obj[keys[i]]);
return result;
}
String.prototype.hasSubstring = function(string, caseInsensitive)
{
if (!caseInsensitive)
return this.indexOf(string) !== -1;
return this.match(new RegExp(string.escapeForRegExp(), "i"));
}
String.prototype.findAll = function(string)
{
var matches = [];
var i = this.indexOf(string);
while (i !== -1) {
matches.push(i);
i = this.indexOf(string, i + string.length);
}
return matches;
}
String.prototype.lineEndings = function()
{
if (!this._lineEndings) {
this._lineEndings = this.findAll("\n");
this._lineEndings.push(this.length);
}
return this._lineEndings;
}
String.prototype.escapeCharacters = function(chars)
{
var foundChar = false;
for (var i = 0; i < chars.length; ++i) {
if (this.indexOf(chars.charAt(i)) !== -1) {
foundChar = true;
break;
}
}
if (!foundChar)
return this;
var result = "";
for (var i = 0; i < this.length; ++i) {
if (chars.indexOf(this.charAt(i)) !== -1)
result += "\\";
result += this.charAt(i);
}
return result;
}
String.prototype.escapeForRegExp = function()
{
return this.escapeCharacters("^[]{}()\\.$*+?|");
}
String.prototype.escapeHTML = function()
{
return this.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
}
String.prototype.collapseWhitespace = function()
{
return this.replace(/[\s\xA0]+/g, " ");
}
String.prototype.trimMiddle = function(maxLength)
{
if (this.length <= maxLength)
return this;
var leftHalf = maxLength >> 1;
var rightHalf = maxLength - leftHalf - 1;
return this.substr(0, leftHalf) + "\u2026" + this.substr(this.length - rightHalf, rightHalf);
}
String.prototype.trimEnd = function(maxLength)
{
if (this.length <= maxLength)
return this;
return this.substr(0, maxLength - 1) + "\u2026";
}
String.prototype.trimURL = function(baseURLDomain)
{
var result = this.replace(/^(https|http|file):\/\//i, "");
if (baseURLDomain)
result = result.replace(new RegExp("^" + baseURLDomain.escapeForRegExp(), "i"), "");
return result;
}
function sanitizeHref(href)
{
return href && href.trim().toLowerCase().startsWith("javascript:") ? "" : href;
}
String.prototype.removeURLFragment = function()
{
var fragmentIndex = this.indexOf("#");
if (fragmentIndex == -1)
fragmentIndex = this.length;
return this.substring(0, fragmentIndex);
}
String.prototype.startsWith = function(substring)
{
return !this.lastIndexOf(substring, 0);
}
String.prototype.endsWith = function(substring)
{
return this.indexOf(substring, this.length - substring.length) !== -1;
}
Number.constrain = function(num, min, max)
{
if (num < min)
num = min;
else if (num > max)
num = max;
return num;
}
Date.prototype.toISO8601Compact = function()
{
function leadZero(x)
{
return x > 9 ? '' + x : '0' + x
}
return this.getFullYear() +
leadZero(this.getMonth() + 1) +
leadZero(this.getDate()) + 'T' +
leadZero(this.getHours()) +
leadZero(this.getMinutes()) +
leadZero(this.getSeconds());
}
Object.defineProperty(Array.prototype, "remove",
{
value: function(value, onlyFirst)
{
if (onlyFirst) {
var index = this.indexOf(value);
if (index !== -1)
this.splice(index, 1);
return;
}
var length = this.length;
for (var i = 0; i < length; ++i) {
if (this[i] === value)
this.splice(i, 1);
}
}
});
Object.defineProperty(Array.prototype, "keySet",
{
value: function()
{
var keys = {};
for (var i = 0; i < this.length; ++i)
keys[this[i]] = true;
return keys;
}
});
Object.defineProperty(Array.prototype, "upperBound",
{
value: function(value)
{
var first = 0;
var count = this.length;
while (count > 0) {
var step = count >> 1;
var middle = first + step;
if (value >= this[middle]) {
first = middle + 1;
count -= step + 1;
} else
count = step;
}
return first;
}
});
Object.defineProperty(Array.prototype, "rotate",
{
value: function(index)
{
var result = [];
for (var i = index; i < index + this.length; ++i)
result.push(this[i % this.length]);
return result;
}
});
Object.defineProperty(Uint32Array.prototype, "sort", {
value: Array.prototype.sort
});
(function() {
var partition = {
value: function(comparator, left, right, pivotIndex)
{
function swap(array, i1, i2)
{
var temp = array[i1];
array[i1] = array[i2];
array[i2] = temp;
}
var pivotValue = this[pivotIndex];
swap(this, right, pivotIndex);
var storeIndex = left;
for (var i = left; i < right; ++i) {
if (comparator(this[i], pivotValue) < 0) {
swap(this, storeIndex, i);
++storeIndex;
}
}
swap(this, right, storeIndex);
return storeIndex;
}
};
Object.defineProperty(Array.prototype, "partition", partition);
Object.defineProperty(Uint32Array.prototype, "partition", partition);
var sortRange = {
value: function(comparator, leftBound, rightBound, k)
{
function quickSortFirstK(array, comparator, left, right, k)
{
if (right <= left)
return;
var pivotIndex = Math.floor(Math.random() * (right - left)) + left;
var pivotNewIndex = array.partition(comparator, left, right, pivotIndex);
quickSortFirstK(array, comparator, left, pivotNewIndex - 1, k);
if (pivotNewIndex < left + k - 1)
quickSortFirstK(array, comparator, pivotNewIndex + 1, right, k);
}
if (leftBound === 0 && rightBound === (this.length - 1) && k === this.length)
this.sort(comparator);
else
quickSortFirstK(this, comparator, leftBound, rightBound, k);
return this;
}
}
Object.defineProperty(Array.prototype, "sortRange", sortRange);
Object.defineProperty(Uint32Array.prototype, "sortRange", sortRange);
})();
Object.defineProperty(Array.prototype, "qselect",
{
value: function(k, comparator)
{
if (k < 0 || k >= this.length)
return;
if (!comparator)
comparator = function(a, b) { return a - b; }
var low = 0;
var high = this.length - 1;
for (;;) {
var pivotPosition = this.partition(comparator, low, high, Math.floor((high + low) / 2));
if (pivotPosition === k)
return this[k];
else if (pivotPosition > k)
high = pivotPosition - 1;
else
low = pivotPosition + 1;
}
}
});
function binarySearch(object, array, comparator)
{
var first = 0;
var last = array.length - 1;
while (first <= last) {
var mid = (first + last) >> 1;
var c = comparator(object, array[mid]);
if (c > 0)
first = mid + 1;
else if (c < 0)
last = mid - 1;
else
return mid;
}
return -(first + 1);
}
Object.defineProperty(Array.prototype, "binaryIndexOf",
{
value: function(value, comparator)
{
var result = binarySearch(value, this, comparator);
return result >= 0 ? result : -1;
}
});
Object.defineProperty(Array.prototype, "select",
{
value: function(field)
{
var result = new Array(this.length);
for (var i = 0; i < this.length; ++i)
result[i] = this[i][field];
return result;
}
});
function insertionIndexForObjectInListSortedByFunction(anObject, aList, aFunction)
{
var index = binarySearch(anObject, aList, aFunction);
if (index < 0)
return -index - 1;
else {
while (index > 0 && aFunction(anObject, aList[index - 1]) === 0)
index--;
return index;
}
}
Array.convert = function(list)
{
return Array.prototype.slice.call(list);
}
String.sprintf = function(format, var_arg)
{
return String.vsprintf(format, Array.prototype.slice.call(arguments, 1));
}
String.tokenizeFormatString = function(format, formatters)
{
var tokens = [];
var substitutionIndex = 0;
function addStringToken(str)
{
tokens.push({ type: "string", value: str });
}
function addSpecifierToken(specifier, precision, substitutionIndex)
{
tokens.push({ type: "specifier", specifier: specifier, precision: precision, substitutionIndex: substitutionIndex });
}
function isDigit(c)
{
return !!/[0-9]/.exec(c);
}
var index = 0;
for (var precentIndex = format.indexOf("%", index); precentIndex !== -1; precentIndex = format.indexOf("%", index)) {
addStringToken(format.substring(index, precentIndex));
index = precentIndex + 1;
if (isDigit(format[index])) {
var number = parseInt(format.substring(index), 10);
while (isDigit(format[index]))
++index;
if (number > 0 && format[index] === "$") {
substitutionIndex = (number - 1);
++index;
}
}
var precision = -1;
if (format[index] === ".") {
++index;
precision = parseInt(format.substring(index), 10);
if (isNaN(precision))
precision = 0;
while (isDigit(format[index]))
++index;
}
if (!(format[index] in formatters)) {
addStringToken(format.substring(precentIndex, index + 1));
++index;
continue;
}
addSpecifierToken(format[index], precision, substitutionIndex);
++substitutionIndex;
++index;
}
addStringToken(format.substring(index));
return tokens;
}
String.standardFormatters = {
d: function(substitution)
{
return !isNaN(substitution) ? substitution : 0;
},
f: function(substitution, token)
{
if (substitution && token.precision > -1)
substitution = substitution.toFixed(token.precision);
return !isNaN(substitution) ? substitution : (token.precision > -1 ? Number(0).toFixed(token.precision) : 0);
},
s: function(substitution)
{
return substitution;
}
}
String.vsprintf = function(format, substitutions)
{
return String.format(format, substitutions, String.standardFormatters, "", function(a, b) { return a + b; }).formattedResult;
}
String.format = function(format, substitutions, formatters, initialValue, append)
{
if (!format || !substitutions || !substitutions.length)
return { formattedResult: append(initialValue, format), unusedSubstitutions: substitutions };
function prettyFunctionName()
{
return "String.format(\"" + format + "\", \"" + substitutions.join("\", \"") + "\")";
}
function warn(msg)
{
console.warn(prettyFunctionName() + ": " + msg);
}
function error(msg)
{
console.error(prettyFunctionName() + ": " + msg);
}
var result = initialValue;
var tokens = String.tokenizeFormatString(format, formatters);
var usedSubstitutionIndexes = {};
for (var i = 0; i < tokens.length; ++i) {
var token = tokens[i];
if (token.type === "string") {
result = append(result, token.value);
continue;
}
if (token.type !== "specifier") {
error("Unknown token type \"" + token.type + "\" found.");
continue;
}
if (token.substitutionIndex >= substitutions.length) {
error("not enough substitution arguments. Had " + substitutions.length + " but needed " + (token.substitutionIndex + 1) + ", so substitution was skipped.");
result = append(result, "%" + (token.precision > -1 ? token.precision : "") + token.specifier);
continue;
}
usedSubstitutionIndexes[token.substitutionIndex] = true;
if (!(token.specifier in formatters)) {
warn("unsupported format character \u201C" + token.specifier + "\u201D. Treating as a string.");
result = append(result, substitutions[token.substitutionIndex]);
continue;
}
result = append(result, formatters[token.specifier](substitutions[token.substitutionIndex], token));
}
var unusedSubstitutions = [];
for (var i = 0; i < substitutions.length; ++i) {
if (i in usedSubstitutionIndexes)
continue;
unusedSubstitutions.push(substitutions[i]);
}
return { formattedResult: result, unusedSubstitutions: unusedSubstitutions };
}
function createSearchRegex(query, caseSensitive, isRegex)
{
var regexFlags = caseSensitive ? "g" : "gi";
var regexObject;
if (isRegex) {
try {
regexObject = new RegExp(query, regexFlags);
} catch (e) {
}
}
if (!regexObject)
regexObject = createPlainTextSearchRegex(query, regexFlags);
return regexObject;
}
function createPlainTextSearchRegex(query, flags)
{
var regexSpecialCharacters = "[](){}+-*.,?\\^$|";
var regex = "";
for (var i = 0; i < query.length; ++i) {
var c = query.charAt(i);
if (regexSpecialCharacters.indexOf(c) != -1)
regex += "\\";
regex += c;
}
return new RegExp(regex, flags || "");
}
function countRegexMatches(regex, content)
{
var text = content;
var result = 0;
var match;
while (text && (match = regex.exec(text))) {
if (match[0].length > 0)
++result;
text = text.substring(match.index + 1);
}
return result;
}
function numberToStringWithSpacesPadding(value, symbolsCount)
{
var numberString = value.toString();
var paddingLength = Math.max(0, symbolsCount - numberString.length);
var paddingString = Array(paddingLength + 1).join("\u00a0");
return paddingString + numberString;
}
var Map = function()
{
this._map = {};
this._size = 0;
}
Map._lastObjectIdentifier = 0;
Map.prototype = {
put: function(key, value)
{
var objectIdentifier = key.__identifier;
if (!objectIdentifier) {
objectIdentifier = ++Map._lastObjectIdentifier;
key.__identifier = objectIdentifier;
}
if (!this._map[objectIdentifier])
++this._size;
this._map[objectIdentifier] = [key, value];
},
remove: function(key)
{
var result = this._map[key.__identifier];
delete this._map[key.__identifier];
--this._size;
return result ? result[1] : undefined;
},
keys: function()
{
return this._list(0);
},
values: function()
{
return this._list(1);
},
_list: function(index)
{
var result = new Array(this._size);
var i = 0;
for (var objectIdentifier in this._map)
result[i++] = this._map[objectIdentifier][index];
return result;
},
get: function(key)
{
var entry = this._map[key.__identifier];
return entry ? entry[1] : undefined;
},
size: function()
{
return this._size;
},
clear: function()
{
this._map = {};
this._size = 0;
}
}
function loadXHR(url, async, callback)
{
function onReadyStateChanged()
{
if (xhr.readyState !== XMLHttpRequest.DONE)
return;
if (xhr.status === 200) {
callback(xhr.responseText);
return;
}
callback(null);
}
var xhr = new XMLHttpRequest();
xhr.open("GET", url, async);
if (async)
xhr.onreadystatechange = onReadyStateChanged;
xhr.send(null);
if (!async) {
if (xhr.status === 200)
return xhr.responseText;
return null;
}
return null;
}
function StringPool()
{
this.reset();
}
StringPool.prototype = {
intern: function(string)
{
if (string === "__proto__")
return "__proto__";
var result = this._strings[string];
if (result === undefined) {
this._strings[string] = string;
result = string;
}
return result;
},
reset: function()
{
this._strings = Object.create(null);
},
internObjectStrings: function(obj, depthLimit)
{
if (typeof depthLimit !== "number")
depthLimit = 100;
else if (--depthLimit < 0)
throw "recursion depth limit reached in StringPool.deepIntern(), perhaps attempting to traverse cyclical references?";
for (var field in obj) {
switch (typeof obj[field]) {
case "string":
obj[field] = this.intern(obj[field]);
break;
case "object":
this.internObjectStrings(obj[field], depthLimit);
break;
}
}
}
}
var _importedScripts = {};
function importScript(scriptName)
{
if (_importedScripts[scriptName])
return;
_importedScripts[scriptName] = true;
var xhr = new XMLHttpRequest();
xhr.open("GET", scriptName, false);
xhr.send(null);
window.eval(xhr.responseText + "\n//@ sourceURL=" + scriptName);
}
__whitespace = {" ":true, "\t":true, "\n":true, "\f":true, "\r":true};
difflib = {
defaultJunkFunction: function (c) {
return __whitespace.hasOwnProperty(c);
},
stripLinebreaks: function (str) { return str.replace(/^[\n\r]*|[\n\r]*$/g, ""); },
stringAsLines: function (str) {
var lfpos = str.indexOf("\n");
var crpos = str.indexOf("\r");
var linebreak = ((lfpos > -1 && crpos > -1) || crpos < 0) ? "\n" : "\r";
var lines = str.split(linebreak);
for (var i = 0; i < lines.length; i++) {
lines[i] = difflib.stripLinebreaks(lines[i]);
}
return lines;
},
__reduce: function (func, list, initial) {
if (initial != null) {
var value = initial;
var idx = 0;
} else if (list) {
var value = list[0];
var idx = 1;
} else {
return null;
}
for (; idx < list.length; idx++) {
value = func(value, list[idx]);
}
return value;
},
__ntuplecomp: function (a, b) {
var mlen = Math.max(a.length, b.length);
for (var i = 0; i < mlen; i++) {
if (a[i] < b[i]) return -1;
if (a[i] > b[i]) return 1;
}
return a.length == b.length ? 0 : (a.length < b.length ? -1 : 1);
},
__calculate_ratio: function (matches, length) {
return length ? 2.0 * matches / length : 1.0;
},
__isindict: function (dict) {
return function (key) { return dict.hasOwnProperty(key); };
},
__dictget: function (dict, key, defaultValue) {
return dict.hasOwnProperty(key) ? dict[key] : defaultValue;
},
SequenceMatcher: function (a, b, isjunk) {
this.set_seqs = function (a, b) {
this.set_seq1(a);
this.set_seq2(b);
}
this.set_seq1 = function (a) {
if (a == this.a) return;
this.a = a;
this.matching_blocks = this.opcodes = null;
}
this.set_seq2 = function (b) {
if (b == this.b) return;
this.b = b;
this.matching_blocks = this.opcodes = this.fullbcount = null;
this.__chain_b();
}
this.__chain_b = function () {
var b = this.b;
var n = b.length;
var b2j = this.b2j = {};
var populardict = {};
for (var i = 0; i < b.length; i++) {
var elt = b[i];
if (b2j.hasOwnProperty(elt)) {
var indices = b2j[elt];
if (n >= 200 && indices.length * 100 > n) {
populardict[elt] = 1;
delete b2j[elt];
} else {
indices.push(i);
}
} else {
b2j[elt] = [i];
}
}
for (var elt in populardict) {
if (populardict.hasOwnProperty(elt)) {
delete b2j[elt];
}
}
var isjunk = this.isjunk;
var junkdict = {};
if (isjunk) {
for (var elt in populardict) {
if (populardict.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete populardict[elt];
}
}
for (var elt in b2j) {
if (b2j.hasOwnProperty(elt) && isjunk(elt)) {
junkdict[elt] = 1;
delete b2j[elt];
}
}
}
this.isbjunk = difflib.__isindict(junkdict);
this.isbpopular = difflib.__isindict(populardict);
}
this.find_longest_match = function (alo, ahi, blo, bhi) {
var a = this.a;
var b = this.b;
var b2j = this.b2j;
var isbjunk = this.isbjunk;
var besti = alo;
var bestj = blo;
var bestsize = 0;
var j = null;
var j2len = {};
var nothing = [];
for (var i = alo; i < ahi; i++) {
var newj2len = {};
var jdict = difflib.__dictget(b2j, a[i], nothing);
for (var jkey in jdict) {
if (jdict.hasOwnProperty(jkey)) {
j = jdict[jkey];
if (j < blo) continue;
if (j >= bhi) break;
newj2len[j] = k = difflib.__dictget(j2len, j - 1, 0) + 1;
if (k > bestsize) {
besti = i - k + 1;
bestj = j - k + 1;
bestsize = k;
}
}
}
j2len = newj2len;
}
while (besti > alo && bestj > blo && !isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}
while (besti + bestsize < ahi && bestj + bestsize < bhi &&
!isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}
while (besti > alo && bestj > blo && isbjunk(b[bestj - 1]) && a[besti - 1] == b[bestj - 1]) {
besti--;
bestj--;
bestsize++;
}
while (besti + bestsize < ahi && bestj + bestsize < bhi && isbjunk(b[bestj + bestsize]) &&
a[besti + bestsize] == b[bestj + bestsize]) {
bestsize++;
}
return [besti, bestj, bestsize];
}
this.get_matching_blocks = function () {
if (this.matching_blocks != null) return this.matching_blocks;
var la = this.a.length;
var lb = this.b.length;
var queue = [[0, la, 0, lb]];
var matching_blocks = [];
var alo, ahi, blo, bhi, qi, i, j, k, x;
while (queue.length) {
qi = queue.pop();
alo = qi[0];
ahi = qi[1];
blo = qi[2];
bhi = qi[3];
x = this.find_longest_match(alo, ahi, blo, bhi);
i = x[0];
j = x[1];
k = x[2];
if (k) {
matching_blocks.push(x);
if (alo < i && blo < j)
queue.push([alo, i, blo, j]);
if (i+k < ahi && j+k < bhi)
queue.push([i + k, ahi, j + k, bhi]);
}
}
matching_blocks.sort(difflib.__ntuplecomp);
var i1 = j1 = k1 = block = 0;
var non_adjacent = [];
for (var idx in matching_blocks) {
if (matching_blocks.hasOwnProperty(idx)) {
block = matching_blocks[idx];
i2 = block[0];
j2 = block[1];
k2 = block[2];
if (i1 + k1 == i2 && j1 + k1 == j2) {
k1 += k2;
} else {
if (k1) non_adjacent.push([i1, j1, k1]);
i1 = i2;
j1 = j2;
k1 = k2;
}
}
}
if (k1) non_adjacent.push([i1, j1, k1]);
non_adjacent.push([la, lb, 0]);
this.matching_blocks = non_adjacent;
return this.matching_blocks;
}
this.get_opcodes = function () {
if (this.opcodes != null) return this.opcodes;
var i = 0;
var j = 0;
var answer = [];
this.opcodes = answer;
var block, ai, bj, size, tag;
var blocks = this.get_matching_blocks();
for (var idx in blocks) {
if (blocks.hasOwnProperty(idx)) {
block = blocks[idx];
ai = block[0];
bj = block[1];
size = block[2];
tag = '';
if (i < ai && j < bj) {
tag = 'replace';
} else if (i < ai) {
tag = 'delete';
} else if (j < bj) {
tag = 'insert';
}
if (tag) answer.push([tag, i, ai, j, bj]);
i = ai + size;
j = bj + size;
if (size) answer.push(['equal', ai, i, bj, j]);
}
}
return answer;
}
this.get_grouped_opcodes = function (n) {
if (!n) n = 3;
var codes = this.get_opcodes();
if (!codes) codes = [["equal", 0, 1, 0, 1]];
var code, tag, i1, i2, j1, j2;
if (codes[0][0] == 'equal') {
code = codes[0];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[0] = [tag, Math.max(i1, i2 - n), i2, Math.max(j1, j2 - n), j2];
}
if (codes[codes.length - 1][0] == 'equal') {
code = codes[codes.length - 1];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
codes[codes.length - 1] = [tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)];
}
var nn = n + n;
var groups = [];
for (var idx in codes) {
if (codes.hasOwnProperty(idx)) {
code = codes[idx];
tag = code[0];
i1 = code[1];
i2 = code[2];
j1 = code[3];
j2 = code[4];
if (tag == 'equal' && i2 - i1 > nn) {
groups.push([tag, i1, Math.min(i2, i1 + n), j1, Math.min(j2, j1 + n)]);
i1 = Math.max(i1, i2-n);
j1 = Math.max(j1, j2-n);
}
groups.push([tag, i1, i2, j1, j2]);
}
}
if (groups && groups[groups.length - 1][0] == 'equal') groups.pop();
return groups;
}
this.ratio = function () {
matches = difflib.__reduce(
function (sum, triple) { return sum + triple[triple.length - 1]; },
this.get_matching_blocks(), 0);
return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}
this.quick_ratio = function () {
var fullbcount, elt;
if (this.fullbcount == null) {
this.fullbcount = fullbcount = {};
for (var i = 0; i < this.b.length; i++) {
elt = this.b[i];
fullbcount[elt] = difflib.__dictget(fullbcount, elt, 0) + 1;
}
}
fullbcount = this.fullbcount;
var avail = {};
var availhas = difflib.__isindict(avail);
var matches = numb = 0;
for (var i = 0; i < this.a.length; i++) {
elt = this.a[i];
if (availhas(elt)) {
numb = avail[elt];
} else {
numb = difflib.__dictget(fullbcount, elt, 0);
}
avail[elt] = numb - 1;
if (numb > 0) matches++;
}
return difflib.__calculate_ratio(matches, this.a.length + this.b.length);
}
this.real_quick_ratio = function () {
var la = this.a.length;
var lb = this.b.length;
return _calculate_ratio(Math.min(la, lb), la + lb);
}
this.isjunk = isjunk ? isjunk : difflib.defaultJunkFunction;
this.a = this.b = null;
this.set_seqs(a, b);
}
}
Node.prototype.rangeOfWord = function(offset, stopCharacters, stayWithinNode, direction)
{
var startNode;
var startOffset = 0;
var endNode;
var endOffset = 0;
if (!stayWithinNode)
stayWithinNode = this;
if (!direction || direction === "backward" || direction === "both") {
var node = this;
while (node) {
if (node === stayWithinNode) {
if (!startNode)
startNode = stayWithinNode;
break;
}
if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? (offset - 1) : (node.nodeValue.length - 1));
for (var i = start; i >= 0; --i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
startNode = node;
startOffset = i + 1;
break;
}
}
}
if (startNode)
break;
node = node.traversePreviousNode(stayWithinNode);
}
if (!startNode) {
startNode = stayWithinNode;
startOffset = 0;
}
} else {
startNode = this;
startOffset = offset;
}
if (!direction || direction === "forward" || direction === "both") {
node = this;
while (node) {
if (node === stayWithinNode) {
if (!endNode)
endNode = stayWithinNode;
break;
}
if (node.nodeType === Node.TEXT_NODE) {
var start = (node === this ? offset : 0);
for (var i = start; i < node.nodeValue.length; ++i) {
if (stopCharacters.indexOf(node.nodeValue[i]) !== -1) {
endNode = node;
endOffset = i;
break;
}
}
}
if (endNode)
break;
node = node.traverseNextNode(stayWithinNode);
}
if (!endNode) {
endNode = stayWithinNode;
endOffset = stayWithinNode.nodeType === Node.TEXT_NODE ? stayWithinNode.nodeValue.length : stayWithinNode.childNodes.length;
}
} else {
endNode = this;
endOffset = offset;
}
var result = this.ownerDocument.createRange();
result.setStart(startNode, startOffset);
result.setEnd(endNode, endOffset);
return result;
}
Node.prototype.traverseNextTextNode = function(stayWithin)
{
var node = this.traverseNextNode(stayWithin);
if (!node)
return;
while (node && node.nodeType !== Node.TEXT_NODE)
node = node.traverseNextNode(stayWithin);
return node;
}
Node.prototype.rangeBoundaryForOffset = function(offset)
{
var node = this.traverseNextTextNode(this);
while (node && offset > node.nodeValue.length) {
offset -= node.nodeValue.length;
node = node.traverseNextTextNode(this);
}
if (!node)
return { container: this, offset: 0 };
return { container: node, offset: offset };
}
Element.prototype.removeStyleClass = function(className)
{
this.classList.remove(className);
}
Element.prototype.removeMatchingStyleClasses = function(classNameRegex)
{
var regex = new RegExp("(^|\\s+)" + classNameRegex + "($|\\s+)");
if (regex.test(this.className))
this.className = this.className.replace(regex, " ");
}
Element.prototype.addStyleClass = function(className)
{
this.classList.add(className);
}
Element.prototype.hasStyleClass = function(className)
{
return this.classList.contains(className);
}
Element.prototype.positionAt = function(x, y)
{
this.style.left = x + "px";
this.style.top = y + "px";
}
Element.prototype.pruneEmptyTextNodes = function()
{
var sibling = this.firstChild;
while (sibling) {
var nextSibling = sibling.nextSibling;
if (sibling.nodeType === this.TEXT_NODE && sibling.nodeValue === "")
this.removeChild(sibling);
sibling = nextSibling;
}
}
Element.prototype.isScrolledToBottom = function()
{
return this.scrollTop + this.clientHeight === this.scrollHeight;
}
Node.prototype.enclosingNodeOrSelfWithNodeNameInArray = function(nameArray)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
for (var i = 0; i < nameArray.length; ++i)
if (node.nodeName.toLowerCase() === nameArray[i].toLowerCase())
return node;
return null;
}
Node.prototype.enclosingNodeOrSelfWithNodeName = function(nodeName)
{
return this.enclosingNodeOrSelfWithNodeNameInArray([nodeName]);
}
Node.prototype.enclosingNodeOrSelfWithClass = function(className)
{
for (var node = this; node && node !== this.ownerDocument; node = node.parentNode)
if (node.nodeType === Node.ELEMENT_NODE && node.hasStyleClass(className))
return node;
return null;
}
Node.prototype.enclosingNodeWithClass = function(className)
{
if (!this.parentNode)
return null;
return this.parentNode.enclosingNodeOrSelfWithClass(className);
}
Element.prototype.query = function(query)
{
return this.ownerDocument.evaluate(query, this, null, XPathResult.FIRST_ORDERED_NODE_TYPE, null).singleNodeValue;
}
Element.prototype.removeChildren = function()
{
if (this.firstChild)
this.textContent = "";
}
Element.prototype.isInsertionCaretInside = function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;
var selectionRange = selection.getRangeAt(0);
return selectionRange.startContainer.isSelfOrDescendant(this);
}
Element.prototype.createChild = function(elementName, className)
{
var element = this.ownerDocument.createElement(elementName);
if (className)
element.className = className;
this.appendChild(element);
return element;
}
DocumentFragment.prototype.createChild = Element.prototype.createChild;
Element.prototype.createTextChild = function(text)
{
var element = this.ownerDocument.createTextNode(text);
this.appendChild(element);
return element;
}
DocumentFragment.prototype.createTextChild = Element.prototype.createTextChild;
Element.prototype.totalOffsetLeft = function()
{
return this.totalOffset().left;
}
Element.prototype.totalOffsetTop = function()
{
return this.totalOffset().top;
}
Element.prototype.totalOffset = function()
{
var totalLeft = 0;
var totalTop = 0;
for (var element = this; element; element = element.offsetParent) {
totalLeft += element.offsetLeft;
totalTop += element.offsetTop;
if (this !== element) {
totalLeft += element.clientLeft - element.scrollLeft;
totalTop += element.clientTop - element.scrollTop;
}
}
return { left: totalLeft, top: totalTop };
}
Element.prototype.scrollOffset = function()
{
var curLeft = 0;
var curTop = 0;
for (var element = this; element; element = element.scrollParent) {
curLeft += element.scrollLeft;
curTop += element.scrollTop;
}
return { left: curLeft, top: curTop };
}
function AnchorBox(x, y, width, height)
{
this.x = x || 0;
this.y = y || 0;
this.width = width || 0;
this.height = height || 0;
}
Element.prototype.offsetRelativeToWindow = function(targetWindow)
{
var elementOffset = new AnchorBox();
var curElement = this;
var curWindow = this.ownerDocument.defaultView;
while (curWindow && curElement) {
elementOffset.x += curElement.totalOffsetLeft();
elementOffset.y += curElement.totalOffsetTop();
if (curWindow === targetWindow)
break;
curElement = curWindow.frameElement;
curWindow = curWindow.parent;
}
return elementOffset;
}
Element.prototype.boxInWindow = function(targetWindow)
{
targetWindow = targetWindow || this.ownerDocument.defaultView;
var anchorBox = this.offsetRelativeToWindow(window);
anchorBox.width = Math.min(this.offsetWidth, window.innerWidth - anchorBox.x);
anchorBox.height = Math.min(this.offsetHeight, window.innerHeight - anchorBox.y);
return anchorBox;
}
Element.prototype.setTextAndTitle = function(text)
{
this.textContent = text;
this.title = text;
}
KeyboardEvent.prototype.__defineGetter__("data", function()
{
switch (this.type) {
case "keypress":
if (!this.ctrlKey && !this.metaKey)
return String.fromCharCode(this.charCode);
else
return "";
case "keydown":
case "keyup":
if (!this.ctrlKey && !this.metaKey && !this.altKey)
return String.fromCharCode(this.which);
else
return "";
}
});
Event.prototype.consume = function(preventDefault)
{
this.stopImmediatePropagation();
if (preventDefault)
this.preventDefault();
this.handled = true;
}
Text.prototype.select = function(start, end)
{
start = start || 0;
end = end || this.textContent.length;
if (start < 0)
start = end + start;
var selection = this.ownerDocument.defaultView.getSelection();
selection.removeAllRanges();
var range = this.ownerDocument.createRange();
range.setStart(this, start);
range.setEnd(this, end);
selection.addRange(range);
return this;
}
Element.prototype.selectionLeftOffset = function()
{
var selection = window.getSelection();
if (!selection.containsNode(this, true))
return null;
var leftOffset = selection.anchorOffset;
var node = selection.anchorNode;
while (node !== this) {
while (node.previousSibling) {
node = node.previousSibling;
leftOffset += node.textContent.length;
}
node = node.parentNode;
}
return leftOffset;
}
Node.prototype.isAncestor = function(node)
{
if (!node)
return false;
var currentNode = node.parentNode;
while (currentNode) {
if (this === currentNode)
return true;
currentNode = currentNode.parentNode;
}
return false;
}
Node.prototype.isDescendant = function(descendant)
{
return !!descendant && descendant.isAncestor(this);
}
Node.prototype.isSelfOrAncestor = function(node)
{
return !!node && (node === this || this.isAncestor(node));
}
Node.prototype.isSelfOrDescendant = function(node)
{
return !!node && (node === this || this.isDescendant(node));
}
Node.prototype.traverseNextNode = function(stayWithin)
{
var node = this.firstChild;
if (node)
return node;
if (stayWithin && this === stayWithin)
return null;
node = this.nextSibling;
if (node)
return node;
node = this;
while (node && !node.nextSibling && (!stayWithin || !node.parentNode || node.parentNode !== stayWithin))
node = node.parentNode;
if (!node)
return null;
return node.nextSibling;
}
Node.prototype.traversePreviousNode = function(stayWithin)
{
if (stayWithin && this === stayWithin)
return null;
var node = this.previousSibling;
while (node && node.lastChild)
node = node.lastChild;
if (node)
return node;
return this.parentNode;
}
HTMLTextAreaElement.prototype.moveCursorToEnd = function()
{
var length = this.value.length;
this.setSelectionRange(length, length);
}
function isEnterKey(event) {
return event.keyCode !== 229 && event.keyIdentifier === "Enter";
}
function consumeEvent(e)
{
e.consume();
}
function TreeOutline(listNode, nonFocusable)
{
this.children = [];
this.selectedTreeElement = null;
this._childrenListNode = listNode;
this.childrenListElement = this._childrenListNode;
this._childrenListNode.removeChildren();
this.expandTreeElementsWhenArrowing = false;
this.root = true;
this.hasChildren = false;
this.expanded = true;
this.selected = false;
this.treeOutline = this;
this.comparator = null;
this.searchable = false;
this.searchInputElement = null;
this.setFocusable(!nonFocusable);
this._childrenListNode.addEventListener("keydown", this._treeKeyDown.bind(this), true);
this._childrenListNode.addEventListener("keypress", this._treeKeyPress.bind(this), true);
this._treeElementsMap = new Map();
this._expandedStateMap = new Map();
}
TreeOutline.prototype.setFocusable = function(focusable)
{
if (focusable)
this._childrenListNode.setAttribute("tabIndex", 0);
else
this._childrenListNode.removeAttribute("tabIndex");
}
TreeOutline.prototype.appendChild = function(child)
{
var insertionIndex;
if (this.treeOutline.comparator)
insertionIndex = insertionIndexForObjectInListSortedByFunction(child, this.children, this.treeOutline.comparator);
else
insertionIndex = this.children.length;
this.insertChild(child, insertionIndex);
}
TreeOutline.prototype.insertChild = function(child, index)
{
if (!child)
throw("child can't be undefined or null");
var previousChild = (index > 0 ? this.children[index - 1] : null);
if (previousChild) {
previousChild.nextSibling = child;
child.previousSibling = previousChild;
} else {
child.previousSibling = null;
}
var nextChild = this.children[index];
if (nextChild) {
nextChild.previousSibling = child;
child.nextSibling = nextChild;
} else {
child.nextSibling = null;
}
this.children.splice(index, 0, child);
this.hasChildren = true;
child.parent = this;
child.treeOutline = this.treeOutline;
child.treeOutline._rememberTreeElement(child);
var current = child.children[0];
while (current) {
current.treeOutline = this.treeOutline;
current.treeOutline._rememberTreeElement(current);
current = current.traverseNextTreeElement(false, child, true);
}
if (child.hasChildren && typeof(child.treeOutline._expandedStateMap.get(child.representedObject)) !== "undefined")
child.expanded = child.treeOutline._expandedStateMap.get(child.representedObject);
if (!this._childrenListNode) {
this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.classList.add("children");
if (this.hidden)
this._childrenListNode.classList.add("hidden");
}
child._attach();
}
TreeOutline.prototype.removeChildAtIndex = function(childIndex)
{
if (childIndex < 0 || childIndex >= this.children.length)
throw("childIndex out of range");
var child = this.children[childIndex];
this.children.splice(childIndex, 1);
var parent = child.parent;
if (child.deselect()) {
if (child.previousSibling)
child.previousSibling.select();
else if (child.nextSibling)
child.nextSibling.select();
else
parent.select();
}
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}
child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}
TreeOutline.prototype.removeChild = function(child)
{
if (!child)
throw("child can't be undefined or null");
var childIndex = this.children.indexOf(child);
if (childIndex === -1)
throw("child not found in this node's children");
this.removeChildAtIndex.call(this, childIndex);
}
TreeOutline.prototype.removeChildren = function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();
if (child.treeOutline) {
child.treeOutline._forgetTreeElement(child);
child.treeOutline._forgetChildrenRecursive(child);
}
child._detach();
child.treeOutline = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}
this.children = [];
}
TreeOutline.prototype._rememberTreeElement = function(element)
{
if (!this._treeElementsMap.get(element.representedObject))
this._treeElementsMap.put(element.representedObject, []);
var elements = this._treeElementsMap.get(element.representedObject);
if (elements.indexOf(element) !== -1)
return;
elements.push(element);
}
TreeOutline.prototype._forgetTreeElement = function(element)
{
if (this._treeElementsMap.get(element.representedObject))
this._treeElementsMap.get(element.representedObject).remove(element, true);
}
TreeOutline.prototype._forgetChildrenRecursive = function(parentElement)
{
var child = parentElement.children[0];
while (child) {
this._forgetTreeElement(child);
child = child.traverseNextTreeElement(false, parentElement, true);
}
}
TreeOutline.prototype.getCachedTreeElement = function(representedObject)
{
if (!representedObject)
return null;
var elements = this._treeElementsMap.get(representedObject);
if (elements && elements.length)
return elements[0];
return null;
}
TreeOutline.prototype.findTreeElement = function(representedObject, isAncestor, getParent)
{
if (!representedObject)
return null;
var cachedElement = this.getCachedTreeElement(representedObject);
if (cachedElement)
return cachedElement;
var item;
var found = false;
for (var i = 0; i < this.children.length; ++i) {
item = this.children[i];
if (item.representedObject === representedObject || isAncestor(item.representedObject, representedObject)) {
found = true;
break;
}
}
if (!found)
return null;
var ancestors = [];
var currentObject = representedObject;
while (currentObject) {
ancestors.unshift(currentObject);
if (currentObject === item.representedObject)
break;
currentObject = getParent(currentObject);
}
for (var i = 0; i < ancestors.length; ++i) {
if (ancestors[i] === representedObject)
continue;
item = this.findTreeElement(ancestors[i], isAncestor, getParent);
if (item)
item.onpopulate();
}
return this.getCachedTreeElement(representedObject);
}
TreeOutline.prototype.treeElementFromPoint = function(x, y)
{
var node = this._childrenListNode.ownerDocument.elementFromPoint(x, y);
if (!node)
return null;
var listNode = node.enclosingNodeOrSelfWithNodeNameInArray(["ol", "li"]);
if (listNode)
return listNode.parentTreeElement || listNode.treeElement;
return null;
}
TreeOutline.prototype._treeKeyPress = function(event)
{
if (!this.searchable || WebInspector.isBeingEdited(this._childrenListNode))
return;
var searchText = String.fromCharCode(event.charCode);
if (searchText.trim() !== searchText)
return;
this._startSearch(searchText);
event.consume(true);
}
TreeOutline.prototype._treeKeyDown = function(event)
{
if (event.target !== this._childrenListNode)
return;
if (!this.selectedTreeElement || event.shiftKey || event.metaKey || event.ctrlKey)
return;
var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traversePreviousTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traversePreviousTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedElement = this.selectedTreeElement.traverseNextTreeElement(true);
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.traverseNextTreeElement(!this.expandTreeElementsWhenArrowing);
handled = nextSelectedElement ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedTreeElement.expanded) {
if (event.altKey)
this.selectedTreeElement.collapseRecursively();
else
this.selectedTreeElement.collapse();
handled = true;
} else if (this.selectedTreeElement.parent && !this.selectedTreeElement.parent.root) {
handled = true;
if (this.selectedTreeElement.parent.selectable) {
nextSelectedElement = this.selectedTreeElement.parent;
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.parent;
handled = nextSelectedElement ? true : false;
} else if (this.selectedTreeElement.parent)
this.selectedTreeElement.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedTreeElement.revealed()) {
this.selectedTreeElement.reveal();
handled = true;
} else if (this.selectedTreeElement.hasChildren) {
handled = true;
if (this.selectedTreeElement.expanded) {
nextSelectedElement = this.selectedTreeElement.children[0];
while (nextSelectedElement && !nextSelectedElement.selectable)
nextSelectedElement = nextSelectedElement.nextSibling;
handled = nextSelectedElement ? true : false;
} else {
if (event.altKey)
this.selectedTreeElement.expandRecursively();
else
this.selectedTreeElement.expand();
}
}
} else if (event.keyCode === 8 || event.keyCode === 46 )
handled = this.selectedTreeElement.ondelete();
else if (isEnterKey(event))
handled = this.selectedTreeElement.onenter();
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
handled = this.selectedTreeElement.onspace();
if (nextSelectedElement) {
nextSelectedElement.reveal();
nextSelectedElement.select(false, true);
}
if (handled)
event.consume(true);
}
TreeOutline.prototype.expand = function()
{
}
TreeOutline.prototype.collapse = function()
{
}
TreeOutline.prototype.revealed = function()
{
return true;
}
TreeOutline.prototype.reveal = function()
{
}
TreeOutline.prototype.select = function()
{
}
TreeOutline.prototype.revealAndSelect = function(omitFocus)
{
}
TreeOutline.prototype._startSearch = function(searchText)
{
if (!this.searchInputElement || !this.searchable)
return;
this._searching = true;
if (this.searchStarted)
this.searchStarted();
this.searchInputElement.value = searchText;
function focusSearchInput()
{
this.searchInputElement.focus();
}
window.setTimeout(focusSearchInput.bind(this), 0);
this._searchTextChanged();
this._boundSearchTextChanged = this._searchTextChanged.bind(this);
this.searchInputElement.addEventListener("paste", this._boundSearchTextChanged);
this.searchInputElement.addEventListener("cut", this._boundSearchTextChanged);
this.searchInputElement.addEventListener("keypress", this._boundSearchTextChanged);
this._boundSearchInputKeyDown = this._searchInputKeyDown.bind(this);
this.searchInputElement.addEventListener("keydown", this._boundSearchInputKeyDown);
this._boundSearchInputBlur = this._searchInputBlur.bind(this);
this.searchInputElement.addEventListener("blur", this._boundSearchInputBlur);
}
TreeOutline.prototype._searchTextChanged = function()
{
function updateSearch()
{
var nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, false);
if (!nextSelectedElement)
nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.children[0], false);
this._showSearchMatchElement(nextSelectedElement);
}
window.setTimeout(updateSearch.bind(this), 0);
}
TreeOutline.prototype._showSearchMatchElement = function(treeElement)
{
this._currentSearchMatchElement = treeElement;
if (treeElement) {
this._childrenListNode.classList.add("search-match-found");
this._childrenListNode.classList.remove("search-match-not-found");
treeElement.revealAndSelect(true);
} else {
this._childrenListNode.classList.remove("search-match-found");
this._childrenListNode.classList.add("search-match-not-found");
}
}
TreeOutline.prototype._searchInputKeyDown = function(event)
{
if (event.shiftKey || event.metaKey || event.ctrlKey || event.altKey)
return;
var handled = false;
var nextSelectedElement;
if (event.keyIdentifier === "Down") {
nextSelectedElement = this._nextSearchMatch(this.searchInputElement.value, this.selectedTreeElement, true);
handled = true;
} else if (event.keyIdentifier === "Up") {
nextSelectedElement = this._previousSearchMatch(this.searchInputElement.value, this.selectedTreeElement);
handled = true;
} else if (event.keyCode === 27 ) {
this._searchFinished();
handled = true;
} else if (isEnterKey(event)) {
var lastSearchMatchElement = this._currentSearchMatchElement;
this._searchFinished();
lastSearchMatchElement.onenter();
handled = true;
}
if (nextSelectedElement)
this._showSearchMatchElement(nextSelectedElement);
if (handled)
event.consume(true);
else
window.setTimeout(this._boundSearchTextChanged, 0);
}
TreeOutline.prototype._nextSearchMatch = function(searchText, startTreeElement, skipStartTreeElement)
{
var currentTreeElement = startTreeElement;
var skipCurrentTreeElement = skipStartTreeElement;
while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
currentTreeElement = currentTreeElement.traverseNextTreeElement(true, null, true);
skipCurrentTreeElement = false;
}
return currentTreeElement;
}
TreeOutline.prototype._previousSearchMatch = function(searchText, startTreeElement)
{
var currentTreeElement = startTreeElement;
var skipCurrentTreeElement = true;
while (currentTreeElement && (skipCurrentTreeElement || !currentTreeElement.matchesSearchText || !currentTreeElement.matchesSearchText(searchText))) {
currentTreeElement = currentTreeElement.traversePreviousTreeElement(true, true);
skipCurrentTreeElement = false;
}
return currentTreeElement;
}
TreeOutline.prototype._searchInputBlur = function(event)
{
this._searchFinished();
}
TreeOutline.prototype._searchFinished = function()
{
if (!this._searching)
return;
delete this._searching;
this._childrenListNode.classList.remove("search-match-found");
this._childrenListNode.classList.remove("search-match-not-found");
delete this._currentSearchMatchElement;
this.searchInputElement.value = "";
this.searchInputElement.removeEventListener("paste", this._boundSearchTextChanged);
this.searchInputElement.removeEventListener("cut", this._boundSearchTextChanged);
delete this._boundSearchTextChanged;
this.searchInputElement.removeEventListener("keydown", this._boundSearchInputKeyDown);
delete this._boundSearchInputKeyDown;
this.searchInputElement.removeEventListener("blur", this._boundSearchInputBlur);
delete this._boundSearchInputBlur;
if (this.searchFinished)
this.searchFinished();
this.treeOutline._childrenListNode.focus();
}
TreeOutline.prototype.stopSearch = function()
{
this._searchFinished();
}
function TreeElement(title, representedObject, hasChildren)
{
this._title = title;
this.representedObject = (representedObject || {});
this._hidden = false;
this._selectable = true;
this.expanded = false;
this.selected = false;
this.hasChildren = hasChildren;
this.children = [];
this.treeOutline = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this._listItemNode = null;
}
TreeElement.prototype = {
arrowToggleWidth: 10,
get selectable() {
if (this._hidden)
return false;
return this._selectable;
},
set selectable(x) {
this._selectable = x;
},
get listItemElement() {
return this._listItemNode;
},
get childrenListElement() {
return this._childrenListNode;
},
get title() {
return this._title;
},
set title(x) {
this._title = x;
this._setListItemNodeContent();
},
get tooltip() {
return this._tooltip;
},
set tooltip(x) {
this._tooltip = x;
if (this._listItemNode)
this._listItemNode.title = x ? x : "";
},
get hasChildren() {
return this._hasChildren;
},
set hasChildren(x) {
if (this._hasChildren === x)
return;
this._hasChildren = x;
if (!this._listItemNode)
return;
if (x)
this._listItemNode.classList.add("parent");
else {
this._listItemNode.classList.remove("parent");
this.collapse();
}
},
get hidden() {
return this._hidden;
},
set hidden(x) {
if (this._hidden === x)
return;
this._hidden = x;
if (x) {
if (this._listItemNode)
this._listItemNode.classList.add("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.add("hidden");
} else {
if (this._listItemNode)
this._listItemNode.classList.remove("hidden");
if (this._childrenListNode)
this._childrenListNode.classList.remove("hidden");
}
},
get shouldRefreshChildren() {
return this._shouldRefreshChildren;
},
set shouldRefreshChildren(x) {
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},
_setListItemNodeContent: function()
{
if (!this._listItemNode)
return;
if (typeof this._title === "string")
this._listItemNode.textContent = this._title;
else {
this._listItemNode.removeChildren();
if (this._title)
this._listItemNode.appendChild(this._title);
}
}
}
TreeElement.prototype.appendChild = TreeOutline.prototype.appendChild;
TreeElement.prototype.insertChild = TreeOutline.prototype.insertChild;
TreeElement.prototype.removeChild = TreeOutline.prototype.removeChild;
TreeElement.prototype.removeChildAtIndex = TreeOutline.prototype.removeChildAtIndex;
TreeElement.prototype.removeChildren = TreeOutline.prototype.removeChildren;
TreeElement.prototype._attach = function()
{
if (!this._listItemNode || this.parent._shouldRefreshChildren) {
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);
this._listItemNode = this.treeOutline._childrenListNode.ownerDocument.createElement("li");
this._listItemNode.treeElement = this;
this._setListItemNodeContent();
this._listItemNode.title = this._tooltip ? this._tooltip : "";
if (this.hidden)
this._listItemNode.classList.add("hidden");
if (this.hasChildren)
this._listItemNode.classList.add("parent");
if (this.expanded)
this._listItemNode.classList.add("expanded");
if (this.selected)
this._listItemNode.classList.add("selected");
this._listItemNode.addEventListener("mousedown", TreeElement.treeElementMouseDown, false);
this._listItemNode.addEventListener("click", TreeElement.treeElementToggled, false);
this._listItemNode.addEventListener("dblclick", TreeElement.treeElementDoubleClicked, false);
this.onattach();
}
var nextSibling = null;
if (this.nextSibling && this.nextSibling._listItemNode && this.nextSibling._listItemNode.parentNode === this.parent._childrenListNode)
nextSibling = this.nextSibling._listItemNode;
this.parent._childrenListNode.insertBefore(this._listItemNode, nextSibling);
if (this._childrenListNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
if (this.selected)
this.select();
if (this.expanded)
this.expand();
}
TreeElement.prototype._detach = function()
{
if (this._listItemNode && this._listItemNode.parentNode)
this._listItemNode.parentNode.removeChild(this._listItemNode);
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);
}
TreeElement.treeElementMouseDown = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement || !element.treeElement.selectable)
return;
if (element.treeElement.isEventWithinDisclosureTriangle(event))
return;
element.treeElement.selectOnMouseDown(event);
}
TreeElement.treeElementToggled = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;
var toggleOnClick = element.treeElement.toggleOnClick && !element.treeElement.selectable;
var isInTriangle = element.treeElement.isEventWithinDisclosureTriangle(event);
if (!toggleOnClick && !isInTriangle)
return;
if (element.treeElement.expanded) {
if (event.altKey)
element.treeElement.collapseRecursively();
else
element.treeElement.collapse();
} else {
if (event.altKey)
element.treeElement.expandRecursively();
else
element.treeElement.expand();
}
event.consume();
}
TreeElement.treeElementDoubleClicked = function(event)
{
var element = event.currentTarget;
if (!element || !element.treeElement)
return;
var handled = element.treeElement.ondblclick.call(element.treeElement, event);
if (handled)
return;
if (element.treeElement.hasChildren && !element.treeElement.expanded)
element.treeElement.expand();
}
TreeElement.prototype.collapse = function()
{
if (this._listItemNode)
this._listItemNode.classList.remove("expanded");
if (this._childrenListNode)
this._childrenListNode.classList.remove("expanded");
this.expanded = false;
if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, false);
this.oncollapse();
}
TreeElement.prototype.collapseRecursively = function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextTreeElement(false, this, true);
}
}
TreeElement.prototype.expand = function()
{
if (!this.hasChildren || (this.expanded && !this._shouldRefreshChildren && this._childrenListNode))
return;
this.expanded = true;
if (this.treeOutline)
this.treeOutline._expandedStateMap.put(this.representedObject, true);
if (this.treeOutline && (!this._childrenListNode || this._shouldRefreshChildren)) {
if (this._childrenListNode && this._childrenListNode.parentNode)
this._childrenListNode.parentNode.removeChild(this._childrenListNode);
this._childrenListNode = this.treeOutline._childrenListNode.ownerDocument.createElement("ol");
this._childrenListNode.parentTreeElement = this;
this._childrenListNode.classList.add("children");
if (this.hidden)
this._childrenListNode.classList.add("hidden");
this.onpopulate();
for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();
delete this._shouldRefreshChildren;
}
if (this._listItemNode) {
this._listItemNode.classList.add("expanded");
if (this._childrenListNode && this._childrenListNode.parentNode != this._listItemNode.parentNode)
this.parent._childrenListNode.insertBefore(this._childrenListNode, this._listItemNode.nextSibling);
}
if (this._childrenListNode)
this._childrenListNode.classList.add("expanded");
this.onexpand();
}
TreeElement.prototype.expandRecursively = function(maxDepth)
{
var item = this;
var info = {};
var depth = 0;
if (typeof maxDepth === "undefined" || typeof maxDepth === "null")
maxDepth = 3;
while (item) {
if (depth < maxDepth)
item.expand();
item = item.traverseNextTreeElement(false, this, (depth >= maxDepth), info);
depth += info.depthChange;
}
}
TreeElement.prototype.hasAncestor = function(ancestor) {
if (!ancestor)
return false;
var currentNode = this.parent;
while (currentNode) {
if (ancestor === currentNode)
return true;
currentNode = currentNode.parent;
}
return false;
}
TreeElement.prototype.reveal = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}
this.onreveal(this);
}
TreeElement.prototype.revealed = function()
{
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor.root) {
if (!currentAncestor.expanded)
return false;
currentAncestor = currentAncestor.parent;
}
return true;
}
TreeElement.prototype.selectOnMouseDown = function(event)
{
if (this.select(false, true))
event.consume(true);
}
TreeElement.prototype.select = function(omitFocus, selectedByUser)
{
if (!this.treeOutline || !this.selectable || this.selected)
return false;
if (this.treeOutline.selectedTreeElement)
this.treeOutline.selectedTreeElement.deselect();
this.selected = true;
if(!omitFocus)
this.treeOutline._childrenListNode.focus();
if (!this.treeOutline)
return false;
this.treeOutline.selectedTreeElement = this;
if (this._listItemNode)
this._listItemNode.classList.add("selected");
return this.onselect(selectedByUser);
}
TreeElement.prototype.revealAndSelect = function(omitFocus)
{
this.reveal();
this.select(omitFocus);
}
TreeElement.prototype.deselect = function(supressOnDeselect)
{
if (!this.treeOutline || this.treeOutline.selectedTreeElement !== this || !this.selected)
return false;
this.selected = false;
this.treeOutline.selectedTreeElement = null;
if (this._listItemNode)
this._listItemNode.classList.remove("selected");
return true;
}
TreeElement.prototype.onpopulate = function() { }
TreeElement.prototype.onenter = function() { }
TreeElement.prototype.ondelete = function() { }
TreeElement.prototype.onspace = function() { }
TreeElement.prototype.onattach = function() { }
TreeElement.prototype.onexpand = function() { }
TreeElement.prototype.oncollapse = function() { }
TreeElement.prototype.ondblclick = function() { }
TreeElement.prototype.onreveal = function() { }
TreeElement.prototype.onselect = function(selectedByUser) { }
TreeElement.prototype.traverseNextTreeElement = function(skipUnrevealed, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.onpopulate();
if (info)
info.depthChange = 0;
var element = skipUnrevealed ? (this.revealed() ? this.children[0] : null) : this.children[0];
if (element && (!skipUnrevealed || (skipUnrevealed && this.expanded))) {
if (info)
info.depthChange = 1;
return element;
}
if (this === stayWithin)
return null;
element = skipUnrevealed ? (this.revealed() ? this.nextSibling : null) : this.nextSibling;
if (element)
return element;
element = this;
while (element && !element.root && !(skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling) && element.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
element = element.parent;
}
if (!element)
return null;
return (skipUnrevealed ? (element.revealed() ? element.nextSibling : null) : element.nextSibling);
}
TreeElement.prototype.traversePreviousTreeElement = function(skipUnrevealed, dontPopulate)
{
var element = skipUnrevealed ? (this.revealed() ? this.previousSibling : null) : this.previousSibling;
if (!dontPopulate && element && element.hasChildren)
element.onpopulate();
while (element && (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1])) {
if (!dontPopulate && element.hasChildren)
element.onpopulate();
element = (skipUnrevealed ? (element.revealed() && element.expanded ? element.children[element.children.length - 1] : null) : element.children[element.children.length - 1]);
}
if (element)
return element;
if (!this.parent || this.parent.root)
return null;
return this.parent;
}
TreeElement.prototype.isEventWithinDisclosureTriangle = function(event)
{
var paddingLeftValue = window.getComputedStyle(this._listItemNode).getPropertyCSSValue("padding-left");
var computedLeftPadding = paddingLeftValue ? paddingLeftValue.getFloatValue(CSSPrimitiveValue.CSS_PX) : 0;
var left = this._listItemNode.totalOffsetLeft() + computedLeftPadding;
return event.pageX >= left && event.pageX <= left + this.arrowToggleWidth && this.hasChildren;
}
var WebInspector = {
_panelDescriptors: function()
{
this.panels = {};
WebInspector.inspectorView = new WebInspector.InspectorView();
var parentElement = document.getElementById("main");
WebInspector.inspectorView.show(parentElement);
WebInspector.inspectorView.addEventListener(WebInspector.InspectorView.Events.PanelSelected, this._panelSelected, this);
var elements = new WebInspector.ElementsPanelDescriptor();
var resources = new WebInspector.PanelDescriptor("resources", WebInspector.UIString("Resources"), "ResourcesPanel", "ResourcesPanel.js");
var network = new WebInspector.NetworkPanelDescriptor();
var scripts = new WebInspector.ScriptsPanelDescriptor();
var timeline = new WebInspector.PanelDescriptor("timeline", WebInspector.UIString("Timeline"), "TimelinePanel", "TimelinePanel.js");
var profiles = new WebInspector.PanelDescriptor("profiles", WebInspector.UIString("Profiles"), "ProfilesPanel", "ProfilesPanel.js");
var audits = new WebInspector.PanelDescriptor("audits", WebInspector.UIString("Audits"), "AuditsPanel", "AuditsPanel.js");
var console = new WebInspector.PanelDescriptor("console", WebInspector.UIString("Console"), "ConsolePanel");
var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
var panelDescriptors = [];
if (WebInspector.WorkerManager.isWorkerFrontend()) {
panelDescriptors.push(scripts);
panelDescriptors.push(timeline);
panelDescriptors.push(profiles);
panelDescriptors.push(console);
return panelDescriptors;
}
var allDescriptors = [elements, resources, network, scripts, timeline, profiles, audits, console];
var hiddenPanels = InspectorFrontendHost.hiddenPanels();
for (var i = 0; i < allDescriptors.length; ++i) {
if (hiddenPanels.indexOf(allDescriptors[i].name()) === -1)
panelDescriptors.push(allDescriptors[i]);
}
return panelDescriptors;
},
_panelSelected: function()
{
this._toggleConsoleButton.disabled = WebInspector.inspectorView.currentPanel().name === "console";
},
_createGlobalStatusBarItems: function()
{
var bottomStatusBarContainer = document.getElementById("bottom-status-bar-container");
this._dockToggleButton = new WebInspector.StatusBarButton("", "dock-status-bar-item", 3);
this._dockToggleButton.makeLongClickEnabled(this._createDockOptions.bind(this));
this._dockToggleButton.addEventListener("click", this._toggleAttach.bind(this), false);
this._updateDockButtonState();
var mainStatusBar = document.getElementById("main-status-bar");
mainStatusBar.insertBefore(this._dockToggleButton.element, bottomStatusBarContainer);
this._toggleConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Show console."), "console-status-bar-item");
this._toggleConsoleButton.addEventListener("click", this._toggleConsoleButtonClicked.bind(this), false);
mainStatusBar.insertBefore(this._toggleConsoleButton.element, bottomStatusBarContainer);
if (!WebInspector.WorkerManager.isWorkerFrontend()) {
this._nodeSearchButton = new WebInspector.StatusBarButton(WebInspector.UIString("Select an element in the page to inspect it."), "node-search-status-bar-item");
this._nodeSearchButton.addEventListener("click", this.toggleSearchingForNode, this);
mainStatusBar.insertBefore(this._nodeSearchButton.element, bottomStatusBarContainer);
}
mainStatusBar.appendChild(this.settingsController.statusBarItem);
},
_createDockOptions: function()
{
var alternateDockToggleButton1 = new WebInspector.StatusBarButton("Dock to main window.", "dock-status-bar-item", 3);
var alternateDockToggleButton2 = new WebInspector.StatusBarButton("Undock into separate window.", "dock-status-bar-item", 3);
if (this.attached) {
alternateDockToggleButton1.state = WebInspector.settings.dockToRight.get() ? "bottom" : "right";
alternateDockToggleButton2.state = "undock";
} else {
alternateDockToggleButton1.state = WebInspector.settings.dockToRight.get() ? "bottom" : "right";
alternateDockToggleButton2.state = WebInspector.settings.dockToRight.get() ? "right" : "bottom";
}
alternateDockToggleButton1.addEventListener("click", onClick.bind(this), false);
alternateDockToggleButton2.addEventListener("click", onClick.bind(this), false);
function onClick(e)
{
var state = e.target.state;
if (state === "undock")
this._toggleAttach();
else if (state === "right") {
if (!this.attached)
this._toggleAttach();
WebInspector.settings.dockToRight.set(true);
} else if (state === "bottom") {
if (!this.attached)
this._toggleAttach();
WebInspector.settings.dockToRight.set(false);
}
}
return [alternateDockToggleButton1, alternateDockToggleButton2];
},
_updateDockButtonState: function()
{
if (!this._dockToggleButton)
return;
if (this.attached) {
this._dockToggleButton.disabled = false;
this._dockToggleButton.state = "undock";
this._dockToggleButton.title = WebInspector.UIString("Undock into separate window.");
} else {
this._dockToggleButton.disabled = this._isDockingUnavailable;
this._dockToggleButton.state = WebInspector.settings.dockToRight.get() ? "right" : "bottom";
this._dockToggleButton.title = WebInspector.UIString("Dock to main window.");
}
},
_toggleAttach: function()
{
if (!this._attached) {
InspectorFrontendHost.requestAttachWindow();
WebInspector.userMetrics.WindowDocked.record();
} else {
InspectorFrontendHost.requestDetachWindow();
WebInspector.userMetrics.WindowUndocked.record();
}
},
_toggleConsoleButtonClicked: function()
{
if (this._toggleConsoleButton.disabled)
return;
this._toggleConsoleButton.toggled = !this._toggleConsoleButton.toggled;
var animationType = window.event && window.event.shiftKey ? WebInspector.Drawer.AnimationType.Slow : WebInspector.Drawer.AnimationType.Normal;
if (this._toggleConsoleButton.toggled) {
this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
this.drawer.show(this.consoleView, animationType);
this._consoleWasShown = true;
} else {
this._toggleConsoleButton.title = WebInspector.UIString("Show console.");
this.drawer.hide(animationType);
delete this._consoleWasShown;
}
},
showViewInDrawer: function(statusBarElement, view, onclose)
{
this._toggleConsoleButton.title = WebInspector.UIString("Hide console.");
this._toggleConsoleButton.toggled = false;
this._closePreviousDrawerView();
var drawerStatusBarHeader = document.createElement("div");
drawerStatusBarHeader.className = "drawer-header status-bar-item";
drawerStatusBarHeader.appendChild(statusBarElement);
drawerStatusBarHeader.onclose = onclose;
var closeButton = drawerStatusBarHeader.createChild("span");
closeButton.textContent = WebInspector.UIString("\u00D7");
closeButton.addStyleClass("drawer-header-close-button");
closeButton.addEventListener("click", this.closeViewInDrawer.bind(this), false);
document.getElementById("panel-status-bar").firstElementChild.appendChild(drawerStatusBarHeader);
this._drawerStatusBarHeader = drawerStatusBarHeader;
this.drawer.show(view, WebInspector.Drawer.AnimationType.Immediately);
},
closeViewInDrawer: function()
{
if (this._drawerStatusBarHeader) {
this._closePreviousDrawerView();
if (!this._consoleWasShown)
this.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
else
this._toggleConsoleButtonClicked();
}
},
_closePreviousDrawerView: function()
{
if (this._drawerStatusBarHeader) {
this._drawerStatusBarHeader.parentElement.removeChild(this._drawerStatusBarHeader);
if (this._drawerStatusBarHeader.onclose)
this._drawerStatusBarHeader.onclose();
delete this._drawerStatusBarHeader;
}
},
get attached()
{
return this._attached;
},
set attached(x)
{
if (this._attached === x)
return;
this._attached = x;
if (x)
document.body.removeStyleClass("detached");
else
document.body.addStyleClass("detached");
this._setCompactMode(x && !WebInspector.settings.dockToRight.get());
this._updateDockButtonState();
},
isCompactMode: function()
{
return this.attached && !WebInspector.settings.dockToRight.get();
},
_setCompactMode: function(x)
{
var body = document.body;
if (x)
body.addStyleClass("compact");
else
body.removeStyleClass("compact");
WebInspector.windowResize();
},
_updateErrorAndWarningCounts: function()
{
var errorWarningElement = document.getElementById("error-warning-count");
if (!errorWarningElement)
return;
var errors = WebInspector.console.errors;
var warnings = WebInspector.console.warnings;
if (!errors && !warnings) {
errorWarningElement.addStyleClass("hidden");
return;
}
errorWarningElement.removeStyleClass("hidden");
errorWarningElement.removeChildren();
if (errors) {
var errorImageElement = document.createElement("img");
errorImageElement.id = "error-count-img";
errorWarningElement.appendChild(errorImageElement);
var errorElement = document.createElement("span");
errorElement.id = "error-count";
errorElement.textContent = errors;
errorWarningElement.appendChild(errorElement);
}
if (warnings) {
var warningsImageElement = document.createElement("img");
warningsImageElement.id = "warning-count-img";
errorWarningElement.appendChild(warningsImageElement);
var warningsElement = document.createElement("span");
warningsElement.id = "warning-count";
warningsElement.textContent = warnings;
errorWarningElement.appendChild(warningsElement);
}
if (errors) {
if (warnings) {
if (errors == 1) {
if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d error, %d warning", errors, warnings);
else
errorWarningElement.title = WebInspector.UIString("%d error, %d warnings", errors, warnings);
} else if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d errors, %d warning", errors, warnings);
else
errorWarningElement.title = WebInspector.UIString("%d errors, %d warnings", errors, warnings);
} else if (errors == 1)
errorWarningElement.title = WebInspector.UIString("%d error", errors);
else
errorWarningElement.title = WebInspector.UIString("%d errors", errors);
} else if (warnings == 1)
errorWarningElement.title = WebInspector.UIString("%d warning", warnings);
else if (warnings)
errorWarningElement.title = WebInspector.UIString("%d warnings", warnings);
else
errorWarningElement.title = null;
},
get inspectedPageDomain()
{
var parsedURL = WebInspector.inspectedPageURL && WebInspector.inspectedPageURL.asParsedURL();
return parsedURL ? parsedURL.host : "";
},
_initializeCapability: function(name, callback, error, result)
{
Capabilities[name] = result;
if (callback)
callback();
},
_zoomIn: function()
{
++this._zoomLevel;
this._requestZoom();
},
_zoomOut: function()
{
--this._zoomLevel;
this._requestZoom();
},
_resetZoom: function()
{
this._zoomLevel = 0;
this._requestZoom();
},
_requestZoom: function()
{
WebInspector.settings.zoomLevel.set(this._zoomLevel);
InspectorFrontendHost.setZoomFactor(Math.pow(1.2, this._zoomLevel));
},
toggleSearchingForNode: function()
{
var enabled = !this._nodeSearchButton.toggled;
function callback(error)
{
if (!error)
this._nodeSearchButton.toggled = enabled;
}
WebInspector.domAgent.setInspectModeEnabled(enabled, callback.bind(this));
},
_profilesLinkifier: function(title)
{
var profileStringMatches = WebInspector.ProfileURLRegExp.exec(title);
if (profileStringMatches) {
var profilesPanel = WebInspector.panel("profiles");
title = WebInspector.ProfilesPanel._instance.displayTitleForProfileLink(profileStringMatches[2], profileStringMatches[1]);
}
return title;
},
_debuggerPaused: function()
{
WebInspector.panel("scripts");
}
}
WebInspector.Events = {
InspectorClosing: "InspectorClosing"
}
{(function parseQueryParameters()
{
WebInspector.queryParamsObject = {};
var queryParams = window.location.search;
if (!queryParams)
return;
var params = queryParams.substring(1).split("&");
for (var i = 0; i < params.length; ++i) {
var pair = params[i].split("=");
WebInspector.queryParamsObject[pair[0]] = pair[1];
}
})();}
WebInspector.loaded = function()
{
InspectorBackend.loadFromJSONIfNeeded("../Inspector.json");
if (WebInspector.WorkerManager.isDedicatedWorkerFrontend()) {
WebInspector.doLoadedDone();
return;
}
var ws;
if ("ws" in WebInspector.queryParamsObject)
ws = "ws://" + WebInspector.queryParamsObject.ws;
else if ("page" in WebInspector.queryParamsObject) {
var page = WebInspector.queryParamsObject.page;
var host = "host" in WebInspector.queryParamsObject ? WebInspector.queryParamsObject.host : window.location.host;
ws = "ws://" + host + "/devtools/page/" + page;
}
if (ws) {
WebInspector.socket = new WebSocket(ws);
WebInspector.socket.onmessage = function(message) { InspectorBackend.dispatch(message.data); }
WebInspector.socket.onerror = function(error) { console.error(error); }
WebInspector.socket.onopen = function() {
InspectorFrontendHost.sendMessageToBackend = WebInspector.socket.send.bind(WebInspector.socket);
WebInspector.doLoadedDone();
}
return;
}
WebInspector.doLoadedDone();
if (InspectorFrontendHost.isStub) {
InspectorFrontendAPI.dispatchQueryParameters();
WebInspector._doLoadedDoneWithCapabilities();
}
}
WebInspector.doLoadedDone = function()
{
WebInspector.installPortStyles();
if (WebInspector.socket)
document.body.addStyleClass("remote");
if (WebInspector.queryParamsObject.toolbarColor && WebInspector.queryParamsObject.textColor)
WebInspector.setToolbarColors(WebInspector.queryParamsObject.toolbarColor, WebInspector.queryParamsObject.textColor);
InspectorFrontendHost.loaded();
WebInspector.WorkerManager.loaded();
DebuggerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "debuggerCausesRecompilation", null));
DebuggerAgent.supportsSeparateScriptCompilationAndExecution(WebInspector._initializeCapability.bind(WebInspector, "separateScriptCompilationAndExecutionEnabled", null));
ProfilerAgent.causesRecompilation(WebInspector._initializeCapability.bind(WebInspector, "profilerCausesRecompilation", null));
ProfilerAgent.isSampling(WebInspector._initializeCapability.bind(WebInspector, "samplingCPUProfiler", null));
ProfilerAgent.hasHeapProfiler(WebInspector._initializeCapability.bind(WebInspector, "heapProfilerPresent", null));
TimelineAgent.supportsFrameInstrumentation(WebInspector._initializeCapability.bind(WebInspector, "timelineSupportsFrameInstrumentation", null));
PageAgent.canOverrideDeviceMetrics(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceMetrics", null));
PageAgent.canOverrideGeolocation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideGeolocation", null));
PageAgent.canOverrideDeviceOrientation(WebInspector._initializeCapability.bind(WebInspector, "canOverrideDeviceOrientation", WebInspector._doLoadedDoneWithCapabilities.bind(WebInspector)));
}
WebInspector._doLoadedDoneWithCapabilities = function()
{
WebInspector.shortcutsScreen = new WebInspector.ShortcutsScreen();
this._registerShortcuts();
WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
WebInspector.shortcutsScreen.section(WebInspector.UIString("Elements Panel"));
this.console = new WebInspector.ConsoleModel();
this.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._updateErrorAndWarningCounts, this);
this.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._updateErrorAndWarningCounts, this);
WebInspector.CSSCompletions.requestCSSNameCompletions();
this.drawer = new WebInspector.Drawer();
this.networkManager = new WebInspector.NetworkManager();
this.resourceTreeModel = new WebInspector.ResourceTreeModel(this.networkManager);
this.debuggerModel = new WebInspector.DebuggerModel();
this.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, this._debuggerPaused, this);
this.networkLog = new WebInspector.NetworkLog();
this.domAgent = new WebInspector.DOMAgent();
this.runtimeModel = new WebInspector.RuntimeModel(this.resourceTreeModel);
this.consoleView = new WebInspector.ConsoleView(WebInspector.WorkerManager.isWorkerFrontend());
InspectorBackend.registerInspectorDispatcher(this);
this.cssModel = new WebInspector.CSSStyleModel();
this.timelineManager = new WebInspector.TimelineManager();
this.userAgentSupport = new WebInspector.UserAgentSupport();
this.searchController = new WebInspector.SearchController();
this.advancedSearchController = new WebInspector.AdvancedSearchController();
this.settingsController = new WebInspector.SettingsController();
this.domBreakpointsSidebarPane = new WebInspector.DOMBreakpointsSidebarPane();
this._zoomLevel = WebInspector.settings.zoomLevel.get();
if (this._zoomLevel)
this._requestZoom();
var autoselectPanel = WebInspector.UIString("a panel chosen automatically");
var openAnchorLocationSetting = WebInspector.settings.createSetting("openLinkHandler", autoselectPanel);
this.openAnchorLocationRegistry = new WebInspector.HandlerRegistry(openAnchorLocationSetting);
this.openAnchorLocationRegistry.registerHandler(autoselectPanel, function() { return false; });
this.workspace = new WebInspector.Workspace();
this.workspaceController = new WebInspector.WorkspaceController(this.workspace);
this.breakpointManager = new WebInspector.BreakpointManager(WebInspector.settings.breakpoints, this.debuggerModel, this.workspace);
this.scriptSnippetModel = new WebInspector.ScriptSnippetModel(this.workspace);
new WebInspector.DebuggerScriptMapping(this.workspace);
new WebInspector.NetworkUISourceCodeProvider(this.workspace);
new WebInspector.StylesSourceMapping(this.workspace);
if (WebInspector.experimentsSettings.sass.isEnabled())
new WebInspector.SASSSourceMapping(this.workspace);
new WebInspector.PresentationConsoleMessageHelper(this.workspace);
this._createGlobalStatusBarItems();
WebInspector._installDockToRight();
this.toolbar = new WebInspector.Toolbar();
WebInspector.startBatchUpdate();
var panelDescriptors = this._panelDescriptors();
for (var i = 0; i < panelDescriptors.length; ++i)
WebInspector.inspectorView.addPanel(panelDescriptors[i]);
WebInspector.endBatchUpdate();
this.addMainEventListeners(document);
WebInspector.registerLinkifierPlugin(this._profilesLinkifier.bind(this));
window.addEventListener("resize", this.windowResize.bind(this), true);
var errorWarningCount = document.getElementById("error-warning-count");
errorWarningCount.addEventListener("click", this.showConsole.bind(this), false);
this._updateErrorAndWarningCounts();
this.extensionServer.initExtensions();
this.console.enableAgent();
function showInitialPanel()
{
if (!WebInspector.inspectorView.currentPanel())
WebInspector.showPanel(WebInspector.settings.lastActivePanel.get());
}
InspectorAgent.enable(showInitialPanel);
this.databaseModel = new WebInspector.DatabaseModel();
this.domStorageModel = new WebInspector.DOMStorageModel();
if (!Capabilities.profilerCausesRecompilation || WebInspector.settings.profilerEnabled.get())
ProfilerAgent.enable();
if (WebInspector.settings.showPaintRects.get())
PageAgent.setShowPaintRects(true);
if (WebInspector.settings.javaScriptDisabled.get())
PageAgent.setScriptExecutionDisabled(true);
this.domAgent._emulateTouchEventsChanged();
WebInspector.WorkerManager.loadCompleted();
InspectorFrontendAPI.loadCompleted();
}
WebInspector._installDockToRight = function()
{
WebInspector.settings.dockToRight.set(WebInspector.queryParamsObject.dockSide === "right");
if (WebInspector.settings.dockToRight.get())
document.body.addStyleClass("dock-to-right");
if (WebInspector.attached)
WebInspector._setCompactMode(!WebInspector.settings.dockToRight.get());
WebInspector.settings.dockToRight.addChangeListener(listener.bind(this));
function listener(event)
{
var value = WebInspector.settings.dockToRight.get();
if (value) {
InspectorFrontendHost.requestSetDockSide("right");
document.body.addStyleClass("dock-to-right");
} else {
InspectorFrontendHost.requestSetDockSide("bottom");
document.body.removeStyleClass("dock-to-right");
}
if (WebInspector.attached)
WebInspector._setCompactMode(!value);
else
WebInspector._updateDockButtonState();
}
}
var windowLoaded = function()
{
var localizedStringsURL = InspectorFrontendHost.localizedStringsURL();
if (localizedStringsURL) {
var localizedStringsScriptElement = document.createElement("script");
localizedStringsScriptElement.addEventListener("load", WebInspector.loaded.bind(WebInspector), false);
localizedStringsScriptElement.type = "text/javascript";
localizedStringsScriptElement.src = localizedStringsURL;
document.head.appendChild(localizedStringsScriptElement);
} else
WebInspector.loaded();
WebInspector.attached = WebInspector.queryParamsObject.docked === "true";
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
delete windowLoaded;
};
window.addEventListener("DOMContentLoaded", windowLoaded, false);
var messagesToDispatch = [];
WebInspector.dispatchQueueIsEmpty = function() {
return messagesToDispatch.length == 0;
}
WebInspector.dispatch = function(message) {
messagesToDispatch.push(message);
setTimeout(function() {
InspectorBackend.dispatch(messagesToDispatch.shift());
}, 0);
}
WebInspector.dispatchMessageFromBackend = function(messageObject)
{
WebInspector.dispatch(messageObject);
}
WebInspector.windowResize = function(event)
{
if (WebInspector.inspectorView)
WebInspector.inspectorView.doResize();
if (WebInspector.drawer)
WebInspector.drawer.resize();
if (WebInspector.toolbar)
WebInspector.toolbar.resize();
if (WebInspector.settingsController)
WebInspector.settingsController.resize();
}
WebInspector.setDockingUnavailable = function(unavailable)
{
this._isDockingUnavailable = unavailable;
this._updateDockButtonState();
}
WebInspector.close = function(event)
{
if (this._isClosing)
return;
this._isClosing = true;
this.notifications.dispatchEventToListeners(WebInspector.Events.InspectorClosing);
InspectorFrontendHost.closeWindow();
}
WebInspector.documentClick = function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (!anchor || anchor.target === "_blank")
return;
event.consume(true);
function followLink()
{
if (WebInspector.isBeingEdited(event.target) || WebInspector._showAnchorLocation(anchor))
return;
const profileMatch = WebInspector.ProfileURLRegExp.exec(anchor.href);
if (profileMatch) {
WebInspector.showProfileForURL(anchor.href);
return;
}
var parsedURL = anchor.href.asParsedURL();
if (parsedURL && parsedURL.scheme === "webkit-link-action") {
if (parsedURL.host === "show-panel") {
var panel = parsedURL.path.substring(1);
if (WebInspector.panel(panel))
WebInspector.showPanel(panel);
}
return;
}
InspectorFrontendHost.openInNewTab(anchor.href);
}
if (WebInspector.followLinkTimeout)
clearTimeout(WebInspector.followLinkTimeout);
if (anchor.preventFollowOnDoubleClick) {
if (event.detail === 1)
WebInspector.followLinkTimeout = setTimeout(followLink, 333);
return;
}
followLink();
}
WebInspector.openResource = function(resourceURL, inResourcesPanel)
{
var resource = WebInspector.resourceForURL(resourceURL);
if (inResourcesPanel && resource)
WebInspector.showPanel("resources").showResource(resource);
else
InspectorFrontendHost.openInNewTab(resourceURL);
}
WebInspector._registerShortcuts = function()
{
var shortcut = WebInspector.KeyboardShortcut;
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("All Panels"));
var keys = [
shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta),
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go to the panel to the left/right"));
var keys = [
shortcut.shortcutToString("[", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt),
shortcut.shortcutToString("]", shortcut.Modifiers.CtrlOrMeta | shortcut.Modifiers.Alt)
];
section.addRelatedKeys(keys, WebInspector.UIString("Go back/forward in panel history"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Esc), WebInspector.UIString("Toggle console"));
section.addKey(shortcut.shortcutToString("f", shortcut.Modifiers.CtrlOrMeta), WebInspector.UIString("Search"));
var advancedSearchShortcut = WebInspector.AdvancedSearchController.createShortcut();
section.addKey(advancedSearchShortcut.name, WebInspector.UIString("Search across all sources"));
var openResourceShortcut = WebInspector.KeyboardShortcut.makeDescriptor("o", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta);
section.addKey(openResourceShortcut.name, WebInspector.UIString("Go to source"));
if (WebInspector.isMac()) {
keys = [
shortcut.shortcutToString("g", shortcut.Modifiers.Meta),
shortcut.shortcutToString("g", shortcut.Modifiers.Meta | shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Find next/previous"));
}
var goToShortcut = WebInspector.GoToLineDialog.createShortcut();
section.addKey(goToShortcut.name, WebInspector.UIString("Go to line"));
}
WebInspector.documentKeyDown = function(event)
{
const helpKey = WebInspector.isMac() ? "U+003F" : "U+00BF";
if (event.keyIdentifier === "F1" ||
(event.keyIdentifier === helpKey && event.shiftKey && (!WebInspector.isBeingEdited(event.target) || event.metaKey))) {
this.settingsController.showSettingsScreen(WebInspector.SettingsScreen.Tabs.Shortcuts);
event.consume(true);
return;
}
if (WebInspector.currentFocusElement() && WebInspector.currentFocusElement().handleKeyEvent) {
WebInspector.currentFocusElement().handleKeyEvent(event);
if (event.handled) {
event.consume(true);
return;
}
}
if (WebInspector.inspectorView.currentPanel()) {
WebInspector.inspectorView.currentPanel().handleShortcut(event);
if (event.handled) {
event.consume(true);
return;
}
}
if (WebInspector.searchController.handleShortcut(event))
return;
if (WebInspector.advancedSearchController.handleShortcut(event))
return;
switch (event.keyIdentifier) {
case "U+004F":
if (!event.shiftKey && !event.altKey && WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
WebInspector.showPanel("scripts").showGoToSourceDialog();
event.consume(true);
}
break;
case "U+0052":
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event)) {
PageAgent.reload(event.shiftKey);
event.consume(true);
}
break;
case "F5":
if (!WebInspector.isMac()) {
PageAgent.reload(event.ctrlKey || event.shiftKey);
event.consume(true);
}
break;
}
var isValidZoomShortcut = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) &&
!event.altKey &&
!InspectorFrontendHost.isStub;
switch (event.keyCode) {
case 107:
case 187:
if (isValidZoomShortcut) {
WebInspector._zoomIn();
event.consume(true);
}
break;
case 109:
case 189:
if (isValidZoomShortcut) {
WebInspector._zoomOut();
event.consume(true);
}
break;
case 48:
if (isValidZoomShortcut && !event.shiftKey) {
WebInspector._resetZoom();
event.consume(true);
}
break;
}
if (event.keyIdentifier === "U+0043") {
if (WebInspector.isMac())
var isNodeSearchKey = event.metaKey && !event.ctrlKey && !event.altKey && event.shiftKey;
else
var isNodeSearchKey = event.ctrlKey && !event.metaKey && !event.altKey && event.shiftKey;
if (isNodeSearchKey) {
this.toggleSearchingForNode();
event.consume(true);
return;
}
return;
}
}
WebInspector.postDocumentKeyDown = function(event)
{
if (event.handled)
return;
if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code) {
if (!this._toggleConsoleButton.toggled && WebInspector.drawer.visible)
this.closeViewInDrawer();
else
this._toggleConsoleButtonClicked();
}
}
WebInspector.documentCanCopy = function(event)
{
if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
event.preventDefault();
}
WebInspector.documentCopy = function(event)
{
if (WebInspector.inspectorView.currentPanel() && WebInspector.inspectorView.currentPanel().handleCopyEvent)
WebInspector.inspectorView.currentPanel().handleCopyEvent(event);
WebInspector.documentCopyEventFired(event);
}
WebInspector.documentCopyEventFired = function(event)
{
}
WebInspector.contextMenuEventFired = function(event)
{
if (event.handled || event.target.hasStyleClass("popup-glasspane"))
event.preventDefault();
}
WebInspector.showConsole = function()
{
if (WebInspector._toggleConsoleButton && !WebInspector._toggleConsoleButton.toggled) {
if (WebInspector.drawer.visible)
this._closePreviousDrawerView();
WebInspector._toggleConsoleButtonClicked();
}
}
WebInspector.showPanel = function(panel)
{
return WebInspector.inspectorView.showPanel(panel);
}
WebInspector.panel = function(panel)
{
return WebInspector.inspectorView.panel(panel);
}
WebInspector.bringToFront = function()
{
InspectorFrontendHost.bringToFront();
}
WebInspector.log = function(message, messageLevel, showConsole)
{
var self = this;
function isLogAvailable()
{
return WebInspector.ConsoleMessage && WebInspector.RemoteObject && self.console;
}
function flushQueue()
{
var queued = WebInspector.log.queued;
if (!queued)
return;
for (var i = 0; i < queued.length; ++i)
logMessage(queued[i]);
delete WebInspector.log.queued;
}
function flushQueueIfAvailable()
{
if (!isLogAvailable())
return;
clearInterval(WebInspector.log.interval);
delete WebInspector.log.interval;
flushQueue();
}
function logMessage(message)
{
var msg = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.Other,
messageLevel || WebInspector.ConsoleMessage.MessageLevel.Debug,
message);
self.console.addMessage(msg);
if (showConsole)
WebInspector.showConsole();
}
if (!isLogAvailable()) {
if (!WebInspector.log.queued)
WebInspector.log.queued = [];
WebInspector.log.queued.push(message);
if (!WebInspector.log.interval)
WebInspector.log.interval = setInterval(flushQueueIfAvailable, 1000);
return;
}
flushQueue();
logMessage(message);
}
WebInspector.showErrorMessage = function(error)
{
WebInspector.log(error, WebInspector.ConsoleMessage.MessageLevel.Error, true);
}
WebInspector.inspect = function(payload, hints)
{
var object = WebInspector.RemoteObject.fromPayload(payload);
if (object.subtype === "node") {
function callback(nodeId)
{
WebInspector._updateFocusedNode(nodeId);
object.release();
}
object.pushNodeToFrontend(callback);
return;
}
if (hints.databaseId)
WebInspector.showPanel("resources").selectDatabase(WebInspector.databaseModel.databaseForId(hints.databaseId));
else if (hints.domStorageId)
WebInspector.showPanel("resources").selectDOMStorage(WebInspector.domStorageModel.storageForId(hints.domStorageId));
object.release();
}
WebInspector._updateFocusedNode = function(nodeId)
{
if (WebInspector._nodeSearchButton.toggled) {
InspectorFrontendHost.bringToFront();
WebInspector._nodeSearchButton.toggled = false;
}
WebInspector.showPanel("elements").revealAndSelectNode(nodeId);
}
WebInspector._showAnchorLocation = function(anchor)
{
if (WebInspector.openAnchorLocationRegistry.dispatch({ url: anchor.href, lineNumber: anchor.lineNumber}))
return true;
var preferredPanel = this.panels[anchor.preferredPanel];
if (preferredPanel && WebInspector._showAnchorLocationInPanel(anchor, preferredPanel))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("scripts")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("resources")))
return true;
if (WebInspector._showAnchorLocationInPanel(anchor, this.panel("network")))
return true;
return false;
}
WebInspector._showAnchorLocationInPanel = function(anchor, panel)
{
if (!panel || !panel.canShowAnchorLocation(anchor))
return false;
if (anchor.hasStyleClass("webkit-html-external-link")) {
anchor.removeStyleClass("webkit-html-external-link");
anchor.addStyleClass("webkit-html-resource-link");
}
WebInspector.inspectorView.showPanelForAnchorNavigation(panel);
panel.showAnchorLocation(anchor);
return true;
}
WebInspector.showProfileForURL = function(url)
{
WebInspector.showPanel("profiles").showProfileForURL(url);
}
WebInspector.evaluateInConsole = function(expression, showResultOnly)
{
this.showConsole();
this.consoleView.evaluateUsingTextPrompt(expression, showResultOnly);
}
WebInspector.addMainEventListeners = function(doc)
{
doc.addEventListener("keydown", this.documentKeyDown.bind(this), true);
doc.addEventListener("keydown", this.postDocumentKeyDown.bind(this), false);
doc.addEventListener("beforecopy", this.documentCanCopy.bind(this), true);
doc.addEventListener("copy", this.documentCopy.bind(this), true);
doc.addEventListener("contextmenu", this.contextMenuEventFired.bind(this), true);
doc.addEventListener("click", this.documentClick.bind(this), true);
}
WebInspector.ProfileURLRegExp = /webkit-profile:\/\/(.+)\/(.+)#([0-9]+)/;
WebInspector.UIString = function(string, vararg)
{
if (Preferences.localizeUI) {
if (window.localizedStrings && string in window.localizedStrings)
string = window.localizedStrings[string];
else {
if (!(string in WebInspector._missingLocalizedStrings)) {
console.warn("Localized string \"" + string + "\" not found.");
WebInspector._missingLocalizedStrings[string] = true;
}
if (Preferences.showMissingLocalizedStrings)
string += " (not localized)";
}
}
return String.vsprintf(string, Array.prototype.slice.call(arguments, 1));
}
WebInspector._missingLocalizedStrings = {};
WebInspector.installDragHandle = function(element, elementDragStart, elementDrag, elementDragEnd, cursor)
{
element.addEventListener("mousedown", WebInspector._elementDragStart.bind(WebInspector, elementDragStart, elementDrag, elementDragEnd, cursor), false);
}
WebInspector._elementDragStart = function(elementDragStart, elementDrag, elementDragEnd, cursor, event)
{
if (event.button || (WebInspector.isMac() && event.ctrlKey))
return;
if (WebInspector._elementDraggingEventListener)
return;
if (elementDragStart && !elementDragStart(event))
return;
if (WebInspector._elementDraggingGlassPane) {
WebInspector._elementDraggingGlassPane.dispose();
delete WebInspector._elementDraggingGlassPane;
}
var targetDocument = event.target.ownerDocument;
WebInspector._elementDraggingEventListener = elementDrag;
WebInspector._elementEndDraggingEventListener = elementDragEnd;
WebInspector._mouseOutWhileDraggingTargetDocument = targetDocument;
targetDocument.addEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
targetDocument.addEventListener("mouseup", WebInspector._elementDragEnd, true);
targetDocument.addEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
targetDocument.body.style.cursor = cursor;
event.preventDefault();
}
WebInspector._mouseOutWhileDragging = function()
{
WebInspector._unregisterMouseOutWhileDragging();
WebInspector._elementDraggingGlassPane = new WebInspector.GlassPane();
}
WebInspector._unregisterMouseOutWhileDragging = function()
{
if (!WebInspector._mouseOutWhileDraggingTargetDocument)
return;
WebInspector._mouseOutWhileDraggingTargetDocument.removeEventListener("mouseout", WebInspector._mouseOutWhileDragging, true);
delete WebInspector._mouseOutWhileDraggingTargetDocument;
}
WebInspector._elementDragEnd = function(event)
{
var targetDocument = event.target.ownerDocument;
targetDocument.removeEventListener("mousemove", WebInspector._elementDraggingEventListener, true);
targetDocument.removeEventListener("mouseup", WebInspector._elementDragEnd, true);
WebInspector._unregisterMouseOutWhileDragging();
targetDocument.body.style.removeProperty("cursor");
if (WebInspector._elementDraggingGlassPane)
WebInspector._elementDraggingGlassPane.dispose();
var elementDragEnd = WebInspector._elementEndDraggingEventListener;
delete WebInspector._elementDraggingGlassPane;
delete WebInspector._elementDraggingEventListener;
delete WebInspector._elementEndDraggingEventListener;
event.preventDefault();
if (elementDragEnd)
elementDragEnd(event);
}
WebInspector.GlassPane = function()
{
this.element = document.createElement("div");
this.element.style.cssText = "position:absolute;top:0;bottom:0;left:0;right:0;background-color:transparent;z-index:1000;";
this.element.id = "glass-pane-for-drag";
document.body.appendChild(this.element);
}
WebInspector.GlassPane.prototype = {
dispose: function()
{
if (this.element.parentElement)
this.element.parentElement.removeChild(this.element);
}
}
WebInspector.animateStyle = function(animations, duration, callback)
{
var interval;
var complete = 0;
var hasCompleted = false;
const intervalDuration = (1000 / 30);
const animationsLength = animations.length;
const propertyUnit = {opacity: ""};
const defaultUnit = "px";
function cubicInOut(t, b, c, d)
{
if ((t/=d/2) < 1) return c/2*t*t*t + b;
return c/2*((t-=2)*t*t + 2) + b;
}
for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = null, start = null, end = null, key = null;
for (key in animation) {
if (key === "element")
element = animation[key];
else if (key === "start")
start = animation[key];
else if (key === "end")
end = animation[key];
}
if (!element || !end)
continue;
if (!start) {
var computedStyle = element.ownerDocument.defaultView.getComputedStyle(element);
start = {};
for (key in end)
start[key] = parseInt(computedStyle.getPropertyValue(key), 10);
animation.start = start;
} else
for (key in start)
element.style.setProperty(key, start[key] + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}
function animateLoop()
{
if (hasCompleted)
return;
complete += intervalDuration;
var next = complete + intervalDuration;
for (var i = 0; i < animationsLength; ++i) {
var animation = animations[i];
var element = animation.element;
var start = animation.start;
var end = animation.end;
if (!element || !end)
continue;
var style = element.style;
for (key in end) {
var endValue = end[key];
if (next < duration) {
var startValue = start[key];
var newValue = cubicInOut(complete, startValue, endValue - startValue, duration);
style.setProperty(key, newValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
} else
style.setProperty(key, endValue + (key in propertyUnit ? propertyUnit[key] : defaultUnit));
}
}
if (complete >= duration) {
hasCompleted = true;
clearInterval(interval);
if (callback)
callback();
}
}
function forceComplete()
{
if (hasCompleted)
return;
complete = duration;
animateLoop();
}
function cancel()
{
hasCompleted = true;
clearInterval(interval);
}
interval = setInterval(animateLoop, intervalDuration);
return {
cancel: cancel,
forceComplete: forceComplete
};
}
WebInspector.isBeingEdited = function(element)
{
if (element.hasStyleClass("text-prompt") || element.nodeName === "INPUT")
return true;
if (!WebInspector.__editingCount)
return false;
while (element) {
if (element.__editing)
return true;
element = element.parentElement;
}
return false;
}
WebInspector.markBeingEdited = function(element, value)
{
if (value) {
if (element.__editing)
return false;
element.__editing = true;
WebInspector.__editingCount = (WebInspector.__editingCount || 0) + 1;
} else {
if (!element.__editing)
return false;
delete element.__editing;
--WebInspector.__editingCount;
}
return true;
}
WebInspector.EditingConfig = function(commitHandler, cancelHandler, context)
{
this.commitHandler = commitHandler;
this.cancelHandler = cancelHandler
this.context = context;
this.pasteHandler;
this.multiline;
this.customFinishHandler;
}
WebInspector.EditingConfig.prototype = {
setPasteHandler: function(pasteHandler)
{
this.pasteHandler = pasteHandler;
},
setMultiline: function(multiline)
{
this.multiline = multiline;
},
setCustomFinishHandler: function(customFinishHandler)
{
this.customFinishHandler = customFinishHandler;
}
}
WebInspector.CSSNumberRegex = /^(-?(?:\d+(?:\.\d+)?|\.\d+))$/;
WebInspector.StyleValueDelimiters = " \xA0\t\n\"':;,/()";
WebInspector._valueModificationDirection = function(event)
{
var direction = null;
if (event.type === "mousewheel") {
if (event.wheelDeltaY > 0)
direction = "Up";
else if (event.wheelDeltaY < 0)
direction = "Down";
} else {
if (event.keyIdentifier === "Up" || event.keyIdentifier === "PageUp")
direction = "Up";
else if (event.keyIdentifier === "Down" || event.keyIdentifier === "PageDown")
direction = "Down";
}
return direction;
}
WebInspector._modifiedHexValue = function(hexString, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return hexString;
var number = parseInt(hexString, 16);
if (isNaN(number) || !isFinite(number))
return hexString;
var maxValue = Math.pow(16, hexString.length) - 1;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var delta;
if (arrowKeyOrMouseWheelEvent)
delta = (direction === "Up") ? 1 : -1;
else
delta = (event.keyIdentifier === "PageUp") ? 16 : -16;
if (event.shiftKey)
delta *= 16;
var result = number + delta;
if (result < 0)
result = 0;
else if (result > maxValue)
return hexString;
var resultString = result.toString(16).toUpperCase();
for (var i = 0, lengthDelta = hexString.length - resultString.length; i < lengthDelta; ++i)
resultString = "0" + resultString;
return resultString;
}
WebInspector._modifiedFloatNumber = function(number, event)
{
var direction = WebInspector._valueModificationDirection(event);
if (!direction)
return number;
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var changeAmount = 1;
if (event.shiftKey && !arrowKeyOrMouseWheelEvent)
changeAmount = 100;
else if (event.shiftKey || !arrowKeyOrMouseWheelEvent)
changeAmount = 10;
else if (event.altKey)
changeAmount = 0.1;
if (direction === "Down")
changeAmount *= -1;
var result = Number((number + changeAmount).toFixed(6));
if (!String(result).match(WebInspector.CSSNumberRegex))
return null;
return result;
}
WebInspector.handleElementValueModifications = function(event, element, finishHandler, suggestionHandler, customNumberHandler)
{
var arrowKeyOrMouseWheelEvent = (event.keyIdentifier === "Up" || event.keyIdentifier === "Down" || event.type === "mousewheel");
var pageKeyPressed = (event.keyIdentifier === "PageUp" || event.keyIdentifier === "PageDown");
if (!arrowKeyOrMouseWheelEvent && !pageKeyPressed)
return false;
var selection = window.getSelection();
if (!selection.rangeCount)
return false;
var selectionRange = selection.getRangeAt(0);
if (!selectionRange.commonAncestorContainer.isSelfOrDescendant(element))
return false;
var originalValue = element.textContent;
var wordRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, WebInspector.StyleValueDelimiters, element);
var wordString = wordRange.toString();
if (suggestionHandler && suggestionHandler(wordString))
return false;
var replacementString;
var prefix, suffix, number;
var matches;
matches = /(.*#)([\da-fA-F]+)(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedHexValue(matches[2], event);
if (customNumberHandler)
number = customNumberHandler(number);
replacementString = prefix + number + suffix;
} else {
matches = /(.*?)(-?(?:\d+(?:\.\d+)?|\.\d+))(.*)/.exec(wordString);
if (matches && matches.length) {
prefix = matches[1];
suffix = matches[3];
number = WebInspector._modifiedFloatNumber(parseFloat(matches[2]), event);
if (number === null)
return false;
if (customNumberHandler)
number = customNumberHandler(number);
replacementString = prefix + number + suffix;
}
}
if (replacementString) {
var replacementTextNode = document.createTextNode(replacementString);
wordRange.deleteContents();
wordRange.insertNode(replacementTextNode);
var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(replacementTextNode, 0);
finalSelectionRange.setEnd(replacementTextNode, replacementString.length);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
event.handled = true;
event.preventDefault();
if (finishHandler)
finishHandler(originalValue, replacementString);
return true;
}
return false;
}
WebInspector.startEditing = function(element, config)
{
if (!WebInspector.markBeingEdited(element, true))
return null;
config = config || new WebInspector.EditingConfig(function() {}, function() {});
var committedCallback = config.commitHandler;
var cancelledCallback = config.cancelHandler;
var pasteCallback = config.pasteHandler;
var context = config.context;
var oldText = getContent(element);
var moveDirection = "";
element.addStyleClass("editing");
var oldTabIndex = element.getAttribute("tabIndex");
if (typeof oldTabIndex !== "number" || oldTabIndex < 0)
element.tabIndex = 0;
function blurEventListener() {
editingCommitted.call(element);
}
function getContent(element) {
if (element.tagName === "INPUT" && element.type === "text")
return element.value;
else
return element.textContent;
}
function cleanUpAfterEditing()
{
WebInspector.markBeingEdited(element, false);
this.removeStyleClass("editing");
if (typeof oldTabIndex !== "number")
element.removeAttribute("tabIndex");
else
this.tabIndex = oldTabIndex;
this.scrollTop = 0;
this.scrollLeft = 0;
element.removeEventListener("blur", blurEventListener, false);
element.removeEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.removeEventListener("paste", pasteEventListener, true);
WebInspector.restoreFocusFromElement(element);
}
function editingCancelled()
{
if (this.tagName === "INPUT" && this.type === "text")
this.value = oldText;
else
this.textContent = oldText;
cleanUpAfterEditing.call(this);
cancelledCallback(this, context);
}
function editingCommitted()
{
cleanUpAfterEditing.call(this);
committedCallback(this, getContent(this), oldText, context, moveDirection);
}
function defaultFinishHandler(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (event.keyIdentifier === "U+0009")
return "move-" + (event.shiftKey ? "backward" : "forward");
}
function handleEditingResult(result, event)
{
if (result === "commit") {
editingCommitted.call(element);
event.consume(true);
} else if (result === "cancel") {
editingCancelled.call(element);
event.consume(true);
} else if (result && result.startsWith("move-")) {
moveDirection = result.substring(5);
if (event.keyIdentifier !== "U+0009")
blurEventListener();
}
}
function pasteEventListener(event)
{
var result = pasteCallback(event);
handleEditingResult(result, event);
}
function keyDownEventListener(event)
{
var handler = config.customFinishHandler || defaultFinishHandler;
var result = handler(event);
handleEditingResult(result, event);
}
element.addEventListener("blur", blurEventListener, false);
element.addEventListener("keydown", keyDownEventListener, true);
if (pasteCallback)
element.addEventListener("paste", pasteEventListener, true);
WebInspector.setCurrentFocusElement(element);
return {
cancel: editingCancelled.bind(element),
commit: editingCommitted.bind(element)
};
}
Number.secondsToString = function(seconds, higherResolution)
{
if (seconds === 0)
return "0";
var ms = seconds * 1000;
if (higherResolution && ms < 1000)
return WebInspector.UIString("%.3fms", ms);
else if (ms < 1000)
return WebInspector.UIString("%.0fms", ms);
if (seconds < 60)
return WebInspector.UIString("%.2fs", seconds);
var minutes = seconds / 60;
if (minutes < 60)
return WebInspector.UIString("%.1fmin", minutes);
var hours = minutes / 60;
if (hours < 24)
return WebInspector.UIString("%.1fhrs", hours);
var days = hours / 24;
return WebInspector.UIString("%.1f days", days);
}
Number.bytesToString = function(bytes, higherResolution)
{
if (typeof higherResolution === "undefined")
higherResolution = true;
if (bytes < 1024)
return WebInspector.UIString("%.0fB", bytes);
var kilobytes = bytes / 1024;
if (higherResolution && kilobytes < 1024)
return WebInspector.UIString("%.2fKB", kilobytes);
else if (kilobytes < 1024)
return WebInspector.UIString("%.0fKB", kilobytes);
var megabytes = kilobytes / 1024;
if (higherResolution)
return WebInspector.UIString("%.2fMB", megabytes);
else
return WebInspector.UIString("%.0fMB", megabytes);
}
Number.withThousandsSeparator = function(num)
{
var str = num + "";
var re = /(\d+)(\d{3})/;
while (str.match(re))
str = str.replace(re, "$1\u2009$2");
return str;
}
WebInspector.useLowerCaseMenuTitles = function()
{
return WebInspector.platform() === "windows" && Preferences.useLowerCaseMenuTitlesOnWindows;
}
WebInspector.formatLocalized = function(format, substitutions, formatters, initialValue, append)
{
return String.format(WebInspector.UIString(format), substitutions, formatters, initialValue, append);
}
WebInspector.openLinkExternallyLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open link in new tab" : "Open Link in New Tab");
}
WebInspector.copyLinkAddressLabel = function()
{
return WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy link address" : "Copy Link Address");
}
WebInspector.platform = function()
{
if (!WebInspector._platform)
WebInspector._platform = InspectorFrontendHost.platform();
return WebInspector._platform;
}
WebInspector.isMac = function()
{
if (typeof WebInspector._isMac === "undefined")
WebInspector._isMac = WebInspector.platform() === "mac";
return WebInspector._isMac;
}
WebInspector.isWin = function()
{
if (typeof WebInspector._isWin === "undefined")
WebInspector._isWin = WebInspector.platform() === "windows";
return WebInspector._isWin;
}
WebInspector.PlatformFlavor = {
WindowsVista: "windows-vista",
MacTiger: "mac-tiger",
MacLeopard: "mac-leopard",
MacSnowLeopard: "mac-snowleopard"
}
WebInspector.platformFlavor = function()
{
function detectFlavor()
{
const userAgent = navigator.userAgent;
if (WebInspector.platform() === "windows") {
var match = userAgent.match(/Windows NT (\d+)\.(?:\d+)/);
if (match && match[1] >= 6)
return WebInspector.PlatformFlavor.WindowsVista;
return null;
} else if (WebInspector.platform() === "mac") {
var match = userAgent.match(/Mac OS X\s*(?:(\d+)_(\d+))?/);
if (!match || match[1] != 10)
return WebInspector.PlatformFlavor.MacSnowLeopard;
switch (Number(match[2])) {
case 4:
return WebInspector.PlatformFlavor.MacTiger;
case 5:
return WebInspector.PlatformFlavor.MacLeopard;
case 6:
default:
return WebInspector.PlatformFlavor.MacSnowLeopard;
}
}
}
if (!WebInspector._platformFlavor)
WebInspector._platformFlavor = detectFlavor();
return WebInspector._platformFlavor;
}
WebInspector.port = function()
{
if (!WebInspector._port)
WebInspector._port = InspectorFrontendHost.port();
return WebInspector._port;
}
WebInspector.installPortStyles = function()
{
var platform = WebInspector.platform();
document.body.addStyleClass("platform-" + platform);
var flavor = WebInspector.platformFlavor();
if (flavor)
document.body.addStyleClass("platform-" + flavor);
var port = WebInspector.port();
document.body.addStyleClass("port-" + port);
}
WebInspector._windowFocused = function(event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.removeStyleClass("inactive");
}
WebInspector._windowBlurred = function(event)
{
if (event.target.document.nodeType === Node.DOCUMENT_NODE)
document.body.addStyleClass("inactive");
}
WebInspector.previousFocusElement = function()
{
return WebInspector._previousFocusElement;
}
WebInspector.currentFocusElement = function()
{
return WebInspector._currentFocusElement;
}
WebInspector._focusChanged = function(event)
{
WebInspector.setCurrentFocusElement(event.target);
}
WebInspector._textInputTypes = ["text", "search", "tel", "url", "email", "password"].keySet();
WebInspector._isTextEditingElement = function(element)
{
if (element instanceof HTMLInputElement)
return element.type in WebInspector._textInputTypes;
if (element instanceof HTMLTextAreaElement)
return true;
return false;
}
WebInspector.setCurrentFocusElement = function(x)
{
if (WebInspector._currentFocusElement !== x)
WebInspector._previousFocusElement = WebInspector._currentFocusElement;
WebInspector._currentFocusElement = x;
if (WebInspector._currentFocusElement) {
WebInspector._currentFocusElement.focus();
var selection = window.getSelection();
if (!WebInspector._isTextEditingElement(WebInspector._currentFocusElement) && selection.isCollapsed && !WebInspector._currentFocusElement.isInsertionCaretInside()) {
var selectionRange = WebInspector._currentFocusElement.ownerDocument.createRange();
selectionRange.setStart(WebInspector._currentFocusElement, 0);
selectionRange.setEnd(WebInspector._currentFocusElement, 0);
selection.removeAllRanges();
selection.addRange(selectionRange);
}
} else if (WebInspector._previousFocusElement)
WebInspector._previousFocusElement.blur();
}
WebInspector.restoreFocusFromElement = function(element)
{
if (element && element.isSelfOrAncestor(WebInspector.currentFocusElement()))
WebInspector.setCurrentFocusElement(WebInspector.previousFocusElement());
}
WebInspector.setToolbarColors = function(backgroundColor, color)
{
if (!WebInspector._themeStyleElement) {
WebInspector._themeStyleElement = document.createElement("style");
document.head.appendChild(WebInspector._themeStyleElement);
}
WebInspector._themeStyleElement.textContent =
"#toolbar {\
background-image: none !important;\
background-color: " + backgroundColor + " !important;\
}\
\
.toolbar-label {\
color: " + color + " !important;\
text-shadow: none;\
}";
}
WebInspector.resetToolbarColors = function()
{
if (WebInspector._themeStyleElement)
WebInspector._themeStyleElement.textContent = "";
}
WebInspector.highlightSearchResult = function(element, offset, length, domChanges)
{
var result = WebInspector.highlightSearchResults(element, [{offset: offset, length: length }], domChanges);
return result.length ? result[0] : null;
}
WebInspector.highlightSearchResults = function(element, resultRanges, changes)
{
return WebInspector.highlightRangesWithStyleClass(element, resultRanges, "webkit-search-result", changes);
}
WebInspector.highlightRangesWithStyleClass = function(element, resultRanges, styleClass, changes)
{
changes = changes || [];
var highlightNodes = [];
var lineText = element.textContent;
var ownerDocument = element.ownerDocument;
var textNodeSnapshot = ownerDocument.evaluate(".//text()", element, null, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
var snapshotLength = textNodeSnapshot.snapshotLength;
if (snapshotLength === 0)
return highlightNodes;
var nodeRanges = [];
var rangeEndOffset = 0;
for (var i = 0; i < snapshotLength; ++i) {
var range = {};
range.offset = rangeEndOffset;
range.length = textNodeSnapshot.snapshotItem(i).textContent.length;
rangeEndOffset = range.offset + range.length;
nodeRanges.push(range);
}
var startIndex = 0;
for (var i = 0; i < resultRanges.length; ++i) {
var startOffset = resultRanges[i].offset;
var endOffset = startOffset + resultRanges[i].length;
while (startIndex < snapshotLength && nodeRanges[startIndex].offset + nodeRanges[startIndex].length <= startOffset)
startIndex++;
var endIndex = startIndex;
while (endIndex < snapshotLength && nodeRanges[endIndex].offset + nodeRanges[endIndex].length < endOffset)
endIndex++;
if (endIndex === snapshotLength)
break;
var highlightNode = ownerDocument.createElement("span");
highlightNode.className = styleClass;
highlightNode.textContent = lineText.substring(startOffset, endOffset);
var lastTextNode = textNodeSnapshot.snapshotItem(endIndex);
var lastText = lastTextNode.textContent;
lastTextNode.textContent = lastText.substring(endOffset - nodeRanges[endIndex].offset);
changes.push({ node: lastTextNode, type: "changed", oldText: lastText, newText: lastTextNode.textContent });
if (startIndex === endIndex) {
lastTextNode.parentElement.insertBefore(highlightNode, lastTextNode);
changes.push({ node: highlightNode, type: "added", nextSibling: lastTextNode, parent: lastTextNode.parentElement });
highlightNodes.push(highlightNode);
var prefixNode = ownerDocument.createTextNode(lastText.substring(0, startOffset - nodeRanges[startIndex].offset));
lastTextNode.parentElement.insertBefore(prefixNode, highlightNode);
changes.push({ node: prefixNode, type: "added", nextSibling: highlightNode, parent: lastTextNode.parentElement });
} else {
var firstTextNode = textNodeSnapshot.snapshotItem(startIndex);
var firstText = firstTextNode.textContent;
var anchorElement = firstTextNode.nextSibling;
firstTextNode.parentElement.insertBefore(highlightNode, anchorElement);
changes.push({ node: highlightNode, type: "added", nextSibling: anchorElement, parent: firstTextNode.parentElement });
highlightNodes.push(highlightNode);
firstTextNode.textContent = firstText.substring(0, startOffset - nodeRanges[startIndex].offset);
changes.push({ node: firstTextNode, type: "changed", oldText: firstText, newText: firstTextNode.textContent });
for (var j = startIndex + 1; j < endIndex; j++) {
var textNode = textNodeSnapshot.snapshotItem(j);
var text = textNode.textContent;
textNode.textContent = "";
changes.push({ node: textNode, type: "changed", oldText: text, newText: textNode.textContent });
}
}
startIndex = endIndex;
nodeRanges[startIndex].offset = endOffset;
nodeRanges[startIndex].length = lastTextNode.textContent.length;
}
return highlightNodes;
}
WebInspector.applyDomChanges = function(domChanges)
{
for (var i = 0, size = domChanges.length; i < size; ++i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}
}
WebInspector.revertDomChanges = function(domChanges)
{
for (var i = domChanges.length - 1; i >= 0; --i) {
var entry = domChanges[i];
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
}
WebInspector._coalescingLevel = 0;
WebInspector.startBatchUpdate = function()
{
if (!WebInspector._coalescingLevel)
WebInspector._postUpdateHandlers = new Map();
WebInspector._coalescingLevel++;
}
WebInspector.endBatchUpdate = function()
{
if (--WebInspector._coalescingLevel)
return;
var handlers = WebInspector._postUpdateHandlers;
delete WebInspector._postUpdateHandlers;
var keys = handlers.keys();
for (var i = 0; i < keys.length; ++i) {
var object = keys[i];
var methods = handlers.get(object).keys();
for (var j = 0; j < methods.length; ++j)
methods[j].call(object);
}
}
WebInspector.invokeOnceAfterBatchUpdate = function(object, method)
{
if (!WebInspector._coalescingLevel) {
method.call(object);
return;
}
var methods = WebInspector._postUpdateHandlers.get(object);
if (!methods) {
methods = new Map();
WebInspector._postUpdateHandlers.put(object, methods);
}
methods.put(method);
}
;(function() {
function windowLoaded()
{
window.addEventListener("focus", WebInspector._windowFocused, false);
window.addEventListener("blur", WebInspector._windowBlurred, false);
document.addEventListener("focus", WebInspector._focusChanged.bind(this), true);
window.removeEventListener("DOMContentLoaded", windowLoaded, false);
}
window.addEventListener("DOMContentLoaded", windowLoaded, false);
})();
function InspectorBackendClass()
{
this._lastCallbackId = 1;
this._pendingResponsesCount = 0;
this._callbacks = {};
this._domainDispatchers = {};
this._eventArgs = {};
this._replyArgs = {};
this.dumpInspectorTimeStats = false;
this.dumpInspectorProtocolMessages = false;
this._initialized = false;
}
InspectorBackendClass.prototype = {
_wrap: function(callback, method)
{
var callbackId = this._lastCallbackId++;
if (!callback)
callback = function() {};
this._callbacks[callbackId] = callback;
callback.methodName = method;
if (this.dumpInspectorTimeStats)
callback.sendRequestTime = Date.now();
return callbackId;
},
registerCommand: function(method, signature, replyArgs)
{
var domainAndMethod = method.split(".");
var agentName = domainAndMethod[0] + "Agent";
if (!window[agentName])
window[agentName] = {};
window[agentName][domainAndMethod[1]] = this._sendMessageToBackend.bind(this, method, signature);
window[agentName][domainAndMethod[1]]["invoke"] = this._invoke.bind(this, method, signature);
this._replyArgs[method] = replyArgs;
this._initialized = true;
},
registerEvent: function(eventName, params)
{
this._eventArgs[eventName] = params;
this._initialized = true;
},
_invoke: function(method, signature, args, callback)
{
this._wrapCallbackAndSendMessageObject(method, args, callback);
},
_sendMessageToBackend: function(method, signature, vararg)
{
var args = Array.prototype.slice.call(arguments, 2);
var callback = (args.length && typeof args[args.length - 1] === "function") ? args.pop() : null;
var params = {};
var hasParams = false;
for (var i = 0; i < signature.length; ++i) {
var param = signature[i];
var paramName = param["name"];
var typeName = param["type"];
var optionalFlag = param["optional"];
if (!args.length && !optionalFlag) {
console.error("Protocol Error: Invalid number of arguments for method '" + method + "' call. It must have the following arguments '" + JSON.stringify(signature) + "'.");
return;
}
var value = args.shift();
if (optionalFlag && typeof value === "undefined") {
continue;
}
if (typeof value !== typeName) {
console.error("Protocol Error: Invalid type of argument '" + paramName + "' for method '" + method + "' call. It must be '" + typeName + "' but it is '" + typeof value + "'.");
return;
}
params[paramName] = value;
hasParams = true;
}
if (args.length === 1 && !callback) {
if (typeof args[0] !== "undefined") {
console.error("Protocol Error: Optional callback argument for method '" + method + "' call must be a function but its type is '" + typeof args[0] + "'.");
return;
}
}
this._wrapCallbackAndSendMessageObject(method, hasParams ? params : null, callback);
},
_wrapCallbackAndSendMessageObject: function(method, params, callback)
{
var messageObject = {};
messageObject.method = method;
if (params)
messageObject.params = params;
messageObject.id = this._wrap(callback, method);
if (this.dumpInspectorProtocolMessages)
console.log("frontend: " + JSON.stringify(messageObject));
++this._pendingResponsesCount;
this.sendMessageObjectToBackend(messageObject);
},
sendMessageObjectToBackend: function(messageObject)
{
var message = JSON.stringify(messageObject);
InspectorFrontendHost.sendMessageToBackend(message);
},
registerDomainDispatcher: function(domain, dispatcher)
{
this._domainDispatchers[domain] = dispatcher;
},
dispatch: function(message)
{
if (this.dumpInspectorProtocolMessages)
console.log("backend: " + ((typeof message === "string") ? message : JSON.stringify(message)));
var messageObject = (typeof message === "string") ? JSON.parse(message) : message;
if ("id" in messageObject) {
if (messageObject.error) {
if (messageObject.error.code !== -32000)
this.reportProtocolError(messageObject);
}
var callback = this._callbacks[messageObject.id];
if (callback) {
var argumentsArray = [];
if (messageObject.result) {
var paramNames = this._replyArgs[callback.methodName];
if (paramNames) {
for (var i = 0; i < paramNames.length; ++i)
argumentsArray.push(messageObject.result[paramNames[i]]);
}
}
var processingStartTime;
if (this.dumpInspectorTimeStats && callback.methodName)
processingStartTime = Date.now();
argumentsArray.unshift(messageObject.error ? messageObject.error.message : null);
callback.apply(null, argumentsArray);
--this._pendingResponsesCount;
delete this._callbacks[messageObject.id];
if (this.dumpInspectorTimeStats && callback.methodName)
console.log("time-stats: " + callback.methodName + " = " + (processingStartTime - callback.sendRequestTime) + " + " + (Date.now() - processingStartTime));
}
if (this._scripts && !this._pendingResponsesCount)
this.runAfterPendingDispatches();
return;
} else {
var method = messageObject.method.split(".");
var domainName = method[0];
var functionName = method[1];
if (!(domainName in this._domainDispatchers)) {
console.error("Protocol Error: the message is for non-existing domain '" + domainName + "'");
return;
}
var dispatcher = this._domainDispatchers[domainName];
if (!(functionName in dispatcher)) {
console.error("Protocol Error: Attempted to dispatch an unimplemented method '" + messageObject.method + "'");
return;
}
if (!this._eventArgs[messageObject.method]) {
console.error("Protocol Error: Attempted to dispatch an unspecified method '" + messageObject.method + "'");
return;
}
var params = [];
if (messageObject.params) {
var paramNames = this._eventArgs[messageObject.method];
for (var i = 0; i < paramNames.length; ++i)
params.push(messageObject.params[paramNames[i]]);
}
var processingStartTime;
if (this.dumpInspectorTimeStats)
processingStartTime = Date.now();
dispatcher[functionName].apply(dispatcher, params);
if (this.dumpInspectorTimeStats)
console.log("time-stats: " + messageObject.method + " = " + (Date.now() - processingStartTime));
}
},
reportProtocolError: function(messageObject)
{
console.error("Request with id = " + messageObject.id + " failed. " + messageObject.error);
},
runAfterPendingDispatches: function(script)
{
if (!this._scripts)
this._scripts = [];
if (script)
this._scripts.push(script);
if (!this._pendingResponsesCount) {
var scripts = this._scripts;
this._scripts = []
for (var id = 0; id < scripts.length; ++id)
scripts[id].call(this);
}
},
loadFromJSONIfNeeded: function(jsonUrl)
{
if (this._initialized)
return;
var xhr = new XMLHttpRequest();
xhr.open("GET", jsonUrl, false);
xhr.send(null);
var schema = JSON.parse(xhr.responseText);
var jsTypes = { integer: "number", array: "object" };
var rawTypes = {};
var domains = schema["domains"];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
for (var j = 0; domain.types && j < domain.types.length; ++j) {
var type = domain.types[j];
rawTypes[domain.domain + "." + type.id] = jsTypes[type.type] || type.type;
}
}
var result = [];
for (var i = 0; i < domains.length; ++i) {
var domain = domains[i];
var commands = domain["commands"] || [];
for (var j = 0; j < commands.length; ++j) {
var command = commands[j];
var parameters = command["parameters"];
var paramsText = [];
for (var k = 0; parameters && k < parameters.length; ++k) {
var parameter = parameters[k];
var type;
if (parameter.type)
type = jsTypes[parameter.type] || parameter.type;
else {
var ref = parameter["$ref"];
if (ref.indexOf(".") !== -1)
type = rawTypes[ref];
else
type = rawTypes[domain.domain + "." + ref];
}
var text = "{\"name\": \"" + parameter.name + "\", \"type\": \"" + type + "\", \"optional\": " + (parameter.optional ? "true" : "false") + "}";
paramsText.push(text);
}
var returnsText = [];
var returns = command["returns"] || [];
for (var k = 0; k < returns.length; ++k) {
var parameter = returns[k];
returnsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerCommand(\"" + domain.domain + "." + command.name + "\", [" + paramsText.join(", ") + "], [" + returnsText.join(", ") + "]);");
}
for (var j = 0; domain.events && j < domain.events.length; ++j) {
var event = domain.events[j];
var paramsText = [];
for (var k = 0; event.parameters && k < event.parameters.length; ++k) {
var parameter = event.parameters[k];
paramsText.push("\"" + parameter.name + "\"");
}
result.push("InspectorBackend.registerEvent(\"" + domain.domain + "." + event.name + "\", [" + paramsText.join(", ") + "]);");
}
result.push("InspectorBackend.register" + domain.domain + "Dispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, \"" + domain.domain + "\");");
}
eval(result.join("\n"));
}
}
InspectorBackend = new InspectorBackendClass();
InspectorBackend.registerInspectorDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Inspector");
InspectorBackend.registerEvent("Inspector.evaluateForTestInFrontend", ["testCallId", "script"]);
InspectorBackend.registerEvent("Inspector.inspect", ["object", "hints"]);
InspectorBackend.registerCommand("Inspector.enable", [], []);
InspectorBackend.registerCommand("Inspector.disable", [], []);
InspectorBackend.registerMemoryDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Memory");
InspectorBackend.registerCommand("Memory.getDOMNodeCount", [], ["domGroups", "strings"]);
InspectorBackend.registerCommand("Memory.getProcessMemoryDistribution", [], ["distribution"]);
InspectorBackend.registerPageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Page");
InspectorBackend.registerEvent("Page.domContentEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.loadEventFired", ["timestamp"]);
InspectorBackend.registerEvent("Page.frameNavigated", ["frame"]);
InspectorBackend.registerEvent("Page.frameDetached", ["frameId"]);
InspectorBackend.registerCommand("Page.enable", [], []);
InspectorBackend.registerCommand("Page.disable", [], []);
InspectorBackend.registerCommand("Page.addScriptToEvaluateOnLoad", [{"name": "scriptSource", "type": "string", "optional": false}], ["identifier"]);
InspectorBackend.registerCommand("Page.removeScriptToEvaluateOnLoad", [{"name": "identifier", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.reload", [{"name": "ignoreCache", "type": "boolean", "optional": true}, {"name": "scriptToEvaluateOnLoad", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("Page.navigate", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getCookies", [], ["cookies", "cookiesString"]);
InspectorBackend.registerCommand("Page.deleteCookie", [{"name": "cookieName", "type": "string", "optional": false}, {"name": "domain", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.getResourceTree", [], ["frameTree"]);
InspectorBackend.registerCommand("Page.getResourceContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}], ["content", "base64Encoded"]);
InspectorBackend.registerCommand("Page.searchInResource", [{"name": "frameId", "type": "string", "optional": false}, {"name": "url", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.searchInResources", [{"name": "text", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Page.setDocumentContent", [{"name": "frameId", "type": "string", "optional": false}, {"name": "html", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Page.canOverrideDeviceMetrics", [], ["result"]);
InspectorBackend.registerCommand("Page.setDeviceMetricsOverride", [{"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "fontScaleFactor", "type": "number", "optional": false}, {"name": "fitWindow", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setShowPaintRects", [{"name": "result", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.getScriptExecutionStatus", [], ["result"]);
InspectorBackend.registerCommand("Page.setScriptExecutionDisabled", [{"name": "value", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Page.setGeolocationOverride", [{"name": "latitude", "type": "number", "optional": true}, {"name": "longitude", "type": "number", "optional": true}, {"name": "accuracy", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("Page.clearGeolocationOverride", [], []);
InspectorBackend.registerCommand("Page.canOverrideGeolocation", [], ["result"]);
InspectorBackend.registerCommand("Page.setDeviceOrientationOverride", [{"name": "alpha", "type": "number", "optional": false}, {"name": "beta", "type": "number", "optional": false}, {"name": "gamma", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Page.clearDeviceOrientationOverride", [], []);
InspectorBackend.registerCommand("Page.canOverrideDeviceOrientation", [], ["result"]);
InspectorBackend.registerCommand("Page.setTouchEmulationEnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerRuntimeDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Runtime");
InspectorBackend.registerEvent("Runtime.executionContextCreated", ["context"]);
InspectorBackend.registerCommand("Runtime.evaluate", [{"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "contextId", "type": "number", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.callFunctionOn", [{"name": "objectId", "type": "string", "optional": false}, {"name": "functionDeclaration", "type": "string", "optional": false}, {"name": "arguments", "type": "object", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Runtime.getProperties", [{"name": "objectId", "type": "string", "optional": false}, {"name": "ownProperties", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Runtime.releaseObject", [{"name": "objectId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.releaseObjectGroup", [{"name": "objectGroup", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Runtime.run", [], []);
InspectorBackend.registerCommand("Runtime.setReportExecutionContextCreation", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerConsoleDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Console");
InspectorBackend.registerEvent("Console.messageAdded", ["message"]);
InspectorBackend.registerEvent("Console.messageRepeatCountUpdated", ["count"]);
InspectorBackend.registerEvent("Console.messagesCleared", []);
InspectorBackend.registerCommand("Console.enable", [], []);
InspectorBackend.registerCommand("Console.disable", [], []);
InspectorBackend.registerCommand("Console.clearMessages", [], []);
InspectorBackend.registerCommand("Console.setMonitoringXHREnabled", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Console.addInspectedHeapObject", [{"name": "heapObjectId", "type": "number", "optional": false}], []);
InspectorBackend.registerNetworkDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Network");
InspectorBackend.registerEvent("Network.requestWillBeSent", ["requestId", "frameId", "loaderId", "documentURL", "request", "timestamp", "initiator", "redirectResponse"]);
InspectorBackend.registerEvent("Network.requestServedFromCache", ["requestId"]);
InspectorBackend.registerEvent("Network.responseReceived", ["requestId", "frameId", "loaderId", "timestamp", "type", "response"]);
InspectorBackend.registerEvent("Network.dataReceived", ["requestId", "timestamp", "dataLength", "encodedDataLength"]);
InspectorBackend.registerEvent("Network.loadingFinished", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.loadingFailed", ["requestId", "timestamp", "errorText", "canceled"]);
InspectorBackend.registerEvent("Network.requestServedFromMemoryCache", ["requestId", "frameId", "loaderId", "documentURL", "timestamp", "initiator", "resource"]);
InspectorBackend.registerEvent("Network.webSocketWillSendHandshakeRequest", ["requestId", "timestamp", "request"]);
InspectorBackend.registerEvent("Network.webSocketHandshakeResponseReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketCreated", ["requestId", "url"]);
InspectorBackend.registerEvent("Network.webSocketClosed", ["requestId", "timestamp"]);
InspectorBackend.registerEvent("Network.webSocketFrameReceived", ["requestId", "timestamp", "response"]);
InspectorBackend.registerEvent("Network.webSocketFrameError", ["requestId", "timestamp", "errorMessage"]);
InspectorBackend.registerEvent("Network.webSocketFrameSent", ["requestId", "timestamp", "response"]);
InspectorBackend.registerCommand("Network.enable", [], []);
InspectorBackend.registerCommand("Network.disable", [], []);
InspectorBackend.registerCommand("Network.setUserAgentOverride", [{"name": "userAgent", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.setExtraHTTPHeaders", [{"name": "headers", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Network.getResponseBody", [{"name": "requestId", "type": "string", "optional": false}], ["body", "base64Encoded"]);
InspectorBackend.registerCommand("Network.replayXHR", [{"name": "requestId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Network.canClearBrowserCache", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCache", [], []);
InspectorBackend.registerCommand("Network.canClearBrowserCookies", [], ["result"]);
InspectorBackend.registerCommand("Network.clearBrowserCookies", [], []);
InspectorBackend.registerCommand("Network.setCacheDisabled", [{"name": "cacheDisabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerDatabaseDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Database");
InspectorBackend.registerEvent("Database.addDatabase", ["database"]);
InspectorBackend.registerCommand("Database.enable", [], []);
InspectorBackend.registerCommand("Database.disable", [], []);
InspectorBackend.registerCommand("Database.getDatabaseTableNames", [{"name": "databaseId", "type": "string", "optional": false}], ["tableNames"]);
InspectorBackend.registerCommand("Database.executeSQL", [{"name": "databaseId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}], ["columnNames", "values", "sqlError"]);
InspectorBackend.registerIndexedDBDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "IndexedDB");
InspectorBackend.registerCommand("IndexedDB.enable", [], []);
InspectorBackend.registerCommand("IndexedDB.disable", [], []);
InspectorBackend.registerCommand("IndexedDB.requestDatabaseNamesForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["securityOriginWithDatabaseNames"]);
InspectorBackend.registerCommand("IndexedDB.requestDatabase", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}], ["databaseWithObjectStores"]);
InspectorBackend.registerCommand("IndexedDB.requestData", [{"name": "frameId", "type": "string", "optional": false}, {"name": "databaseName", "type": "string", "optional": false}, {"name": "objectStoreName", "type": "string", "optional": false}, {"name": "indexName", "type": "string", "optional": false}, {"name": "skipCount", "type": "number", "optional": false}, {"name": "pageSize", "type": "number", "optional": false}, {"name": "keyRange", "type": "object", "optional": true}], ["objectStoreDataEntries", "hasMore"]);
InspectorBackend.registerDOMStorageDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOMStorage");
InspectorBackend.registerEvent("DOMStorage.addDOMStorage", ["storage"]);
InspectorBackend.registerEvent("DOMStorage.domStorageUpdated", ["storageId"]);
InspectorBackend.registerCommand("DOMStorage.enable", [], []);
InspectorBackend.registerCommand("DOMStorage.disable", [], []);
InspectorBackend.registerCommand("DOMStorage.getDOMStorageEntries", [{"name": "storageId", "type": "string", "optional": false}], ["entries"]);
InspectorBackend.registerCommand("DOMStorage.setDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], ["success"]);
InspectorBackend.registerCommand("DOMStorage.removeDOMStorageItem", [{"name": "storageId", "type": "string", "optional": false}, {"name": "key", "type": "string", "optional": false}], ["success"]);
InspectorBackend.registerApplicationCacheDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "ApplicationCache");
InspectorBackend.registerEvent("ApplicationCache.applicationCacheStatusUpdated", ["frameId", "manifestURL", "status"]);
InspectorBackend.registerEvent("ApplicationCache.networkStateUpdated", ["isNowOnline"]);
InspectorBackend.registerCommand("ApplicationCache.getFramesWithManifests", [], ["frameIds"]);
InspectorBackend.registerCommand("ApplicationCache.enable", [], []);
InspectorBackend.registerCommand("ApplicationCache.getManifestForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["manifestURL"]);
InspectorBackend.registerCommand("ApplicationCache.getApplicationCacheForFrame", [{"name": "frameId", "type": "string", "optional": false}], ["applicationCache"]);
InspectorBackend.registerFileSystemDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "FileSystem");
InspectorBackend.registerCommand("FileSystem.enable", [], []);
InspectorBackend.registerCommand("FileSystem.disable", [], []);
InspectorBackend.registerCommand("FileSystem.requestFileSystemRoot", [{"name": "origin", "type": "string", "optional": false}, {"name": "type", "type": "string", "optional": false}], ["errorCode", "root"]);
InspectorBackend.registerCommand("FileSystem.requestDirectoryContent", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "entries"]);
InspectorBackend.registerCommand("FileSystem.requestMetadata", [{"name": "url", "type": "string", "optional": false}], ["errorCode", "metadata"]);
InspectorBackend.registerCommand("FileSystem.requestFileContent", [{"name": "url", "type": "string", "optional": false}, {"name": "readAsText", "type": "boolean", "optional": false}, {"name": "start", "type": "number", "optional": true}, {"name": "end", "type": "number", "optional": true}, {"name": "charset", "type": "string", "optional": true}], ["errorCode", "content", "charset"]);
InspectorBackend.registerCommand("FileSystem.deleteEntry", [{"name": "url", "type": "string", "optional": false}], ["errorCode"]);
InspectorBackend.registerDOMDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "DOM");
InspectorBackend.registerEvent("DOM.documentUpdated", []);
InspectorBackend.registerEvent("DOM.setChildNodes", ["parentId", "nodes"]);
InspectorBackend.registerEvent("DOM.attributeModified", ["nodeId", "name", "value"]);
InspectorBackend.registerEvent("DOM.attributeRemoved", ["nodeId", "name"]);
InspectorBackend.registerEvent("DOM.inlineStyleInvalidated", ["nodeIds"]);
InspectorBackend.registerEvent("DOM.characterDataModified", ["nodeId", "characterData"]);
InspectorBackend.registerEvent("DOM.childNodeCountUpdated", ["nodeId", "childNodeCount"]);
InspectorBackend.registerEvent("DOM.childNodeInserted", ["parentNodeId", "previousNodeId", "node"]);
InspectorBackend.registerEvent("DOM.childNodeRemoved", ["parentNodeId", "nodeId"]);
InspectorBackend.registerEvent("DOM.shadowRootPushed", ["hostId", "root"]);
InspectorBackend.registerEvent("DOM.shadowRootPopped", ["hostId", "rootId"]);
InspectorBackend.registerCommand("DOM.getDocument", [], ["root"]);
InspectorBackend.registerCommand("DOM.requestChildNodes", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.querySelector", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.querySelectorAll", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.setNodeName", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setNodeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.removeNode", [{"name": "nodeId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributeValue", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}, {"name": "value", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.setAttributesAsText", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "name", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("DOM.removeAttribute", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "name", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.getEventListenersForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["listeners"]);
InspectorBackend.registerCommand("DOM.getOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}], ["outerHTML"]);
InspectorBackend.registerCommand("DOM.setOuterHTML", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "outerHTML", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.performSearch", [{"name": "query", "type": "string", "optional": false}], ["searchId", "resultCount"]);
InspectorBackend.registerCommand("DOM.getSearchResults", [{"name": "searchId", "type": "string", "optional": false}, {"name": "fromIndex", "type": "number", "optional": false}, {"name": "toIndex", "type": "number", "optional": false}], ["nodeIds"]);
InspectorBackend.registerCommand("DOM.discardSearchResults", [{"name": "searchId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOM.requestNode", [{"name": "objectId", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.setInspectModeEnabled", [{"name": "enabled", "type": "boolean", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightRect", [{"name": "x", "type": "number", "optional": false}, {"name": "y", "type": "number", "optional": false}, {"name": "width", "type": "number", "optional": false}, {"name": "height", "type": "number", "optional": false}, {"name": "color", "type": "object", "optional": true}, {"name": "outlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.highlightNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "highlightConfig", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("DOM.hideHighlight", [], []);
InspectorBackend.registerCommand("DOM.highlightFrame", [{"name": "frameId", "type": "string", "optional": false}, {"name": "contentColor", "type": "object", "optional": true}, {"name": "contentOutlineColor", "type": "object", "optional": true}], []);
InspectorBackend.registerCommand("DOM.pushNodeByPathToFrontend", [{"name": "path", "type": "string", "optional": false}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.resolveNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["object"]);
InspectorBackend.registerCommand("DOM.getAttributes", [{"name": "nodeId", "type": "number", "optional": false}], ["attributes"]);
InspectorBackend.registerCommand("DOM.moveTo", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "targetNodeId", "type": "number", "optional": false}, {"name": "insertBeforeNodeId", "type": "number", "optional": true}], ["nodeId"]);
InspectorBackend.registerCommand("DOM.undo", [], []);
InspectorBackend.registerCommand("DOM.redo", [], []);
InspectorBackend.registerCommand("DOM.markUndoableState", [], []);
InspectorBackend.registerCSSDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "CSS");
InspectorBackend.registerEvent("CSS.mediaQueryResultChanged", []);
InspectorBackend.registerEvent("CSS.styleSheetChanged", ["styleSheetId"]);
InspectorBackend.registerEvent("CSS.namedFlowCreated", ["namedFlow"]);
InspectorBackend.registerEvent("CSS.namedFlowRemoved", ["documentNodeId", "flowName"]);
InspectorBackend.registerEvent("CSS.regionLayoutUpdated", ["namedFlow"]);
InspectorBackend.registerCommand("CSS.enable", [], []);
InspectorBackend.registerCommand("CSS.disable", [], []);
InspectorBackend.registerCommand("CSS.getMatchedStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "includePseudo", "type": "boolean", "optional": true}, {"name": "includeInherited", "type": "boolean", "optional": true}], ["matchedCSSRules", "pseudoElements", "inherited"]);
InspectorBackend.registerCommand("CSS.getInlineStylesForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["inlineStyle", "attributesStyle"]);
InspectorBackend.registerCommand("CSS.getComputedStyleForNode", [{"name": "nodeId", "type": "number", "optional": false}], ["computedStyle"]);
InspectorBackend.registerCommand("CSS.getAllStyleSheets", [], ["headers"]);
InspectorBackend.registerCommand("CSS.getStyleSheet", [{"name": "styleSheetId", "type": "string", "optional": false}], ["styleSheet"]);
InspectorBackend.registerCommand("CSS.getStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}], ["text"]);
InspectorBackend.registerCommand("CSS.setStyleSheetText", [{"name": "styleSheetId", "type": "string", "optional": false}, {"name": "text", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("CSS.setPropertyText", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "text", "type": "string", "optional": false}, {"name": "overwrite", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.toggleProperty", [{"name": "styleId", "type": "object", "optional": false}, {"name": "propertyIndex", "type": "number", "optional": false}, {"name": "disable", "type": "boolean", "optional": false}], ["style"]);
InspectorBackend.registerCommand("CSS.setRuleSelector", [{"name": "ruleId", "type": "object", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.addRule", [{"name": "contextNodeId", "type": "number", "optional": false}, {"name": "selector", "type": "string", "optional": false}], ["rule"]);
InspectorBackend.registerCommand("CSS.getSupportedCSSProperties", [], ["cssProperties"]);
InspectorBackend.registerCommand("CSS.forcePseudoState", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "forcedPseudoClasses", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("CSS.startSelectorProfiler", [], []);
InspectorBackend.registerCommand("CSS.stopSelectorProfiler", [], ["profile"]);
InspectorBackend.registerCommand("CSS.getNamedFlowCollection", [{"name": "documentNodeId", "type": "number", "optional": false}], ["namedFlows"]);
InspectorBackend.registerTimelineDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Timeline");
InspectorBackend.registerEvent("Timeline.eventRecorded", ["record"]);
InspectorBackend.registerCommand("Timeline.start", [{"name": "maxCallStackDepth", "type": "number", "optional": true}], []);
InspectorBackend.registerCommand("Timeline.stop", [], []);
InspectorBackend.registerCommand("Timeline.setIncludeMemoryDetails", [{"name": "enabled", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Timeline.supportsFrameInstrumentation", [], ["result"]);
InspectorBackend.registerDebuggerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Debugger");
InspectorBackend.registerEvent("Debugger.globalObjectCleared", []);
InspectorBackend.registerEvent("Debugger.scriptParsed", ["scriptId", "url", "startLine", "startColumn", "endLine", "endColumn", "isContentScript", "sourceMapURL"]);
InspectorBackend.registerEvent("Debugger.scriptFailedToParse", ["url", "scriptSource", "startLine", "errorLine", "errorMessage"]);
InspectorBackend.registerEvent("Debugger.breakpointResolved", ["breakpointId", "location"]);
InspectorBackend.registerEvent("Debugger.paused", ["callFrames", "reason", "data"]);
InspectorBackend.registerEvent("Debugger.resumed", []);
InspectorBackend.registerCommand("Debugger.causesRecompilation", [], ["result"]);
InspectorBackend.registerCommand("Debugger.supportsSeparateScriptCompilationAndExecution", [], ["result"]);
InspectorBackend.registerCommand("Debugger.enable", [], []);
InspectorBackend.registerCommand("Debugger.disable", [], []);
InspectorBackend.registerCommand("Debugger.setBreakpointsActive", [{"name": "active", "type": "boolean", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.setBreakpointByUrl", [{"name": "lineNumber", "type": "number", "optional": false}, {"name": "url", "type": "string", "optional": true}, {"name": "urlRegex", "type": "string", "optional": true}, {"name": "columnNumber", "type": "number", "optional": true}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "locations"]);
InspectorBackend.registerCommand("Debugger.setBreakpoint", [{"name": "location", "type": "object", "optional": false}, {"name": "condition", "type": "string", "optional": true}], ["breakpointId", "actualLocation"]);
InspectorBackend.registerCommand("Debugger.removeBreakpoint", [{"name": "breakpointId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.continueToLocation", [{"name": "location", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.stepOver", [], []);
InspectorBackend.registerCommand("Debugger.stepInto", [], []);
InspectorBackend.registerCommand("Debugger.stepOut", [], []);
InspectorBackend.registerCommand("Debugger.pause", [], []);
InspectorBackend.registerCommand("Debugger.resume", [], []);
InspectorBackend.registerCommand("Debugger.searchInContent", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "query", "type": "string", "optional": false}, {"name": "caseSensitive", "type": "boolean", "optional": true}, {"name": "isRegex", "type": "boolean", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Debugger.canSetScriptSource", [], ["result"]);
InspectorBackend.registerCommand("Debugger.setScriptSource", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "scriptSource", "type": "string", "optional": false}, {"name": "preview", "type": "boolean", "optional": true}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.restartFrame", [{"name": "callFrameId", "type": "string", "optional": false}], ["callFrames", "result"]);
InspectorBackend.registerCommand("Debugger.getScriptSource", [{"name": "scriptId", "type": "string", "optional": false}], ["scriptSource"]);
InspectorBackend.registerCommand("Debugger.getFunctionDetails", [{"name": "functionId", "type": "string", "optional": false}], ["details"]);
InspectorBackend.registerCommand("Debugger.setPauseOnExceptions", [{"name": "state", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("Debugger.evaluateOnCallFrame", [{"name": "callFrameId", "type": "string", "optional": false}, {"name": "expression", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "includeCommandLineAPI", "type": "boolean", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}, {"name": "returnByValue", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.compileScript", [{"name": "expression", "type": "string", "optional": false}, {"name": "sourceURL", "type": "string", "optional": false}], ["scriptId", "syntaxErrorMessage"]);
InspectorBackend.registerCommand("Debugger.runScript", [{"name": "scriptId", "type": "string", "optional": false}, {"name": "contextId", "type": "number", "optional": true}, {"name": "objectGroup", "type": "string", "optional": true}, {"name": "doNotPauseOnExceptionsAndMuteConsole", "type": "boolean", "optional": true}], ["result", "wasThrown"]);
InspectorBackend.registerCommand("Debugger.setOverlayMessage", [{"name": "message", "type": "string", "optional": true}], []);
InspectorBackend.registerCommand("DOMDebugger.setDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeDOMBreakpoint", [{"name": "nodeId", "type": "number", "optional": false}, {"name": "type", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeEventListenerBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeInstrumentationBreakpoint", [{"name": "eventName", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.setXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("DOMDebugger.removeXHRBreakpoint", [{"name": "url", "type": "string", "optional": false}], []);
InspectorBackend.registerProfilerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Profiler");
InspectorBackend.registerEvent("Profiler.addProfileHeader", ["header"]);
InspectorBackend.registerEvent("Profiler.addHeapSnapshotChunk", ["uid", "chunk"]);
InspectorBackend.registerEvent("Profiler.finishHeapSnapshot", ["uid"]);
InspectorBackend.registerEvent("Profiler.setRecordingProfile", ["isProfiling"]);
InspectorBackend.registerEvent("Profiler.resetProfiles", []);
InspectorBackend.registerEvent("Profiler.reportHeapSnapshotProgress", ["done", "total"]);
InspectorBackend.registerCommand("Profiler.causesRecompilation", [], ["result"]);
InspectorBackend.registerCommand("Profiler.isSampling", [], ["result"]);
InspectorBackend.registerCommand("Profiler.hasHeapProfiler", [], ["result"]);
InspectorBackend.registerCommand("Profiler.enable", [], []);
InspectorBackend.registerCommand("Profiler.disable", [], []);
InspectorBackend.registerCommand("Profiler.start", [], []);
InspectorBackend.registerCommand("Profiler.stop", [], []);
InspectorBackend.registerCommand("Profiler.getProfileHeaders", [], ["headers"]);
InspectorBackend.registerCommand("Profiler.getProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], ["profile"]);
InspectorBackend.registerCommand("Profiler.removeProfile", [{"name": "type", "type": "string", "optional": false}, {"name": "uid", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Profiler.clearProfiles", [], []);
InspectorBackend.registerCommand("Profiler.takeHeapSnapshot", [], []);
InspectorBackend.registerCommand("Profiler.collectGarbage", [], []);
InspectorBackend.registerCommand("Profiler.getObjectByHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}, {"name": "objectGroup", "type": "string", "optional": true}], ["result"]);
InspectorBackend.registerCommand("Profiler.getHeapObjectId", [{"name": "objectId", "type": "string", "optional": false}], ["heapSnapshotObjectId"]);
InspectorBackend.registerWorkerDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "Worker");
InspectorBackend.registerEvent("Worker.workerCreated", ["workerId", "url", "inspectorConnected"]);
InspectorBackend.registerEvent("Worker.workerTerminated", ["workerId"]);
InspectorBackend.registerEvent("Worker.dispatchMessageFromWorker", ["workerId", "message"]);
InspectorBackend.registerEvent("Worker.disconnectedFromWorker", []);
InspectorBackend.registerCommand("Worker.enable", [], []);
InspectorBackend.registerCommand("Worker.disable", [], []);
InspectorBackend.registerCommand("Worker.sendMessageToWorker", [{"name": "workerId", "type": "number", "optional": false}, {"name": "message", "type": "object", "optional": false}], []);
InspectorBackend.registerCommand("Worker.connectToWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.disconnectFromWorker", [{"name": "workerId", "type": "number", "optional": false}], []);
InspectorBackend.registerCommand("Worker.setAutoconnectToWorkers", [{"name": "value", "type": "boolean", "optional": false}], []);
InspectorBackend.registerWebGLDispatcher = InspectorBackend.registerDomainDispatcher.bind(InspectorBackend, "WebGL");
InspectorBackend.registerCommand("WebGL.enable", [], []);
InspectorBackend.registerCommand("WebGL.disable", [], []);
InspectorBackend.registerCommand("WebGL.dropTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], []);
InspectorBackend.registerCommand("WebGL.captureFrame", [], ["traceLogId"]);
InspectorBackend.registerCommand("WebGL.getTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}], ["traceLog"]);
InspectorBackend.registerCommand("WebGL.replayTraceLog", [{"name": "traceLogId", "type": "string", "optional": false}, {"name": "stepNo", "type": "number", "optional": false}], ["screenshotDataUrl"]);
if (!window.InspectorExtensionRegistry) {
WebInspector.InspectorExtensionRegistryStub = function()
{
}
WebInspector.InspectorExtensionRegistryStub.prototype = {
getExtensionsAsync: function()
{
}
}
var InspectorExtensionRegistry = new WebInspector.InspectorExtensionRegistryStub();
}
InspectorFrontendAPI = {
_pendingCommands: [],
isDebuggingEnabled: function()
{
return WebInspector.debuggerModel.debuggerEnabled();
},
setDebuggingEnabled: function(enabled)
{
if (enabled) {
WebInspector.debuggerModel.enableDebugger();
WebInspector.showPanel("scripts");
} else
WebInspector.debuggerModel.disableDebugger();
},
isTimelineProfilingEnabled: function()
{
return WebInspector.panels.timeline && WebInspector.panels.timeline.timelineProfilingEnabled;
},
setTimelineProfilingEnabled: function(enabled)
{
WebInspector.showPanel("timeline").setTimelineProfilingEnabled(enabled);
},
isProfilingJavaScript: function()
{
return WebInspector.panels.profiles && WebInspector.CPUProfileType.instance && WebInspector.CPUProfileType.instance.isRecordingProfile();
},
startProfilingJavaScript: function()
{
WebInspector.showPanel("profiles").enableProfiler();
if (WebInspector.CPUProfileType.instance)
WebInspector.CPUProfileType.instance.startRecordingProfile();
},
stopProfilingJavaScript: function()
{
WebInspector.showPanel("profiles");
if (WebInspector.CPUProfileType.instance)
WebInspector.CPUProfileType.instance.stopRecordingProfile();
},
setAttachedWindow: function(attached)
{
WebInspector.attached = attached;
},
showConsole: function()
{
WebInspector.showPanel("console");
},
showMainResourceForFrame: function(frameId)
{
},
showResources: function()
{
WebInspector.showPanel("resources");
},
setDockingUnavailable: function(unavailable)
{
WebInspector.setDockingUnavailable(unavailable);
},
enterInspectElementMode: function()
{
WebInspector.toggleSearchingForNode();
},
savedURL: function(url)
{
WebInspector.fileManager.savedURL(url);
},
appendedToURL: function(url)
{
WebInspector.fileManager.appendedToURL(url);
},
setToolbarColors: function(backgroundColor, color)
{
WebInspector.setToolbarColors(backgroundColor, color);
},
evaluateForTest: function(callId, script)
{
WebInspector.evaluateForTestInFrontend(callId, script);
},
dispatch: function(signature)
{
if (InspectorFrontendAPI._isLoaded) {
var methodName = signature.shift();
return InspectorFrontendAPI[methodName].apply(InspectorFrontendAPI, signature);
}
InspectorFrontendAPI._pendingCommands.push(signature);
},
dispatchQueryParameters: function()
{
if ("dispatch" in WebInspector.queryParamsObject)
InspectorFrontendAPI.dispatch(JSON.parse(window.decodeURI(WebInspector.queryParamsObject["dispatch"])));
},
loadTimelineFromURL: function(url)
{
WebInspector.showPanel("timeline").loadFromURL(url);
},
loadCompleted: function()
{
InspectorFrontendAPI._isLoaded = true;
for (var i = 0; i < InspectorFrontendAPI._pendingCommands.length; ++i)
InspectorFrontendAPI.dispatch(InspectorFrontendAPI._pendingCommands[i]);
InspectorFrontendAPI._pendingCommands = [];
if (window.opener)
window.opener.postMessage(["loadCompleted"], "*");
}
}
if (window.opener) {
function onMessageFromOpener(event)
{
if (event.source === window.opener)
InspectorFrontendAPI.dispatch(event.data);
}
window.addEventListener("message", onMessageFromOpener, true);
}
WebInspector.Object = function() {
}
WebInspector.Object.prototype = {
addEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);
if (!this._listeners)
this._listeners = {};
if (!this._listeners[eventType])
this._listeners[eventType] = [];
this._listeners[eventType].push({ thisObject: thisObject, listener: listener });
},
removeEventListener: function(eventType, listener, thisObject)
{
console.assert(listener);
if (!this._listeners || !this._listeners[eventType])
return;
var listeners = this._listeners[eventType];
for (var i = 0; i < listeners.length; ++i) {
if (listener && listeners[i].listener === listener && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
else if (!listener && thisObject && listeners[i].thisObject === thisObject)
listeners.splice(i, 1);
}
if (!listeners.length)
delete this._listeners[eventType];
},
removeAllListeners: function()
{
delete this._listeners;
},
hasEventListeners: function(eventType)
{
if (!this._listeners || !this._listeners[eventType])
return false;
return true;
},
dispatchEventToListeners: function(eventType, eventData)
{
if (!this._listeners || !this._listeners[eventType])
return false;
var event = new WebInspector.Event(this, eventType, eventData);
var listeners = this._listeners[eventType].slice(0);
for (var i = 0; i < listeners.length; ++i) {
listeners[i].listener.call(listeners[i].thisObject, event);
if (event._stoppedPropagation)
break;
}
return event.defaultPrevented;
}
}
WebInspector.Event = function(target, type, data)
{
this.target = target;
this.type = type;
this.data = data;
this.defaultPrevented = false;
this._stoppedPropagation = false;
}
WebInspector.Event.prototype = {
stopPropagation: function()
{
this._stoppedPropagation = true;
},
preventDefault: function()
{
this.defaultPrevented = true;
},
consume: function(preventDefault)
{
this.stopPropagation();
if (preventDefault)
this.preventDefault();
}
}
WebInspector.notifications = new WebInspector.Object();
var Preferences = {
maxInlineTextChildLength: 80,
minConsoleHeight: 75,
minSidebarWidth: 100,
minElementsSidebarWidth: 200,
minScriptsSidebarWidth: 200,
styleRulesExpandedState: {},
showMissingLocalizedStrings: false,
useLowerCaseMenuTitlesOnWindows: false,
sharedWorkersDebugNote: undefined,
localizeUI: true,
exposeDisableCache: false,
applicationTitle: "Web Inspector - %s",
showDockToRight: false,
exposeFileSystemInspection: false
}
var Capabilities = {
samplingCPUProfiler: false,
debuggerCausesRecompilation: true,
separateScriptCompilationAndExecutionEnabled: false,
profilerCausesRecompilation: true,
heapProfilerPresent: false,
canOverrideDeviceMetrics: false,
timelineSupportsFrameInstrumentation: false,
canOverrideGeolocation: false,
canOverrideDeviceOrientation: false,
}
WebInspector.Settings = function()
{
this._eventSupport = new WebInspector.Object();
this.colorFormat = this.createSetting("colorFormat", "hex");
this.consoleHistory = this.createSetting("consoleHistory", []);
this.debuggerEnabled = this.createSetting("debuggerEnabled", false);
this.domWordWrap = this.createSetting("domWordWrap", true);
this.profilerEnabled = this.createSetting("profilerEnabled", false);
this.eventListenersFilter = this.createSetting("eventListenersFilter", "all");
this.lastActivePanel = this.createSetting("lastActivePanel", "elements");
this.lastViewedScriptFile = this.createSetting("lastViewedScriptFile", "application");
this.monitoringXHREnabled = this.createSetting("monitoringXHREnabled", false);
this.preserveConsoleLog = this.createSetting("preserveConsoleLog", false);
this.resourcesLargeRows = this.createSetting("resourcesLargeRows", true);
this.resourcesSortOptions = this.createSetting("resourcesSortOptions", {timeOption: "responseTime", sizeOption: "transferSize"});
this.resourceViewTab = this.createSetting("resourceViewTab", "preview");
this.showInheritedComputedStyleProperties = this.createSetting("showInheritedComputedStyleProperties", false);
this.showUserAgentStyles = this.createSetting("showUserAgentStyles", true);
this.watchExpressions = this.createSetting("watchExpressions", []);
this.breakpoints = this.createSetting("breakpoints", []);
this.eventListenerBreakpoints = this.createSetting("eventListenerBreakpoints", []);
this.domBreakpoints = this.createSetting("domBreakpoints", []);
this.xhrBreakpoints = this.createSetting("xhrBreakpoints", []);
this.sourceMapsEnabled = this.createSetting("sourceMapsEnabled", false);
this.cacheDisabled = this.createSetting("cacheDisabled", false);
this.overrideUserAgent = this.createSetting("overrideUserAgent", "");
this.userAgent = this.createSetting("userAgent", "");
this.deviceMetrics = this.createSetting("deviceMetrics", "");
this.deviceFitWindow = this.createSetting("deviceFitWindow", false);
this.showScriptFolders = this.createSetting("showScriptFolders", true);
this.dockToRight = this.createSetting("dockToRight", false);
this.emulateTouchEvents = this.createSetting("emulateTouchEvents", false);
this.showPaintRects = this.createSetting("showPaintRects", false);
this.zoomLevel = this.createSetting("zoomLevel", 0);
this.savedURLs = this.createSetting("savedURLs", {});
this.javaScriptDisabled = this.createSetting("javaScriptDisabled", false);
this.geolocationOverride = this.createSetting("geolocationOverride", "");
this.deviceOrientationOverride = this.createSetting("deviceOrientationOverride", "");
this.showHeapSnapshotObjectsHiddenProperties = this.createSetting("showHeaSnapshotObjectsHiddenProperties", false);
this.searchInContentScripts = this.createSetting("searchInContentScripts", false);
this.textEditorIndent = this.createSetting("textEditorIndent", " ");
if (this.breakpoints.get().length > 500000)
this.breakpoints.set([]);
}
WebInspector.Settings.prototype = {
createSetting: function(key, defaultValue)
{
return new WebInspector.Setting(key, defaultValue, this._eventSupport);
}
}
WebInspector.Setting = function(name, defaultValue, eventSupport)
{
this._name = name;
this._defaultValue = defaultValue;
this._eventSupport = eventSupport;
}
WebInspector.Setting.prototype = {
addChangeListener: function(listener, thisObject)
{
this._eventSupport.addEventListener(this._name, listener, thisObject);
},
removeChangeListener: function(listener, thisObject)
{
this._eventSupport.removeEventListener(this._name, listener, thisObject);
},
get name()
{
return this._name;
},
get: function()
{
if (typeof this._value !== "undefined")
return this._value;
this._value = this._defaultValue;
if (window.localStorage != null && this._name in window.localStorage) {
try {
this._value = JSON.parse(window.localStorage[this._name]);
} catch(e) {
window.localStorage.removeItem(this._name);
}
}
return this._value;
},
set: function(value)
{
this._value = value;
if (window.localStorage != null) {
try {
window.localStorage[this._name] = JSON.stringify(value);
} catch(e) {
console.error("Error saving setting with name:" + this._name);
}
}
this._eventSupport.dispatchEventToListeners(this._name, value);
}
}
WebInspector.ExperimentsSettings = function()
{
this._setting = WebInspector.settings.createSetting("experiments", {});
this._experiments = [];
this._enabledForTest = {};
this.showShadowDOM = this._createExperiment("showShadowDOM", "Show shadow DOM");
this.snippetsSupport = this._createExperiment("snippetsSupport", "Snippets support");
this.nativeMemorySnapshots = this._createExperiment("nativeMemorySnapshots", "Native memory profiling");
this.liveNativeMemoryChart = this._createExperiment("liveNativeMemoryChart", "Live native memory chart");
this.fileSystemInspection = this._createExperiment("fileSystemInspection", "FileSystem inspection");
this.webGLInspection = this._createExperiment("webGLInspection ", "WebGL inspection");
this.mainThreadMonitoring = this._createExperiment("mainThreadMonitoring", "Show CPU activity in Timeline");
this.geolocationOverride = this._createExperiment("geolocationOverride", "Override Device Geolocation");
this.deviceOrientationOverride = this._createExperiment("deviceOrientationOverride", "Override Device Orientation");
this.sass = this._createExperiment("sass", "Support for SASS");
this.codemirror = this._createExperiment("codemirror", "Use CodeMirror editor");
this.cssRegions = this._createExperiment("cssRegions", "CSS Regions Support");
this._cleanUpSetting();
}
WebInspector.ExperimentsSettings.prototype = {
get experiments()
{
return this._experiments.slice();
},
get experimentsEnabled()
{
return "experiments" in WebInspector.queryParamsObject;
},
_createExperiment: function(experimentName, experimentTitle)
{
var experiment = new WebInspector.Experiment(this, experimentName, experimentTitle);
this._experiments.push(experiment);
return experiment;
},
isEnabled: function(experimentName)
{
if (this._enabledForTest[experimentName])
return true;
if (!this.experimentsEnabled)
return false;
var experimentsSetting = this._setting.get();
return experimentsSetting[experimentName];
},
setEnabled: function(experimentName, enabled)
{
var experimentsSetting = this._setting.get();
experimentsSetting[experimentName] = enabled;
this._setting.set(experimentsSetting);
},
_enableForTest: function(experimentName)
{
this._enabledForTest[experimentName] = true;
},
_cleanUpSetting: function()
{
var experimentsSetting = this._setting.get();
var cleanedUpExperimentSetting = {};
for (var i = 0; i < this._experiments.length; ++i) {
var experimentName = this._experiments[i].name;
if (experimentsSetting[experimentName])
cleanedUpExperimentSetting[experimentName] = true;
}
this._setting.set(cleanedUpExperimentSetting);
}
}
WebInspector.Experiment = function(experimentsSettings, name, title)
{
this._name = name;
this._title = title;
this._experimentsSettings = experimentsSettings;
}
WebInspector.Experiment.prototype = {
get name()
{
return this._name;
},
get title()
{
return this._title;
},
isEnabled: function()
{
return this._experimentsSettings.isEnabled(this._name);
},
setEnabled: function(enabled)
{
return this._experimentsSettings.setEnabled(this._name, enabled);
},
enableForTest: function()
{
this._experimentsSettings._enableForTest(this._name);
}
}
WebInspector.settings = new WebInspector.Settings();
WebInspector.experimentsSettings = new WebInspector.ExperimentsSettings();
WebInspector.View = function()
{
this.element = document.createElement("div");
this.element.__view = this;
this._visible = true;
this._isRoot = false;
this._isShowing = false;
this._children = [];
this._hideOnDetach = false;
this._cssFiles = [];
}
WebInspector.View._cssFileToVisibleViewCount = {};
WebInspector.View._cssFileToStyleElement = {};
WebInspector.View.prototype = {
markAsRoot: function()
{
this._isRoot = true;
},
isShowing: function()
{
return this._isShowing;
},
setHideOnDetach: function()
{
this._hideOnDetach = true;
},
_parentIsShowing: function()
{
return this._isRoot || (this._parentView && this._parentView.isShowing());
},
_callOnVisibleChildren: function(method)
{
for (var i = 0; i < this._children.length; ++i)
if (this._children[i]._visible)
method.call(this._children[i]);
},
_processWillShow: function()
{
this._loadCSSIfNeeded();
this._callOnVisibleChildren(this._processWillShow);
},
_processWasShown: function()
{
this._isShowing = true;
this.restoreScrollPositions();
this.wasShown();
this.onResize();
this._callOnVisibleChildren(this._processWasShown);
},
_processWillHide: function()
{
this.storeScrollPositions();
this._callOnVisibleChildren(this._processWillHide);
this.willHide();
this._isShowing = false;
},
_processWasHidden: function()
{
this._disableCSSIfNeeded();
this._callOnVisibleChildren(this._processWasHidden);
},
_processOnResize: function()
{
if (!this.isShowing())
return;
this.onResize();
this._callOnVisibleChildren(this._processOnResize);
},
wasShown: function()
{
},
willHide: function()
{
},
onResize: function()
{
},
show: function(parentElement, insertBefore)
{
WebInspector.View._assert(parentElement, "Attempt to attach view with no parent element");
if (this.element.parentElement !== parentElement) {
var currentParent = parentElement;
while (currentParent && !currentParent.__view)
currentParent = currentParent.parentElement;
if (currentParent) {
this._parentView = currentParent.__view;
this._parentView._children.push(this);
this._isRoot = false;
} else
WebInspector.View._assert(this._isRoot, "Attempt to attach view to orphan node");
} else if (this._visible)
return;
this._visible = true;
if (this._parentIsShowing())
this._processWillShow();
this.element.addStyleClass("visible");
if (this.element.parentElement !== parentElement) {
WebInspector.View._incrementViewCounter(parentElement, this.element);
if (insertBefore)
WebInspector.View._originalInsertBefore.call(parentElement, this.element, insertBefore);
else
WebInspector.View._originalAppendChild.call(parentElement, this.element);
}
if (this._parentIsShowing())
this._processWasShown();
},
detach: function(overrideHideOnDetach)
{
var parentElement = this.element.parentElement;
if (!parentElement)
return;
if (this._parentIsShowing())
this._processWillHide();
if (this._hideOnDetach && !overrideHideOnDetach) {
this.element.removeStyleClass("visible");
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
return;
}
WebInspector.View._decrementViewCounter(parentElement, this.element);
WebInspector.View._originalRemoveChild.call(parentElement, this.element);
this._visible = false;
if (this._parentIsShowing())
this._processWasHidden();
if (this._parentView) {
var childIndex = this._parentView._children.indexOf(this);
WebInspector.View._assert(childIndex >= 0, "Attempt to remove non-child view");
this._parentView._children.splice(childIndex, 1);
this._parentView = null;
} else
WebInspector.View._assert(this._isRoot, "Removing non-root view from DOM");
},
detachChildViews: function()
{
var children = this._children.slice();
for (var i = 0; i < children.length; ++i)
children[i].detach();
},
elementsToRestoreScrollPositionsFor: function()
{
return [this.element];
},
storeScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
container._scrollTop = container.scrollTop;
container._scrollLeft = container.scrollLeft;
}
},
restoreScrollPositions: function()
{
var elements = this.elementsToRestoreScrollPositionsFor();
for (var i = 0; i < elements.length; ++i) {
var container = elements[i];
if (container._scrollTop)
container.scrollTop = container._scrollTop;
if (container._scrollLeft)
container.scrollLeft = container._scrollLeft;
}
},
canHighlightLine: function()
{
return false;
},
highlightLine: function(line)
{
},
doResize: function()
{
this._processOnResize();
},
registerRequiredCSS: function(cssFile)
{
this._cssFiles.push(cssFile);
},
_loadCSSIfNeeded: function()
{
for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];
var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
WebInspector.View._cssFileToVisibleViewCount[cssFile] = (viewsWithCSSFile || 0) + 1;
if (!viewsWithCSSFile)
this._doLoadCSS(cssFile);
}
},
_doLoadCSS: function(cssFile)
{
var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
if (styleElement) {
styleElement.disabled = false;
return;
}
if (window.debugCSS) {
styleElement = document.createElement("link");
styleElement.rel = "stylesheet";
styleElement.type = "text/css";
styleElement.href = cssFile;
} else {
var xhr = new XMLHttpRequest();
xhr.open("GET", cssFile, false);
xhr.send(null);
styleElement = document.createElement("style");
styleElement.type = "text/css";
styleElement.textContent = xhr.responseText;
}
document.head.insertBefore(styleElement, document.head.firstChild);
WebInspector.View._cssFileToStyleElement[cssFile] = styleElement;
},
_disableCSSIfNeeded: function()
{
for (var i = 0; i < this._cssFiles.length; ++i) {
var cssFile = this._cssFiles[i];
var viewsWithCSSFile = WebInspector.View._cssFileToVisibleViewCount[cssFile];
viewsWithCSSFile--;
WebInspector.View._cssFileToVisibleViewCount[cssFile] = viewsWithCSSFile;
if (!viewsWithCSSFile)
this._doUnloadCSS(cssFile);
}
},
_doUnloadCSS: function(cssFile)
{
var styleElement = WebInspector.View._cssFileToStyleElement[cssFile];
styleElement.disabled = true;
},
printViewHierarchy: function()
{
var lines = [];
this._collectViewHierarchy("", lines);
console.log(lines.join("\n"));
},
_collectViewHierarchy: function(prefix, lines)
{
lines.push(prefix + "[" + this.element.className + "]" + (this._children.length ? " {" : ""));
for (var i = 0; i < this._children.length; ++i)
this._children[i]._collectViewHierarchy(prefix + " ", lines);
if (this._children.length)
lines.push(prefix + "}");
},
defaultFocusedElement: function()
{
return this._defaultFocusedElement || this.element;
},
setDefaultFocusedElement: function(element)
{
this._defaultFocusedElement = element;
},
focus: function()
{
var element = this.defaultFocusedElement();
if (!element || element.isAncestor(document.activeElement))
return;
WebInspector.setCurrentFocusElement(element);
}
}
WebInspector.View.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.View._originalAppendChild = Element.prototype.appendChild;
WebInspector.View._originalInsertBefore = Element.prototype.insertBefore;
WebInspector.View._originalRemoveChild = Element.prototype.removeChild;
WebInspector.View._originalRemoveChildren = Element.prototype.removeChildren;
WebInspector.View._incrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;
while (parentElement) {
parentElement.__viewCounter = (parentElement.__viewCounter || 0) + count;
parentElement = parentElement.parentElement;
}
}
WebInspector.View._decrementViewCounter = function(parentElement, childElement)
{
var count = (childElement.__viewCounter || 0) + (childElement.__view ? 1 : 0);
if (!count)
return;
while (parentElement) {
parentElement.__viewCounter -= count;
parentElement = parentElement.parentElement;
}
}
WebInspector.View._assert = function(condition, message)
{
if (!condition) {
console.trace();
throw new Error(message);
}
}
Element.prototype.appendChild = function(child)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalAppendChild.call(this, child);
}
Element.prototype.insertBefore = function(child, anchor)
{
WebInspector.View._assert(!child.__view, "Attempt to add view via regular DOM operation.");
return WebInspector.View._originalInsertBefore.call(this, child, anchor);
}
Element.prototype.removeChild = function(child)
{
WebInspector.View._assert(!child.__viewCounter && !child.__view, "Attempt to remove element containing view via regular DOM operation");
return WebInspector.View._originalRemoveChild.call(this, child);
}
Element.prototype.removeChildren = function()
{
WebInspector.View._assert(!this.__viewCounter, "Attempt to remove element containing view via regular DOM operation");
WebInspector.View._originalRemoveChildren.call(this);
}
WebInspector.HelpScreen = function(title)
{
WebInspector.View.call(this);
this.markAsRoot();
this.registerRequiredCSS("helpScreen.css");
this.element.className = "help-window-outer";
this.element.addEventListener("keydown", this._onKeyDown.bind(this), false);
this.element.tabIndex = 0;
this.element.addEventListener("focus", this._onBlur.bind(this), false);
if (title) {
var mainWindow = this.element.createChild("div", "help-window-main");
var captionWindow = mainWindow.createChild("div", "help-window-caption");
captionWindow.appendChild(this._createCloseButton());
this.contentElement = mainWindow.createChild("div", "help-content");
captionWindow.createChild("h1", "help-window-title").textContent = title;
}
}
WebInspector.HelpScreen._visibleScreen = null;
WebInspector.HelpScreen.prototype = {
_createCloseButton: function()
{
var closeButton = document.createElement("button");
closeButton.className = "help-close-button";
closeButton.textContent = "\u2716";
closeButton.addEventListener("click", this.hide.bind(this), false);
return closeButton;
},
showModal: function()
{
var visibleHelpScreen = WebInspector.HelpScreen._visibleScreen;
if (visibleHelpScreen === this)
return;
if (visibleHelpScreen)
visibleHelpScreen.hide();
WebInspector.HelpScreen._visibleScreen = this;
this.show(document.body);
this.focus();
},
hide: function()
{
if (!this.isShowing())
return;
WebInspector.HelpScreen._visibleScreen = null;
WebInspector.restoreFocusFromElement(this.element);
this.detach();
},
isClosingKey: function(keyCode)
{
return [
WebInspector.KeyboardShortcut.Keys.Enter.code,
WebInspector.KeyboardShortcut.Keys.Esc.code,
WebInspector.KeyboardShortcut.Keys.Space.code,
].indexOf(keyCode) >= 0;
},
_onKeyDown: function(event)
{
if (this.isShowing() && this.isClosingKey(event.keyCode)) {
this.hide();
event.consume();
}
},
_onBlur: function(event)
{
if (this.isShowing() && !this.element.isSelfOrAncestor(event.target))
WebInspector.setCurrentFocusElement(this.element);
}
}
WebInspector.HelpScreen.prototype.__proto__ = WebInspector.View.prototype;
if (!window.InspectorFrontendHost) {
WebInspector.InspectorFrontendHostStub = function()
{
this._attachedWindowHeight = 0;
this.isStub = true;
WebInspector.documentCopyEventFired = this.documentCopy.bind(this);
}
WebInspector.InspectorFrontendHostStub.prototype = {
platform: function()
{
var match = navigator.userAgent.match(/Windows NT/);
if (match)
return "windows";
match = navigator.userAgent.match(/Mac OS X/);
if (match)
return "mac";
return "linux";
},
port: function()
{
return "unknown";
},
bringToFront: function()
{
this._windowVisible = true;
},
closeWindow: function()
{
this._windowVisible = false;
},
requestAttachWindow: function()
{
},
requestDetachWindow: function()
{
},
requestSetDockSide: function()
{
},
setAttachedWindowHeight: function(height)
{
},
moveWindowBy: function(x, y)
{
},
setInjectedScriptForOrigin: function(origin, script)
{
},
loaded: function()
{
},
localizedStringsURL: function()
{
return undefined;
},
hiddenPanels: function()
{
return WebInspector.queryParamsObject["hiddenPanels"] || "";
},
inspectedURLChanged: function(url)
{
document.title = WebInspector.UIString(Preferences.applicationTitle, url);
},
documentCopy: function(event)
{
if (!this._textToCopy)
return;
event.clipboardData.setData("text", this._textToCopy);
event.preventDefault();
delete this._textToCopy;
},
copyText: function(text)
{
this._textToCopy = text;
if (!document.execCommand("copy")) {
var screen = new WebInspector.ClipboardAccessDeniedScreen();
screen.showModal();
}
},
openInNewTab: function(url)
{
window.open(url, "_blank");
},
canSave: function()
{
return true;
},
save: function(url, content, forceSaveAs)
{
var builder = new WebKitBlobBuilder();
builder.append(content);
var blob = builder.getBlob("application/octet-stream");
var fr = new FileReader();
fr.onload = function(e) {
window.location = this.result;
}
fr.readAsDataURL(blob);
},
canAppend: function()
{
return false;
},
append: function(url, content)
{
},
sendMessageToBackend: function(message)
{
},
recordActionTaken: function(actionCode)
{
},
recordPanelShown: function(panelCode)
{
},
recordSettingChanged: function(settingCode)
{
},
loadResourceSynchronously: function(url)
{
return loadXHR(url);
},
setZoomFactor: function(zoom)
{
},
canInspectWorkers: function()
{
return true;
}
}
InspectorFrontendHost = new WebInspector.InspectorFrontendHostStub();
Preferences.localizeUI = false;
WebInspector.clipboardAccessDeniedMessage = function()
{
return "";
}
WebInspector.ClipboardAccessDeniedScreen = function()
{
WebInspector.HelpScreen.call(this, WebInspector.UIString("Clipboard access is denied"));
var platformMessage = WebInspector.clipboardAccessDeniedMessage();
if (platformMessage) {
var p = this.contentElement.createChild("p");
p.addStyleClass("help-section");
p.textContent = platformMessage;
}
}
WebInspector.ClipboardAccessDeniedScreen.prototype.__proto__ = WebInspector.HelpScreen.prototype;
}
WebInspector.FileManager = function()
{
}
WebInspector.FileManager.EventTypes = {
SavedURL: "SavedURL",
AppendedToURL: "AppendedToURL"
}
WebInspector.FileManager.prototype = {
canSave: function()
{
return InspectorFrontendHost.canSave();
},
canAppend: function()
{
return InspectorFrontendHost.canSave() && ("append" in InspectorFrontendHost);
},
save: function(url, content, forceSaveAs)
{
var savedURLs = WebInspector.settings.savedURLs.get();
delete savedURLs[url];
WebInspector.settings.savedURLs.set(savedURLs);
InspectorFrontendHost.save(url, content, forceSaveAs);
},
savedURL: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
savedURLs[url] = true;
WebInspector.settings.savedURLs.set(savedURLs);
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.SavedURL, url);
},
isURLSaved: function(url)
{
var savedURLs = WebInspector.settings.savedURLs.get();
return savedURLs[url];
},
append: function(url, content)
{
InspectorFrontendHost.append(url, content);
},
appendedToURL: function(url)
{
this.dispatchEventToListeners(WebInspector.FileManager.EventTypes.AppendedToURL, url);
}
}
WebInspector.FileManager.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.fileManager = new WebInspector.FileManager();
WebInspector.Checkbox = function(label, className, tooltip)
{
this.element = document.createElement('label');
this._inputElement = document.createElement('input');
this._inputElement.type = "checkbox";
this.element.className = className;
this.element.appendChild(this._inputElement);
this.element.appendChild(document.createTextNode(label));
if (tooltip)
this.element.title = tooltip;
}
WebInspector.Checkbox.prototype = {
set checked(checked)
{
this._inputElement.checked = checked;
},
get checked()
{
return this._inputElement.checked;
},
addEventListener: function(listener)
{
function listenerWrapper(event)
{
if (listener)
listener(event);
event.consume();
return true;
}
this._inputElement.addEventListener("click", listenerWrapper, false);
this.element.addEventListener("click", listenerWrapper, false);
}
}
WebInspector.ContextMenuItem = function(topLevelMenu, type, label, disabled, checked)
{
this._type = type;
this._label = label;
this._disabled = disabled;
this._checked = checked;
this._contextMenu = topLevelMenu;
if (type === "item" || type === "checkbox")
this._id = topLevelMenu.nextId();
}
WebInspector.ContextMenuItem.prototype = {
id: function()
{
return this._id;
},
type: function()
{
return this._type;
},
_buildDescriptor: function()
{
switch (this._type) {
case "item":
return { type: "item", id: this._id, label: this._label, enabled: !this._disabled };
case "separator":
return { type: "separator" };
case "checkbox":
return { type: "checkbox", id: this._id, label: this._label, checked: !!this._checked, enabled: !this._disabled };
}
}
}
WebInspector.ContextSubMenuItem = function(topLevelMenu, label, disabled)
{
WebInspector.ContextMenuItem.call(this, topLevelMenu, "subMenu", label, disabled);
this._items = [];
}
WebInspector.ContextSubMenuItem.prototype = {
appendItem: function(label, handler, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "item", label, disabled);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},
appendSubMenuItem: function(label, disabled)
{
var item = new WebInspector.ContextSubMenuItem(this._contextMenu, label, disabled);
this._pushItem(item);
return item;
},
appendCheckboxItem: function(label, handler, checked, disabled)
{
var item = new WebInspector.ContextMenuItem(this._contextMenu, "checkbox", label, disabled, checked);
this._pushItem(item);
this._contextMenu._setHandler(item.id(), handler);
return item;
},
appendSeparator: function()
{
if (this._items.length)
this._pendingSeparator = true;
},
_pushItem: function(item)
{
if (this._pendingSeparator) {
this._items.push(new WebInspector.ContextMenuItem(this._contextMenu, "separator"));
delete this._pendingSeparator;
}
this._items.push(item);
},
isEmpty: function()
{
return !this._items.length;
},
_buildDescriptor: function()
{
var result = { type: "subMenu", label: this._label, enabled: !this._disabled, subItems: [] };
for (var i = 0; i < this._items.length; ++i)
result.subItems.push(this._items[i]._buildDescriptor());
return result;
}
}
WebInspector.ContextSubMenuItem.prototype.__proto__ = WebInspector.ContextMenuItem.prototype;
WebInspector.ContextMenu = function() {
WebInspector.ContextSubMenuItem.call(this, this, "");
this._handlers = {};
this._id = 0;
}
WebInspector.ContextMenu.prototype = {
nextId: function()
{
return this._id++;
},
show: function(event)
{
var menuObject = this._buildDescriptor();
if (menuObject.length) {
WebInspector._contextMenu = this;
InspectorFrontendHost.showContextMenu(event, menuObject);
}
event.consume();
},
_setHandler: function(id, handler)
{
if (handler)
this._handlers[id] = handler;
},
_buildDescriptor: function()
{
var result = [];
for (var i = 0; i < this._items.length; ++i)
result.push(this._items[i]._buildDescriptor());
return result;
},
_itemSelected: function(id)
{
if (this._handlers[id])
this._handlers[id].call(this);
},
appendApplicableItems: function(target)
{
for (var i = 0; i < WebInspector.ContextMenu._providers.length; ++i) {
var provider = WebInspector.ContextMenu._providers[i];
this.appendSeparator();
provider.appendApplicableItems(this, target);
this.appendSeparator();
}
}
}
WebInspector.ContextMenu.prototype.__proto__ = WebInspector.ContextSubMenuItem.prototype;
WebInspector.ContextMenu.Provider = function() {
}
WebInspector.ContextMenu.Provider.prototype = {
appendApplicableItems: function(contextMenu, target) { }
}
WebInspector.ContextMenu.registerProvider = function(provider)
{
WebInspector.ContextMenu._providers.push(provider);
}
WebInspector.ContextMenu._providers = [];
WebInspector.contextMenuItemSelected = function(id)
{
if (WebInspector._contextMenu)
WebInspector._contextMenu._itemSelected(id);
}
WebInspector.contextMenuCleared = function()
{
}
if (!InspectorFrontendHost.showContextMenu) {
WebInspector.SoftContextMenu = function(items, parentMenu)
{
this._items = items;
this._parentMenu = parentMenu;
}
WebInspector.SoftContextMenu.prototype = {
show: function(event)
{
this._x = event.x;
this._y = event.y;
this._time = new Date().getTime();
var absoluteX = event.pageX;
var absoluteY = event.pageY;
var targetElement = event.target;
while (targetElement && window !== targetElement.ownerDocument.defaultView) {
var frameElement = targetElement.ownerDocument.defaultView.frameElement;
absoluteY += frameElement.totalOffsetTop();
absoluteX += frameElement.totalOffsetLeft();
targetElement = frameElement;
}
this._contextMenuElement = document.createElement("div");
this._contextMenuElement.className = "soft-context-menu";
this._contextMenuElement.tabIndex = 0;
this._contextMenuElement.style.top = absoluteY + "px";
this._contextMenuElement.style.left = absoluteX + "px";
this._contextMenuElement.addEventListener("mouseup", consumeEvent, false);
this._contextMenuElement.addEventListener("keydown", this._menuKeyDown.bind(this), false);
for (var i = 0; i < this._items.length; ++i)
this._contextMenuElement.appendChild(this._createMenuItem(this._items[i]));
if (!this._parentMenu) {
this._glassPaneElement = document.createElement("div");
this._glassPaneElement.className = "soft-context-menu-glass-pane";
this._glassPaneElement.tabIndex = 0;
this._glassPaneElement.addEventListener("mouseup", this._glassPaneMouseUp.bind(this), false);
this._glassPaneElement.appendChild(this._contextMenuElement);
document.body.appendChild(this._glassPaneElement);
this._focus();
} else
this._parentMenu._parentGlassPaneElement().appendChild(this._contextMenuElement);
if (document.body.offsetWidth < this._contextMenuElement.offsetLeft + this._contextMenuElement.offsetWidth)
this._contextMenuElement.style.left = (absoluteX - this._contextMenuElement.offsetWidth) + "px";
if (document.body.offsetHeight < this._contextMenuElement.offsetTop + this._contextMenuElement.offsetHeight)
this._contextMenuElement.style.top = (document.body.offsetHeight - this._contextMenuElement.offsetHeight) + "px";
event.consume(true);
},
_parentGlassPaneElement: function()
{
if (this._glassPaneElement)
return this._glassPaneElement;
if (this._parentMenu)
return this._parentMenu._parentGlassPaneElement();
return null;
},
_createMenuItem: function(item)
{
if (item.type === "separator")
return this._createSeparator();
if (item.type === "subMenu")
return this._createSubMenu(item);
var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";
var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 ";
checkMarkElement.className = "soft-context-menu-item-checkmark";
if (!item.checked)
checkMarkElement.style.opacity = "0";
menuItemElement.appendChild(checkMarkElement);
menuItemElement.appendChild(document.createTextNode(item.label));
menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
menuItemElement._actionId = item.id;
return menuItemElement;
},
_createSubMenu: function(item)
{
var menuItemElement = document.createElement("div");
menuItemElement.className = "soft-context-menu-item";
menuItemElement._subItems = item.subItems;
var checkMarkElement = document.createElement("span");
checkMarkElement.textContent = "\u2713 ";
checkMarkElement.className = "soft-context-menu-item-checkmark";
checkMarkElement.style.opacity = "0";
menuItemElement.appendChild(checkMarkElement);
var subMenuArrowElement = document.createElement("span");
subMenuArrowElement.textContent = "\u25B6";
subMenuArrowElement.className = "soft-context-menu-item-submenu-arrow";
menuItemElement.appendChild(document.createTextNode(item.label));
menuItemElement.appendChild(subMenuArrowElement);
menuItemElement.addEventListener("mousedown", this._menuItemMouseDown.bind(this), false);
menuItemElement.addEventListener("mouseup", this._menuItemMouseUp.bind(this), false);
menuItemElement.addEventListener("mouseover", this._menuItemMouseOver.bind(this), false);
menuItemElement.addEventListener("mouseout", this._menuItemMouseOut.bind(this), false);
return menuItemElement;
},
_createSeparator: function()
{
var separatorElement = document.createElement("div");
separatorElement.className = "soft-context-menu-separator";
separatorElement._isSeparator = true;
separatorElement.addEventListener("mouseover", this._hideSubMenu.bind(this), false);
separatorElement.createChild("div", "separator-line");
return separatorElement;
},
_menuItemMouseDown: function(event)
{
event.consume(true);
},
_menuItemMouseUp: function(event)
{
this._triggerAction(event.target, event);
event.consume();
},
_focus: function()
{
this._contextMenuElement.focus();
},
_triggerAction: function(menuItemElement, event)
{
if (!menuItemElement._subItems) {
this._discardMenu(true, event);
if (typeof menuItemElement._actionId !== "undefined") {
WebInspector.contextMenuItemSelected(menuItemElement._actionId);
delete menuItemElement._actionId;
}
return;
}
this._showSubMenu(menuItemElement, event);
event.consume();
},
_showSubMenu: function(menuItemElement, event)
{
if (menuItemElement._subMenuTimer) {
clearTimeout(menuItemElement._subMenuTimer);
delete menuItemElement._subMenuTimer;
}
if (this._subMenu)
return;
this._subMenu = new WebInspector.SoftContextMenu(menuItemElement._subItems, this);
this._subMenu.show(this._buildMouseEventForSubMenu(menuItemElement));
},
_buildMouseEventForSubMenu: function(subMenuItemElement)
{
var subMenuOffset = { x: subMenuItemElement.offsetWidth - 3, y: subMenuItemElement.offsetTop - 1 };
var targetX = this._x + subMenuOffset.x;
var targetY = this._y + subMenuOffset.y;
var targetPageX = parseInt(this._contextMenuElement.style.left, 10) + subMenuOffset.x;
var targetPageY = parseInt(this._contextMenuElement.style.top, 10) + subMenuOffset.y;
return { x: targetX, y: targetY, pageX: targetPageX, pageY: targetPageY, consume: function() {} };
},
_hideSubMenu: function()
{
if (!this._subMenu)
return;
this._subMenu._discardSubMenus();
this._focus();
},
_menuItemMouseOver: function(event)
{
this._highlightMenuItem(event.target);
},
_menuItemMouseOut: function(event)
{
if (!this._subMenu || !event.relatedTarget) {
this._highlightMenuItem(null);
return;
}
var relatedTarget = event.relatedTarget;
if (this._contextMenuElement.isSelfOrAncestor(relatedTarget) || relatedTarget.hasStyleClass("soft-context-menu-glass-pane"))
this._highlightMenuItem(null);
},
_highlightMenuItem: function(menuItemElement)
{
if (this._highlightedMenuItemElement === menuItemElement)
return;
this._hideSubMenu();
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.removeStyleClass("soft-context-menu-item-mouse-over");
if (this._highlightedMenuItemElement._subItems && this._highlightedMenuItemElement._subMenuTimer) {
clearTimeout(this._highlightedMenuItemElement._subMenuTimer);
delete this._highlightedMenuItemElement._subMenuTimer;
}
}
this._highlightedMenuItemElement = menuItemElement;
if (this._highlightedMenuItemElement) {
this._highlightedMenuItemElement.addStyleClass("soft-context-menu-item-mouse-over");
this._contextMenuElement.focus();
if (this._highlightedMenuItemElement._subItems && !this._highlightedMenuItemElement._subMenuTimer)
this._highlightedMenuItemElement._subMenuTimer = setTimeout(this._showSubMenu.bind(this, this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement)), 150);
}
},
_highlightPrevious: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.previousSibling : this._contextMenuElement.lastChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.previousSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},
_highlightNext: function()
{
var menuItemElement = this._highlightedMenuItemElement ? this._highlightedMenuItemElement.nextSibling : this._contextMenuElement.firstChild;
while (menuItemElement && menuItemElement._isSeparator)
menuItemElement = menuItemElement.nextSibling;
if (menuItemElement)
this._highlightMenuItem(menuItemElement);
},
_menuKeyDown: function(event)
{
switch (event.keyIdentifier) {
case "Up":
this._highlightPrevious(); break;
case "Down":
this._highlightNext(); break;
case "Left":
if (this._parentMenu) {
this._highlightMenuItem(null);
this._parentMenu._focus();
}
break;
case "Right":
if (!this._highlightedMenuItemElement)
break;
if (this._highlightedMenuItemElement._subItems) {
this._showSubMenu(this._highlightedMenuItemElement, this._buildMouseEventForSubMenu(this._highlightedMenuItemElement));
this._subMenu._focus();
this._subMenu._highlightNext();
}
break;
case "U+001B":
this._discardMenu(true, event); break;
case "Enter":
if (!isEnterKey(event))
break;
case "U+0020":
if (this._highlightedMenuItemElement)
this._triggerAction(this._highlightedMenuItemElement, event);
break;
}
event.consume(true);
},
_glassPaneMouseUp: function(event)
{
if (event.x === this._x && event.y === this._y && new Date().getTime() - this._time < 300)
return;
this._discardMenu(true, event);
event.consume();
},
_discardMenu: function(closeParentMenus, event)
{
if (this._subMenu && !closeParentMenus)
return;
if (this._glassPaneElement) {
var glassPane = this._glassPaneElement;
delete this._glassPaneElement;
document.body.removeChild(glassPane);
if (this._parentMenu) {
delete this._parentMenu._subMenu;
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
}
if (event)
event.consume(true);
} else if (this._parentMenu && this._contextMenuElement.parentElement) {
this._discardSubMenus();
if (closeParentMenus)
this._parentMenu._discardMenu(closeParentMenus, event);
if (event)
event.consume(true);
}
},
_discardSubMenus: function()
{
if (this._subMenu)
this._subMenu._discardSubMenus();
if (this._contextMenuElement.parentElement)
this._contextMenuElement.parentElement.removeChild(this._contextMenuElement);
if (this._parentMenu)
delete this._parentMenu._subMenu;
}
}
InspectorFrontendHost.showContextMenu = function(event, items)
{
new WebInspector.SoftContextMenu(items).show(event);
}
}
WebInspector.KeyboardShortcut = function()
{
}
WebInspector.KeyboardShortcut.Modifiers = {
None: 0,
Shift: 1,
Ctrl: 2,
Alt: 4,
Meta: 8,
get CtrlOrMeta()
{
return WebInspector.isMac() ? this.Meta : this.Ctrl;
}
};
WebInspector.KeyboardShortcut.Keys = {
Backspace: { code: 8, name: "\u21a4" },
Tab: { code: 9, name: { mac: "\u21e5", other: "<Tab>" } },
Enter: { code: 13, name: { mac: "\u21a9", other: "<Enter>" } },
Esc: { code: 27, name: { mac: "\u238b", other: "<Esc>" } },
Space: { code: 32, name: "<Space>" },
PageUp: { code: 33, name: { mac: "\u21de", other: "<PageUp>" } },
PageDown: { code: 34, name: { mac: "\u21df", other: "<PageDown>" } },
End: { code: 35, name: { mac: "\u2197", other: "<End>" } },
Home: { code: 36, name: { mac: "\u2196", other: "<Home>" } },
Left: { code: 37, name: "<Left>" },
Up: { code: 38, name: "<Up>" },
Right: { code: 39, name: "<Right>" },
Down: { code: 40, name: "<Down>" },
Delete: { code: 46, name: "<Del>" },
Zero: { code: 48, name: "0" },
F1: { code: 112, name: "F1" },
F2: { code: 113, name: "F2" },
F3: { code: 114, name: "F3" },
F4: { code: 115, name: "F4" },
F5: { code: 116, name: "F5" },
F6: { code: 117, name: "F6" },
F7: { code: 118, name: "F7" },
F8: { code: 119, name: "F8" },
F9: { code: 120, name: "F9" },
F10: { code: 121, name: "F10" },
F11: { code: 122, name: "F11" },
F12: { code: 123, name: "F12" },
Semicolon: { code: 186, name: ";" },
Plus: { code: 187, name: "+" },
Comma: { code: 188, name: "," },
Minus: { code: 189, name: "-" },
Period: { code: 190, name: "." },
Slash: { code: 191, name: "/" },
Apostrophe: { code: 192, name: "`" },
SingleQuote: { code: 222, name: "\'" }
};
WebInspector.KeyboardShortcut.makeKey = function(keyCode, modifiers)
{
if (typeof keyCode === "string")
keyCode = keyCode.charCodeAt(0) - 32;
modifiers = modifiers || WebInspector.KeyboardShortcut.Modifiers.None;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyCode, modifiers);
}
WebInspector.KeyboardShortcut.makeKeyFromEvent = function(keyboardEvent)
{
var modifiers = WebInspector.KeyboardShortcut.Modifiers.None;
if (keyboardEvent.shiftKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Shift;
if (keyboardEvent.ctrlKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Ctrl;
if (keyboardEvent.altKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Alt;
if (keyboardEvent.metaKey)
modifiers |= WebInspector.KeyboardShortcut.Modifiers.Meta;
return WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers(keyboardEvent.keyCode, modifiers);
}
WebInspector.KeyboardShortcut.eventHasCtrlOrMeta = function(event)
{
return WebInspector.isMac() ? event.metaKey && !event.ctrlKey : event.ctrlKey && !event.metaKey;
}
WebInspector.KeyboardShortcut.makeDescriptor = function(key, modifiers)
{
return {
key: WebInspector.KeyboardShortcut.makeKey(typeof key === "string" ? key : key.code, modifiers),
name: WebInspector.KeyboardShortcut.shortcutToString(key, modifiers)
};
}
WebInspector.KeyboardShortcut.shortcutToString = function(key, modifiers)
{
return WebInspector.KeyboardShortcut._modifiersToString(modifiers) + WebInspector.KeyboardShortcut._keyName(key);
}
WebInspector.KeyboardShortcut._keyName = function(key)
{
if (typeof key === "string")
return key.toUpperCase();
if (typeof key.name === "string")
return key.name;
return key.name[WebInspector.platform()] || key.name.other;
}
WebInspector.KeyboardShortcut._makeKeyFromCodeAndModifiers = function(keyCode, modifiers)
{
return (keyCode & 255) | (modifiers << 8);
};
WebInspector.KeyboardShortcut._modifiersToString = function(modifiers)
{
const cmdKey = "\u2318";
const optKey = "\u2325";
const shiftKey = "\u21e7";
const ctrlKey = "\u2303";
var isMac = WebInspector.isMac();
var res = "";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Ctrl)
res += isMac ? ctrlKey : "<Ctrl> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Alt)
res += isMac ? optKey : "<Alt> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Shift)
res += isMac ? shiftKey : "<Shift> + ";
if (modifiers & WebInspector.KeyboardShortcut.Modifiers.Meta)
res += isMac ? cmdKey : "<Win> + ";
return res;
};
WebInspector.TextPrompt = function(completions, stopCharacters)
{
this._proxyElement;
this._proxyElementDisplay = "inline-block";
this._loadCompletions = completions;
this._completionStopCharacters = stopCharacters;
this._suggestForceable = true;
}
WebInspector.TextPrompt.Events = {
ItemApplied: "text-prompt-item-applied",
ItemAccepted: "text-prompt-item-accepted"
};
WebInspector.TextPrompt.prototype = {
get proxyElement()
{
return this._proxyElement;
},
setSuggestForceable: function(x)
{
this._suggestForceable = x;
},
setSuggestBoxEnabled: function(className)
{
this._suggestBoxClassName = className;
},
renderAsBlock: function()
{
this._proxyElementDisplay = "block";
},
attach: function(element)
{
return this._attachInternal(element);
},
attachAndStartEditing: function(element, blurListener)
{
this._attachInternal(element);
this._startEditing(blurListener);
return this.proxyElement;
},
_attachInternal: function(element)
{
if (this.proxyElement)
throw "Cannot attach an attached TextPrompt";
this._element = element;
this._boundOnKeyDown = this.onKeyDown.bind(this);
this._boundOnMouseWheel = this.onMouseWheel.bind(this);
this._boundSelectStart = this._selectStart.bind(this);
this._proxyElement = element.ownerDocument.createElement("span");
this._proxyElement.style.display = this._proxyElementDisplay;
element.parentElement.insertBefore(this.proxyElement, element);
this.proxyElement.appendChild(element);
this._element.addStyleClass("text-prompt");
this._element.addEventListener("keydown", this._boundOnKeyDown, false);
this._element.addEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.addEventListener("selectstart", this._boundSelectStart, false);
if (typeof this._suggestBoxClassName === "string")
this._suggestBox = new WebInspector.TextPrompt.SuggestBox(this, this._element, this._suggestBoxClassName);
return this.proxyElement;
},
detach: function()
{
this._removeFromElement();
this.proxyElement.parentElement.insertBefore(this._element, this.proxyElement);
this.proxyElement.parentElement.removeChild(this.proxyElement);
this._element.removeStyleClass("text-prompt");
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("mousewheel", this._boundOnMouseWheel, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
delete this._proxyElement;
WebInspector.restoreFocusFromElement(this._element);
},
get text()
{
return this._element.textContent;
},
set text(x)
{
this._removeSuggestionAids();
if (!x) {
this._element.removeChildren();
this._element.appendChild(document.createElement("br"));
} else
this._element.textContent = x;
this.moveCaretToEndOfPrompt();
this._element.scrollIntoView();
},
_removeFromElement: function()
{
this.clearAutoComplete(true);
this._element.removeEventListener("keydown", this._boundOnKeyDown, false);
this._element.removeEventListener("selectstart", this._boundSelectStart, false);
if (this._isEditing)
this._stopEditing();
if (this._suggestBox)
this._suggestBox.removeFromElement();
},
_startEditing: function(blurListener)
{
this._isEditing = true;
this._element.addStyleClass("editing");
if (blurListener) {
this._blurListener = blurListener;
this._element.addEventListener("blur", this._blurListener, false);
}
this._oldTabIndex = this._element.tabIndex;
if (this._element.tabIndex < 0)
this._element.tabIndex = 0;
WebInspector.setCurrentFocusElement(this._element);
},
_stopEditing: function()
{
this._element.tabIndex = this._oldTabIndex;
if (this._blurListener)
this._element.removeEventListener("blur", this._blurListener, false);
this._element.removeStyleClass("editing");
delete this._isEditing;
},
_removeSuggestionAids: function()
{
this.clearAutoComplete();
this.hideSuggestBox();
},
_selectStart: function(event)
{
if (this._selectionTimeout)
clearTimeout(this._selectionTimeout);
this._removeSuggestionAids();
function moveBackIfOutside()
{
delete this._selectionTimeout;
if (!this.isCaretInsidePrompt() && window.getSelection().isCollapsed) {
this.moveCaretToEndOfPrompt();
this.autoCompleteSoon();
}
}
this._selectionTimeout = setTimeout(moveBackIfOutside.bind(this), 100);
},
defaultKeyHandler: function(event, force)
{
this.clearAutoComplete();
this.autoCompleteSoon(force);
return false;
},
onMouseWheel: function(event)
{
},
onKeyDown: function(event)
{
var handled = false;
var invokeDefault = true;
switch (event.keyIdentifier) {
case "Up":
handled = this.upKeyPressed(event);
break;
case "Down":
handled = this.downKeyPressed(event);
break;
case "PageUp":
handled = this.pageUpKeyPressed(event);
break;
case "PageDown":
handled = this.pageDownKeyPressed(event);
break;
case "U+0009":
handled = this.tabKeyPressed(event);
break;
case "Enter":
handled = this.enterKeyPressed(event);
break;
case "Left":
case "Home":
this._removeSuggestionAids();
invokeDefault = false;
break;
case "Right":
case "End":
if (this.isCaretAtEndOfPrompt())
handled = this.acceptAutoComplete();
else
this._removeSuggestionAids();
invokeDefault = false;
break;
case "U+001B":
if (this.isSuggestBoxVisible()) {
this._suggestBox.hide();
handled = true;
}
break;
case "U+0020":
if (this._suggestForceable && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
this.defaultKeyHandler(event, true);
handled = true;
}
break;
case "Alt":
case "Meta":
case "Shift":
case "Control":
invokeDefault = false;
break;
}
if (!handled && invokeDefault)
handled = this.defaultKeyHandler(event);
if (handled)
event.consume(true);
return handled;
},
acceptAutoComplete: function()
{
var result = false;
if (this.isSuggestBoxVisible())
result = this._suggestBox.acceptSuggestion();
if (!result)
result = this.acceptSuggestion();
return result;
},
clearAutoComplete: function(includeTimeout)
{
if (includeTimeout && this._completeTimeout) {
clearTimeout(this._completeTimeout);
delete this._completeTimeout;
}
delete this._waitingForCompletions;
if (!this.autoCompleteElement)
return;
if (this.autoCompleteElement.parentNode)
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;
if (!this._userEnteredRange || !this._userEnteredText)
return;
this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();
var userTextNode = document.createTextNode(this._userEnteredText);
this._userEnteredRange.insertNode(userTextNode);
var selectionRange = document.createRange();
selectionRange.setStart(userTextNode, this._userEnteredText.length);
selectionRange.setEnd(userTextNode, this._userEnteredText.length);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(selectionRange);
delete this._userEnteredRange;
delete this._userEnteredText;
},
autoCompleteSoon: function(force)
{
var immediately = this.isSuggestBoxVisible() || force;
if (!this._completeTimeout)
this._completeTimeout = setTimeout(this.complete.bind(this, true, force), immediately ? 0 : 250);
},
complete: function(auto, force, reverse)
{
this.clearAutoComplete(true);
var selection = window.getSelection();
if (!selection.rangeCount)
return;
var selectionRange = selection.getRangeAt(0);
var isEmptyInput = selectionRange.commonAncestorContainer === this._element;
var shouldExit;
if (auto && isEmptyInput && !force)
shouldExit = true;
else if (!auto && !isEmptyInput && !selectionRange.commonAncestorContainer.isDescendant(this._element))
shouldExit = true;
else if (auto && !force && !this.isCaretAtEndOfPrompt() && !this.isSuggestBoxVisible())
shouldExit = true;
else if (!selection.isCollapsed)
shouldExit = true;
else if (!force) {
var wordSuffixRange = selectionRange.startContainer.rangeOfWord(selectionRange.endOffset, this._completionStopCharacters, this._element, "forward");
if (wordSuffixRange.toString().length)
shouldExit = true;
}
if (shouldExit) {
this.hideSuggestBox();
return;
}
var wordPrefixRange = selectionRange.startContainer.rangeOfWord(selectionRange.startOffset, this._completionStopCharacters, this._element, "backward");
this._waitingForCompletions = true;
this._loadCompletions(this, wordPrefixRange, force, this._completionsReady.bind(this, selection, auto, wordPrefixRange, !!reverse));
},
_boxForAnchorAtStart: function(selection, textRange)
{
var rangeCopy = selection.getRangeAt(0).cloneRange();
var anchorElement = document.createElement("span");
anchorElement.textContent = "\u200B";
textRange.insertNode(anchorElement);
var box = anchorElement.boxInWindow(window);
anchorElement.parentElement.removeChild(anchorElement);
selection.removeAllRanges();
selection.addRange(rangeCopy);
return box;
},
_buildCommonPrefix: function(completions, wordPrefixLength)
{
var commonPrefix = completions[0];
for (var i = 0; i < completions.length; ++i) {
var completion = completions[i];
var lastIndex = Math.min(commonPrefix.length, completion.length);
for (var j = wordPrefixLength; j < lastIndex; ++j) {
if (commonPrefix[j] !== completion[j]) {
commonPrefix = commonPrefix.substr(0, j);
break;
}
}
}
return commonPrefix;
},
_completionsReady: function(selection, auto, originalWordPrefixRange, reverse, completions)
{
if (!this._waitingForCompletions || !completions || !completions.length) {
this.hideSuggestBox();
return;
}
delete this._waitingForCompletions;
var selectionRange = selection.getRangeAt(0);
var fullWordRange = document.createRange();
fullWordRange.setStart(originalWordPrefixRange.startContainer, originalWordPrefixRange.startOffset);
fullWordRange.setEnd(selectionRange.endContainer, selectionRange.endOffset);
if (originalWordPrefixRange.toString() + selectionRange.toString() != fullWordRange.toString())
return;
this._userEnteredRange = fullWordRange;
this._userEnteredText = fullWordRange.toString();
if (this._suggestBox)
this._suggestBox.updateSuggestions(this._boxForAnchorAtStart(selection, fullWordRange), completions, !this.isCaretAtEndOfPrompt());
var wordPrefixLength = originalWordPrefixRange.toString().length;
if (auto) {
var completionText = completions[0];
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
this._commonPrefix = commonPrefix;
} else {
if (completions.length === 1) {
var completionText = completions[0];
wordPrefixLength = completionText.length;
} else {
var commonPrefix = this._buildCommonPrefix(completions, wordPrefixLength);
wordPrefixLength = commonPrefix.length;
if (selection.isCollapsed)
var completionText = completions[0];
else {
var currentText = fullWordRange.toString();
var foundIndex = null;
for (var i = 0; i < completions.length; ++i) {
if (completions[i] === currentText)
foundIndex = i;
}
var nextIndex = foundIndex + (reverse ? -1 : 1);
if (foundIndex === null || nextIndex >= completions.length)
var completionText = completions[0];
else if (nextIndex < 0)
var completionText = completions[completions.length - 1];
else
var completionText = completions[nextIndex];
}
}
}
if (auto) {
if (this.isCaretAtEndOfPrompt()) {
this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();
var finalSelectionRange = document.createRange();
var prefixText = completionText.substring(0, wordPrefixLength);
var suffixText = completionText.substring(wordPrefixLength);
var prefixTextNode = document.createTextNode(prefixText);
fullWordRange.insertNode(prefixTextNode);
this.autoCompleteElement = document.createElement("span");
this.autoCompleteElement.className = "auto-complete-text";
this.autoCompleteElement.textContent = suffixText;
prefixTextNode.parentNode.insertBefore(this.autoCompleteElement, prefixTextNode.nextSibling);
finalSelectionRange.setStart(prefixTextNode, wordPrefixLength);
finalSelectionRange.setEnd(prefixTextNode, wordPrefixLength);
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
}
} else
this.applySuggestion(completionText, completions.length > 1, originalWordPrefixRange);
},
_completeCommonPrefix: function()
{
if (!this.autoCompleteElement || !this._commonPrefix || !this._userEnteredText || !this._commonPrefix.startsWith(this._userEnteredText))
return;
if (!this.isSuggestBoxVisible()) {
this.acceptAutoComplete();
return;
}
this.autoCompleteElement.textContent = this._commonPrefix.substring(this._userEnteredText.length);
this.acceptSuggestion(true)
},
applySuggestion: function(completionText, isIntermediateSuggestion, originalPrefixRange)
{
var wordPrefixLength;
if (originalPrefixRange)
wordPrefixLength = originalPrefixRange.toString().length;
else
wordPrefixLength = this._userEnteredText ? this._userEnteredText.length : 0;
this._userEnteredRange.deleteContents();
this._element.pruneEmptyTextNodes();
var finalSelectionRange = document.createRange();
var completionTextNode = document.createTextNode(completionText);
this._userEnteredRange.insertNode(completionTextNode);
if (this.autoCompleteElement && this.autoCompleteElement.parentNode) {
this.autoCompleteElement.parentNode.removeChild(this.autoCompleteElement);
delete this.autoCompleteElement;
}
if (isIntermediateSuggestion)
finalSelectionRange.setStart(completionTextNode, wordPrefixLength);
else
finalSelectionRange.setStart(completionTextNode, completionText.length);
finalSelectionRange.setEnd(completionTextNode, completionText.length);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (isIntermediateSuggestion)
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemApplied, { itemText: completionText });
},
acceptSuggestion: function(prefixAccepted)
{
if (this._isAcceptingSuggestion)
return false;
if (!this.autoCompleteElement || !this.autoCompleteElement.parentNode)
return false;
var text = this.autoCompleteElement.textContent;
var textNode = document.createTextNode(text);
this.autoCompleteElement.parentNode.replaceChild(textNode, this.autoCompleteElement);
delete this.autoCompleteElement;
var finalSelectionRange = document.createRange();
finalSelectionRange.setStart(textNode, text.length);
finalSelectionRange.setEnd(textNode, text.length);
var selection = window.getSelection();
selection.removeAllRanges();
selection.addRange(finalSelectionRange);
if (!prefixAccepted) {
this.hideSuggestBox();
this.dispatchEventToListeners(WebInspector.TextPrompt.Events.ItemAccepted);
} else
this.autoCompleteSoon(true);
return true;
},
hideSuggestBox: function()
{
if (this.isSuggestBoxVisible())
this._suggestBox.hide();
},
isSuggestBoxVisible: function()
{
return this._suggestBox && this._suggestBox.visible;
},
isCaretInsidePrompt: function()
{
return this._element.isInsertionCaretInside();
},
isCaretAtEndOfPrompt: function()
{
var selection = window.getSelection();
if (!selection.rangeCount || !selection.isCollapsed)
return false;
var selectionRange = selection.getRangeAt(0);
var node = selectionRange.startContainer;
if (!node.isSelfOrDescendant(this._element))
return false;
if (node.nodeType === Node.TEXT_NODE && selectionRange.startOffset < node.nodeValue.length)
return false;
var foundNextText = false;
while (node) {
if (node.nodeType === Node.TEXT_NODE && node.nodeValue.length) {
if (foundNextText && (!this.autoCompleteElement || !this.autoCompleteElement.isAncestor(node)))
return false;
foundNextText = true;
}
node = node.traverseNextNode(this._element);
}
return true;
},
isCaretOnFirstLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;
if (focusNode.textContent.substring(0, selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.previousSibling;
}
return true;
},
isCaretOnLastLine: function()
{
var selection = window.getSelection();
var focusNode = selection.focusNode;
if (!focusNode || focusNode.nodeType !== Node.TEXT_NODE || focusNode.parentNode !== this._element)
return true;
if (focusNode.textContent.substring(selection.focusOffset).indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
while (focusNode) {
if (focusNode.nodeType !== Node.TEXT_NODE)
return true;
if (focusNode.textContent.indexOf("\n") !== -1)
return false;
focusNode = focusNode.nextSibling;
}
return true;
},
moveCaretToEndOfPrompt: function()
{
var selection = window.getSelection();
var selectionRange = document.createRange();
var offset = this._element.childNodes.length;
selectionRange.setStart(this._element, offset);
selectionRange.setEnd(this._element, offset);
selection.removeAllRanges();
selection.addRange(selectionRange);
},
tabKeyPressed: function(event)
{
this._completeCommonPrefix();
return true;
},
enterKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.enterKeyPressed(event);
return false;
},
upKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.upKeyPressed(event);
return false;
},
downKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.downKeyPressed(event);
return false;
},
pageUpKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageUpKeyPressed(event);
return false;
},
pageDownKeyPressed: function(event)
{
if (this.isSuggestBoxVisible())
return this._suggestBox.pageDownKeyPressed(event);
return false;
},
}
WebInspector.TextPrompt.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.TextPromptWithHistory = function(completions, stopCharacters)
{
WebInspector.TextPrompt.call(this, completions, stopCharacters);
this._data = [];
this._historyOffset = 1;
this._coalesceHistoryDupes = true;
}
WebInspector.TextPromptWithHistory.prototype = {
get historyData()
{
return this._data;
},
setCoalesceHistoryDupes: function(x)
{
this._coalesceHistoryDupes = x;
},
setHistoryData: function(data)
{
this._data = [].concat(data);
this._historyOffset = 1;
},
pushHistoryItem: function(text)
{
if (this._uncommittedIsTop) {
this._data.pop();
delete this._uncommittedIsTop;
}
this._historyOffset = 1;
if (this._coalesceHistoryDupes && text === this._currentHistoryItem())
return;
this._data.push(text);
},
_pushCurrentText: function()
{
if (this._uncommittedIsTop)
this._data.pop();
this._uncommittedIsTop = true;
this.clearAutoComplete(true);
this._data.push(this.text);
},
_previous: function()
{
if (this._historyOffset > this._data.length)
return undefined;
if (this._historyOffset === 1)
this._pushCurrentText();
++this._historyOffset;
return this._currentHistoryItem();
},
_next: function()
{
if (this._historyOffset === 1)
return undefined;
--this._historyOffset;
return this._currentHistoryItem();
},
_currentHistoryItem: function()
{
return this._data[this._data.length - this._historyOffset];
},
defaultKeyHandler: function(event, force)
{
var newText;
var isPrevious;
switch (event.keyIdentifier) {
case "Up":
if (!this.isCaretOnFirstLine())
break;
newText = this._previous();
isPrevious = true;
break;
case "Down":
if (!this.isCaretOnLastLine())
break;
newText = this._next();
break;
case "U+0050":
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey) {
newText = this._previous();
isPrevious = true;
}
break;
case "U+004E":
if (WebInspector.isMac() && event.ctrlKey && !event.metaKey && !event.altKey && !event.shiftKey)
newText = this._next();
break;
}
if (newText !== undefined) {
event.consume(true);
this.text = newText;
if (isPrevious) {
var firstNewlineIndex = this.text.indexOf("\n");
if (firstNewlineIndex === -1)
this.moveCaretToEndOfPrompt();
else {
var selection = window.getSelection();
var selectionRange = document.createRange();
selectionRange.setStart(this._element.firstChild, firstNewlineIndex);
selectionRange.setEnd(this._element.firstChild, firstNewlineIndex);
selection.removeAllRanges();
selection.addRange(selectionRange);
}
}
return true;
}
return WebInspector.TextPrompt.prototype.defaultKeyHandler.apply(this, arguments);
}
}
WebInspector.TextPromptWithHistory.prototype.__proto__ = WebInspector.TextPrompt.prototype;
WebInspector.TextPrompt.SuggestBox = function(textPrompt, inputElement, className)
{
this._textPrompt = textPrompt;
this._inputElement = inputElement;
this._selectedElement = null;
this._boundOnScroll = this._onscrollresize.bind(this, true);
this._boundOnResize = this._onscrollresize.bind(this, false);
window.addEventListener("scroll", this._boundOnScroll, true);
window.addEventListener("resize", this._boundOnResize, true);
this._bodyElement = inputElement.ownerDocument.body;
this._element = inputElement.ownerDocument.createElement("div");
this._element.className = "suggest-box " + (className || "");
this._element.addEventListener("mousedown", this._onboxmousedown.bind(this), true);
this.containerElement = this._element.createChild("div", "container");
this.contentElement = this.containerElement.createChild("div", "content");
}
WebInspector.TextPrompt.SuggestBox.prototype = {
get visible()
{
return !!this._element.parentElement;
},
get hasSelection()
{
return !!this._selectedElement;
},
_onscrollresize: function(isScroll, event)
{
if (isScroll && this._element.isAncestor(event.target) || !this.visible)
return;
this._updateBoxPositionWithExistingAnchor();
},
_updateBoxPositionWithExistingAnchor: function()
{
this._updateBoxPosition(this._anchorBox);
},
_updateBoxPosition: function(anchorBox)
{
this.contentElement.style.display = "inline-block";
document.body.appendChild(this.contentElement);
this.contentElement.positionAt(0, 0);
var contentWidth = this.contentElement.offsetWidth;
var contentHeight = this.contentElement.offsetHeight;
this.contentElement.style.display = "block";
this.containerElement.appendChild(this.contentElement);
this._anchorBox = anchorBox;
const spacer = 6;
const suggestBoxPaddingX = 21;
var maxWidth = document.body.offsetWidth - anchorBox.x - spacer;
var width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
var paddedWidth = contentWidth + suggestBoxPaddingX;
var boxX = anchorBox.x;
if (width < paddedWidth) {
maxWidth = document.body.offsetWidth - spacer;
width = Math.min(contentWidth, maxWidth - suggestBoxPaddingX) + suggestBoxPaddingX;
boxX = document.body.offsetWidth - width;
}
const suggestBoxPaddingY = 2;
var boxY;
var aboveHeight = anchorBox.y;
var underHeight = document.body.offsetHeight - anchorBox.y - anchorBox.height;
var maxHeight = Math.max(underHeight, aboveHeight) - spacer;
var height = Math.min(contentHeight, maxHeight - suggestBoxPaddingY) + suggestBoxPaddingY;
if (underHeight >= aboveHeight) {
boxY = anchorBox.y + anchorBox.height;
this._element.removeStyleClass("above-anchor");
this._element.addStyleClass("under-anchor");
} else {
boxY = anchorBox.y - height;
this._element.removeStyleClass("under-anchor");
this._element.addStyleClass("above-anchor");
}
this._element.positionAt(boxX, boxY);
this._element.style.width = width + "px";
this._element.style.height = height + "px";
},
_onboxmousedown: function(event)
{
event.preventDefault();
},
hide: function()
{
if (!this.visible)
return;
this._element.parentElement.removeChild(this._element);
delete this._selectedElement;
},
removeFromElement: function()
{
window.removeEventListener("scroll", this._boundOnScroll, true);
window.removeEventListener("resize", this._boundOnResize, true);
this.hide();
},
_applySuggestion: function(text, isIntermediateSuggestion)
{
if (!this.visible || !(text || this._selectedElement))
return false;
var suggestion = text || this._selectedElement.textContent;
if (!suggestion)
return false;
this._textPrompt.applySuggestion(suggestion, isIntermediateSuggestion);
return true;
},
acceptSuggestion: function(text)
{
var result = this._applySuggestion(text, false);
this.hide();
if (!result)
return false;
this._textPrompt.acceptSuggestion();
return true;
},
_onNextItem: function(event, isPageScroll)
{
var children = this.contentElement.childNodes;
if (!children.length)
return false;
if (!this._selectedElement)
this._selectedElement = this.contentElement.firstChild;
else {
if (!isPageScroll)
this._selectedElement = this._selectedElement.nextSibling || this.contentElement.firstChild;
else {
var candidate = this._selectedElement;
for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
if (candidate.nextSibling)
candidate = candidate.nextSibling;
else
break;
}
this._selectedElement = candidate;
}
}
this._updateSelection();
this._applySuggestion(undefined, true);
return true;
},
_onPreviousItem: function(event, isPageScroll)
{
var children = this.contentElement.childNodes;
if (!children.length)
return false;
if (!this._selectedElement)
this._selectedElement = this.contentElement.lastChild;
else {
if (!isPageScroll)
this._selectedElement = this._selectedElement.previousSibling || this.contentElement.lastChild;
else {
var candidate = this._selectedElement;
for (var itemsLeft = this._rowCountPerViewport; itemsLeft; --itemsLeft) {
if (candidate.previousSibling)
candidate = candidate.previousSibling;
else
break;
}
this._selectedElement = candidate;
}
}
this._updateSelection();
this._applySuggestion(undefined, true);
return true;
},
updateSuggestions: function(anchorBox, completions, canShowForSingleItem)
{
if (this._suggestTimeout) {
clearTimeout(this._suggestTimeout);
delete this._suggestTimeout;
}
this._completionsReady(anchorBox, completions, canShowForSingleItem);
},
_onItemMouseDown: function(text, event)
{
this.acceptSuggestion(text);
event.consume(true);
},
_createItemElement: function(prefix, text)
{
var element = document.createElement("div");
element.className = "suggest-box-content-item source-code";
element.tabIndex = -1;
if (prefix && prefix.length && !text.indexOf(prefix)) {
var prefixElement = element.createChild("span", "prefix");
prefixElement.textContent = prefix;
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text.substring(prefix.length);
} else {
var suffixElement = element.createChild("span", "suffix");
suffixElement.textContent = text;
}
element.addEventListener("mousedown", this._onItemMouseDown.bind(this, text), false);
return element;
},
_updateItems: function(items, canShowForSingleItem)
{
this.contentElement.removeChildren();
var userEnteredText = this._textPrompt._userEnteredText;
for (var i = 0; i < items.length; ++i) {
var item = items[i];
var currentItemElement = this._createItemElement(userEnteredText, item);
this.contentElement.appendChild(currentItemElement);
}
this._selectedElement = canShowForSingleItem ? this.contentElement.firstChild : null;
this._updateSelection();
},
_updateSelection: function()
{
for (var child = this.contentElement.firstChild; child; child = child.nextSibling) {
if (child !== this._selectedElement)
child.removeStyleClass("selected");
}
if (this._selectedElement) {
this._selectedElement.addStyleClass("selected");
this._selectedElement.scrollIntoViewIfNeeded(false);
}
},
_canShowBox: function(completions, canShowForSingleItem)
{
if (!completions || !completions.length)
return false;
if (completions.length > 1)
return true;
return canShowForSingleItem && completions[0] !== this._textPrompt._userEnteredText;
},
_rememberRowCountPerViewport: function()
{
if (!this.contentElement.firstChild)
return;
this._rowCountPerViewport = Math.floor(this.containerElement.offsetHeight / this.contentElement.firstChild.offsetHeight);
},
_completionsReady: function(anchorBox, completions, canShowForSingleItem)
{
if (this._canShowBox(completions, canShowForSingleItem)) {
this._updateItems(completions, canShowForSingleItem);
this._updateBoxPosition(anchorBox);
if (!this.visible)
this._bodyElement.appendChild(this._element);
this._rememberRowCountPerViewport();
} else
this.hide();
},
upKeyPressed: function(event)
{
return this._onPreviousItem(event, false);
},
downKeyPressed: function(event)
{
return this._onNextItem(event, false);
},
pageUpKeyPressed: function(event)
{
return this._onPreviousItem(event, true);
},
pageDownKeyPressed: function(event)
{
return this._onNextItem(event, true);
},
enterKeyPressed: function(event)
{
var hasSelectedItem = !!this._selectedElement;
this.acceptSuggestion();
return hasSelectedItem;
},
tabKeyPressed: function(event)
{
return this.enterKeyPressed(event);
}
}
WebInspector.Popover = function(popoverHelper)
{
this.element = document.createElement("div");
this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll";
this._popupArrowElement = document.createElement("div");
this._popupArrowElement.className = "arrow";
this.element.appendChild(this._popupArrowElement);
this._contentDiv = document.createElement("div");
this._contentDiv.className = "content";
this._visible = false;
this._popoverHelper = popoverHelper;
}
WebInspector.Popover.prototype = {
show: function(contentElement, anchor, preferredWidth, preferredHeight)
{
if (this._disposed)
return;
this.contentElement = contentElement;
if (WebInspector.Popover._popoverElement)
document.body.removeChild(WebInspector.Popover._popoverElement);
WebInspector.Popover._popoverElement = this.element;
this.contentElement.positionAt(0, 0);
document.body.appendChild(this.contentElement);
preferredWidth = preferredWidth || this.contentElement.offsetWidth;
preferredHeight = preferredHeight || this.contentElement.offsetHeight;
this._contentDiv.appendChild(this.contentElement);
this.element.appendChild(this._contentDiv);
document.body.appendChild(this.element);
this._positionElement(anchor, preferredWidth, preferredHeight);
this._visible = true;
if (this._popoverHelper)
contentElement.addEventListener("mousemove", this._popoverHelper._killHidePopoverTimer.bind(this._popoverHelper), true);
},
hide: function()
{
if (WebInspector.Popover._popoverElement) {
delete WebInspector.Popover._popoverElement;
document.body.removeChild(this.element);
}
this._visible = false;
},
get visible()
{
return this._visible;
},
get disposed()
{
return this._disposed;
},
dispose: function()
{
if (this.visible)
this.hide();
this._disposed = true;
},
setCanShrink: function(canShrink)
{
this._hasFixedHeight = !canShrink;
this._contentDiv.addStyleClass("fixed-height");
},
_positionElement: function(anchorElement, preferredWidth, preferredHeight)
{
const borderWidth = 25;
const scrollerWidth = this._hasFixedHeight ? 0 : 11;
const arrowHeight = 15;
const arrowOffset = 10;
const borderRadius = 10;
preferredWidth = Math.max(preferredWidth, 50);
const totalWidth = window.innerWidth;
const totalHeight = window.innerHeight;
var anchorBox = anchorElement.boxInWindow(window);
var newElementPosition = { x: 0, y: 0, width: preferredWidth + scrollerWidth, height: preferredHeight };
var verticalAlignment;
var roomAbove = anchorBox.y;
var roomBelow = totalHeight - anchorBox.y - anchorBox.height;
if (roomAbove > roomBelow) {
if (anchorBox.y > newElementPosition.height + arrowHeight + borderRadius)
newElementPosition.y = anchorBox.y - newElementPosition.height - arrowHeight;
else {
newElementPosition.y = borderRadius;
newElementPosition.height = anchorBox.y - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = borderRadius;
newElementPosition.height = preferredHeight;
}
}
verticalAlignment = "bottom";
} else {
newElementPosition.y = anchorBox.y + anchorBox.height + arrowHeight;
if (newElementPosition.y + newElementPosition.height + arrowHeight - borderWidth >= totalHeight) {
newElementPosition.height = totalHeight - anchorBox.y - anchorBox.height - borderRadius * 2 - arrowHeight;
if (this._hasFixedHeight && newElementPosition.height < preferredHeight) {
newElementPosition.y = totalHeight - preferredHeight - borderRadius;
newElementPosition.height = preferredHeight;
}
}
verticalAlignment = "top";
}
var horizontalAlignment;
if (anchorBox.x + newElementPosition.width < totalWidth) {
newElementPosition.x = Math.max(borderRadius, anchorBox.x - borderRadius - arrowOffset);
horizontalAlignment = "left";
} else if (newElementPosition.width + borderRadius * 2 < totalWidth) {
newElementPosition.x = totalWidth - newElementPosition.width - borderRadius;
horizontalAlignment = "right";
var arrowRightPosition = Math.max(0, totalWidth - anchorBox.x - anchorBox.width - borderRadius - arrowOffset);
arrowRightPosition += anchorBox.width / 2;
arrowRightPosition = Math.min(arrowRightPosition, newElementPosition.width - borderRadius - arrowOffset);
this._popupArrowElement.style.right = arrowRightPosition + "px";
} else {
newElementPosition.x = borderRadius;
newElementPosition.width = totalWidth - borderRadius * 2;
newElementPosition.height += scrollerWidth;
horizontalAlignment = "left";
if (verticalAlignment === "bottom")
newElementPosition.y -= scrollerWidth;
this._popupArrowElement.style.left = Math.max(0, anchorBox.x - borderRadius * 2 - arrowOffset) + "px";
this._popupArrowElement.style.left += anchorBox.width / 2;
}
this.element.className = "popover custom-popup-vertical-scroll custom-popup-horizontal-scroll " + verticalAlignment + "-" + horizontalAlignment + "-arrow";
this.element.positionAt(newElementPosition.x - borderWidth, newElementPosition.y - borderWidth);
this.element.style.width = newElementPosition.width + borderWidth * 2 + "px";
this.element.style.height = newElementPosition.height + borderWidth * 2 + "px";
}
}
WebInspector.PopoverHelper = function(panelElement, getAnchor, showPopover, onHide, disableOnClick)
{
this._panelElement = panelElement;
this._getAnchor = getAnchor;
this._showPopover = showPopover;
this._onHide = onHide;
this._disableOnClick = !!disableOnClick;
panelElement.addEventListener("mousedown", this._mouseDown.bind(this), false);
panelElement.addEventListener("mousemove", this._mouseMove.bind(this), false);
panelElement.addEventListener("mouseout", this._mouseOut.bind(this), false);
this.setTimeout(1000);
}
WebInspector.PopoverHelper.prototype = {
setTimeout: function(timeout)
{
this._timeout = timeout;
},
_mouseDown: function(event)
{
if (this._disableOnClick || !event.target.isSelfOrDescendant(this._hoverElement))
this.hidePopover();
else {
this._killHidePopoverTimer();
this._handleMouseAction(event, true);
}
},
_mouseMove: function(event)
{
if (event.target.isSelfOrDescendant(this._hoverElement))
return;
this._startHidePopoverTimer();
this._handleMouseAction(event, false);
},
_mouseOut: function(event)
{
if (event.target === this._hoverElement)
this._startHidePopoverTimer();
},
_startHidePopoverTimer: function()
{
if (!this._popover || this._hidePopoverTimer)
return;
function doHide()
{
this._hidePopover();
delete this._hidePopoverTimer;
}
this._hidePopoverTimer = setTimeout(doHide.bind(this), this._timeout / 2);
},
_handleMouseAction: function(event, isMouseDown)
{
this._resetHoverTimer();
if (event.which && this._disableOnClick)
return;
this._hoverElement = this._getAnchor(event.target, event);
if (!this._hoverElement)
return;
const toolTipDelay = isMouseDown ? 0 : (this._popup ? this._timeout * 0.6 : this._timeout);
this._hoverTimer = setTimeout(this._mouseHover.bind(this, this._hoverElement), toolTipDelay);
},
_resetHoverTimer: function()
{
if (this._hoverTimer) {
clearTimeout(this._hoverTimer);
delete this._hoverTimer;
}
},
isPopoverVisible: function()
{
return !!this._popover;
},
hidePopover: function()
{
this._resetHoverTimer();
this._hidePopover();
},
_hidePopover: function()
{
if (!this._popover)
return;
if (this._onHide)
this._onHide();
this._popover.dispose();
delete this._popover;
this._hoverElement = null;
},
_mouseHover: function(element)
{
delete this._hoverTimer;
this._hidePopover();
this._popover = new WebInspector.Popover(this);
this._showPopover(element, this._popover);
},
_killHidePopoverTimer: function()
{
if (this._hidePopoverTimer) {
clearTimeout(this._hidePopoverTimer);
delete this._hidePopoverTimer;
this._resetHoverTimer();
}
}
}
WebInspector.Placard = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "placard";
this.element.placard = this;
this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";
this.element.appendChild(this.subtitleElement);
this.element.appendChild(this.titleElement);
this.title = title;
this.subtitle = subtitle;
this.selected = false;
}
WebInspector.Placard.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},
get subtitle()
{
return this._subtitle;
},
set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},
get selected()
{
return this._selected;
},
set selected(x)
{
if (x)
this.select();
else
this.deselect();
},
select: function()
{
if (this._selected)
return;
this._selected = true;
this.element.addStyleClass("selected");
},
deselect: function()
{
if (!this._selected)
return;
this._selected = false;
this.element.removeStyleClass("selected");
},
toggleSelected: function()
{
this.selected = !this.selected;
},
discard: function()
{
}
}
WebInspector.TabbedPane = function()
{
WebInspector.View.call(this);
this.registerRequiredCSS("tabbedPane.css");
this.element.addStyleClass("tabbed-pane");
this._headerElement = this.element.createChild("div", "tabbed-pane-header");
this._headerContentsElement = this._headerElement.createChild("div", "tabbed-pane-header-contents");
this._tabsElement = this._headerContentsElement.createChild("div", "tabbed-pane-header-tabs");
this._contentElement = this.element.createChild("div", "tabbed-pane-content");
this._tabs = [];
this._tabsHistory = [];
this._tabsById = {};
this.element.addEventListener("click", this.focus.bind(this), false);
this._dropDownButton = this._createDropDownButton();
}
WebInspector.TabbedPane.EventTypes = {
TabSelected: "TabSelected",
TabClosed: "TabClosed"
}
WebInspector.TabbedPane.prototype = {
get visibleView()
{
return this._currentTab ? this._currentTab.view : null;
},
get selectedTabId()
{
return this._currentTab ? this._currentTab.id : null;
},
set shrinkableTabs(shrinkableTabs)
{
this._shrinkableTabs = shrinkableTabs;
},
set closeableTabs(closeableTabs)
{
this._closeableTabs = closeableTabs;
},
defaultFocusedElement: function()
{
return this.visibleView ? this.visibleView.defaultFocusedElement() : null;
},
appendTab: function(id, tabTitle, view, tabTooltip, userGesture)
{
var tab = new WebInspector.TabbedPaneTab(this, id, tabTitle, this._closeableTabs, view, tabTooltip);
this._tabsById[id] = tab;
this._tabs.push(tab);
this._tabsHistory.push(tab);
if (this._tabsHistory[0] === tab)
this.selectTab(tab.id, userGesture);
this._updateTabElements();
},
closeTab: function(id, userGesture)
{
this._innerCloseTab(id, userGesture);
this._updateTabElements();
if (this._tabsHistory.length)
this.selectTab(this._tabsHistory[0].id, userGesture);
},
_innerCloseTab: function(id, userGesture)
{
if (this._currentTab && this._currentTab.id === id)
this._hideCurrentTab();
var tab = this._tabsById[id];
delete this._tabsById[id];
this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabs.splice(this._tabs.indexOf(tab), 1);
if (tab._shown)
this._hideTabElement(tab);
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabClosed, eventData);
return true;
},
closeAllTabs: function(userGesture)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i)
this._innerCloseTab(tabs[i].id, userGesture);
this._updateTabElements();
},
closeOtherTabs: function(id)
{
var tabs = this._tabs.slice();
for (var i = 0; i < tabs.length; ++i) {
if (tabs[i].id !== id)
this._innerCloseTab(tabs[i].id, true);
}
this._updateTabElements();
this.selectTab(id, true);
},
selectTab: function(id, userGesture)
{
var tab = this._tabsById[id];
if (!tab)
return;
if (this._currentTab && this._currentTab.id === id)
return;
this._hideCurrentTab();
this._showTab(tab);
this._currentTab = tab;
this._tabsHistory.splice(this._tabsHistory.indexOf(tab), 1);
this._tabsHistory.splice(0, 0, tab);
this._updateTabElements();
var eventData = { tabId: id, view: tab.view, isUserGesture: userGesture };
this.dispatchEventToListeners(WebInspector.TabbedPane.EventTypes.TabSelected, eventData);
return true;
},
lastOpenedTabIds: function(tabsCount)
{
function tabToTabId(tab) {
return tab.id;
}
return this._tabsHistory.slice(0, tabsCount).map(tabToTabId);
},
changeTabTitle: function(id, tabTitle)
{
var tab = this._tabsById[id];
tab.title = tabTitle;
this._updateTabElements();
},
changeTabView: function(id, view)
{
var tab = this._tabsById[id];
if (this._currentTab && this._currentTab.id === tab.id) {
this._hideTab(tab);
tab.view = view;
this._showTab(tab);
} else
tab.view = view;
},
changeTabTooltip: function(id, tabTooltip)
{
var tab = this._tabsById[id];
tab.tooltip = tabTooltip;
},
onResize: function()
{
this._updateTabElements();
},
_updateTabElements: function()
{
WebInspector.invokeOnceAfterBatchUpdate(this, this._innerUpdateTabElements);
},
_innerUpdateTabElements: function()
{
if (!this.isShowing())
return;
if (!this._tabs.length)
this._contentElement.addStyleClass("has-no-tabs");
else
this._contentElement.removeStyleClass("has-no-tabs");
if (!this._measuredDropDownButtonWidth)
this._measureDropDownButton();
this._updateWidths();
this._updateTabsDropDown();
},
_showTabElement: function(index, tab)
{
if (index >= this._tabsElement.children.length)
this._tabsElement.appendChild(tab.tabElement);
else
this._tabsElement.insertBefore(tab.tabElement, this._tabsElement.children[index]);
tab._shown = true;
},
_hideTabElement: function(tab)
{
this._tabsElement.removeChild(tab.tabElement);
tab._shown = false;
},
_createDropDownButton: function()
{
var dropDownContainer = document.createElement("div");
dropDownContainer.addStyleClass("tabbed-pane-header-tabs-drop-down-container");
var dropDownButton = dropDownContainer.createChild("div", "tabbed-pane-header-tabs-drop-down");
dropDownButton.appendChild(document.createTextNode("\u00bb"));
this._tabsSelect = dropDownButton.createChild("select", "tabbed-pane-header-tabs-drop-down-select");
this._tabsSelect.addEventListener("change", this._tabsSelectChanged.bind(this), false);
return dropDownContainer;
},
_totalWidth: function()
{
return this._headerContentsElement.getBoundingClientRect().width;
},
_updateTabsDropDown: function()
{
var tabsToShowIndexes = this._tabsToShowIndexes(this._tabs, this._tabsHistory, this._totalWidth(), this._measuredDropDownButtonWidth);
for (var i = 0; i < this._tabs.length; ++i) {
if (this._tabs[i]._shown && tabsToShowIndexes.indexOf(i) === -1)
this._hideTabElement(this._tabs[i]);
}
for (var i = 0; i < tabsToShowIndexes.length; ++i) {
var tab = this._tabs[tabsToShowIndexes[i]];
if (!tab._shown)
this._showTabElement(i, tab);
}
this._populateDropDownFromIndex();
},
_populateDropDownFromIndex: function()
{
if (this._dropDownButton.parentElement)
this._headerContentsElement.removeChild(this._dropDownButton);
this._tabsSelect.removeChildren();
var tabsToShow = [];
for (var i = 0; i < this._tabs.length; ++i) {
if (!this._tabs[i]._shown)
tabsToShow.push(this._tabs[i]);
continue;
}
function compareFunction(tab1, tab2)
{
return tab1.title.localeCompare(tab2.title);
}
tabsToShow.sort(compareFunction);
for (var i = 0; i < tabsToShow.length; ++i) {
var option = new Option(tabsToShow[i].title);
option.tab = tabsToShow[i];
this._tabsSelect.appendChild(option);
}
if (this._tabsSelect.options.length) {
this._headerContentsElement.appendChild(this._dropDownButton);
this._tabsSelect.selectedIndex = -1;
}
},
_tabsSelectChanged: function()
{
var options = this._tabsSelect.options;
var selectedOption = options[this._tabsSelect.selectedIndex];
this.selectTab(selectedOption.tab.id, true);
},
_measureDropDownButton: function()
{
this._dropDownButton.addStyleClass("measuring");
this._headerContentsElement.appendChild(this._dropDownButton);
this._measuredDropDownButtonWidth = this._dropDownButton.getBoundingClientRect().width;
this._headerContentsElement.removeChild(this._dropDownButton);
this._dropDownButton.removeStyleClass("measuring");
},
_updateWidths: function()
{
var measuredWidths = this._measureWidths();
var maxWidth = this._shrinkableTabs ? this._calculateMaxWidth(measuredWidths.slice(), this._totalWidth()) : Number.MAX_VALUE;
var i = 0;
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
tab.setWidth(Math.min(maxWidth, measuredWidths[i++]));
}
},
_measureWidths: function()
{
var measuringTabElements = [];
for (var tabId in this._tabs) {
var tab = this._tabs[tabId];
if (typeof tab._measuredWidth === "number")
continue;
var measuringTabElement = tab._createTabElement(true);
measuringTabElement.__tab = tab;
measuringTabElements.push(measuringTabElement);
this._tabsElement.appendChild(measuringTabElement);
}
for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].__tab._measuredWidth = measuringTabElements[i].getBoundingClientRect().width;
for (var i = 0; i < measuringTabElements.length; ++i)
measuringTabElements[i].parentElement.removeChild(measuringTabElements[i]);
var measuredWidths = [];
for (var tabId in this._tabs)
measuredWidths.push(this._tabs[tabId]._measuredWidth);
return measuredWidths;
},
_calculateMaxWidth: function(measuredWidths, totalWidth)
{
if (!measuredWidths.length)
return 0;
measuredWidths.sort(function(x, y) { return x - y });
var totalMeasuredWidth = 0;
for (var i = 0; i < measuredWidths.length; ++i)
totalMeasuredWidth += measuredWidths[i];
if (totalWidth >= totalMeasuredWidth)
return measuredWidths[measuredWidths.length - 1];
var totalExtraWidth = 0;
for (var i = measuredWidths.length - 1; i > 0; --i) {
var extraWidth = measuredWidths[i] - measuredWidths[i - 1];
totalExtraWidth += (measuredWidths.length - i) * extraWidth;
if (totalWidth + totalExtraWidth >= totalMeasuredWidth)
return measuredWidths[i - 1] + (totalWidth + totalExtraWidth - totalMeasuredWidth) / (measuredWidths.length - i);
}
return totalWidth / measuredWidths.length;
},
_tabsToShowIndexes: function(tabsOrdered, tabsHistory, totalWidth, measuredDropDownButtonWidth)
{
var tabsToShowIndexes = [];
var totalTabsWidth = 0;
for (var i = 0; i < tabsHistory.length; ++i) {
totalTabsWidth += tabsHistory[i].width();
var minimalRequiredWidth = totalTabsWidth;
if (i !== tabsHistory.length - 1)
minimalRequiredWidth += measuredDropDownButtonWidth;
if (minimalRequiredWidth > totalWidth)
break;
tabsToShowIndexes.push(tabsOrdered.indexOf(tabsHistory[i]));
}
tabsToShowIndexes.sort(function(x, y) { return x - y });
return tabsToShowIndexes;
},
_hideCurrentTab: function()
{
if (!this._currentTab)
return;
this._hideTab(this._currentTab);
delete this._currentTab;
},
_showTab: function(tab)
{
tab.tabElement.addStyleClass("selected");
tab.view.show(this._contentElement);
},
_hideTab: function(tab)
{
tab.tabElement.removeStyleClass("selected");
tab.view.detach();
},
canHighlightLine: function()
{
return this._currentTab && this._currentTab.view && this._currentTab.view.canHighlightLine();
},
highlightLine: function(line)
{
if (this.canHighlightLine())
this._currentTab.view.highlightLine(line);
},
elementsToRestoreScrollPositionsFor: function()
{
return [ this._contentElement ];
},
_insertBefore: function(tab, index)
{
this._tabsElement.insertBefore(tab._tabElement, this._tabsElement.childNodes[index]);
var oldIndex = this._tabs.indexOf(tab);
this._tabs.splice(oldIndex, 1);
if (oldIndex < index)
--index;
this._tabs.splice(index, 0, tab);
}
}
WebInspector.TabbedPane.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.TabbedPaneTab = function(tabbedPane, id, title, closeable, view, tooltip)
{
this._closeable = closeable;
this._tabbedPane = tabbedPane;
this._id = id;
this._title = title;
this._tooltip = tooltip;
this._view = view;
this._shown = false;
this._measuredWidth;
this._tabElement;
}
WebInspector.TabbedPaneTab.prototype = {
get id()
{
return this._id;
},
get title()
{
return this._title;
},
set title(title)
{
this._title = title;
if (this._titleElement)
this._titleElement.textContent = title;
delete this._measuredWidth;
},
get view()
{
return this._view;
},
set view(view)
{
this._view = view;
},
get tooltip()
{
return this._tooltip;
},
set tooltip(tooltip)
{
this._tooltip = tooltip;
if (this._titleElement)
this._titleElement.title = tooltip || "";
},
get tabElement()
{
if (typeof(this._tabElement) !== "undefined")
return this._tabElement;
this._createTabElement(false);
return this._tabElement;
},
width: function()
{
return this._width;
},
setWidth: function(width)
{
this.tabElement.style.width = width + "px";
this._width = width;
},
_createTabElement: function(measuring)
{
var tabElement = document.createElement("div");
tabElement.addStyleClass("tabbed-pane-header-tab");
tabElement.tabIndex = -1;
var titleElement = tabElement.createChild("span", "tabbed-pane-header-tab-title");
titleElement.textContent = this.title;
titleElement.title = this.tooltip || "";
if (!measuring)
this._titleElement = titleElement;
if (this._closeable) {
var closeButtonSpan = tabElement.createChild("span", "tabbed-pane-header-tab-close-button");
closeButtonSpan.textContent = "\u00D7";
}
if (measuring)
tabElement.addStyleClass("measuring");
else {
this._tabElement = tabElement;
tabElement.addEventListener("click", this._tabClicked.bind(this), false);
tabElement.addEventListener("mousedown", this._tabMouseDown.bind(this), false);
if (this._closeable) {
tabElement.addEventListener("contextmenu", this._tabContextMenu.bind(this), false);
WebInspector.installDragHandle(tabElement, this._startTabDragging.bind(this), this._tabDragging.bind(this), this._endTabDragging.bind(this), "pointer");
}
}
return tabElement;
},
_tabClicked: function(event)
{
if (this._closeable && (event.button === 1 || event.target.hasStyleClass("tabbed-pane-header-tab-close-button")))
this._tabbedPane.closeTab(this.id, true);
},
_tabMouseDown: function(event)
{
if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button") || event.button === 1)
return;
this._tabbedPane.selectTab(this.id, true);
},
_tabContextMenu: function(event)
{
function close()
{
this._tabbedPane.closeTab(this.id, true);
}
function closeOthers()
{
this._tabbedPane.closeOtherTabs(this.id);
}
function closeAll()
{
this._tabbedPane.closeAllTabs(true);
}
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Close"), close.bind(this));
contextMenu.appendItem(WebInspector.UIString("Close Others"), closeOthers.bind(this));
contextMenu.appendItem(WebInspector.UIString("Close All"), closeAll.bind(this));
contextMenu.show(event);
},
_startTabDragging: function(event)
{
if (event.target.hasStyleClass("tabbed-pane-header-tab-close-button"))
return false;
this._dragStartX = event.pageX;
return true;
},
_tabDragging: function(event)
{
var tabElements = this._tabbedPane._tabsElement.childNodes;
for (var i = 0; i < tabElements.length; ++i) {
var tabElement = tabElements[i];
if (tabElement === this._tabElement)
continue;
var intersects = tabElement.offsetLeft + tabElement.clientWidth > this._tabElement.offsetLeft &&
this._tabElement.offsetLeft + this._tabElement.clientWidth > tabElement.offsetLeft;
if (!intersects)
continue;
if (Math.abs(event.pageX - this._dragStartX) < tabElement.clientWidth / 2 + 5)
break;
if (event.pageX - this._dragStartX > 0) {
tabElement = tabElement.nextSibling;
++i;
}
var oldOffsetLeft = this._tabElement.offsetLeft;
this._tabbedPane._insertBefore(this, i);
this._dragStartX += this._tabElement.offsetLeft - oldOffsetLeft;
break;
}
if (!this._tabElement.previousSibling && event.pageX - this._dragStartX < 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
if (!this._tabElement.nextSibling && event.pageX - this._dragStartX > 0) {
this._tabElement.style.setProperty("left", "0px");
return;
}
this._tabElement.style.setProperty("position", "relative");
this._tabElement.style.setProperty("left", (event.pageX - this._dragStartX) + "px");
},
_endTabDragging: function(event)
{
this._tabElement.style.removeProperty("position");
this._tabElement.style.removeProperty("left");
delete this._dragStartX;
}
}
WebInspector.Drawer = function()
{
this.element = document.getElementById("drawer");
this._savedHeight = 200;
this._mainElement = document.getElementById("main");
this._toolbarElement = document.getElementById("toolbar");
this._floatingStatusBarContainer = document.getElementById("floating-status-bar-container");
WebInspector.installDragHandle(this._floatingStatusBarContainer, this._startStatusBarDragging.bind(this), this._statusBarDragging.bind(this), this._endStatusBarDragging.bind(this), "row-resize");
this._drawerContentsElement = document.createElement("div");
this._drawerContentsElement.id = "drawer-contents";
this._drawerContentsElement.className = "drawer-contents";
this.element.appendChild(this._drawerContentsElement);
this._viewStatusBar = document.createElement("div");
this._bottomStatusBar = document.getElementById("bottom-status-bar-container");
}
WebInspector.Drawer.AnimationType = {
Immediately: 0,
Normal: 1,
Slow: 2
}
WebInspector.Drawer.prototype = {
get visible()
{
return !!this._view;
},
_constrainHeight: function(height)
{
return Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
},
show: function(view, animationType)
{
this.immediatelyFinishAnimation();
var drawerWasVisible = this.visible;
if (this._view) {
this._view.detach();
this._drawerContentsElement.removeChildren();
}
this._view = view;
var statusBarItems = this._view.statusBarItems || [];
this._viewStatusBar.removeChildren();
for (var i = 0; i < statusBarItems.length; ++i)
this._viewStatusBar.appendChild(statusBarItems[i]);
document.body.addStyleClass("drawer-visible");
this._floatingStatusBarContainer.insertBefore(document.getElementById("panel-status-bar"), this._floatingStatusBarContainer.firstElementChild);
this._bottomStatusBar.appendChild(this._viewStatusBar);
this._view.markAsRoot();
this._view.show(this._drawerContentsElement);
if (drawerWasVisible)
return;
var height = this._constrainHeight(this._savedHeight || this.element.offsetHeight);
var animations = [
{element: this.element, end: {height: height}},
{element: this._mainElement, end: {bottom: height}},
{element: this._floatingStatusBarContainer, start: {"padding-left": this._bottomStatusBar.offsetLeft}, end: {"padding-left": 0}},
{element: this._viewStatusBar, start: {opacity: 0}, end: {opacity: 1}}
];
function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
if (this._view && this._view.afterShow)
this._view.afterShow();
delete this._currentAnimation;
}
this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
if (animationType === WebInspector.Drawer.AnimationType.Immediately)
this._currentAnimation.forceComplete();
},
hide: function(animationType)
{
this.immediatelyFinishAnimation();
if (!this.visible)
return;
this._savedHeight = this.element.offsetHeight;
WebInspector.restoreFocusFromElement(this.element);
document.body.removeStyleClass("drawer-visible");
WebInspector.inspectorView.currentPanel().statusBarResized();
document.body.addStyleClass("drawer-visible");
var animations = [
{element: this._mainElement, end: {bottom: 0}},
{element: this.element, end: {height: 0}},
{element: this._floatingStatusBarContainer, start: {"padding-left": 0}, end: {"padding-left": this._bottomStatusBar.offsetLeft} },
{element: this._viewStatusBar, start: {opacity: 1}, end: {opacity: 0}}
];
function animationFinished()
{
WebInspector.inspectorView.currentPanel().doResize();
this._view.detach();
delete this._view;
this._bottomStatusBar.removeChildren();
this._bottomStatusBar.appendChild(document.getElementById("panel-status-bar"));
this._drawerContentsElement.removeChildren();
document.body.removeStyleClass("drawer-visible");
delete this._currentAnimation;
}
this._currentAnimation = WebInspector.animateStyle(animations, this._animationDuration(animationType), animationFinished.bind(this));
if (animationType === WebInspector.Drawer.AnimationType.Immediately)
this._currentAnimation.forceComplete();
},
resize: function()
{
if (!this.visible)
return;
this._view.storeScrollPositions();
var height = this._constrainHeight(parseInt(this.element.style.height, 10));
this._mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";
this._view.doResize();
},
immediatelyFinishAnimation: function()
{
if (this._currentAnimation)
this._currentAnimation.forceComplete();
},
_animationDuration: function(animationType)
{
switch (animationType) {
case WebInspector.Drawer.AnimationType.Slow:
return 2000;
case WebInspector.Drawer.AnimationType.Normal:
return 250;
default:
return 0;
}
},
_startStatusBarDragging: function(event)
{
if (!this.visible || event.target !== this._floatingStatusBarContainer)
return false;
this._view.storeScrollPositions();
this._statusBarDragOffset = event.pageY - this.element.totalOffsetTop();
return true;
},
_statusBarDragging: function(event)
{
var height = window.innerHeight - event.pageY + this._statusBarDragOffset;
height = Number.constrain(height, Preferences.minConsoleHeight, window.innerHeight - this._mainElement.totalOffsetTop() - Preferences.minConsoleHeight);
this._mainElement.style.bottom = height + "px";
this.element.style.height = height + "px";
if (WebInspector.inspectorView.currentPanel())
WebInspector.inspectorView.currentPanel().doResize();
this._view.doResize();
event.consume(true);
},
_endStatusBarDragging: function(event)
{
this._savedHeight = this.element.offsetHeight;
delete this._statusBarDragOffset;
event.consume();
}
}
WebInspector.drawer = null;
WebInspector.ConsoleModel = function()
{
this.messages = [];
this.warnings = 0;
this.errors = 0;
this._interruptRepeatCount = false;
InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleDispatcher(this));
}
WebInspector.ConsoleModel.Events = {
ConsoleCleared: "console-cleared",
MessageAdded: "console-message-added",
RepeatCountUpdated: "repeat-count-updated"
}
WebInspector.ConsoleModel.prototype = {
enableAgent: function()
{
if (WebInspector.settings.monitoringXHREnabled.get())
ConsoleAgent.setMonitoringXHREnabled(true);
this._enablingConsole = true;
function callback()
{
delete this._enablingConsole;
}
ConsoleAgent.enable(callback.bind(this));
},
enablingConsole: function()
{
return !!this._enablingConsole;
},
addMessage: function(msg)
{
this.messages.push(msg);
this._previousMessage = msg;
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.MessageAdded, msg);
this._interruptRepeatCount = false;
},
_incrementErrorWarningCount: function(msg)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
this.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
this.errors += msg.repeatDelta;
break;
}
},
requestClearMessages: function()
{
ConsoleAgent.clearMessages();
this.clearMessages();
},
clearMessages: function()
{
this.messages = [];
this.errors = 0;
this.warnings = 0;
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.ConsoleCleared);
},
interruptRepeatCount: function()
{
this._interruptRepeatCount = true;
},
_messageRepeatCountUpdated: function(count)
{
var msg = this._previousMessage;
if (!msg)
return;
var prevRepeatCount = msg.totalRepeatCount;
if (!this._interruptRepeatCount) {
msg.repeatDelta = count - prevRepeatCount;
msg.repeatCount = msg.repeatCount + msg.repeatDelta;
msg.totalRepeatCount = count;
msg.updateRepeatCount();
this._incrementErrorWarningCount(msg);
this.dispatchEventToListeners(WebInspector.ConsoleModel.Events.RepeatCountUpdated, msg);
} else {
var msgCopy = msg.clone();
msgCopy.totalRepeatCount = count;
msgCopy.repeatCount = (count - prevRepeatCount) || 1;
msgCopy.repeatDelta = msgCopy.repeatCount;
this.addMessage(msgCopy);
}
}
}
WebInspector.ConsoleModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.ConsoleMessage = function(source, level, url, line, repeatCount)
{
this.source = source;
this.level = level;
this.url = url || null;
this.line = line || 0;
this.message = "";
repeatCount = repeatCount || 1;
this.repeatCount = repeatCount;
this.repeatDelta = repeatCount;
this.totalRepeatCount = repeatCount;
}
WebInspector.ConsoleMessage.prototype = {
isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},
updateRepeatCount: function()
{
},
clone: function()
{
},
location: function()
{
}
}
WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
}
WebInspector.ConsoleMessage.MessageSource = {
HTML: "html",
XML: "xml",
JS: "javascript",
Network: "network",
ConsoleAPI: "console-api",
Other: "other"
}
WebInspector.ConsoleMessage.MessageType = {
Log: "log",
Dir: "dir",
DirXML: "dirxml",
Trace: "trace",
StartGroup: "startGroup",
StartGroupCollapsed: "startGroupCollapsed",
EndGroup: "endGroup",
Assert: "assert",
Result: "result"
}
WebInspector.ConsoleMessage.MessageLevel = {
Tip: "tip",
Log: "log",
Warning: "warning",
Error: "error",
Debug: "debug"
}
WebInspector.ConsoleDispatcher = function(console)
{
this._console = console;
}
WebInspector.ConsoleDispatcher.prototype = {
messageAdded: function(payload)
{
var consoleMessage = WebInspector.ConsoleMessage.create(
payload.source,
payload.level,
payload.text,
payload.type,
payload.url,
payload.line,
payload.repeatCount,
payload.parameters,
payload.stackTrace,
payload.networkRequestId,
this._console._enablingConsole);
this._console.addMessage(consoleMessage);
},
messageRepeatCountUpdated: function(count)
{
this._console._messageRepeatCountUpdated(count);
},
messagesCleared: function()
{
if (!WebInspector.settings.preserveConsoleLog.get())
this._console.clearMessages();
}
}
WebInspector.console = null;
WebInspector.ConsoleMessageImpl = function(source, level, message, linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
WebInspector.ConsoleMessage.call(this, source, level, url, line, repeatCount);
this._linkifier = linkifier;
this.type = type || WebInspector.ConsoleMessage.MessageType.Log;
this._messageText = message;
this._parameters = parameters;
this._stackTrace = stackTrace;
this._request = requestId ? WebInspector.networkLog.requestForId(requestId) : null;
this._isOutdated = isOutdated;
this._customFormatters = {
"object": this._formatParameterAsObject,
"array": this._formatParameterAsArray,
"node": this._formatParameterAsNode,
"string": this._formatParameterAsString
};
}
WebInspector.ConsoleMessageImpl.prototype = {
_formatMessage: function()
{
this._formattedMessage = document.createElement("span");
this._formattedMessage.className = "console-message-text source-code";
if (this.source === WebInspector.ConsoleMessage.MessageSource.ConsoleAPI) {
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Trace:
this._messageElement = document.createTextNode("console.trace()");
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
var args = [WebInspector.UIString("Assertion failed:")];
if (this._parameters)
args = args.concat(this._parameters);
this._messageElement = this._format(args);
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
var obj = this._parameters ? this._parameters[0] : undefined;
var args = ["%O", obj];
this._messageElement = this._format(args);
break;
default:
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}
} else if (this.source === WebInspector.ConsoleMessage.MessageSource.Network) {
if (this._request) {
this._stackTrace = this._request.initiator.stackTrace;
if (this._request.initiator && this._request.initiator.url) {
this.url = this._request.initiator.url;
this.line = this._request.initiator.lineNumber;
}
this._messageElement = document.createElement("span");
if (this.level === WebInspector.ConsoleMessage.MessageLevel.Error) {
this._messageElement.appendChild(document.createTextNode(this._request.requestMethod + " "));
this._messageElement.appendChild(WebInspector.linkifyRequestAsNode(this._request));
if (this._request.failed)
this._messageElement.appendChild(document.createTextNode(" " + this._request.localizedFailDescription));
else
this._messageElement.appendChild(document.createTextNode(" " + this._request.statusCode + " (" + this._request.statusText + ")"));
} else {
var fragment = WebInspector.linkifyStringAsFragmentWithCustomLinkifier(this._messageText, WebInspector.linkifyRequestAsNode.bind(null, this._request, ""));
this._messageElement.appendChild(fragment);
}
} else {
if (this.url) {
var isExternal = !WebInspector.resourceForURL(this.url);
this._anchorElement = WebInspector.linkifyURLAsNode(this.url, this.url, "console-message-url", isExternal);
}
this._messageElement = this._format([this._messageText]);
}
} else {
var args = this._parameters || [this._messageText];
this._messageElement = this._format(args);
}
if (this.source !== WebInspector.ConsoleMessage.MessageSource.Network || this._request) {
if (this._stackTrace && this._stackTrace.length && this._stackTrace[0].url) {
this._anchorElement = this._linkifyCallFrame(this._stackTrace[0]);
} else if (this.url && this.url !== "undefined") {
this._anchorElement = this._linkifyLocation(this.url, this.line, 0);
}
}
this._formattedMessage.appendChild(this._messageElement);
if (this._anchorElement) {
this._formattedMessage.appendChild(document.createTextNode(" "));
this._formattedMessage.appendChild(this._anchorElement);
}
var dumpStackTrace = !!this._stackTrace && this._stackTrace.length && (this.source === WebInspector.ConsoleMessage.MessageSource.Network || this.level === WebInspector.ConsoleMessage.MessageLevel.Error || this.type === WebInspector.ConsoleMessage.MessageType.Trace);
if (dumpStackTrace) {
var ol = document.createElement("ol");
ol.className = "outline-disclosure";
var treeOutline = new TreeOutline(ol);
var content = this._formattedMessage;
var root = new TreeElement(content, null, true);
content.treeElementForTest = root;
treeOutline.appendChild(root);
if (this.type === WebInspector.ConsoleMessage.MessageType.Trace)
root.expand();
this._populateStackTraceTreeElement(root);
this._formattedMessage = ol;
}
this._message = this._messageElement.textContent;
},
get message()
{
var formattedMessage = this.formattedMessage;
return this._message;
},
get formattedMessage()
{
if (!this._formattedMessage)
this._formatMessage();
return this._formattedMessage;
},
_linkifyLocation: function(url, lineNumber, columnNumber)
{
lineNumber = lineNumber ? lineNumber - 1 : 0;
columnNumber = columnNumber ? columnNumber - 1 : 0;
return this._linkifier.linkifyLocation(url, lineNumber, columnNumber, "console-message-url");
},
_linkifyCallFrame: function(callFrame)
{
return this._linkifyLocation(callFrame.url, callFrame.lineNumber, callFrame.columnNumber);
},
isErrorOrWarning: function()
{
return (this.level === WebInspector.ConsoleMessage.MessageLevel.Warning || this.level === WebInspector.ConsoleMessage.MessageLevel.Error);
},
_format: function(parameters)
{
var formattedResult = document.createElement("span");
if (!parameters.length)
return formattedResult;
for (var i = 0; i < parameters.length; ++i) {
if (parameters[i] instanceof WebInspector.RemoteObject)
continue;
if (typeof parameters[i] === "object")
parameters[i] = WebInspector.RemoteObject.fromPayload(parameters[i]);
else
parameters[i] = WebInspector.RemoteObject.fromPrimitiveValue(parameters[i]);
}
var shouldFormatMessage = WebInspector.RemoteObject.type(parameters[0]) === "string" && this.type !== WebInspector.ConsoleMessage.MessageType.Result;
if (shouldFormatMessage) {
var result = this._formatWithSubstitutionString(parameters, formattedResult);
parameters = result.unusedSubstitutions;
if (parameters.length)
formattedResult.appendChild(document.createTextNode(" "));
}
for (var i = 0; i < parameters.length; ++i) {
if (shouldFormatMessage && parameters[i].type === "string")
formattedResult.appendChild(document.createTextNode(parameters[i].description));
else
formattedResult.appendChild(this._formatParameter(parameters[i], false, true));
if (i < parameters.length - 1)
formattedResult.appendChild(document.createTextNode(" "));
}
return formattedResult;
},
_formatParameter: function(output, forceObjectFormat, includePreview)
{
var type;
if (forceObjectFormat)
type = "object";
else if (output instanceof WebInspector.RemoteObject)
type = output.subtype || output.type;
else
type = typeof output;
var formatter = this._customFormatters[type];
if (!formatter) {
formatter = this._formatParameterAsValue;
output = output.description;
}
var span = document.createElement("span");
span.className = "console-formatted-" + type + " source-code";
formatter.call(this, output, span, includePreview);
return span;
},
_formatParameterAsValue: function(val, elem)
{
elem.appendChild(document.createTextNode(val));
},
_formatParameterAsObject: function(obj, elem, includePreview)
{
this._formatParameterAsArrayOrObject(obj, obj.description, elem, includePreview);
},
_formatParameterAsArrayOrObject: function(obj, description, elem, includePreview)
{
var titleElement = document.createElement("span");
if (description)
titleElement.createTextChild(description);
if (includePreview && obj.preview) {
titleElement.addStyleClass("console-object-preview");
var lossless = this._appendObjectPreview(obj, description, titleElement);
if (lossless) {
elem.appendChild(titleElement);
return;
}
}
var section = new WebInspector.ObjectPropertiesSection(obj, titleElement);
section.enableContextMenu();
elem.appendChild(section.element);
},
_appendObjectPreview: function(obj, description, titleElement)
{
var preview = obj.preview;
var isArray = obj.subtype === "array";
if (description)
titleElement.createTextChild(" ");
titleElement.createTextChild(isArray ? "[" : "{");
for (var i = 0; i < preview.properties.length; ++i) {
if (i > 0)
titleElement.createTextChild(", ");
var property = preview.properties[i];
if (!isArray || property.name != i) {
titleElement.createChild("span", "name").textContent = property.name;
titleElement.createTextChild(": ");
}
var span = titleElement.createChild("span", "console-formatted-" + property.type);
if (property.type === "object") {
if (property.subtype === "node")
span.addStyleClass("console-formatted-preview-node");
else if (property.subtype === "regexp")
span.addStyleClass("console-formatted-string");
}
span.textContent = property.value;
}
if (preview.overflow)
titleElement.createChild("span").textContent = "\u2026";
titleElement.createTextChild(isArray ? "]" : "}");
return preview.lossless;
},
_formatParameterAsNode: function(object, elem)
{
function printNode(nodeId)
{
if (!nodeId) {
this._formatParameterAsObject(object, elem, false);
return;
}
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.setVisible(true);
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
if (!treeOutline.children[0].hasChildren)
treeOutline.element.addStyleClass("single-node");
elem.appendChild(treeOutline.element);
treeOutline.element.treeElementForTest = treeOutline.children[0];
}
object.pushNodeToFrontend(printNode.bind(this));
},
_formatParameterAsArray: function(array, elem)
{
if (array.preview) {
this._formatParameterAsArrayOrObject(array, "", elem, true);
return;
}
const maxFlatArrayLength = 100;
if (this._isOutdated || array.arrayLength() > maxFlatArrayLength)
this._formatParameterAsObject(array, elem, false);
else
array.getOwnProperties(this._printArray.bind(this, array, elem));
},
_formatParameterAsString: function(output, elem)
{
var span = document.createElement("span");
span.className = "console-formatted-string source-code";
span.appendChild(WebInspector.linkifyStringAsFragment(output.description));
elem.removeStyleClass("console-formatted-string");
elem.appendChild(document.createTextNode("\""));
elem.appendChild(span);
elem.appendChild(document.createTextNode("\""));
},
_printArray: function(array, elem, properties)
{
if (!properties)
return;
var elements = [];
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
var name = property.name;
if (!isNaN(name))
elements[name] = this._formatAsArrayEntry(property.value);
}
elem.appendChild(document.createTextNode("["));
var lastNonEmptyIndex = -1;
function appendUndefined(elem, index)
{
if (index - lastNonEmptyIndex <= 1)
return;
var span = elem.createChild(span, "console-formatted-undefined");
span.textContent = WebInspector.UIString("undefined × %d", index - lastNonEmptyIndex - 1);
}
var length = array.arrayLength();
for (var i = 0; i < length; ++i) {
var element = elements[i];
if (!element)
continue;
if (i - lastNonEmptyIndex > 1) {
appendUndefined(elem, i);
elem.appendChild(document.createTextNode(", "));
}
elem.appendChild(element);
lastNonEmptyIndex = i;
if (i < length - 1)
elem.appendChild(document.createTextNode(", "));
}
appendUndefined(elem, length);
elem.appendChild(document.createTextNode("]"));
},
_formatAsArrayEntry: function(output)
{
return this._formatParameter(output, output.subtype && output.subtype === "array", false);
},
_formatWithSubstitutionString: function(parameters, formattedResult)
{
var formatters = {}
function parameterFormatter(force, obj)
{
return this._formatParameter(obj, force, false);
}
function valueFormatter(obj)
{
return obj.description;
}
formatters.o = parameterFormatter.bind(this, false);
formatters.s = valueFormatter;
formatters.f = valueFormatter;
formatters.i = valueFormatter;
formatters.d = valueFormatter;
formatters.O = parameterFormatter.bind(this, true);
function append(a, b)
{
if (!(b instanceof Node))
a.appendChild(WebInspector.linkifyStringAsFragment(b.toString()));
else
a.appendChild(b);
return a;
}
return String.format(parameters[0].description, parameters.slice(1), formatters, formattedResult, append);
},
clearHighlight: function()
{
if (!this._formattedMessage)
return;
var highlightedMessage = this._formattedMessage;
delete this._formattedMessage;
delete this._anchorElement;
delete this._messageElement;
this._formatMessage();
this._element.replaceChild(this._formattedMessage, highlightedMessage);
},
highlightSearchResults: function(regexObject)
{
if (!this._formattedMessage)
return;
this._highlightSearchResultsInElement(regexObject, this._messageElement);
if (this._anchorElement)
this._highlightSearchResultsInElement(regexObject, this._anchorElement);
this._element.scrollIntoViewIfNeeded();
},
_highlightSearchResultsInElement: function(regexObject, element)
{
regexObject.lastIndex = 0;
var text = element.textContent;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(element, matchRanges);
},
matchesRegex: function(regexObject)
{
return regexObject.test(this._message) || (this._anchorElement && regexObject.test(this._anchorElement.textContent));
},
toMessageElement: function()
{
if (this._element)
return this._element;
var element = document.createElement("div");
element.message = this;
element.className = "console-message";
this._element = element;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
element.addStyleClass("console-tip-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
element.addStyleClass("console-log-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
element.addStyleClass("console-debug-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
element.addStyleClass("console-warning-level");
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
element.addStyleClass("console-error-level");
break;
}
if (this.type === WebInspector.ConsoleMessage.MessageType.StartGroup || this.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
element.addStyleClass("console-group-title");
element.appendChild(this.formattedMessage);
if (this.repeatCount > 1)
this.updateRepeatCount();
return element;
},
_populateStackTraceTreeElement: function(parentTreeElement)
{
for (var i = 0; i < this._stackTrace.length; i++) {
var frame = this._stackTrace[i];
var content = document.createElement("div");
var messageTextElement = document.createElement("span");
messageTextElement.className = "console-message-text source-code";
var functionName = frame.functionName || WebInspector.UIString("(anonymous function)");
messageTextElement.appendChild(document.createTextNode(functionName));
content.appendChild(messageTextElement);
if (frame.url) {
content.appendChild(document.createTextNode(" "));
var urlElement = this._linkifyCallFrame(frame);
content.appendChild(urlElement);
}
var treeElement = new TreeElement(content);
parentTreeElement.appendChild(treeElement);
}
},
updateRepeatCount: function() {
if (!this.repeatCountElement) {
this.repeatCountElement = document.createElement("span");
this.repeatCountElement.className = "bubble";
this._element.insertBefore(this.repeatCountElement, this._element.firstChild);
this._element.addStyleClass("repeated-message");
}
this.repeatCountElement.textContent = this.repeatCount;
},
toString: function()
{
var sourceString;
switch (this.source) {
case WebInspector.ConsoleMessage.MessageSource.HTML:
sourceString = "HTML";
break;
case WebInspector.ConsoleMessage.MessageSource.XML:
sourceString = "XML";
break;
case WebInspector.ConsoleMessage.MessageSource.JS:
sourceString = "JS";
break;
case WebInspector.ConsoleMessage.MessageSource.Network:
sourceString = "Network";
break;
case WebInspector.ConsoleMessage.MessageSource.ConsoleAPI:
sourceString = "ConsoleAPI";
break;
case WebInspector.ConsoleMessage.MessageSource.Other:
sourceString = "Other";
break;
}
var typeString;
switch (this.type) {
case WebInspector.ConsoleMessage.MessageType.Log:
typeString = "Log";
break;
case WebInspector.ConsoleMessage.MessageType.Dir:
typeString = "Dir";
break;
case WebInspector.ConsoleMessage.MessageType.DirXML:
typeString = "Dir XML";
break;
case WebInspector.ConsoleMessage.MessageType.Trace:
typeString = "Trace";
break;
case WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed:
case WebInspector.ConsoleMessage.MessageType.StartGroup:
typeString = "Start Group";
break;
case WebInspector.ConsoleMessage.MessageType.EndGroup:
typeString = "End Group";
break;
case WebInspector.ConsoleMessage.MessageType.Assert:
typeString = "Assert";
break;
case WebInspector.ConsoleMessage.MessageType.Result:
typeString = "Result";
break;
}
var levelString;
switch (this.level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
levelString = "Tip";
break;
case WebInspector.ConsoleMessage.MessageLevel.Log:
levelString = "Log";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
levelString = "Warning";
break;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
levelString = "Debug";
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
levelString = "Error";
break;
}
return sourceString + " " + typeString + " " + levelString + ": " + this.formattedMessage.textContent + "\n" + this.url + " line " + this.line;
},
get text()
{
return this._messageText;
},
location: function()
{
var lineNumber = this.stackTrace ? this.stackTrace[0].lineNumber - 1 : this.line - 1;
var columnNumber = this.stackTrace && this.stackTrace[0].columnNumber ? this.stackTrace[0].columnNumber - 1 : 0;
return WebInspector.debuggerModel.createRawLocationByURL(this.url, lineNumber, columnNumber);
},
isEqual: function(msg)
{
if (!msg)
return false;
if (this._stackTrace) {
if (!msg._stackTrace)
return false;
var l = this._stackTrace;
var r = msg._stackTrace;
for (var i = 0; i < l.length; i++) {
if (l[i].url !== r[i].url ||
l[i].functionName !== r[i].functionName ||
l[i].lineNumber !== r[i].lineNumber ||
l[i].columnNumber !== r[i].columnNumber)
return false;
}
}
return (this.source === msg.source)
&& (this.type === msg.type)
&& (this.level === msg.level)
&& (this.line === msg.line)
&& (this.url === msg.url)
&& (this.message === msg.message)
&& (this._request === msg._request);
},
get stackTrace()
{
return this._stackTrace;
},
clone: function()
{
return WebInspector.ConsoleMessage.create(this.source, this.level, this._messageText, this.type, this.url, this.line, this.repeatCount, this._parameters, this._stackTrace, this._request ? this._request.requestId : undefined, this._isOutdated);
}
}
WebInspector.ConsoleMessageImpl.prototype.__proto__ = WebInspector.ConsoleMessage.prototype;
const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>";
WebInspector.ConsoleView = function(hideContextSelector)
{
WebInspector.View.call(this);
this.element.id = "console-view";
this.messages = [];
this._clearConsoleButton = new WebInspector.StatusBarButton(WebInspector.UIString("Clear console log."), "clear-status-bar-item");
this._clearConsoleButton.addEventListener("click", this._requestClearMessages, this);
this._frameSelector = new WebInspector.StatusBarComboBox(this._frameChanged.bind(this), "console-context");
this._contextSelector = new WebInspector.StatusBarComboBox(this._contextChanged.bind(this), "console-context");
if (hideContextSelector) {
this._frameSelector.element.addStyleClass("hidden");
this._contextSelector.element.addStyleClass("hidden");
}
this.messagesElement = document.createElement("div");
this.messagesElement.id = "console-messages";
this.messagesElement.className = "monospace";
this.messagesElement.addEventListener("click", this._messagesClicked.bind(this), true);
this.element.appendChild(this.messagesElement);
this._scrolledToBottom = true;
this.promptElement = document.createElement("div");
this.promptElement.id = "console-prompt";
this.promptElement.className = "source-code";
this.promptElement.spellcheck = false;
this.messagesElement.appendChild(this.promptElement);
this.messagesElement.appendChild(document.createElement("br"));
this.topGroup = new WebInspector.ConsoleGroup(null);
this.messagesElement.insertBefore(this.topGroup.element, this.promptElement);
this.currentGroup = this.topGroup;
this._filterBarElement = document.createElement("div");
this._filterBarElement.className = "scope-bar status-bar-item";
function createDividerElement()
{
var dividerElement = document.createElement("div");
dividerElement.addStyleClass("scope-bar-divider");
this._filterBarElement.appendChild(dividerElement);
}
var updateFilterHandler = this._updateFilter.bind(this);
function createFilterElement(category, label)
{
var categoryElement = document.createElement("li");
categoryElement.category = category;
categoryElement.className = category;
categoryElement.addEventListener("click", updateFilterHandler, false);
categoryElement.textContent = label;
this._filterBarElement.appendChild(categoryElement);
return categoryElement;
}
this.allElement = createFilterElement.call(this, "all", WebInspector.UIString("All"));
createDividerElement.call(this);
this.errorElement = createFilterElement.call(this, "errors", WebInspector.UIString("Errors"));
this.warningElement = createFilterElement.call(this, "warnings", WebInspector.UIString("Warnings"));
this.logElement = createFilterElement.call(this, "logs", WebInspector.UIString("Logs"));
this.filter(this.allElement, false);
this._registerShortcuts();
this.registerRequiredCSS("textPrompt.css");
this.messagesElement.addEventListener("contextmenu", this._handleContextMenuEvent.bind(this), false);
WebInspector.settings.monitoringXHREnabled.addChangeListener(this._monitoringXHREnabledSettingChanged.bind(this));
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
this._linkifier = new WebInspector.Linkifier();
this.prompt = new WebInspector.TextPromptWithHistory(this.completionsForTextPrompt.bind(this), ExpressionStopCharacters + ".");
this.prompt.setSuggestBoxEnabled("generic-suggest");
this.prompt.renderAsBlock();
this.prompt.attach(this.promptElement);
this.prompt.proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this), false);
this.prompt.setHistoryData(WebInspector.settings.consoleHistory.get());
WebInspector.runtimeModel.contextLists().forEach(this._addFrame, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListAdded, this._frameAdded, this);
WebInspector.runtimeModel.addEventListener(WebInspector.RuntimeModel.Events.FrameExecutionContextListRemoved, this._frameRemoved, this);
}
WebInspector.ConsoleView.Events = {
ConsoleCleared: "console-cleared",
EntryAdded: "console-entry-added",
}
WebInspector.ConsoleView.prototype = {
get statusBarItems()
{
return [this._clearConsoleButton.element, this._frameSelector.element, this._contextSelector.element, this._filterBarElement];
},
_frameAdded: function(event)
{
var contextList = event.data;
this._addFrame(contextList);
},
_addFrame: function(contextList)
{
var option = document.createElement("option");
option.text = contextList.displayName;
option.title = contextList.url;
option._contextList = contextList;
contextList._consoleOption = option;
this._frameSelector.addOption(option);
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextsUpdated, this._frameUpdated, this);
contextList.addEventListener(WebInspector.FrameExecutionContextList.EventTypes.ContextAdded, this._contextAdded, this);
this._frameChanged();
},
_frameRemoved: function(event)
{
var contextList = event.data;
this._frameSelector.removeOption(contextList._consoleOption);
this._frameChanged();
},
_frameChanged: function()
{
var context = this._currentFrame();
if (!context) {
delete this._currentExecutionContext;
this._contextSelector.element.addStyleClass("hidden");
return;
}
var executionContexts = context.executionContexts();
if (executionContexts.length)
this._currentExecutionContext = executionContexts[0];
if (executionContexts.length === 1) {
this._contextSelector.element.addStyleClass("hidden");
return;
}
this._contextSelector.element.removeStyleClass("hidden");
this._contextSelector.removeOptions();
for (var i = 0; i < executionContexts.length; i++)
this._appendContextOption(executionContexts[i]);
},
_appendContextOption: function(executionContext)
{
if (!this._currentExecutionContext)
this._currentExecutionContext = executionContext;
var option = document.createElement("option");
option.text = executionContext.name;
option.title = executionContext.id;
option._executionContext = executionContext;
this._contextSelector.addOption(option);
},
_contextChanged: function(event)
{
var option = this._contextSelector.selectedOption();
this._currentExecutionContext = option ? option._executionContext : undefined;
},
_frameUpdated: function(event)
{
var contextList = event.data;
var option = contextList._consoleOption;
option.text = contextList.displayName;
option.title = contextList.url;
},
_contextAdded: function(event)
{
var contextList = event.data;
if (contextList === this._currentFrame())
this._frameChanged();
},
_currentFrame: function()
{
var option = this._frameSelector.selectedOption();
return option ? option._contextList : undefined;
},
_updateFilter: function(e)
{
var isMac = WebInspector.isMac();
var selectMultiple = false;
if (isMac && e.metaKey && !e.ctrlKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
if (!isMac && e.ctrlKey && !e.metaKey && !e.altKey && !e.shiftKey)
selectMultiple = true;
this.filter(e.target, selectMultiple);
},
filter: function(target, selectMultiple)
{
function unselectAll()
{
this.allElement.removeStyleClass("selected");
this.errorElement.removeStyleClass("selected");
this.warningElement.removeStyleClass("selected");
this.logElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
this.messagesElement.removeStyleClass("filter-errors");
this.messagesElement.removeStyleClass("filter-warnings");
this.messagesElement.removeStyleClass("filter-logs");
}
var targetFilterClass = "filter-" + target.category;
if (target.category === "all") {
if (target.hasStyleClass("selected")) {
return;
}
unselectAll.call(this);
} else {
if (this.allElement.hasStyleClass("selected")) {
this.allElement.removeStyleClass("selected");
this.messagesElement.removeStyleClass("filter-all");
}
}
if (!selectMultiple) {
unselectAll.call(this);
target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
return;
}
if (target.hasStyleClass("selected")) {
target.removeStyleClass("selected");
this.messagesElement.removeStyleClass(targetFilterClass);
} else {
target.addStyleClass("selected");
this.messagesElement.addStyleClass(targetFilterClass);
}
},
willHide: function()
{
this.prompt.hideSuggestBox();
this.prompt.clearAutoComplete(true);
},
wasShown: function()
{
if (!this.prompt.isCaretInsidePrompt())
this.prompt.moveCaretToEndOfPrompt();
},
afterShow: function()
{
WebInspector.setCurrentFocusElement(this.promptElement);
},
storeScrollPositions: function()
{
WebInspector.View.prototype.storeScrollPositions.call(this);
this._scrolledToBottom = this.messagesElement.isScrolledToBottom();
},
restoreScrollPositions: function()
{
if (this._scrolledToBottom)
this._immediatelyScrollIntoView();
else
WebInspector.View.prototype.restoreScrollPositions.call(this);
},
onResize: function()
{
this.restoreScrollPositions();
},
_isScrollIntoViewScheduled: function()
{
return !!this._scrollIntoViewTimer;
},
_scheduleScrollIntoView: function()
{
if (this._scrollIntoViewTimer)
return;
function scrollIntoView()
{
delete this._scrollIntoViewTimer;
this.promptElement.scrollIntoView(true);
}
this._scrollIntoViewTimer = setTimeout(scrollIntoView.bind(this), 20);
},
_immediatelyScrollIntoView: function()
{
this.promptElement.scrollIntoView(true);
this._cancelScheduledScrollIntoView();
},
_cancelScheduledScrollIntoView: function()
{
if (!this._isScrollIntoViewScheduled())
return;
clearTimeout(this._scrollIntoViewTimer);
delete this._scrollIntoViewTimer;
},
_consoleMessageAdded: function(event)
{
this._appendConsoleMessage(event.data);
},
_appendConsoleMessage: function(msg)
{
if (!this._isScrollIntoViewScheduled() && ((msg instanceof WebInspector.ConsoleCommandResult) || this.messagesElement.isScrolledToBottom()))
this._scheduleScrollIntoView();
this.messages.push(msg);
if (msg.type === WebInspector.ConsoleMessage.MessageType.EndGroup) {
var parentGroup = this.currentGroup.parentGroup
if (parentGroup)
this.currentGroup = parentGroup;
} else {
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
var group = new WebInspector.ConsoleGroup(this.currentGroup);
this.currentGroup.messagesElement.appendChild(group.element);
this.currentGroup = group;
}
this.currentGroup.addMessage(msg);
}
this.dispatchEventToListeners(WebInspector.ConsoleView.Events.EntryAdded, msg);
},
_consoleCleared: function()
{
this._scrolledToBottom = true;
this.messages = [];
this.currentGroup = this.topGroup;
this.topGroup.messagesElement.removeChildren();
this.dispatchEventToListeners(WebInspector.ConsoleView.Events.ConsoleCleared);
this._linkifier.reset();
},
completionsForTextPrompt: function(textPrompt, wordRange, force, completionsReadyCallback)
{
var expressionRange = wordRange.startContainer.rangeOfWord(wordRange.startOffset, ExpressionStopCharacters, textPrompt.proxyElement, "backward");
var expressionString = expressionRange.toString();
var prefix = wordRange.toString();
this.completionsForExpression(expressionString, prefix, force, completionsReadyCallback);
},
completionsForExpression: function(expressionString, prefix, force, completionsReadyCallback)
{
var lastIndex = expressionString.length - 1;
var dotNotation = (expressionString[lastIndex] === ".");
var bracketNotation = (expressionString[lastIndex] === "[");
if (dotNotation || bracketNotation)
expressionString = expressionString.substr(0, lastIndex);
if (expressionString && parseInt(expressionString, 10) == expressionString) {
completionsReadyCallback([]);
return;
}
if (!prefix && !expressionString && !force) {
completionsReadyCallback([]);
return;
}
if (!expressionString && WebInspector.debuggerModel.selectedCallFrame())
WebInspector.debuggerModel.getSelectedCallFrameVariables(receivedPropertyNames.bind(this));
else
this.evalInInspectedWindow(expressionString, "completion", true, true, false, evaluated.bind(this));
function evaluated(result, wasThrown)
{
if (!result || wasThrown) {
completionsReadyCallback([]);
return;
}
function getCompletions(primitiveType)
{
var object;
if (primitiveType === "string")
object = new String("");
else if (primitiveType === "number")
object = new Number(0);
else if (primitiveType === "boolean")
object = new Boolean(false);
else
object = this;
var resultSet = {};
for (var o = object; o; o = o.__proto__) {
try {
var names = Object.getOwnPropertyNames(o);
for (var i = 0; i < names.length; ++i)
resultSet[names[i]] = true;
} catch (e) {
}
}
return resultSet;
}
if (result.type === "object" || result.type === "function")
result.callFunctionJSON(getCompletions, undefined, receivedPropertyNames.bind(this));
else if (result.type === "string" || result.type === "number" || result.type === "boolean")
this.evalInInspectedWindow("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, receivedPropertyNamesFromEval.bind(this));
}
function receivedPropertyNamesFromEval(notRelevant, wasThrown, result)
{
if (result && !wasThrown)
receivedPropertyNames.call(this, result.value);
else
completionsReadyCallback([]);
}
function receivedPropertyNames(propertyNames)
{
RuntimeAgent.releaseObjectGroup("completion");
if (!propertyNames) {
completionsReadyCallback([]);
return;
}
var includeCommandLineAPI = (!dotNotation && !bracketNotation);
if (includeCommandLineAPI) {
const commandLineAPI = ["dir", "dirxml", "keys", "values", "profile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clear"];
for (var i = 0; i < commandLineAPI.length; ++i)
propertyNames[commandLineAPI[i]] = true;
}
this._reportCompletions(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, Object.keys(propertyNames));
}
},
_reportCompletions: function(completionsReadyCallback, dotNotation, bracketNotation, expressionString, prefix, properties) {
if (bracketNotation) {
if (prefix.length && prefix[0] === "'")
var quoteUsed = "'";
else
var quoteUsed = "\"";
}
var results = [];
if (!expressionString) {
const keywords = ["break", "case", "catch", "continue", "default", "delete", "do", "else", "finally", "for", "function", "if", "in",
"instanceof", "new", "return", "switch", "this", "throw", "try", "typeof", "var", "void", "while", "with"];
properties = properties.concat(keywords);
}
properties.sort();
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (dotNotation && !/^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(property))
continue;
if (bracketNotation) {
if (!/^[0-9]+$/.test(property))
property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
property += "]";
}
if (property.length < prefix.length)
continue;
if (prefix.length && !property.startsWith(prefix))
continue;
results.push(property);
}
completionsReadyCallback(results);
},
_handleContextMenuEvent: function(event)
{
if (!window.getSelection().isCollapsed) {
return;
}
if (event.target.enclosingNodeOrSelfWithNodeName("a"))
return;
var contextMenu = new WebInspector.ContextMenu();
function monitoringXHRItemAction()
{
WebInspector.settings.monitoringXHREnabled.set(!WebInspector.settings.monitoringXHREnabled.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString("Log XMLHttpRequests"), monitoringXHRItemAction.bind(this), WebInspector.settings.monitoringXHREnabled.get());
function preserveLogItemAction()
{
WebInspector.settings.preserveConsoleLog.set(!WebInspector.settings.preserveConsoleLog.get());
}
contextMenu.appendCheckboxItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Preserve log upon navigation" : "Preserve Log upon Navigation"), preserveLogItemAction.bind(this), WebInspector.settings.preserveConsoleLog.get());
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Clear console" : "Clear Console"), this._requestClearMessages.bind(this));
contextMenu.show(event);
},
_monitoringXHREnabledSettingChanged: function(event)
{
ConsoleAgent.setMonitoringXHREnabled(event.data);
},
_messagesClicked: function(event)
{
if (!this.prompt.isCaretInsidePrompt() && window.getSelection().isCollapsed)
this.prompt.moveCaretToEndOfPrompt();
},
_registerShortcuts: function()
{
this._shortcuts = {};
var shortcut = WebInspector.KeyboardShortcut;
if (WebInspector.isMac()) {
var shortcutK = shortcut.makeDescriptor("k", WebInspector.KeyboardShortcut.Modifiers.Meta);
this._shortcuts[shortcutK.key] = this._requestClearMessages.bind(this);
}
var shortcutL = shortcut.makeDescriptor("l", WebInspector.KeyboardShortcut.Modifiers.Ctrl);
this._shortcuts[shortcutL.key] = this._requestClearMessages.bind(this);
var shortcutM = shortcut.makeDescriptor("m", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta | WebInspector.KeyboardShortcut.Modifiers.Shift);
this._shortcuts[shortcutM.key] = this._dumpMemory.bind(this);
var section = WebInspector.shortcutsScreen.section(WebInspector.UIString("Console"));
var keys = WebInspector.isMac() ? [ shortcutK.name, shortcutL.name ] : [ shortcutL.name ];
section.addAlternateKeys(keys, WebInspector.UIString("Clear console"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Tab),
shortcut.shortcutToString(shortcut.Keys.Tab, shortcut.Modifiers.Shift)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous suggestion"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Right), WebInspector.UIString("Accept suggestion"));
keys = [
shortcut.shortcutToString(shortcut.Keys.Down),
shortcut.shortcutToString(shortcut.Keys.Up)
];
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous line"));
keys = [
shortcut.shortcutToString("N", shortcut.Modifiers.Alt),
shortcut.shortcutToString("P", shortcut.Modifiers.Alt)
];
if (WebInspector.isMac())
section.addRelatedKeys(keys, WebInspector.UIString("Next/previous command"));
section.addKey(shortcut.shortcutToString(shortcut.Keys.Enter), WebInspector.UIString("Execute command"));
},
_requestClearMessages: function()
{
WebInspector.console.requestClearMessages();
},
_promptKeyDown: function(event)
{
if (isEnterKey(event)) {
this._enterKeyPressed(event);
return;
}
var shortcut = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcut];
if (handler) {
handler();
event.preventDefault();
return;
}
},
evalInInspectedWindow: function(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback)
{
if (WebInspector.debuggerModel.selectedCallFrame()) {
WebInspector.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, returnByValue, callback);
return;
}
if (!expression) {
expression = "this";
}
function evalCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
callback(null, false);
return;
}
if (returnByValue)
callback(null, !!wasThrown, wasThrown ? null : result);
else
callback(WebInspector.RemoteObject.fromPayload(result), !!wasThrown);
}
RuntimeAgent.evaluate(expression, objectGroup, includeCommandLineAPI, doNotPauseOnExceptionsAndMuteConsole, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, returnByValue, evalCallback);
},
evaluateUsingTextPrompt: function(expression, showResultOnly)
{
this._appendCommand(expression, this.prompt.text, false, showResultOnly);
},
_enterKeyPressed: function(event)
{
if (event.altKey || event.ctrlKey || event.shiftKey)
return;
event.consume(true);
this.prompt.clearAutoComplete(true);
var str = this.prompt.text;
if (!str.length)
return;
this._appendCommand(str, "", true, false);
},
runScript: function(scriptId)
{
DebuggerAgent.runScript(scriptId, this._currentExecutionContext ? this._currentExecutionContext.id : undefined, "console", false, runCallback.bind(this));
WebInspector.userMetrics.ConsoleEvaluated.record();
function runCallback(error, result, wasThrown)
{
if (error) {
console.error(error);
return;
}
this._printResult(result, wasThrown, null);
}
},
_printResult: function(result, wasThrown, originatingCommand)
{
if (!result)
return;
this._appendConsoleMessage(new WebInspector.ConsoleCommandResult(result, wasThrown, originatingCommand, this._linkifier));
},
_appendCommand: function(text, newPromptText, useCommandLineAPI, showResultOnly)
{
if (!showResultOnly) {
var commandMessage = new WebInspector.ConsoleCommand(text);
WebInspector.console.interruptRepeatCount();
this._appendConsoleMessage(commandMessage);
}
this.prompt.text = newPromptText;
function printResult(result, wasThrown)
{
if (!result)
return;
if (!showResultOnly) {
this.prompt.pushHistoryItem(text);
WebInspector.settings.consoleHistory.set(this.prompt.historyData.slice(-30));
}
this._printResult(result, wasThrown, commandMessage);
}
this.evalInInspectedWindow(text, "console", useCommandLineAPI, false, false, printResult.bind(this));
WebInspector.userMetrics.ConsoleEvaluated.record();
},
elementsToRestoreScrollPositionsFor: function()
{
return [this.messagesElement];
},
_dumpMemory: function()
{
function comparator(a, b)
{
if (a.size < b.size)
return 1;
if (a.size > b.size)
return -1;
return a.title.localeCompare(b.title);
}
function callback(error, groups)
{
var titles = [];
groups.sort(comparator);
for (var i = 0; i < groups.length; ++i) {
var suffix = groups[i].size > 0 ? " [" + groups[i].size + "]" : "";
titles.push(groups[i].title + suffix + (groups[i].documentURI ? " (" + groups[i].documentURI + ")" : ""));
}
var counter = 1;
var previousTitle = null;
for (var i = 0; i < titles.length; ++i) {
var title = titles[i];
if (title === previousTitle) {
counter++;
continue;
}
if (previousTitle)
WebInspector.log(counter > 1 ? counter + " x " + previousTitle : previousTitle);
previousTitle = title;
counter = 1;
}
WebInspector.log(counter > 1 ? counter + " x " + previousTitle : previousTitle);
}
MemoryAgent.getDOMNodeCount(callback);
}
}
WebInspector.ConsoleView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ConsoleCommand = function(command)
{
this.command = command;
}
WebInspector.ConsoleCommand.prototype = {
clearHighlight: function()
{
var highlightedMessage = this._formattedCommand;
delete this._formattedCommand;
this._formatCommand();
this._element.replaceChild(this._formattedCommand, highlightedMessage);
},
highlightSearchResults: function(regexObject)
{
regexObject.lastIndex = 0;
var text = this.command;
var match = regexObject.exec(text);
var offset = 0;
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
WebInspector.highlightSearchResults(this._formattedCommand, matchRanges);
this._element.scrollIntoViewIfNeeded();
},
matchesRegex: function(regexObject)
{
return regexObject.test(this.command);
},
toMessageElement: function()
{
if (!this._element) {
this._element = document.createElement("div");
this._element.command = this;
this._element.className = "console-user-command";
this._formatCommand();
this._element.appendChild(this._formattedCommand);
}
return this._element;
},
_formatCommand: function()
{
this._formattedCommand = document.createElement("span");
this._formattedCommand.className = "console-message-text source-code";
this._formattedCommand.textContent = this.command;
},
}
WebInspector.ConsoleCommandResult = function(result, wasThrown, originatingCommand, linkifier)
{
var level = (wasThrown ? WebInspector.ConsoleMessage.MessageLevel.Error : WebInspector.ConsoleMessage.MessageLevel.Log);
this.originatingCommand = originatingCommand;
WebInspector.ConsoleMessageImpl.call(this, WebInspector.ConsoleMessage.MessageSource.JS, level, "", linkifier, WebInspector.ConsoleMessage.MessageType.Result, undefined, undefined, undefined, [result]);
}
WebInspector.ConsoleCommandResult.prototype = {
toMessageElement: function()
{
var element = WebInspector.ConsoleMessageImpl.prototype.toMessageElement.call(this);
element.addStyleClass("console-user-command-result");
return element;
}
}
WebInspector.ConsoleCommandResult.prototype.__proto__ = WebInspector.ConsoleMessageImpl.prototype;
WebInspector.ConsoleGroup = function(parentGroup)
{
this.parentGroup = parentGroup;
var element = document.createElement("div");
element.className = "console-group";
element.group = this;
this.element = element;
if (parentGroup) {
var bracketElement = document.createElement("div");
bracketElement.className = "console-group-bracket";
element.appendChild(bracketElement);
}
var messagesElement = document.createElement("div");
messagesElement.className = "console-group-messages";
element.appendChild(messagesElement);
this.messagesElement = messagesElement;
}
WebInspector.ConsoleGroup.prototype = {
addMessage: function(msg)
{
var element = msg.toMessageElement();
if (msg.type === WebInspector.ConsoleMessage.MessageType.StartGroup || msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed) {
this.messagesElement.parentNode.insertBefore(element, this.messagesElement);
element.addEventListener("click", this._titleClicked.bind(this), false);
var groupElement = element.enclosingNodeOrSelfWithClass("console-group");
if (groupElement && msg.type === WebInspector.ConsoleMessage.MessageType.StartGroupCollapsed)
groupElement.addStyleClass("collapsed");
} else
this.messagesElement.appendChild(element);
if (element.previousSibling && msg.originatingCommand && element.previousSibling.command === msg.originatingCommand)
element.previousSibling.addStyleClass("console-adjacent-user-command-result");
},
_titleClicked: function(event)
{
var groupTitleElement = event.target.enclosingNodeOrSelfWithClass("console-group-title");
if (groupTitleElement) {
var groupElement = groupTitleElement.enclosingNodeOrSelfWithClass("console-group");
if (groupElement)
if (groupElement.hasStyleClass("collapsed"))
groupElement.removeStyleClass("collapsed");
else
groupElement.addStyleClass("collapsed");
groupTitleElement.scrollIntoViewIfNeeded(true);
}
event.consume(true);
}
}
WebInspector.consoleView = null;
WebInspector.ConsoleMessage.create = function(source, level, message, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated)
{
return new WebInspector.ConsoleMessageImpl(source, level, message, WebInspector.consoleView._linkifier, type, url, line, repeatCount, parameters, stackTrace, requestId, isOutdated);
}
WebInspector.Panel = function(name)
{
WebInspector.View.call(this);
WebInspector.panels[name] = this;
this.element.addStyleClass("panel");
this.element.addStyleClass(name);
this._panelName = name;
this._shortcuts = {};
WebInspector.settings[this._sidebarWidthSettingName()] = WebInspector.settings.createSetting(this._sidebarWidthSettingName(), undefined);
}
WebInspector.Panel.counterRightMargin = 25;
WebInspector.Panel.prototype = {
get name()
{
return this._panelName;
},
show: function()
{
WebInspector.View.prototype.show.call(this, WebInspector.inspectorView.panelsElement());
},
wasShown: function()
{
var statusBarItems = this.statusBarItems;
if (statusBarItems) {
this._statusBarItemContainer = document.createElement("div");
for (var i = 0; i < statusBarItems.length; ++i)
this._statusBarItemContainer.appendChild(statusBarItems[i]);
document.getElementById("panel-status-bar").appendChild(this._statusBarItemContainer);
}
this.focus();
},
willHide: function()
{
if (this._statusBarItemContainer && this._statusBarItemContainer.parentNode)
this._statusBarItemContainer.parentNode.removeChild(this._statusBarItemContainer);
delete this._statusBarItemContainer;
},
reset: function()
{
this.searchCanceled();
},
defaultFocusedElement: function()
{
return this.sidebarTreeElement || this.element;
},
searchCanceled: function()
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
},
performSearch: function(query)
{
this.searchCanceled();
},
jumpToNextSearchResult: function()
{
},
jumpToPreviousSearchResult: function()
{
},
canSearchAndReplace: function()
{
return false;
},
replaceSelectionWith: function(text)
{
},
replaceAllWith: function(query, text)
{
},
canFilter: function()
{
return false;
},
performFilter: function(query)
{
},
createSplitView: function(parentElement, position, defaultWidth)
{
if (this.splitView)
return;
if (!parentElement)
parentElement = this.element;
this.splitView = new WebInspector.SplitView(position || WebInspector.SplitView.SidebarPosition.Left, this._sidebarWidthSettingName(), defaultWidth);
this.splitView.show(parentElement);
this.splitView.addEventListener(WebInspector.SplitView.EventTypes.Resized, this.sidebarResized.bind(this));
this.sidebarElement = this.splitView.sidebarElement;
},
createSplitViewWithSidebarTree: function(parentElement, position, defaultWidth)
{
if (this.splitView)
return;
this.createSplitView(parentElement, position);
this.sidebarTreeElement = document.createElement("ol");
this.sidebarTreeElement.className = "sidebar-tree";
this.splitView.sidebarElement.appendChild(this.sidebarTreeElement);
this.splitView.sidebarElement.addStyleClass("sidebar");
this.sidebarTree = new TreeOutline(this.sidebarTreeElement);
this.sidebarTree.panel = this;
},
_sidebarWidthSettingName: function()
{
return this._panelName + "SidebarWidth";
},
get statusBarItems()
{
},
sidebarResized: function(width)
{
},
statusBarResized: function()
{
},
canShowAnchorLocation: function(anchor)
{
return false;
},
showAnchorLocation: function(anchor)
{
},
elementsToRestoreScrollPositionsFor: function()
{
return [];
},
handleShortcut: function(event)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(event);
var handler = this._shortcuts[shortcutKey];
if (handler) {
handler(event);
event.handled = true;
}
},
registerShortcut: function(key, handler)
{
this._shortcuts[key] = handler;
},
unregisterShortcut: function(key)
{
delete this._shortcuts[key];
}
}
WebInspector.Panel.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.PanelDescriptor = function(name, title, className, scriptName, panel)
{
this._name = name;
this._title = title;
this._className = className;
this._scriptName = scriptName;
this._panel = panel;
}
WebInspector.PanelDescriptor.prototype = {
name: function()
{
return this._name;
},
title: function()
{
return this._title;
},
iconURL: function()
{
return this._iconURL;
},
setIconURL: function(iconURL)
{
this._iconURL = iconURL;
},
panel: function()
{
if (this._panel)
return this._panel;
if (this._scriptName)
importScript(this._scriptName);
this._panel = new WebInspector[this._className];
return this._panel;
}
}
WebInspector.InspectorView = function()
{
WebInspector.View.call(this);
this.markAsRoot();
this.element.id = "main-panels";
this.element.setAttribute("spellcheck", false);
this._history = [];
this._historyIterator = -1;
document.addEventListener("keydown", this._keyDown.bind(this), false);
document.addEventListener("keypress", this._keyPress.bind(this), false);
this._panelOrder = [];
this._panelDescriptors = {};
this._openBracketIdentifiers = ["U+005B", "U+00DB"].keySet();
this._closeBracketIdentifiers = ["U+005D", "U+00DD"].keySet();
this._footerElementContainer = this.element.createChild("div", "inspector-footer status-bar hidden");
this._panelsElement = this.element.createChild("div", "fill");
}
WebInspector.InspectorView.Events = {
PanelSelected: "PanelSelected"
}
WebInspector.InspectorView.prototype = {
addPanel: function(panelDescriptor)
{
this._panelOrder.push(panelDescriptor.name());
this._panelDescriptors[panelDescriptor.name()] = panelDescriptor;
WebInspector.toolbar.addPanel(panelDescriptor);
},
panel: function(panelName)
{
var panelDescriptor = this._panelDescriptors[panelName];
if (!panelDescriptor && this._panelOrder.length)
panelDescriptor = this._panelDescriptors[this._panelOrder[0]];
return panelDescriptor ? panelDescriptor.panel() : null;
},
showPanel: function(panelName)
{
var panel = this.panel(panelName);
if (panel)
this.setCurrentPanel(panel);
return panel;
},
currentPanel: function()
{
return this._currentPanel;
},
setCurrentPanel: function(x)
{
if (this._currentPanel === x)
return;
if (this._currentPanel)
this._currentPanel.detach();
this._currentPanel = x;
if (x) {
x.show();
this.dispatchEventToListeners(WebInspector.InspectorView.Events.PanelSelected);
WebInspector.searchController.cancelSearch();
}
for (var panelName in WebInspector.panels) {
if (WebInspector.panels[panelName] === x) {
WebInspector.settings.lastActivePanel.set(panelName);
this._pushToHistory(panelName);
WebInspector.userMetrics.panelShown(panelName);
}
}
},
_keyPress: function(event)
{
clearTimeout(this._keyDownTimer);
delete this._keyDownTimer;
},
_keyDown: function(event)
{
if (!WebInspector.isWin() || (!this._openBracketIdentifiers.hasOwnProperty(event.keyIdentifier) && !this._closeBracketIdentifiers.hasOwnProperty(event.keyIdentifier))) {
this._keyDownInternal(event);
return;
}
this._keyDownTimer = setTimeout(this._keyDownInternal.bind(this, event), 0);
},
_keyDownInternal: function(event)
{
if (this._openBracketIdentifiers.hasOwnProperty(event.keyIdentifier)) {
var isRotateLeft = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && !event.altKey;
if (isRotateLeft) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index === 0) ? this._panelOrder.length - 1 : index - 1;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}
var isGoBack = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && event.altKey;
if (isGoBack && this._canGoBackInHistory()) {
this._goBackInHistory();
event.consume(true);
}
return;
}
if (this._closeBracketIdentifiers.hasOwnProperty(event.keyIdentifier)) {
var isRotateRight = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && !event.shiftKey && !event.altKey;
if (isRotateRight) {
var index = this._panelOrder.indexOf(this.currentPanel().name);
index = (index + 1) % this._panelOrder.length;
this.showPanel(this._panelOrder[index]);
event.consume(true);
return;
}
var isGoForward = WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && event.altKey;
if (isGoForward && this._canGoForwardInHistory()) {
this._goForwardInHistory();
event.consume(true);
}
return;
}
},
_canGoBackInHistory: function()
{
return this._historyIterator > 0;
},
_goBackInHistory: function()
{
this._inHistory = true;
this.setCurrentPanel(WebInspector.panels[this._history[--this._historyIterator]]);
delete this._inHistory;
},
_canGoForwardInHistory: function()
{
return this._historyIterator < this._history.length - 1;
},
_goForwardInHistory: function()
{
this._inHistory = true;
this.setCurrentPanel(WebInspector.panels[this._history[++this._historyIterator]]);
delete this._inHistory;
},
_pushToHistory: function(panelName)
{
if (this._inHistory)
return;
this._history.splice(this._historyIterator + 1, this._history.length - this._historyIterator - 1);
if (!this._history.length || this._history[this._history.length - 1] !== panelName)
this._history.push(panelName);
this._historyIterator = this._history.length - 1;
},
panelsElement: function()
{
return this._panelsElement;
},
setFooterElement: function(element)
{
if (element) {
this._footerElementContainer.removeStyleClass("hidden");
this._footerElementContainer.appendChild(element);
this._panelsElement.style.bottom = this._footerElementContainer.offsetHeight + "px";
} else {
this._footerElementContainer.addStyleClass("hidden");
this._footerElementContainer.removeChildren();
this._panelsElement.style.bottom = 0;
}
this.doResize();
},
showPanelForAnchorNavigation: function(panel)
{
WebInspector.searchController.disableSearchUntilExplicitAction();
this.setCurrentPanel(panel);
}
}
WebInspector.InspectorView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.inspectorView = null;
WebInspector.AdvancedSearchController = function()
{
this._shortcut = WebInspector.AdvancedSearchController.createShortcut();
this._searchId = 0;
WebInspector.settings.advancedSearchConfig = WebInspector.settings.createSetting("advancedSearchConfig", new WebInspector.SearchConfig("", true, false));
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
}
WebInspector.AdvancedSearchController.createShortcut = function()
{
if (WebInspector.isMac())
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Meta | WebInspector.KeyboardShortcut.Modifiers.Alt);
else
return WebInspector.KeyboardShortcut.makeDescriptor("f", WebInspector.KeyboardShortcut.Modifiers.Ctrl | WebInspector.KeyboardShortcut.Modifiers.Shift);
}
WebInspector.AdvancedSearchController.prototype = {
handleShortcut: function(event)
{
if (WebInspector.KeyboardShortcut.makeKeyFromEvent(event) === this._shortcut.key) {
if (!this._searchView || !this._searchView.isShowing() || this._searchView._search !== document.activeElement) {
WebInspector.showPanel("scripts");
this.show();
} else
this.close();
event.consume(true);
return true;
}
return false;
},
_frameNavigated: function()
{
this.resetSearch();
},
registerSearchScope: function(searchScope)
{
this._searchScope = searchScope;
},
show: function()
{
if (!this._searchView)
this._searchView = new WebInspector.SearchView(this);
if (this._searchView.isShowing())
this._searchView.focus();
else
WebInspector.showViewInDrawer(this._searchView._searchPanelElement, this._searchView, this.stopSearch.bind(this));
},
close: function()
{
this.stopSearch();
WebInspector.closeViewInDrawer();
},
_onSearchResult: function(searchId, searchResult)
{
if (searchId !== this._searchId)
return;
this._searchView.addSearchResult(searchResult);
if (!searchResult.searchMatches.length)
return;
if (!this._searchResultsPane)
this._searchResultsPane = this._currentSearchScope.createSearchResultsPane(this._searchConfig);
this._searchView.resultsPane = this._searchResultsPane;
this._searchResultsPane.addSearchResult(searchResult);
},
_onSearchFinished: function(searchId, finished)
{
if (searchId !== this._searchId)
return;
if (!this._searchResultsPane)
this._searchView.nothingFound();
this._searchView.searchFinished(finished);
},
startSearch: function(searchConfig)
{
this.resetSearch();
++this._searchId;
this._searchConfig = searchConfig;
this._currentSearchScope = this._searchScope;
var totalSearchResultsCount = this._currentSearchScope.performSearch(searchConfig, this._onSearchResult.bind(this, this._searchId), this._onSearchFinished.bind(this, this._searchId));
this._searchView.searchStarted(totalSearchResultsCount);
},
resetSearch: function()
{
this.stopSearch();
if (this._searchResultsPane) {
this._searchView.resetResults();
delete this._searchResultsPane;
}
},
stopSearch: function()
{
if (this._currentSearchScope)
this._currentSearchScope.stopSearch();
}
}
WebInspector.SearchView = function(controller)
{
WebInspector.View.call(this);
this.registerRequiredCSS("textEditor.css");
this._controller = controller;
this.element.className = "search-view";
this._searchPanelElement = document.createElement("span");
this._searchPanelElement.className = "search-drawer-header";
this._searchPanelElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
this._searchResultsElement = this.element.createChild("div");
this._searchResultsElement.className = "search-results";
this._searchLabel = this._searchPanelElement.createChild("span");
this._searchLabel.textContent = WebInspector.UIString("Search sources");
this._search = this._searchPanelElement.createChild("input");
this._search.setAttribute("type", "search");
this._search.addStyleClass("search-config-search");
this._search.setAttribute("results", "0");
this._search.setAttribute("size", 30);
this._ignoreCaseLabel = this._searchPanelElement.createChild("label");
this._ignoreCaseLabel.addStyleClass("search-config-label");
this._ignoreCaseCheckbox = this._ignoreCaseLabel.createChild("input");
this._ignoreCaseCheckbox.setAttribute("type", "checkbox");
this._ignoreCaseCheckbox.addStyleClass("search-config-checkbox");
this._ignoreCaseLabel.appendChild(document.createTextNode(WebInspector.UIString("Ignore case")));
this._regexLabel = this._searchPanelElement.createChild("label");
this._regexLabel.addStyleClass("search-config-label");
this._regexCheckbox = this._regexLabel.createChild("input");
this._regexCheckbox.setAttribute("type", "checkbox");
this._regexCheckbox.addStyleClass("search-config-checkbox");
this._regexLabel.appendChild(document.createTextNode(WebInspector.UIString("Regular expression")));
this._searchStatusBarElement = document.createElement("div");
this._searchStatusBarElement.className = "search-status-bar-item";
this._searchMessageElement = this._searchStatusBarElement.createChild("div");
this._searchMessageElement.className = "search-status-bar-message";
this._searchResultsMessageElement = document.createElement("span");
this._searchResultsMessageElement.className = "search-results-status-bar-message";
this._load();
}
WebInspector.SearchView.maxQueriesCount = 20;
WebInspector.SearchView.prototype = {
__proto__: WebInspector.View.prototype,
get statusBarItems()
{
return [this._searchStatusBarElement, this._searchResultsMessageElement];
},
get searchConfig()
{
return new WebInspector.SearchConfig(this._search.value, this._ignoreCaseCheckbox.checked, this._regexCheckbox.checked);
},
set resultsPane(resultsPane)
{
this.resetResults();
this._searchResultsElement.appendChild(resultsPane.element);
},
searchStarted: function(totalSearchResultsCount)
{
this.resetResults();
this._resetCounters();
this._searchMessageElement.textContent = WebInspector.UIString("Searching...");
this._progressIndicator = new WebInspector.ProgressIndicator();
this._progressIndicator.setTotalWork(totalSearchResultsCount);
this._progressIndicator.show(this._searchStatusBarElement);
this._updateSearchResultsMessage();
if (!this._searchingView)
this._searchingView = new WebInspector.EmptyView(WebInspector.UIString("Searching..."));
this._searchingView.show(this._searchResultsElement);
},
_updateSearchResultsMessage: function()
{
if (this._searchMatchesCount && this._searchResultsCount)
this._searchResultsMessageElement.textContent = WebInspector.UIString("Found %d matches in %d files.", this._searchMatchesCount, this._nonEmptySearchResultsCount);
else
this._searchResultsMessageElement.textContent = "";
},
resetResults: function()
{
if (this._searchingView)
this._searchingView.detach();
if (this._notFoundView)
this._notFoundView.detach();
this._searchResultsElement.removeChildren();
},
_resetCounters: function()
{
this._searchMatchesCount = 0;
this._searchResultsCount = 0;
this._nonEmptySearchResultsCount = 0;
},
nothingFound: function()
{
this.resetResults();
if (!this._notFoundView)
this._notFoundView = new WebInspector.EmptyView(WebInspector.UIString("No matches found."));
this._notFoundView.show(this._searchResultsElement);
this._searchResultsMessageElement.textContent = WebInspector.UIString("No matches found.");
},
addSearchResult: function(searchResult)
{
this._searchMatchesCount += searchResult.searchMatches.length;
this._searchResultsCount++;
if (searchResult.searchMatches.length)
this._nonEmptySearchResultsCount++;
this._updateSearchResultsMessage();
if (this._progressIndicator.isCanceled())
this._onCancel();
else
this._progressIndicator.setWorked(this._searchResultsCount);
},
searchFinished: function(finished)
{
this._progressIndicator.done();
this._searchMessageElement.textContent = finished ? WebInspector.UIString("Search finished.") : WebInspector.UIString("Search interrupted.");
},
focus: function()
{
WebInspector.setCurrentFocusElement(this._search);
this._search.select();
},
wasShown: function()
{
this.focus();
},
willHide: function()
{
this._controller.stopSearch();
},
_onKeyDown: function(event)
{
switch (event.keyCode) {
case WebInspector.KeyboardShortcut.Keys.Enter.code:
this._onAction();
break;
case WebInspector.KeyboardShortcut.Keys.Esc.code:
this._controller.close();
event.consume(true);
break;
}
},
_save: function()
{
var searchConfig = new WebInspector.SearchConfig(this.searchConfig.query, this.searchConfig.ignoreCase, this.searchConfig.isRegex);
WebInspector.settings.advancedSearchConfig.set(searchConfig);
},
_load: function()
{
var searchConfig = WebInspector.settings.advancedSearchConfig.get();
this._search.value = searchConfig.query;
this._ignoreCaseCheckbox.checked = searchConfig.ignoreCase;
this._regexCheckbox.checked = searchConfig.isRegex;
},
_onCancel: function()
{
this._controller.stopSearch();
this.focus();
},
_onAction: function()
{
if (!this.searchConfig.query || !this.searchConfig.query.length)
return;
this._save();
this._controller.startSearch(this.searchConfig);
}
}
WebInspector.SearchConfig = function(query, ignoreCase, isRegex)
{
this.query = query;
this.ignoreCase = ignoreCase;
this.isRegex = isRegex;
}
WebInspector.SearchScope = function()
{
}
WebInspector.SearchScope.prototype = {
performSearch: function(searchConfig, searchResultCallback, searchFinishedCallback) { },
stopSearch: function() { },
createSearchResultsPane: function(searchConfig) { }
}
WebInspector.SearchResult = function(offset, length)
{
this.offset = offset;
this.length = length;
}
WebInspector.SearchResultsPane = function(searchConfig)
{
this._searchConfig = searchConfig;
this.element = document.createElement("div");
}
WebInspector.SearchResultsPane.prototype = {
get searchConfig()
{
return this._searchConfig;
},
addSearchResult: function(searchResult) { }
}
WebInspector.FileBasedSearchResultsPane = function(searchConfig)
{
WebInspector.SearchResultsPane.call(this, searchConfig);
this._searchResults = [];
this.element.id ="search-results-pane-file-based";
this._treeOutlineElement = document.createElement("ol");
this._treeOutlineElement.className = "search-results-outline-disclosure";
this.element.appendChild(this._treeOutlineElement);
this._treeOutline = new TreeOutline(this._treeOutlineElement);
this._matchesExpandedCount = 0;
}
WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount = 20;
WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce = 20;
WebInspector.FileBasedSearchResultsPane.prototype = {
_createAnchor: function(uiSourceCode, lineNumber, columnNumber)
{
var anchor = document.createElement("a");
anchor.preferredPanel = "scripts";
anchor.href = sanitizeHref(uiSourceCode.url);
anchor.uiSourceCode = uiSourceCode;
anchor.lineNumber = lineNumber;
return anchor;
},
addSearchResult: function(searchResult)
{
this._searchResults.push(searchResult);
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;
var fileTreeElement = this._addFileTreeElement(uiSourceCode.url, searchMatches.length, this._searchResults.length - 1);
},
_fileTreeElementExpanded: function(searchResult, fileTreeElement)
{
if (fileTreeElement._initialized)
return;
var toIndex = Math.min(searchResult.searchMatches.length, WebInspector.FileBasedSearchResultsPane.fileMatchesShownAtOnce);
if (toIndex < searchResult.searchMatches.length) {
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex - 1);
this._appendShowMoreMatchesElement(fileTreeElement, searchResult, toIndex - 1);
} else
this._appendSearchMatches(fileTreeElement, searchResult, 0, toIndex);
fileTreeElement._initialized = true;
},
_appendSearchMatches: function(fileTreeElement, searchResult, fromIndex, toIndex)
{
var uiSourceCode = searchResult.uiSourceCode;
var searchMatches = searchResult.searchMatches;
var regex = createSearchRegex(this._searchConfig.query, !this._searchConfig.ignoreCase, this._searchConfig.isRegex);
for (var i = fromIndex; i < toIndex; ++i) {
var lineNumber = searchMatches[i].lineNumber;
var lineContent = searchMatches[i].lineContent;
var matchRanges = this._regexMatchRanges(lineContent, regex);
var anchor = this._createAnchor(uiSourceCode, lineNumber, matchRanges[0].offset);
var numberString = numberToStringWithSpacesPadding(lineNumber + 1, 4);
var lineNumberSpan = document.createElement("span");
lineNumberSpan.addStyleClass("webkit-line-number");
lineNumberSpan.addStyleClass("search-match-line-number");
lineNumberSpan.textContent = numberString;
anchor.appendChild(lineNumberSpan);
var contentSpan = this._createContentSpan(lineContent, matchRanges);
anchor.appendChild(contentSpan);
var searchMatchElement = new TreeElement("", null, false);
fileTreeElement.appendChild(searchMatchElement);
searchMatchElement.listItemElement.className = "search-match source-code";
searchMatchElement.listItemElement.appendChild(anchor);
}
},
_appendShowMoreMatchesElement: function(fileTreeElement, searchResult, startMatchIndex)
{
var matchesLeftCount = searchResult.searchMatches.length - startMatchIndex;
var showMoreMatchesText = WebInspector.UIString("Show all matches (%d more).", matchesLeftCount);
var showMoreMatchesElement = new TreeElement(showMoreMatchesText, null, false);
fileTreeElement.appendChild(showMoreMatchesElement);
showMoreMatchesElement.listItemElement.addStyleClass("show-more-matches");
showMoreMatchesElement.onselect = this._showMoreMatchesElementSelected.bind(this, searchResult, startMatchIndex, showMoreMatchesElement);
},
_showMoreMatchesElementSelected: function(searchResult, startMatchIndex, showMoreMatchesElement)
{
var fileTreeElement = showMoreMatchesElement.parent;
fileTreeElement.removeChild(showMoreMatchesElement);
this._appendSearchMatches(fileTreeElement, searchResult, startMatchIndex, searchResult.searchMatches.length);
},
_addFileTreeElement: function(fileName, searchMatchesCount, searchResultIndex)
{
var fileTreeElement = new TreeElement("", null, true);
fileTreeElement.toggleOnClick = true;
fileTreeElement.selectable = false;
this._treeOutline.appendChild(fileTreeElement);
fileTreeElement.listItemElement.addStyleClass("search-result");
var fileNameSpan = document.createElement("span");
fileNameSpan.className = "search-result-file-name";
fileNameSpan.textContent = fileName;
fileTreeElement.listItemElement.appendChild(fileNameSpan);
var matchesCountSpan = document.createElement("span");
matchesCountSpan.className = "search-result-matches-count";
if (searchMatchesCount === 1)
matchesCountSpan.textContent = WebInspector.UIString("(%d match)", searchMatchesCount);
else
matchesCountSpan.textContent = WebInspector.UIString("(%d matches)", searchMatchesCount);
fileTreeElement.listItemElement.appendChild(matchesCountSpan);
var searchResult = this._searchResults[searchResultIndex];
fileTreeElement.onexpand = this._fileTreeElementExpanded.bind(this, searchResult, fileTreeElement);
if (this._matchesExpandedCount < WebInspector.FileBasedSearchResultsPane.matchesExpandedByDefaultCount)
fileTreeElement.expand();
this._matchesExpandedCount += searchResult.searchMatches.length;
return fileTreeElement;
},
_regexMatchRanges: function(lineContent, regex)
{
regex.lastIndex = 0;
var match;
var offset = 0;
var matchRanges = [];
while ((regex.lastIndex < lineContent.length) && (match = regex.exec(lineContent)))
matchRanges.push(new WebInspector.SearchResult(match.index, match[0].length));
return matchRanges;
},
_createContentSpan: function(lineContent, matchRanges)
{
var contentSpan = document.createElement("span");
contentSpan.className = "search-match-content";
contentSpan.textContent = lineContent;
WebInspector.highlightRangesWithStyleClass(contentSpan, matchRanges, "highlighted-match");
return contentSpan;
}
}
WebInspector.FileBasedSearchResultsPane.prototype.__proto__ = WebInspector.SearchResultsPane.prototype;
WebInspector.FileBasedSearchResultsPane.SearchResult = function(uiSourceCode, searchMatches) {
this.uiSourceCode = uiSourceCode;
this.searchMatches = searchMatches;
}
WebInspector.advancedSearchController = null;
WebInspector.TimelineGrid = function()
{
this.element = document.createElement("div");
this._itemsGraphsElement = document.createElement("div");
this._itemsGraphsElement.id = "resources-graphs";
this.element.appendChild(this._itemsGraphsElement);
this._dividersElement = document.createElement("div");
this._dividersElement.className = "resources-dividers";
this.element.appendChild(this._dividersElement);
this._gridHeaderElement = document.createElement("div");
this._eventDividersElement = document.createElement("div");
this._eventDividersElement.className = "resources-event-dividers";
this._gridHeaderElement.appendChild(this._eventDividersElement);
this._dividersLabelBarElement = document.createElement("div");
this._dividersLabelBarElement.className = "resources-dividers-label-bar";
this._gridHeaderElement.appendChild(this._dividersLabelBarElement);
this.element.appendChild(this._gridHeaderElement);
}
WebInspector.TimelineGrid.prototype = {
get itemsGraphsElement()
{
return this._itemsGraphsElement;
},
get dividersElement()
{
return this._dividersElement;
},
get dividersLabelBarElement()
{
return this._dividersLabelBarElement;
},
get gridHeaderElement()
{
return this._gridHeaderElement;
},
removeDividers: function()
{
this._dividersElement.removeChildren();
this._dividersLabelBarElement.removeChildren();
},
updateDividers: function(calculator)
{
var dividersElementClientWidth = this._dividersElement.clientWidth;
var dividerCount = Math.round(dividersElementClientWidth / 64);
var slice = calculator.boundarySpan() / dividerCount;
this._currentDividerSlice = slice;
var divider = this._dividersElement.firstChild;
var dividerLabelBar = this._dividersLabelBarElement.firstChild;
var paddingLeft = calculator.paddingLeft;
for (var i = paddingLeft ? 0 : 1; i <= dividerCount; ++i) {
if (!divider) {
divider = document.createElement("div");
divider.className = "resources-divider";
this._dividersElement.appendChild(divider);
dividerLabelBar = document.createElement("div");
dividerLabelBar.className = "resources-divider";
var label = document.createElement("div");
label.className = "resources-divider-label";
dividerLabelBar._labelElement = label;
dividerLabelBar.appendChild(label);
this._dividersLabelBarElement.appendChild(dividerLabelBar);
}
if (i === (paddingLeft ? 0 : 1)) {
divider.addStyleClass("first");
dividerLabelBar.addStyleClass("first");
} else {
divider.removeStyleClass("first");
dividerLabelBar.removeStyleClass("first");
}
if (i === dividerCount) {
divider.addStyleClass("last");
dividerLabelBar.addStyleClass("last");
} else {
divider.removeStyleClass("last");
dividerLabelBar.removeStyleClass("last");
}
var left;
if (!slice) {
left = dividersElementClientWidth / dividerCount * i + paddingLeft;
dividerLabelBar._labelElement.textContent = "";
} else {
left = calculator.computePosition(calculator.minimumBoundary() + slice * i);
dividerLabelBar._labelElement.textContent = calculator.formatTime(slice * i);
}
var percentLeft = 100 * left / dividersElementClientWidth;
this._setDividerAndBarLeft(divider, dividerLabelBar, percentLeft);
divider = divider.nextSibling;
dividerLabelBar = dividerLabelBar.nextSibling;
}
while (divider) {
var nextDivider = divider.nextSibling;
this._dividersElement.removeChild(divider);
divider = nextDivider;
}
while (dividerLabelBar) {
var nextDivider = dividerLabelBar.nextSibling;
this._dividersLabelBarElement.removeChild(dividerLabelBar);
dividerLabelBar = nextDivider;
}
return true;
},
_setDividerAndBarLeft: function(divider, dividerLabelBar, percentLeft)
{
var percentStyleLeft = parseFloat(divider.style.left);
if (!isNaN(percentStyleLeft) && Math.abs(percentStyleLeft - percentLeft) < 0.1)
return;
divider.style.left = percentLeft + "%";
dividerLabelBar.style.left = percentLeft + "%";
},
addEventDivider: function(divider)
{
this._eventDividersElement.appendChild(divider);
},
addEventDividers: function(dividers)
{
this._gridHeaderElement.removeChild(this._eventDividersElement);
for (var i = 0; i < dividers.length; ++i) {
if (dividers[i])
this._eventDividersElement.appendChild(dividers[i]);
}
this._gridHeaderElement.appendChild(this._eventDividersElement);
},
removeEventDividers: function()
{
this._eventDividersElement.removeChildren();
},
hideEventDividers: function()
{
this._eventDividersElement.addStyleClass("hidden");
},
showEventDividers: function()
{
this._eventDividersElement.removeStyleClass("hidden");
},
setScrollAndDividerTop: function(scrollTop, dividersTop)
{
this._dividersElement.style.top = scrollTop + "px";
}
}
WebInspector.TimelineGrid.Calculator = function() { }
WebInspector.TimelineGrid.Calculator.prototype = {
computePosition: function(time) { },
formatTime: function(time) { },
minimumBoundary: function() { },
maximumBoundary: function() { },
boundarySpan: function() { }
}
WebInspector.ContentProvider = function() { }
WebInspector.ContentProvider.prototype = {
contentURL: function() { },
contentType: function() { },
requestContent: function(callback) { },
searchInContent: function(query, caseSensitive, isRegex, callback) { }
}
WebInspector.ContentProvider.SearchMatch = function(lineNumber, lineContent) {
this.lineNumber = lineNumber;
this.lineContent = lineContent;
}
WebInspector.Resource = function(request, url, documentURL, frameId, loaderId, type, mimeType, isHidden)
{
this._request = request;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._type = type || WebInspector.resourceTypes.Other;
this._mimeType = mimeType;
this._isHidden = isHidden;
this._content;
this._contentEncoded;
this._pendingContentCallbacks = [];
if (this._request && !this._request.finished)
this._request.addEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
}
WebInspector.Resource.Events = {
MessageAdded: "message-added",
MessagesCleared: "messages-cleared",
}
WebInspector.Resource.prototype = {
get request()
{
return this._request;
},
get url()
{
return this._url;
},
set url(x)
{
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
},
get parsedURL()
{
return this._parsedURL;
},
get documentURL()
{
return this._documentURL;
},
get frameId()
{
return this._frameId;
},
get loaderId()
{
return this._loaderId;
},
get displayName()
{
return this._parsedURL.displayName;
},
get type()
{
return this._request ? this._request.type : this._type;
},
get mimeType()
{
return this._request ? this._request.mimeType : this._mimeType;
},
get messages()
{
return this._messages || [];
},
addMessage: function(msg)
{
if (!msg.isErrorOrWarning() || !msg.message)
return;
if (!this._messages)
this._messages = [];
this._messages.push(msg);
this.dispatchEventToListeners(WebInspector.Resource.Events.MessageAdded, msg);
},
get errors()
{
return this._errors || 0;
},
set errors(x)
{
this._errors = x;
},
get warnings()
{
return this._warnings || 0;
},
set warnings(x)
{
this._warnings = x;
},
clearErrorsAndWarnings: function()
{
this._messages = [];
this._warnings = 0;
this._errors = 0;
this.dispatchEventToListeners(WebInspector.Resource.Events.MessagesCleared);
},
get content()
{
return this._content;
},
get contentEncoded()
{
return this._contentEncoded;
},
contentURL: function()
{
return this._url;
},
contentType: function()
{
return this.type;
},
requestContent: function(callback)
{
if (typeof this._content !== "undefined") {
callback(this._content, !!this._contentEncoded, this.canonicalMimeType());
return;
}
this._pendingContentCallbacks.push(callback);
if (!this._request || this._request.finished)
this._innerRequestContent();
},
canonicalMimeType: function()
{
return this.type.canonicalMimeType() || this.mimeType;
},
searchInContent: function(query, caseSensitive, isRegex, callback)
{
function callbackWrapper(error, searchMatches)
{
callback(searchMatches || []);
}
if (this.frameId)
PageAgent.searchInResource(this.frameId, this.url, query, caseSensitive, isRegex, callbackWrapper);
else
callback([]);
},
populateImageSource: function(image)
{
function onResourceContent()
{
image.src = this._contentURL();
}
this.requestContent(onResourceContent.bind(this));
},
_contentURL: function()
{
const maxDataUrlSize = 1024 * 1024;
if (this._content == null || this._content.length > maxDataUrlSize)
return this.url;
return "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
},
_requestFinished: function()
{
this._request.removeEventListener(WebInspector.NetworkRequest.Events.FinishedLoading, this._requestFinished, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
},
_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;
function contentLoaded(content, contentEncoded)
{
this._content = content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this.canonicalMimeType());
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
function resourceContentLoaded(error, content, contentEncoded)
{
if (error)
console.error("Resource content request failed: " + error);
contentLoaded.call(this, error ? null : content, contentEncoded);
}
if (this.request) {
function requestContentLoaded(content, contentEncoded, mimeType)
{
contentLoaded.call(this, content, contentEncoded);
}
this.request.requestContent(requestContentLoaded.bind(this));
return;
}
PageAgent.getResourceContent(this.frameId, this.url, resourceContentLoaded.bind(this));
},
isHidden: function()
{
return !!this._isHidden;
}
}
WebInspector.Resource.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.NetworkRequest = function(requestId, url, documentURL, frameId, loaderId)
{
this._requestId = requestId;
this.url = url;
this._documentURL = documentURL;
this._frameId = frameId;
this._loaderId = loaderId;
this._startTime = -1;
this._endTime = -1;
this.statusCode = 0;
this.statusText = "";
this.requestMethod = "";
this.requestTime = 0;
this.receiveHeadersEnd = 0;
this._type = WebInspector.resourceTypes.Other;
this._content = undefined;
this._contentEncoded = false;
this._pendingContentCallbacks = [];
this._frames = [];
}
WebInspector.NetworkRequest.Events = {
FinishedLoading: "FinishedLoading",
TimingChanged: "TimingChanged",
RequestHeadersChanged: "RequestHeadersChanged",
ResponseHeadersChanged: "ResponseHeadersChanged",
}
WebInspector.NetworkRequest.prototype = {
get requestId()
{
return this._requestId;
},
set requestId(requestId)
{
this._requestId = requestId;
},
get url()
{
return this._url;
},
set url(x)
{
if (this._url === x)
return;
this._url = x;
this._parsedURL = new WebInspector.ParsedURL(x);
delete this._parsedQueryParameters;
},
get documentURL()
{
return this._documentURL;
},
get parsedURL()
{
return this._parsedURL;
},
get frameId()
{
return this._frameId;
},
get loaderId()
{
return this._loaderId;
},
get startTime()
{
return this._startTime || -1;
},
set startTime(x)
{
this._startTime = x;
},
get responseReceivedTime()
{
return this._responseReceivedTime || -1;
},
set responseReceivedTime(x)
{
this._responseReceivedTime = x;
},
get endTime()
{
return this._endTime || -1;
},
set endTime(x)
{
if (this.timing && this.timing.requestTime) {
this._endTime = Math.max(x, this.responseReceivedTime);
} else {
this._endTime = x;
if (this._responseReceivedTime > x)
this._responseReceivedTime = x;
}
},
get duration()
{
if (this._endTime === -1 || this._startTime === -1)
return -1;
return this._endTime - this._startTime;
},
get latency()
{
if (this._responseReceivedTime === -1 || this._startTime === -1)
return -1;
return this._responseReceivedTime - this._startTime;
},
get receiveDuration()
{
if (this._endTime === -1 || this._responseReceivedTime === -1)
return -1;
return this._endTime - this._responseReceivedTime;
},
get resourceSize()
{
return this._resourceSize || 0;
},
set resourceSize(x)
{
this._resourceSize = x;
},
get transferSize()
{
if (this.cached)
return 0;
if (this.statusCode === 304)
return this.responseHeadersSize;
if (this._transferSize !== undefined)
return this._transferSize;
var bodySize = Number(this.responseHeaderValue("Content-Length") || this.resourceSize);
return this.responseHeadersSize + bodySize;
},
increaseTransferSize: function(x)
{
this._transferSize = (this._transferSize || 0) + x;
},
get finished()
{
return this._finished;
},
set finished(x)
{
if (this._finished === x)
return;
this._finished = x;
if (x) {
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.FinishedLoading, this);
if (this._pendingContentCallbacks.length)
this._innerRequestContent();
}
},
get failed()
{
return this._failed;
},
set failed(x)
{
this._failed = x;
},
get canceled()
{
return this._canceled;
},
set canceled(x)
{
this._canceled = x;
},
get cached()
{
return this._cached;
},
set cached(x)
{
this._cached = x;
if (x)
delete this._timing;
},
get timing()
{
return this._timing;
},
set timing(x)
{
if (x && !this._cached) {
this._startTime = x.requestTime;
this._responseReceivedTime = x.requestTime + x.receiveHeadersEnd / 1000.0;
this._timing = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.TimingChanged, this);
}
},
get mimeType()
{
return this._mimeType;
},
set mimeType(x)
{
this._mimeType = x;
},
get displayName()
{
return this._parsedURL.displayName;
},
get folder()
{
var path = this._parsedURL.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1)
path = path.substring(0, indexOfQuery);
var lastSlashIndex = path.lastIndexOf("/");
return lastSlashIndex !== -1 ? path.substring(0, lastSlashIndex) : "";
},
get type()
{
return this._type;
},
set type(x)
{
this._type = x;
},
get redirectSource()
{
if (this.redirects && this.redirects.length > 0)
return this.redirects[this.redirects.length - 1];
return this._redirectSource;
},
set redirectSource(x)
{
this._redirectSource = x;
},
get requestHeaders()
{
return this._requestHeaders || [];
},
set requestHeaders(x)
{
this._requestHeaders = x;
delete this._sortedRequestHeaders;
delete this._requestCookies;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},
get requestHeadersText()
{
if (this._requestHeadersText === undefined) {
this._requestHeadersText = this.requestMethod + " " + this.url + " HTTP/1.1\r\n";
for (var i = 0; i < this.requestHeaders; ++i)
this._requestHeadersText += this.requestHeaders[i].name + ": " + this.requestHeaders[i].value + "\r\n";
}
return this._requestHeadersText;
},
set requestHeadersText(x)
{
this._requestHeadersText = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.RequestHeadersChanged);
},
get requestHeadersSize()
{
return this.requestHeadersText.length;
},
get sortedRequestHeaders()
{
if (this._sortedRequestHeaders !== undefined)
return this._sortedRequestHeaders;
this._sortedRequestHeaders = [];
this._sortedRequestHeaders = this.requestHeaders.slice();
this._sortedRequestHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
return this._sortedRequestHeaders;
},
requestHeaderValue: function(headerName)
{
return this._headerValue(this.requestHeaders, headerName);
},
get requestCookies()
{
if (!this._requestCookies)
this._requestCookies = WebInspector.CookieParser.parseCookie(this.requestHeaderValue("Cookie"));
return this._requestCookies;
},
get requestFormData()
{
return this._requestFormData;
},
set requestFormData(x)
{
this._requestFormData = x;
delete this._parsedFormParameters;
},
get requestHttpVersion()
{
var firstLine = this.requestHeadersText.split(/\r\n/)[0];
var match = firstLine.match(/(HTTP\/\d+\.\d+)$/);
return match ? match[1] : undefined;
},
get responseHeaders()
{
return this._responseHeaders || [];
},
set responseHeaders(x)
{
this._responseHeaders = x;
delete this._sortedResponseHeaders;
delete this._responseCookies;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},
get responseHeadersText()
{
if (this._responseHeadersText === undefined) {
this._responseHeadersText = "HTTP/1.1 " + this.statusCode + " " + this.statusText + "\r\n";
for (var i = 0; i < this.requestHeaders; ++i)
this._responseHeadersText += this.responseHeaders[i].name + ": " + this.responseHeaders[i].value + "\r\n";
}
return this._responseHeadersText;
},
set responseHeadersText(x)
{
this._responseHeadersText = x;
this.dispatchEventToListeners(WebInspector.NetworkRequest.Events.ResponseHeadersChanged);
},
get responseHeadersSize()
{
return this.responseHeadersText.length;
},
get sortedResponseHeaders()
{
if (this._sortedResponseHeaders !== undefined)
return this._sortedResponseHeaders;
this._sortedResponseHeaders = [];
this._sortedResponseHeaders = this.responseHeaders.slice();
this._sortedResponseHeaders.sort(function(a,b) { return a.name.toLowerCase().localeCompare(b.name.toLowerCase()) });
return this._sortedResponseHeaders;
},
responseHeaderValue: function(headerName)
{
return this._headerValue(this.responseHeaders, headerName);
},
get responseCookies()
{
if (!this._responseCookies)
this._responseCookies = WebInspector.CookieParser.parseSetCookie(this.responseHeaderValue("Set-Cookie"));
return this._responseCookies;
},
get queryParameters()
{
if (this._parsedQueryParameters)
return this._parsedQueryParameters;
var queryString = this.url.split("?", 2)[1];
if (!queryString)
return null;
queryString = queryString.split("#", 2)[0];
this._parsedQueryParameters = this._parseParameters(queryString);
return this._parsedQueryParameters;
},
get formParameters()
{
if (this._parsedFormParameters)
return this._parsedFormParameters;
if (!this.requestFormData)
return null;
var requestContentType = this.requestContentType();
if (!requestContentType || !requestContentType.match(/^application\/x-www-form-urlencoded\s*(;.*)?$/i))
return null;
this._parsedFormParameters = this._parseParameters(this.requestFormData);
return this._parsedFormParameters;
},
get responseHttpVersion()
{
var match = this.responseHeadersText.match(/^(HTTP\/\d+\.\d+)/);
return match ? match[1] : undefined;
},
_parseParameters: function(queryString)
{
function parseNameValue(pair)
{
var parameter = {};
var splitPair = pair.split("=", 2);
parameter.name = splitPair[0];
if (splitPair.length === 1)
parameter.value = "";
else
parameter.value = splitPair[1];
return parameter;
}
return queryString.split("&").map(parseNameValue);
},
_headerValue: function(headers, headerName)
{
headerName = headerName.toLowerCase();
var values = [];
for (var i = 0; i < headers.length; ++i) {
if (headers[i].name.toLowerCase() === headerName)
values.push(headers[i].value);
}
if (headerName === "set-cookie")
return values.join("\n");
return values.join(", ");
},
get content()
{
return this._content;
},
get contentEncoded()
{
return this._contentEncoded;
},
contentURL: function()
{
return this._url;
},
contentType: function()
{
return this._type;
},
requestContent: function(callback)
{
if (this.type === WebInspector.resourceTypes.WebSocket) {
callback(null, false, this._mimeType);
return;
}
if (typeof this._content !== "undefined") {
callback(this.content || null, this._contentEncoded, this._mimeType);
return;
}
this._pendingContentCallbacks.push(callback);
if (this.finished)
this._innerRequestContent();
},
searchInContent: function(query, caseSensitive, isRegex, callback)
{
callback([]);
},
isHttpFamily: function()
{
return !!this.url.match(/^https?:/i);
},
requestContentType: function()
{
return this.requestHeaderValue("Content-Type");
},
isPingRequest: function()
{
return "text/ping" === this.requestContentType();
},
hasErrorStatusCode: function()
{
return this.statusCode >= 400;
},
populateImageSource: function(image)
{
function onResourceContent(content, contentEncoded, mimeType)
{
const maxDataUrlSize = 1024 * 1024;
if (this._content == null || this._content.length > maxDataUrlSize)
return this.url;
image.src = "data:" + this.mimeType + (this._contentEncoded ? ";base64," : ",") + this._content;
}
this.requestContent(onResourceContent.bind(this));
},
_innerRequestContent: function()
{
if (this._contentRequested)
return;
this._contentRequested = true;
function onResourceContent(error, content, contentEncoded)
{
this._content = error ? null : content;
this._contentEncoded = contentEncoded;
var callbacks = this._pendingContentCallbacks.slice();
for (var i = 0; i < callbacks.length; ++i)
callbacks[i](this._content, this._contentEncoded, this._mimeType);
this._pendingContentCallbacks.length = 0;
delete this._contentRequested;
}
NetworkAgent.getResponseBody(this._requestId, onResourceContent.bind(this));
},
frames: function()
{
return this._frames;
},
frame: function(position)
{
return this._frames[position];
},
addFrameError: function(errorMessage, time)
{
var errorObject = {};
errorObject.errorMessage = errorMessage;
errorObject.time = time;
this._pushFrame(errorObject);
},
addFrame: function(response, time, sent)
{
response.time = time;
if (sent)
response.sent = true;
this._pushFrame(response);
},
_pushFrame: function(object)
{
if (this._frames.length >= 100) {
this._frames.splice(0, 10);
}
this._frames.push(object);
}
}
WebInspector.NetworkRequest.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.CSSStyleModel = function()
{
this._pendingCommandsMajorState = [];
this._sourceMappings = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoRequested, this._undoRedoRequested, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.UndoRedoCompleted, this._undoRedoCompleted, this);
this._resourceBinding = new WebInspector.CSSStyleModelResourceBinding(this);
this._namedFlowCollections = {};
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._resetNamedFlowCollections, this);
InspectorBackend.registerCSSDispatcher(new WebInspector.CSSDispatcher(this));
CSSAgent.enable();
}
WebInspector.CSSStyleModel.parseRuleArrayPayload = function(ruleArray)
{
var result = [];
for (var i = 0; i < ruleArray.length; ++i)
result.push(WebInspector.CSSRule.parsePayload(ruleArray[i]));
return result;
}
WebInspector.CSSStyleModel.Events = {
StyleSheetChanged: "StyleSheetChanged",
MediaQueryResultChanged: "MediaQueryResultChanged",
NamedFlowCreated: "NamedFlowCreated",
NamedFlowRemoved: "NamedFlowRemoved",
RegionLayoutUpdated: "RegionLayoutUpdated"
}
WebInspector.CSSStyleModel.prototype = {
getMatchedStylesAsync: function(nodeId, needPseudo, needInherited, userCallback)
{
function callback(userCallback, error, matchedPayload, pseudoPayload, inheritedPayload)
{
if (error) {
if (userCallback)
userCallback(null);
return;
}
var result = {};
if (matchedPayload)
result.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(matchedPayload);
if (pseudoPayload) {
result.pseudoElements = [];
for (var i = 0; i < pseudoPayload.length; ++i) {
var entryPayload = pseudoPayload[i];
result.pseudoElements.push({ pseudoId: entryPayload.pseudoId, rules: WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.rules) });
}
}
if (inheritedPayload) {
result.inherited = [];
for (var i = 0; i < inheritedPayload.length; ++i) {
var entryPayload = inheritedPayload[i];
var entry = {};
if (entryPayload.inlineStyle)
entry.inlineStyle = WebInspector.CSSStyleDeclaration.parsePayload(entryPayload.inlineStyle);
if (entryPayload.matchedCSSRules)
entry.matchedCSSRules = WebInspector.CSSStyleModel.parseRuleArrayPayload(entryPayload.matchedCSSRules);
result.inherited.push(entry);
}
}
if (userCallback)
userCallback(result);
}
CSSAgent.getMatchedStylesForNode(nodeId, needPseudo, needInherited, callback.bind(null, userCallback));
},
getComputedStyleAsync: function(nodeId, userCallback)
{
function callback(userCallback, error, computedPayload)
{
if (error || !computedPayload)
userCallback(null);
else
userCallback(WebInspector.CSSStyleDeclaration.parseComputedStylePayload(computedPayload));
}
CSSAgent.getComputedStyleForNode(nodeId, callback.bind(null, userCallback));
},
getInlineStylesAsync: function(nodeId, userCallback)
{
function callback(userCallback, error, inlinePayload, attributesStylePayload)
{
if (error || !inlinePayload)
userCallback(null, null);
else
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(inlinePayload), attributesStylePayload ? WebInspector.CSSStyleDeclaration.parsePayload(attributesStylePayload) : null);
}
CSSAgent.getInlineStylesForNode(nodeId, callback.bind(null, userCallback));
},
forcePseudoState: function(nodeId, forcedPseudoClasses, userCallback)
{
CSSAgent.forcePseudoState(nodeId, forcedPseudoClasses || [], userCallback);
},
getNamedFlowCollectionAsync: function(documentNodeId, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection);
return;
}
function callback(userCallback, error, namedFlowPayload)
{
if (error || !namedFlowPayload)
userCallback(null);
else {
var namedFlowCollection = new WebInspector.NamedFlowCollection(namedFlowPayload);
this._namedFlowCollections[documentNodeId] = namedFlowCollection;
userCallback(namedFlowCollection);
}
}
CSSAgent.getNamedFlowCollection(documentNodeId, callback.bind(this, userCallback));
},
getFlowByNameAsync: function(documentNodeId, flowName, userCallback)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (namedFlowCollection) {
userCallback(namedFlowCollection.flowByName(flowName));
return;
}
function callback(userCallback, namedFlowCollection)
{
if (!namedFlowCollection)
userCallback(null);
else
userCallback(namedFlowCollection.flowByName(flowName));
}
this.getNamedFlowCollectionAsync(documentNodeId, callback.bind(this, userCallback));
},
setRuleSelector: function(ruleId, nodeId, newSelector, successCallback, failureCallback)
{
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}
function callback(nodeId, successCallback, failureCallback, newSelector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error)
failureCallback();
else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, newSelector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}
this._pendingCommandsMajorState.push(true);
CSSAgent.setRuleSelector(ruleId, newSelector, callback.bind(this, nodeId, successCallback, failureCallback, newSelector));
},
addRule: function(nodeId, selector, successCallback, failureCallback)
{
function checkAffectsCallback(nodeId, successCallback, rulePayload, selectedNodeIds)
{
if (!selectedNodeIds)
return;
var doesAffectSelectedNode = (selectedNodeIds.indexOf(nodeId) >= 0);
var rule = WebInspector.CSSRule.parsePayload(rulePayload);
successCallback(rule, doesAffectSelectedNode);
}
function callback(successCallback, failureCallback, selector, error, rulePayload)
{
this._pendingCommandsMajorState.pop();
if (error) {
failureCallback();
} else {
WebInspector.domAgent.markUndoableState();
var ownerDocumentId = this._ownerDocumentId(nodeId);
if (ownerDocumentId)
WebInspector.domAgent.querySelectorAll(ownerDocumentId, selector, checkAffectsCallback.bind(this, nodeId, successCallback, rulePayload));
else
failureCallback();
}
}
this._pendingCommandsMajorState.push(true);
CSSAgent.addRule(nodeId, selector, callback.bind(this, successCallback, failureCallback, selector));
},
mediaQueryResultChanged: function()
{
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.MediaQueryResultChanged);
},
_ownerDocumentId: function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return null;
return node.ownerDocument ? node.ownerDocument.id : null;
},
_fireStyleSheetChanged: function(styleSheetId)
{
if (!this._pendingCommandsMajorState.length)
return;
var majorChange = this._pendingCommandsMajorState[this._pendingCommandsMajorState.length - 1];
if (!majorChange || !styleSheetId || !this.hasEventListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged))
return;
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.StyleSheetChanged, { styleSheetId: styleSheetId, majorChange: majorChange });
},
_namedFlowCreated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
if (!namedFlowCollection)
return;
namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowCreated, namedFlow);
},
_namedFlowRemoved: function(documentNodeId, flowName)
{
var namedFlowCollection = this._namedFlowCollections[documentNodeId];
if (!namedFlowCollection)
return;
namedFlowCollection._removeNamedFlow(flowName);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.NamedFlowRemoved, { documentNodeId: documentNodeId, flowName: flowName });
},
_regionLayoutUpdated: function(namedFlowPayload)
{
var namedFlow = WebInspector.NamedFlow.parsePayload(namedFlowPayload);
var namedFlowCollection = this._namedFlowCollections[namedFlow.documentNodeId];
if (!namedFlowCollection)
return;
namedFlowCollection._appendNamedFlow(namedFlow);
this.dispatchEventToListeners(WebInspector.CSSStyleModel.Events.RegionLayoutUpdated, namedFlow);
},
setStyleSheetText: function(styleSheetId, newText, majorChange, userCallback)
{
function callback(error)
{
this._pendingCommandsMajorState.pop();
if (!error && majorChange)
WebInspector.domAgent.markUndoableState();
if (!error && userCallback)
userCallback(error);
}
this._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(styleSheetId, newText, callback.bind(this));
},
_undoRedoRequested: function()
{
this._pendingCommandsMajorState.push(true);
},
_undoRedoCompleted: function()
{
this._pendingCommandsMajorState.pop();
},
getViaInspectorResourceForRule: function(rule, callback)
{
if (!rule.id) {
callback(null);
return;
}
this._resourceBinding._requestViaInspectorResource(rule.id.styleSheetId, callback);
},
resourceBinding: function()
{
return this._resourceBinding;
},
setSourceMapping: function(url, sourceMapping)
{
this._sourceMappings[url] = sourceMapping;
},
resetSourceMappings: function()
{
this._sourceMappings = {};
},
_resetNamedFlowCollections: function()
{
this._namedFlowCollections = {};
},
_rawLocationToUILocation: function(rawLocation)
{
var sourceMapping = this._sourceMappings[rawLocation.url];
return sourceMapping ? sourceMapping.rawLocationToUILocation(rawLocation) : null;
}
}
WebInspector.CSSStyleModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.CSSLocation = function(url, lineNumber)
{
this.url = url;
this.lineNumber = lineNumber;
}
WebInspector.CSSStyleDeclaration = function(payload)
{
this.id = payload.styleId;
this.width = payload.width;
this.height = payload.height;
this.range = payload.range;
this._shorthandValues = WebInspector.CSSStyleDeclaration.buildShorthandValueMap(payload.shorthandEntries);
this._livePropertyMap = {};
this._allProperties = [];
this.__disabledProperties = {};
var payloadPropertyCount = payload.cssProperties.length;
var propertyIndex = 0;
for (var i = 0; i < payloadPropertyCount; ++i) {
var property = WebInspector.CSSProperty.parsePayload(this, i, payload.cssProperties[i]);
this._allProperties.push(property);
if (property.disabled)
this.__disabledProperties[i] = property;
if (!property.active && !property.styleBased)
continue;
var name = property.name;
this[propertyIndex] = name;
this._livePropertyMap[name] = property;
++propertyIndex;
}
this.length = propertyIndex;
if ("cssText" in payload)
this.cssText = payload.cssText;
}
WebInspector.CSSStyleDeclaration.buildShorthandValueMap = function(shorthandEntries)
{
var result = {};
for (var i = 0; i < shorthandEntries.length; ++i)
result[shorthandEntries[i].name] = shorthandEntries[i].value;
return result;
}
WebInspector.CSSStyleDeclaration.parsePayload = function(payload)
{
return new WebInspector.CSSStyleDeclaration(payload);
}
WebInspector.CSSStyleDeclaration.parseComputedStylePayload = function(payload)
{
var newPayload = { cssProperties: [], shorthandEntries: [], width: "", height: "" };
if (payload)
newPayload.cssProperties = payload;
return new WebInspector.CSSStyleDeclaration(newPayload);
}
WebInspector.CSSStyleDeclaration.prototype = {
get allProperties()
{
return this._allProperties;
},
getLiveProperty: function(name)
{
return this._livePropertyMap[name];
},
getPropertyValue: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.value : "";
},
getPropertyPriority: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.priority : "";
},
isPropertyImplicit: function(name)
{
var property = this._livePropertyMap[name];
return property ? property.implicit : "";
},
longhandProperties: function(name)
{
var longhands = WebInspector.CSSCompletions.cssPropertiesMetainfo.longhands(name);
var result = [];
for (var i = 0; longhands && i < longhands.length; ++i) {
var property = this._livePropertyMap[longhands[i]];
if (property)
result.push(property);
}
return result;
},
shorthandValue: function(shorthandProperty)
{
return this._shorthandValues[shorthandProperty];
},
propertyAt: function(index)
{
return (index < this.allProperties.length) ? this.allProperties[index] : null;
},
pastLastSourcePropertyIndex: function()
{
for (var i = this.allProperties.length - 1; i >= 0; --i) {
var property = this.allProperties[i];
if (property.active || property.disabled)
return i + 1;
}
return 0;
},
newBlankProperty: function(index)
{
index = (typeof index === "undefined") ? this.pastLastSourcePropertyIndex() : index;
return new WebInspector.CSSProperty(this, index, "", "", "", "active", true, false, "");
},
insertPropertyAt: function(index, name, value, userCallback)
{
function callback(userCallback, error, payload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!userCallback)
return;
if (error) {
console.error(error);
userCallback(null);
} else {
userCallback(WebInspector.CSSStyleDeclaration.parsePayload(payload));
}
}
if (!this.id)
throw "No style id";
WebInspector.cssModel._pendingCommandsMajorState.push(true);
CSSAgent.setPropertyText(this.id, index, name + ": " + value + ";", false, callback.bind(this, userCallback));
},
appendProperty: function(name, value, userCallback)
{
this.insertPropertyAt(this.allProperties.length, name, value, userCallback);
}
}
WebInspector.CSSRule = function(payload)
{
this.id = payload.ruleId;
this.selectorText = payload.selectorText;
this.sourceLine = payload.sourceLine;
this.sourceURL = payload.sourceURL;
if (payload.sourceURL)
this._rawLocation = new WebInspector.CSSLocation(payload.sourceURL, payload.sourceLine);
this.origin = payload.origin;
this.style = WebInspector.CSSStyleDeclaration.parsePayload(payload.style);
this.style.parentRule = this;
this.selectorRange = payload.selectorRange;
if (payload.media)
this.media = WebInspector.CSSMedia.parseMediaArrayPayload(payload.media);
}
WebInspector.CSSRule.parsePayload = function(payload)
{
return new WebInspector.CSSRule(payload);
}
WebInspector.CSSRule.prototype = {
get isUserAgent()
{
return this.origin === "user-agent";
},
get isUser()
{
return this.origin === "user";
},
get isViaInspector()
{
return this.origin === "inspector";
},
get isRegular()
{
return this.origin === "regular";
},
uiLocation: function()
{
if (!this._rawLocation)
return null;
return WebInspector.cssModel._rawLocationToUILocation(this._rawLocation);
}
}
WebInspector.CSSProperty = function(ownerStyle, index, name, value, priority, status, parsedOk, implicit, text)
{
this.ownerStyle = ownerStyle;
this.index = index;
this.name = name;
this.value = value;
this.priority = priority;
this.status = status;
this.parsedOk = parsedOk;
this.implicit = implicit;
this.text = text;
}
WebInspector.CSSProperty.parsePayload = function(ownerStyle, index, payload)
{
var result = new WebInspector.CSSProperty(
ownerStyle, index, payload.name, payload.value, payload.priority || "", payload.status || "style", ("parsedOk" in payload) ? !!payload.parsedOk : true, !!payload.implicit, payload.text);
return result;
}
WebInspector.CSSProperty.prototype = {
get propertyText()
{
if (this.text !== undefined)
return this.text;
if (this.name === "")
return "";
return this.name + ": " + this.value + (this.priority ? " !" + this.priority : "") + ";";
},
get isLive()
{
return this.active || this.styleBased;
},
get active()
{
return this.status === "active";
},
get styleBased()
{
return this.status === "style";
},
get inactive()
{
return this.status === "inactive";
},
get disabled()
{
return this.status === "disabled";
},
setText: function(propertyText, majorChange, overwrite, userCallback)
{
function enabledCallback(style)
{
if (userCallback)
userCallback(style);
}
function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (!error) {
if (majorChange)
WebInspector.domAgent.markUndoableState();
this.text = propertyText;
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
var newProperty = style.allProperties[this.index];
if (newProperty && this.disabled && !propertyText.match(/^\s*$/)) {
newProperty.setDisabled(false, enabledCallback);
return;
}
if (userCallback)
userCallback(style);
} else {
if (userCallback)
userCallback(null);
}
}
if (!this.ownerStyle)
throw "No ownerStyle for property";
if (!this.ownerStyle.id)
throw "No owner style id";
WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setPropertyText(this.ownerStyle.id, this.index, propertyText, overwrite, callback.bind(this));
},
setValue: function(newValue, majorChange, overwrite, userCallback)
{
var text = this.name + ": " + newValue + (this.priority ? " !" + this.priority : "") + ";"
this.setText(text, majorChange, overwrite, userCallback);
},
setDisabled: function(disabled, userCallback)
{
if (!this.ownerStyle && userCallback)
userCallback(null);
if (disabled === this.disabled && userCallback)
userCallback(this.ownerStyle);
function callback(error, stylePayload)
{
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (error) {
if (userCallback)
userCallback(null);
return;
}
WebInspector.domAgent.markUndoableState();
if (userCallback) {
var style = WebInspector.CSSStyleDeclaration.parsePayload(stylePayload);
userCallback(style);
}
}
if (!this.ownerStyle.id)
throw "No owner style id";
WebInspector.cssModel._pendingCommandsMajorState.push(false);
CSSAgent.toggleProperty(this.ownerStyle.id, this.index, disabled, callback.bind(this));
}
}
WebInspector.CSSMedia = function(payload)
{
this.text = payload.text;
this.source = payload.source;
this.sourceURL = payload.sourceURL || "";
this.sourceLine = typeof payload.sourceLine === "undefined" || this.source === "linkedSheet" ? -1 : payload.sourceLine;
}
WebInspector.CSSMedia.Source = {
LINKED_SHEET: "linkedSheet",
INLINE_SHEET: "inlineSheet",
MEDIA_RULE: "mediaRule",
IMPORT_RULE: "importRule"
};
WebInspector.CSSMedia.parsePayload = function(payload)
{
return new WebInspector.CSSMedia(payload);
}
WebInspector.CSSMedia.parseMediaArrayPayload = function(payload)
{
var result = [];
for (var i = 0; i < payload.length; ++i)
result.push(WebInspector.CSSMedia.parsePayload(payload[i]));
return result;
}
WebInspector.CSSStyleSheet = function(payload)
{
this.id = payload.styleSheetId;
this.rules = [];
this.styles = {};
for (var i = 0; i < payload.rules.length; ++i) {
var rule = WebInspector.CSSRule.parsePayload(payload.rules[i]);
this.rules.push(rule);
if (rule.style)
this.styles[rule.style.id] = rule.style;
}
if ("text" in payload)
this._text = payload.text;
}
WebInspector.CSSStyleSheet.createForId = function(styleSheetId, userCallback)
{
function callback(error, styleSheetPayload)
{
if (error)
userCallback(null);
else
userCallback(new WebInspector.CSSStyleSheet(styleSheetPayload));
}
CSSAgent.getStyleSheet(styleSheetId, callback.bind(this));
}
WebInspector.CSSStyleSheet.prototype = {
getText: function()
{
return this._text;
},
setText: function(newText, majorChange, userCallback)
{
function callback(error)
{
if (!error)
WebInspector.domAgent.markUndoableState();
WebInspector.cssModel._pendingCommandsMajorState.pop();
if (userCallback)
userCallback(error);
}
WebInspector.cssModel._pendingCommandsMajorState.push(majorChange);
CSSAgent.setStyleSheetText(this.id, newText, callback.bind(this));
}
}
WebInspector.CSSStyleModelResourceBinding = function(cssModel)
{
this._cssModel = cssModel;
this._frameAndURLToStyleSheetId = {};
this._styleSheetIdToHeader = {};
this._cssModel.addEventListener(WebInspector.CSSStyleModel.Events.StyleSheetChanged, this._styleSheetChanged, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
}
WebInspector.CSSStyleModelResourceBinding.prototype = {
setStyleContent: function(styleSource, content, majorChange, userCallback)
{
var resource = styleSource.resource();
if (this._styleSheetIdForResource(resource)) {
this._innerSetContent(resource, content, majorChange, userCallback, null);
return;
}
this._loadStyleSheetHeaders(this._innerSetContent.bind(this, resource, content, majorChange, userCallback));
},
_styleSheetIdForResource: function(resource)
{
return this._frameAndURLToStyleSheetId[resource.frameId + ":" + resource.url];
},
_inspectedURLChanged: function(event)
{
this._frameAndURLToStyleSheetId = {};
this._styleSheetIdToHeader = {};
},
_innerSetContent: function(resource, content, majorChange, userCallback, error)
{
if (error) {
userCallback(error);
return;
}
var styleSheetId = this._styleSheetIdForResource(resource);
if (!styleSheetId) {
userCallback("No stylesheet found: " + resource.frameId + ":" + resource.url);
return;
}
this._isSettingContent = true;
function callbackWrapper(error)
{
userCallback(error);
delete this._isSettingContent;
}
this._cssModel.setStyleSheetText(styleSheetId, content, majorChange, callbackWrapper.bind(this));
},
_loadStyleSheetHeaders: function(callback)
{
function didGetAllStyleSheets(error, infos)
{
if (error) {
callback(error);
return;
}
for (var i = 0; i < infos.length; ++i) {
var info = infos[i];
if (info.origin === "inspector") {
this._getOrCreateInspectorResource(info);
continue;
}
this._frameAndURLToStyleSheetId[info.frameId + ":" + info.sourceURL] = info.styleSheetId;
this._styleSheetIdToHeader[info.styleSheetId] = info;
}
callback(null);
}
CSSAgent.getAllStyleSheets(didGetAllStyleSheets.bind(this));
},
_styleSheetChanged: function(event)
{
if (this._isSettingContent)
return;
if (!event.data.majorChange)
return;
function callback(error, content)
{
if (!error)
this._innerStyleSheetChanged(event.data.styleSheetId, content);
}
CSSAgent.getStyleSheetText(event.data.styleSheetId, callback.bind(this));
},
_innerStyleSheetChanged: function(styleSheetId, content)
{
function setContent()
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (!header)
return;
var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return;
var styleSheetURL = header.origin === "inspector" ? this._viaInspectorResourceURL(header.sourceURL) : header.sourceURL;
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(styleSheetURL);
if (!uiSourceCode)
return;
if (uiSourceCode.contentType() === WebInspector.resourceTypes.Stylesheet)
uiSourceCode.addRevision(content);
}
if (!this._styleSheetIdToHeader[styleSheetId]) {
this._loadStyleSheetHeaders(setContent.bind(this));
return;
}
setContent.call(this);
},
_requestViaInspectorResource: function(styleSheetId, callback)
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (header) {
callback(this._getOrCreateInspectorResource(header));
return;
}
function headersLoaded()
{
var header = this._styleSheetIdToHeader[styleSheetId];
if (header)
callback(this._getOrCreateInspectorResource(header));
else
callback(null);
}
this._loadStyleSheetHeaders(headersLoaded.bind(this));
},
_getOrCreateInspectorResource: function(header)
{
var frame = WebInspector.resourceTreeModel.frameForId(header.frameId);
if (!frame)
return null;
var viaInspectorURL = this._viaInspectorResourceURL(header.sourceURL);
var inspectorResource = frame.resourceForURL(viaInspectorURL);
if (inspectorResource)
return inspectorResource;
var resource = frame.resourceForURL(header.sourceURL);
if (!resource)
return null;
this._frameAndURLToStyleSheetId[header.frameId + ":" + viaInspectorURL] = header.styleSheetId;
this._styleSheetIdToHeader[header.styleSheetId] = header;
inspectorResource = new WebInspector.Resource(null, viaInspectorURL, resource.documentURL, resource.frameId, resource.loaderId, WebInspector.resourceTypes.Stylesheet, "text/css", true);
function overrideRequestContent(callback)
{
function callbackWrapper(error, content)
{
callback(error ? "" : content, false, "text/css");
}
CSSAgent.getStyleSheetText(header.styleSheetId, callbackWrapper);
}
inspectorResource.requestContent = overrideRequestContent;
frame.addResource(inspectorResource);
return inspectorResource;
},
_viaInspectorResourceURL: function(documentURL)
{
var parsedURL = new WebInspector.ParsedURL(documentURL);
var fakeURL = "inspector://" + parsedURL.host + parsedURL.folderPathComponents;
if (!fakeURL.endsWith("/"))
fakeURL += "/";
fakeURL += "inspector-stylesheet";
return fakeURL;
}
}
WebInspector.CSSDispatcher = function(cssModel)
{
this._cssModel = cssModel;
}
WebInspector.CSSDispatcher.prototype = {
mediaQueryResultChanged: function()
{
this._cssModel.mediaQueryResultChanged();
},
styleSheetChanged: function(styleSheetId)
{
this._cssModel._fireStyleSheetChanged(styleSheetId);
},
namedFlowCreated: function(namedFlowPayload)
{
this._cssModel._namedFlowCreated(namedFlowPayload);
},
namedFlowRemoved: function(documentNodeId, flowName)
{
this._cssModel._namedFlowRemoved(documentNodeId, flowName);
},
regionLayoutUpdated: function(namedFlowPayload)
{
this._cssModel._regionLayoutUpdated(namedFlowPayload);
}
}
WebInspector.NamedFlow = function(payload)
{
this.documentNodeId = payload.documentNodeId;
this.name = payload.name;
this.overset = payload.overset;
this.content = payload.content;
this.regions = payload.regions;
}
WebInspector.NamedFlow.parsePayload = function(payload)
{
return new WebInspector.NamedFlow(payload);
}
WebInspector.NamedFlowCollection = function(payload)
{
this.namedFlowMap = {};
for (var i = 0; i < payload.length; ++i) {
var namedFlow = WebInspector.NamedFlow.parsePayload(payload[i]);
this.namedFlowMap[namedFlow.name] = namedFlow;
}
}
WebInspector.NamedFlowCollection.prototype = {
_appendNamedFlow: function(namedFlow)
{
this.namedFlowMap[namedFlow.name] = namedFlow;
},
_removeNamedFlow: function(flowName)
{
delete this.namedFlowMap[flowName];
},
flowByName: function(flowName)
{
var namedFlow = this.namedFlowMap[flowName];
if (!namedFlow)
return null;
return namedFlow;
}
}
WebInspector.cssModel = null;
WebInspector.NetworkManager = function()
{
WebInspector.Object.call(this);
this._dispatcher = new WebInspector.NetworkDispatcher(this);
if (WebInspector.settings.cacheDisabled.get())
NetworkAgent.setCacheDisabled(true);
NetworkAgent.enable();
WebInspector.settings.cacheDisabled.addChangeListener(this._cacheDisabledSettingChanged, this);
if (WebInspector.settings.userAgent.get())
this._userAgentSettingChanged();
WebInspector.settings.userAgent.addChangeListener(this._userAgentSettingChanged, this);
}
WebInspector.NetworkManager.EventTypes = {
RequestStarted: "RequestStarted",
RequestUpdated: "RequestUpdated",
RequestFinished: "RequestFinished",
RequestUpdateDropped: "RequestUpdateDropped"
}
WebInspector.NetworkManager._MIMETypes = {
"text/html": {"document": true},
"text/xml": {"document": true},
"text/plain": {"document": true},
"application/xhtml+xml": {"document": true},
"text/css": {"stylesheet": true},
"text/xsl": {"stylesheet": true},
"image/jpeg": {"image": true},
"image/png": {"image": true},
"image/gif": {"image": true},
"image/bmp": {"image": true},
"image/svg+xml": {"image": true},
"image/vnd.microsoft.icon": {"image": true},
"image/webp": {"image": true},
"image/x-icon": {"image": true},
"image/x-xbitmap": {"image": true},
"font/ttf": {"font": true},
"font/opentype": {"font": true},
"font/woff": {"font": true},
"application/x-font-type1": {"font": true},
"application/x-font-ttf": {"font": true},
"application/x-font-woff": {"font": true},
"application/x-truetype-font": {"font": true},
"text/javascript": {"script": true},
"text/ecmascript": {"script": true},
"application/javascript": {"script": true},
"application/ecmascript": {"script": true},
"application/x-javascript": {"script": true},
"application/json": {"script": true},
"text/javascript1.1": {"script": true},
"text/javascript1.2": {"script": true},
"text/javascript1.3": {"script": true},
"text/jscript": {"script": true},
"text/livescript": {"script": true},
}
WebInspector.NetworkManager.prototype = {
inflightRequestForURL: function(url)
{
return this._dispatcher._inflightRequestsByURL[url];
},
_cacheDisabledSettingChanged: function(event)
{
var enabled = event.data;
NetworkAgent.setCacheDisabled(enabled);
},
_userAgentSettingChanged: function()
{
NetworkAgent.setUserAgentOverride(WebInspector.settings.userAgent.get());
}
}
WebInspector.NetworkManager.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.NetworkDispatcher = function(manager)
{
this._manager = manager;
this._inflightRequestsById = {};
this._inflightRequestsByURL = {};
InspectorBackend.registerNetworkDispatcher(this);
}
WebInspector.NetworkDispatcher.prototype = {
_headersMapToHeadersArray: function(headersMap)
{
var result = [];
for (var name in headersMap) {
var values = headersMap[name].split("\n");
for (var i = 0; i < values.length; ++i)
result.push({ name: name, value: values[i] });
}
return result;
},
_updateNetworkRequestWithRequest: function(networkRequest, request)
{
networkRequest.requestMethod = request.method;
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.requestFormData = request.postData;
},
_updateNetworkRequestWithResponse: function(networkRequest, response)
{
if (!response)
return;
if (response.url && networkRequest.url !== response.url)
networkRequest.url = response.url;
networkRequest.mimeType = response.mimeType;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
if (response.headersText)
networkRequest.responseHeadersText = response.headersText;
if (response.requestHeaders)
networkRequest.requestHeaders = this._headersMapToHeadersArray(response.requestHeaders);
if (response.requestHeadersText)
networkRequest.requestHeadersText = response.requestHeadersText;
networkRequest.connectionReused = response.connectionReused;
networkRequest.connectionId = response.connectionId;
if (response.fromDiskCache)
networkRequest.cached = true;
else
networkRequest.timing = response.timing;
if (!this._mimeTypeIsConsistentWithType(networkRequest)) {
WebInspector.console.addMessage(WebInspector.ConsoleMessage.create(WebInspector.ConsoleMessage.MessageSource.Network,
WebInspector.ConsoleMessage.MessageLevel.Warning,
WebInspector.UIString("Resource interpreted as %s but transferred with MIME type %s: \"%s\".", networkRequest.type.title(), networkRequest.mimeType, networkRequest.url),
WebInspector.ConsoleMessage.MessageType.Log,
"",
0,
1,
[],
null,
networkRequest.requestId));
}
},
_mimeTypeIsConsistentWithType: function(networkRequest)
{
if (networkRequest.hasErrorStatusCode() || networkRequest.statusCode === 304 || networkRequest.statusCode === 204)
return true;
if (typeof networkRequest.type === "undefined"
|| networkRequest.type === WebInspector.resourceTypes.Other
|| networkRequest.type === WebInspector.resourceTypes.XHR
|| networkRequest.type === WebInspector.resourceTypes.WebSocket)
return true;
if (!networkRequest.mimeType)
return true;
if (networkRequest.mimeType in WebInspector.NetworkManager._MIMETypes)
return networkRequest.type.name() in WebInspector.NetworkManager._MIMETypes[networkRequest.mimeType];
return false;
},
_updateNetworkRequestWithCachedResource: function(networkRequest, cachedResource)
{
networkRequest.type = WebInspector.resourceTypes[cachedResource.type];
networkRequest.resourceSize = cachedResource.bodySize;
this._updateNetworkRequestWithResponse(networkRequest, cachedResource.response);
},
_isNull: function(response)
{
if (!response)
return true;
return !response.status && !response.mimeType && (!response.headers || !Object.keys(response.headers).length);
},
requestWillBeSent: function(requestId, frameId, loaderId, documentURL, request, time, initiator, redirectResponse)
{
var networkRequest = this._inflightRequestsById[requestId];
if (networkRequest) {
if (!redirectResponse)
return;
this.responseReceived(requestId, frameId, loaderId, time, "Other", redirectResponse);
networkRequest = this._appendRedirect(requestId, time, request.url);
} else
networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, request.url, documentURL, initiator);
networkRequest.hasNetworkData = true;
this._updateNetworkRequestWithRequest(networkRequest, request);
networkRequest.startTime = time;
this._startNetworkRequest(networkRequest);
},
requestServedFromCache: function(requestId)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.cached = true;
},
responseReceived: function(requestId, frameId, loaderId, time, resourceType, response)
{
if (this._isNull(response))
return;
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest) {
var eventData = {};
eventData.url = response.url;
eventData.frameId = frameId;
eventData.loaderId = loaderId;
eventData.resourceType = resourceType;
eventData.mimeType = response.mimeType;
this._manager.dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, eventData);
return;
}
networkRequest.responseReceivedTime = time;
networkRequest.type = WebInspector.resourceTypes[resourceType];
this._updateNetworkRequestWithResponse(networkRequest, response);
this._updateNetworkRequest(networkRequest);
},
dataReceived: function(requestId, time, dataLength, encodedDataLength)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.resourceSize += dataLength;
if (encodedDataLength != -1)
networkRequest.increaseTransferSize(encodedDataLength);
networkRequest.endTime = time;
this._updateNetworkRequest(networkRequest);
},
loadingFinished: function(requestId, finishTime)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, finishTime);
},
loadingFailed: function(requestId, time, localizedDescription, canceled)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.failed = true;
networkRequest.canceled = canceled;
networkRequest.localizedFailDescription = localizedDescription;
this._finishNetworkRequest(networkRequest, time);
},
requestServedFromMemoryCache: function(requestId, frameId, loaderId, documentURL, time, initiator, cachedResource)
{
var networkRequest = this._createNetworkRequest(requestId, frameId, loaderId, cachedResource.url, documentURL, initiator);
this._updateNetworkRequestWithCachedResource(networkRequest, cachedResource);
networkRequest.cached = true;
networkRequest.requestMethod = "GET";
this._startNetworkRequest(networkRequest);
networkRequest.startTime = networkRequest.responseReceivedTime = time;
this._finishNetworkRequest(networkRequest, time);
},
webSocketCreated: function(requestId, requestURL)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, requestURL, "", "", "");
networkRequest.type = WebInspector.resourceTypes.WebSocket;
this._startNetworkRequest(networkRequest);
},
webSocketWillSendHandshakeRequest: function(requestId, time, request)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.requestMethod = "GET";
networkRequest.requestHeaders = this._headersMapToHeadersArray(request.headers);
networkRequest.webSocketRequestKey3 = request.requestKey3;
networkRequest.startTime = time;
this._updateNetworkRequest(networkRequest);
},
webSocketHandshakeResponseReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.statusCode = response.status;
networkRequest.statusText = response.statusText;
networkRequest.responseHeaders = this._headersMapToHeadersArray(response.headers);
networkRequest.webSocketChallengeResponse = response.challengeResponse;
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
webSocketFrameReceived: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrame(response, time);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
webSocketFrameSent: function(requestId, time, response)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrame(response, time, true);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
webSocketFrameError: function(requestId, time, errorMessage)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
networkRequest.addFrameError(errorMessage, time);
networkRequest.responseReceivedTime = time;
this._updateNetworkRequest(networkRequest);
},
webSocketClosed: function(requestId, time)
{
var networkRequest = this._inflightRequestsById[requestId];
if (!networkRequest)
return;
this._finishNetworkRequest(networkRequest, time);
},
_appendRedirect: function(requestId, time, redirectURL)
{
var originalNetworkRequest = this._inflightRequestsById[requestId];
var previousRedirects = originalNetworkRequest.redirects || [];
originalNetworkRequest.requestId = "redirected:" + requestId + "." + previousRedirects.length;
delete originalNetworkRequest.redirects;
if (previousRedirects.length > 0)
originalNetworkRequest.redirectSource = previousRedirects[previousRedirects.length - 1];
this._finishNetworkRequest(originalNetworkRequest, time);
var newNetworkRequest = this._createNetworkRequest(requestId, originalNetworkRequest.frameId, originalNetworkRequest.loaderId,
redirectURL, originalNetworkRequest.documentURL, originalNetworkRequest.initiator);
newNetworkRequest.redirects = previousRedirects.concat(originalNetworkRequest);
return newNetworkRequest;
},
_startNetworkRequest: function(networkRequest)
{
this._inflightRequestsById[networkRequest.requestId] = networkRequest;
this._inflightRequestsByURL[networkRequest.url] = networkRequest;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestStarted, networkRequest);
},
_updateNetworkRequest: function(networkRequest)
{
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestUpdated, networkRequest);
},
_finishNetworkRequest: function(networkRequest, finishTime)
{
networkRequest.endTime = finishTime;
networkRequest.finished = true;
this._dispatchEventToListeners(WebInspector.NetworkManager.EventTypes.RequestFinished, networkRequest);
delete this._inflightRequestsById[networkRequest.requestId];
delete this._inflightRequestsByURL[networkRequest.url];
},
_dispatchEventToListeners: function(eventType, networkRequest)
{
this._manager.dispatchEventToListeners(eventType, networkRequest);
},
_createNetworkRequest: function(requestId, frameId, loaderId, url, documentURL, initiator)
{
var networkRequest = new WebInspector.NetworkRequest(requestId, url, documentURL, frameId, loaderId);
networkRequest.initiator = initiator;
return networkRequest;
}
}
WebInspector.networkManager = null;
WebInspector.NetworkLog = function()
{
this._requests = [];
this._requestForId = {};
WebInspector.networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestStarted, this._onRequestStarted, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._onMainFrameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.OnLoad, this._onLoad, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, this._onDOMContentLoaded, this);
}
WebInspector.NetworkLog.prototype = {
get requests()
{
return this._requests;
},
pageLoadForRequest: function(request)
{
return request.__page;
},
_onMainFrameNavigated: function(event)
{
var mainFrame = event.data;
this._currentPageLoad = null;
var oldRequests = this._requests.splice(0, this._requests.length);
for (var i = 0; i < oldRequests.length; ++i) {
var request = oldRequests[i];
if (request.loaderId === mainFrame.loaderId) {
if (!this._currentPageLoad)
this._currentPageLoad = new WebInspector.PageLoad(request);
this._requests.push(request);
request.__page = this._currentPageLoad;
}
}
},
_onRequestStarted: function(event)
{
var request = event.data;
this._requests.push(request);
this._requestForId[request.requestId] = request;
request.__page = this._currentPageLoad;
},
_onDOMContentLoaded: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.contentLoadTime = event.data;
},
_onLoad: function(event)
{
if (this._currentPageLoad)
this._currentPageLoad.loadTime = event.data;
},
requestForId: function(requestId)
{
return this._requestForId[requestId];
}
}
WebInspector.networkLog = null;
WebInspector.PageLoad = function(mainRequest)
{
this.id = ++WebInspector.PageLoad._lastIdentifier;
this.url = mainRequest.url;
this.startTime = mainRequest.startTime;
}
WebInspector.PageLoad._lastIdentifier = 0;
WebInspector.ResourceTreeModel = function(networkManager)
{
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestFinished, this._onRequestFinished, this);
networkManager.addEventListener(WebInspector.NetworkManager.EventTypes.RequestUpdateDropped, this._onRequestUpdateDropped, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.RepeatCountUpdated, this._consoleMessageAdded, this);
WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.ConsoleCleared, this._consoleCleared, this);
PageAgent.enable();
NetworkAgent.enable();
this._fetchResourceTree();
InspectorBackend.registerPageDispatcher(new WebInspector.PageDispatcher(this));
this._pendingConsoleMessages = {};
}
WebInspector.ResourceTreeModel.EventTypes = {
FrameAdded: "FrameAdded",
FrameNavigated: "FrameNavigated",
FrameDetached: "FrameDetached",
MainFrameNavigated: "MainFrameNavigated",
ResourceAdded: "ResourceAdded",
WillLoadCachedResources: "WillLoadCachedResources",
CachedResourcesLoaded: "CachedResourcesLoaded",
DOMContentLoaded: "DOMContentLoaded",
OnLoad: "OnLoad",
InspectedURLChanged: "InspectedURLChanged"
}
WebInspector.ResourceTreeModel.prototype = {
_fetchResourceTree: function()
{
this._frames = {};
delete this._cachedResourcesProcessed;
PageAgent.getResourceTree(this._processCachedResources.bind(this));
},
_processCachedResources: function(error, mainFramePayload)
{
if (error) {
console.error(JSON.stringify(error));
return;
}
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.WillLoadCachedResources);
WebInspector.inspectedPageURL = mainFramePayload.frame.url;
this._addFramesRecursively(null, mainFramePayload);
this._dispatchInspectedURLChanged();
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.CachedResourcesLoaded);
this._cachedResourcesProcessed = true;
},
cachedResourcesLoaded: function()
{
return this._cachedResourcesProcessed;
},
_dispatchInspectedURLChanged: function()
{
InspectorFrontendHost.inspectedURLChanged(WebInspector.inspectedPageURL);
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, WebInspector.inspectedPageURL);
},
_addFrame: function(frame)
{
this._frames[frame.id] = frame;
if (frame.isMainFrame())
this.mainFrame = frame;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, frame);
},
_frameNavigated: function(framePayload)
{
if (!this._cachedResourcesProcessed)
return;
var frame = this._frames[framePayload.id];
if (frame) {
frame._navigate(framePayload);
} else {
var parentFrame = this._frames[framePayload.parentId];
frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
if (frame.isMainFrame() && this.mainFrame) {
this._frameDetached(this.mainFrame.id);
}
this._addFrame(frame);
}
if (frame.isMainFrame())
WebInspector.inspectedPageURL = frame.url;
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, frame);
if (frame.isMainFrame())
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, frame);
var resources = frame.resources();
for (var i = 0; i < resources.length; ++i)
this.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resources[i]);
if (frame.isMainFrame())
this._dispatchInspectedURLChanged();
},
_frameDetached: function(frameId)
{
if (!this._cachedResourcesProcessed)
return;
var frame = this._frames[frameId];
if (!frame)
return;
if (frame.parentFrame)
frame.parentFrame._removeChildFrame(frame);
else
frame._remove();
},
_onRequestFinished: function(event)
{
if (!this._cachedResourcesProcessed)
return;
var request = event.data;
if (request.failed || request.type === WebInspector.resourceTypes.XHR)
return;
var frame = this._frames[request.frameId];
if (frame) {
var resource = frame._addRequest(request);
this._addPendingConsoleMessagesToResource(resource);
}
},
_onRequestUpdateDropped: function(event)
{
if (!this._cachedResourcesProcessed)
return;
var frameId = event.data.frameId;
var frame = this._frames[frameId];
if (!frame)
return;
var url = event.data.url;
if (frame._resourcesMap[url])
return;
var resource = new WebInspector.Resource(null, url, frame.url, frameId, event.data.loaderId, WebInspector.resourceTypes[event.data.resourceType], event.data.mimeType);
frame.addResource(resource);
},
frameForId: function(frameId)
{
return this._frames[frameId];
},
forAllResources: function(callback)
{
if (this.mainFrame)
return this.mainFrame._callForFrameResources(callback);
return false;
},
_consoleMessageAdded: function(event)
{
var msg = event.data;
var resource = msg.url ? this.resourceForURL(msg.url) : null;
if (resource)
this._addConsoleMessageToResource(msg, resource);
else
this._addPendingConsoleMessage(msg);
},
_addPendingConsoleMessage: function(msg)
{
if (!msg.url)
return;
if (!this._pendingConsoleMessages[msg.url])
this._pendingConsoleMessages[msg.url] = [];
this._pendingConsoleMessages[msg.url].push(msg);
},
_addPendingConsoleMessagesToResource: function(resource)
{
var messages = this._pendingConsoleMessages[resource.url];
if (messages) {
for (var i = 0; i < messages.length; i++)
this._addConsoleMessageToResource(messages[i], resource);
delete this._pendingConsoleMessages[resource.url];
}
},
_addConsoleMessageToResource: function(msg, resource)
{
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Warning:
resource.warnings += msg.repeatDelta;
break;
case WebInspector.ConsoleMessage.MessageLevel.Error:
resource.errors += msg.repeatDelta;
break;
}
resource.addMessage(msg);
},
_consoleCleared: function()
{
function callback(resource)
{
resource.clearErrorsAndWarnings();
}
this._pendingConsoleMessages = {};
this.forAllResources(callback);
},
resourceForURL: function(url)
{
return this.mainFrame ? this.mainFrame.resourceForURL(url) : null;
},
_addFramesRecursively: function(parentFrame, frameTreePayload)
{
var framePayload = frameTreePayload.frame;
var frame = new WebInspector.ResourceTreeFrame(this, parentFrame, framePayload);
this._addFrame(frame);
var frameResource = this._createResourceFromFramePayload(framePayload, framePayload.url, WebInspector.resourceTypes.Document, framePayload.mimeType);
if (frame.isMainFrame())
WebInspector.inspectedPageURL = frameResource.url;
frame.addResource(frameResource);
for (var i = 0; frameTreePayload.childFrames && i < frameTreePayload.childFrames.length; ++i)
this._addFramesRecursively(frame, frameTreePayload.childFrames[i]);
for (var i = 0; i < frameTreePayload.resources.length; ++i) {
var subresource = frameTreePayload.resources[i];
var resource = this._createResourceFromFramePayload(framePayload, subresource.url, WebInspector.resourceTypes[subresource.type], subresource.mimeType);
frame.addResource(resource);
}
},
_createResourceFromFramePayload: function(frame, url, type, mimeType)
{
return new WebInspector.Resource(null, url, frame.url, frame.id, frame.loaderId, type, mimeType);
}
}
WebInspector.ResourceTreeModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.ResourceTreeFrame = function(model, parentFrame, payload)
{
this._model = model;
this._parentFrame = parentFrame;
this._id = payload.id;
this._loaderId = payload.loaderId;
this._name = payload.name;
this._url = payload.url;
this._securityOrigin = payload.securityOrigin || "";
this._mimeType = payload.mimeType;
this._childFrames = [];
this._resourcesMap = {};
if (this._parentFrame)
this._parentFrame._childFrames.push(this);
}
WebInspector.ResourceTreeFrame.prototype = {
get id()
{
return this._id;
},
get name()
{
return this._name || "";
},
get url()
{
return this._url;
},
get securityOrigin()
{
return this._securityOrigin;
},
get loaderId()
{
return this._loaderId;
},
get parentFrame()
{
return this._parentFrame;
},
get childFrames()
{
return this._childFrames;
},
isMainFrame: function()
{
return !this._parentFrame;
},
_navigate: function(framePayload)
{
this._loaderId = framePayload.loaderId;
this._name = framePayload.name;
this._url = framePayload.url;
this._securityOrigin = framePayload.securityOrigin || "";
this._mimeType = framePayload.mimeType;
var mainResource = this._resourcesMap[this._url];
this._resourcesMap = {};
this._removeChildFrames();
if (mainResource && mainResource.loaderId === this._loaderId)
this.addResource(mainResource);
},
get mainResource()
{
return this._resourcesMap[this._url];
},
_removeChildFrame: function(frame)
{
this._childFrames.remove(frame);
frame._remove();
},
_removeChildFrames: function()
{
var copy = this._childFrames.slice();
for (var i = 0; i < copy.length; ++i)
this._removeChildFrame(copy[i]);
},
_remove: function()
{
this._removeChildFrames();
delete this._model._frames[this.id];
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this);
},
addResource: function(resource)
{
if (this._resourcesMap[resource.url] === resource) {
return;
}
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
},
_addRequest: function(request)
{
var resource = this._resourcesMap[request.url];
if (resource && resource.request === request) {
return resource;
}
resource = new WebInspector.Resource(request, request.url, request.documentURL, request.frameId, request.loaderId, request.type, request.mimeType);
this._resourcesMap[resource.url] = resource;
this._model.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.ResourceAdded, resource);
return resource;
},
resources: function()
{
var result = [];
for (var url in this._resourcesMap)
result.push(this._resourcesMap[url]);
return result;
},
resourceForURL: function(url)
{
var result;
function filter(resource)
{
if (resource.url === url) {
result = resource;
return true;
}
}
this._callForFrameResources(filter);
return result;
},
_callForFrameResources: function(callback)
{
for (var url in this._resourcesMap) {
if (callback(this._resourcesMap[url]))
return true;
}
for (var i = 0; i < this._childFrames.length; ++i) {
if (this._childFrames[i]._callForFrameResources(callback))
return true;
}
return false;
}
}
WebInspector.PageDispatcher = function(resourceTreeModel)
{
this._resourceTreeModel = resourceTreeModel;
}
WebInspector.PageDispatcher.prototype = {
domContentEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.DOMContentLoaded, time);
},
loadEventFired: function(time)
{
this._resourceTreeModel.dispatchEventToListeners(WebInspector.ResourceTreeModel.EventTypes.OnLoad, time);
},
frameNavigated: function(frame)
{
this._resourceTreeModel._frameNavigated(frame);
},
frameDetached: function(frameId)
{
this._resourceTreeModel._frameDetached(frameId);
}
}
WebInspector.resourceTreeModel = null;
WebInspector.ParsedURL = function(url)
{
this.isValid = false;
this.url = url;
this.scheme = "";
this.host = "";
this.port = "";
this.path = "";
this.queryParams = "";
this.fragment = "";
this.folderPathComponents = "";
this.lastPathComponent = "";
var match = url.match(/^([^:]+):\/\/([^\/:]*)(?::([\d]+))?(?:(\/[^#]*)(?:#(.*))?)?$/i);
if (match) {
this.isValid = true;
this.scheme = match[1].toLowerCase();
this.host = match[2];
this.port = match[3];
this.path = match[4] || "/";
this.fragment = match[5];
} else {
if (this.url.startsWith("data:")) {
this.scheme = "data";
return;
}
if (this.url === "about:blank") {
this.scheme = "about";
return;
}
this.path = this.url;
}
if (this.path) {
var path = this.path;
var indexOfQuery = path.indexOf("?");
if (indexOfQuery !== -1) {
this.queryParams = path.substring(indexOfQuery + 1)
path = path.substring(0, indexOfQuery);
}
var lastSlashIndex = path.lastIndexOf("/");
if (lastSlashIndex !== -1) {
this.folderPathComponents = path.substring(0, lastSlashIndex);
this.lastPathComponent = path.substring(lastSlashIndex + 1);
} else
this.lastPathComponent = path;
}
}
WebInspector.ParsedURL.completeURL = function(baseURL, href)
{
if (href) {
var trimmedHref = href.trim();
if (trimmedHref.startsWith("data:") || trimmedHref.startsWith("blob:") || trimmedHref.startsWith("javascript:"))
return href;
var parsedHref = trimmedHref.asParsedURL();
if (parsedHref && parsedHref.scheme)
return trimmedHref;
} else
return baseURL;
var parsedURL = baseURL.asParsedURL();
if (parsedURL) {
var path = href;
if (path.charAt(0) !== "/") {
var basePath = parsedURL.path;
var questionMarkIndex = basePath.indexOf("?");
if (questionMarkIndex > 0)
basePath = basePath.substring(0, questionMarkIndex);
var prefix;
if (path.charAt(0) === "?") {
var basePathCutIndex = basePath.indexOf("?");
if (basePathCutIndex !== -1)
prefix = basePath.substring(0, basePathCutIndex);
else
prefix = basePath;
} else
prefix = basePath.substring(0, basePath.lastIndexOf("/")) + "/";
path = prefix + path;
} else if (path.length > 1 && path.charAt(1) === "/") {
return parsedURL.scheme + ":" + path;
}
return parsedURL.scheme + "://" + parsedURL.host + (parsedURL.port ? (":" + parsedURL.port) : "") + path;
}
return null;
}
WebInspector.ParsedURL.prototype = {
get displayName()
{
if (this._displayName)
return this._displayName;
if (this.scheme === "data") {
this._displayName = this.url.trimEnd(20);
return this._displayName;
}
if (this.url === "about:blank")
return this.url;
this._displayName = this.lastPathComponent;
if (!this._displayName)
this._displayName = this.host;
if (!this._displayName && this.url)
this._displayName = this.url.trimURL(WebInspector.inspectedPageDomain ? WebInspector.inspectedPageDomain : "");
if (this._displayName === "/")
this._displayName = this.url;
return this._displayName;
}
}
String.prototype.asParsedURL = function()
{
var parsedURL = new WebInspector.ParsedURL(this.toString());
if (parsedURL.isValid)
return parsedURL;
return null;
}
WebInspector.resourceForURL = function(url)
{
return WebInspector.resourceTreeModel.resourceForURL(url);
}
WebInspector.forAllResources = function(callback)
{
WebInspector.resourceTreeModel.forAllResources(callback);
}
WebInspector.displayNameForURL = function(url)
{
if (!url)
return "";
var resource = WebInspector.resourceForURL(url);
if (resource)
return resource.displayName;
if (!WebInspector.inspectedPageURL)
return url.trimURL("");
var parsedURL = WebInspector.inspectedPageURL.asParsedURL();
var lastPathComponent = parsedURL ? parsedURL.lastPathComponent : parsedURL;
var index = WebInspector.inspectedPageURL.indexOf(lastPathComponent);
if (index !== -1 && index + lastPathComponent.length === WebInspector.inspectedPageURL.length) {
var baseURL = WebInspector.inspectedPageURL.substring(0, index);
if (url.startsWith(baseURL))
return url.substring(index);
}
return parsedURL ? url.trimURL(parsedURL.host) : url;
}
WebInspector.linkifyStringAsFragmentWithCustomLinkifier = function(string, linkifier)
{
var container = document.createDocumentFragment();
var linkStringRegEx = /(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\/\/|www\.)[\w$\-_+*'=\|\/\\(){}[\]%@&#~,:;.!?]{2,}[\w$\-_+*=\|\/\\({%@&#~]/;
var lineColumnRegEx = /:(\d+)(:(\d+))?$/;
while (string) {
var linkString = linkStringRegEx.exec(string);
if (!linkString)
break;
linkString = linkString[0];
var linkIndex = string.indexOf(linkString);
var nonLink = string.substring(0, linkIndex);
container.appendChild(document.createTextNode(nonLink));
var title = linkString;
var realURL = (linkString.startsWith("www.") ? "http://" + linkString : linkString);
var lineColumnMatch = lineColumnRegEx.exec(realURL);
var lineNumber;
if (lineColumnMatch) {
realURL = realURL.substring(0, realURL.length - lineColumnMatch[0].length);
lineNumber = parseInt(lineColumnMatch[1], 10);
lineNumber = isNaN(lineNumber) ? undefined : lineNumber;
}
var linkNode = linkifier(title, realURL, lineNumber);
container.appendChild(linkNode);
string = string.substring(linkIndex + linkString.length, string.length);
}
if (string)
container.appendChild(document.createTextNode(string));
return container;
}
WebInspector._linkifierPlugins = [];
/**
* @param {function(string):string} plugin
*/
WebInspector.registerLinkifierPlugin = function(plugin)
{
WebInspector._linkifierPlugins.push(plugin);
}
/**
* @param {string} string
* @return {DocumentFragment}
*/
WebInspector.linkifyStringAsFragment = function(string)
{
/**
* @param {string} title
* @param {string} url
* @param {number=} lineNumber
* @return {Node}
*/
function linkifier(title, url, lineNumber)
{
for (var i = 0; i < WebInspector._linkifierPlugins.length; ++i)
title = WebInspector._linkifierPlugins[i](title);
var isExternal = !WebInspector.resourceForURL(url);
var urlNode = WebInspector.linkifyURLAsNode(url, title, undefined, isExternal);
if (typeof(lineNumber) !== "undefined") {
urlNode.lineNumber = lineNumber;
urlNode.preferredPanel = "scripts";
}
return urlNode;
}
return WebInspector.linkifyStringAsFragmentWithCustomLinkifier(string, linkifier);
}
/**
* @param {string} url
* @param {string=} linkText
* @param {string=} classes
* @param {boolean=} isExternal
* @param {string=} tooltipText
* @return {Element}
*/
WebInspector.linkifyURLAsNode = function(url, linkText, classes, isExternal, tooltipText)
{
if (!linkText)
linkText = url;
classes = (classes ? classes + " " : "");
classes += isExternal ? "webkit-html-external-link" : "webkit-html-resource-link";
var a = document.createElement("a");
a.href = sanitizeHref(url);
a.className = classes;
if (typeof tooltipText === "undefined")
a.title = url;
else if (typeof tooltipText !== "string" || tooltipText.length)
a.title = tooltipText;
a.textContent = linkText;
a.style.maxWidth = "100%";
if (isExternal)
a.setAttribute("target", "_blank");
return a;
}
/**
* @param {string} url
* @param {number=} lineNumber
* @return {string}
*/
WebInspector.formatLinkText = function(url, lineNumber)
{
var text = WebInspector.displayNameForURL(url);
if (typeof lineNumber === "number")
text += ":" + (lineNumber + 1);
return text;
}
/**
* @param {string} url
* @param {number=} lineNumber
* @param {string=} classes
* @param {string=} tooltipText
* @return {Element}
*/
WebInspector.linkifyResourceAsNode = function(url, lineNumber, classes, tooltipText)
{
var linkText = WebInspector.formatLinkText(url, lineNumber);
var anchor = WebInspector.linkifyURLAsNode(url, linkText, classes, false, tooltipText);
anchor.preferredPanel = "resources";
anchor.lineNumber = lineNumber;
return anchor;
}
/**
* @param {WebInspector.NetworkRequest} request
* @param {string=} classes
* @return {Element}
*/
WebInspector.linkifyRequestAsNode = function(request, classes)
{
var anchor = WebInspector.linkifyURLAsNode(request.url);
anchor.preferredPanel = "network";
anchor.requestId = request.requestId;
return anchor;
}
/* ResourceType.js */
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {string} name
* @param {string} title
* @param {string} categoryTitle
* @param {string} color
* @param {boolean} isTextType
*/
WebInspector.ResourceType = function(name, title, categoryTitle, color, isTextType)
{
this._name = name;
this._title = title;
this._categoryTitle = categoryTitle;
this._color = color;
this._isTextType = isTextType;
}
WebInspector.ResourceType.prototype = {
/**
* @return {string}
*/
name: function()
{
return this._name;
},
/**
* @return {string}
*/
title: function()
{
return this._title;
},
/**
* @return {string}
*/
categoryTitle: function()
{
return this._categoryTitle;
},
/**
* @return {string}
*/
color: function()
{
return this._color;
},
/**
* @return {boolean}
*/
isTextType: function()
{
return this._isTextType;
},
/**
* @return {string}
*/
toString: function()
{
return this._name;
},
/**
* @return {string}
*/
canonicalMimeType: function()
{
if (this === WebInspector.resourceTypes.Document)
return "text/html";
if (this === WebInspector.resourceTypes.Script)
return "text/javascript";
if (this === WebInspector.resourceTypes.Stylesheet)
return "text/css";
return "";
}
}
//Keep these in sync with WebCore::InspectorPageAgent::resourceTypeJson
WebInspector.resourceTypes = {
Document: new WebInspector.ResourceType("document", "Document", "Documents", "rgb(47,102,236)", true),
Stylesheet: new WebInspector.ResourceType("stylesheet", "Stylesheet", "Stylesheets", "rgb(157,231,119)", true),
Image: new WebInspector.ResourceType("image", "Image", "Images", "rgb(164,60,255)", false),
Script: new WebInspector.ResourceType("script", "Script", "Scripts", "rgb(255,121,0)", true),
XHR: new WebInspector.ResourceType("xhr", "XHR", "XHR", "rgb(231,231,10)", true),
Font: new WebInspector.ResourceType("font", "Font", "Fonts", "rgb(255,82,62)", false),
WebSocket: new WebInspector.ResourceType("websocket", "WebSocket", "WebSockets", "rgb(186,186,186)", false), // FIXME: Decide the color.
Other: new WebInspector.ResourceType("other", "Other", "Other", "rgb(186,186,186)", false)
}
/* TimelineManager.js */
/*
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.TimelineManager = function()
{
WebInspector.Object.call(this);
this._dispatcher = new WebInspector.TimelineDispatcher(this);
this._enablementCount = 0;
}
WebInspector.TimelineManager.EventTypes = {
TimelineStarted: "TimelineStarted",
TimelineStopped: "TimelineStopped",
TimelineEventRecorded: "TimelineEventRecorded"
}
WebInspector.TimelineManager.prototype = {
/**
* @param {number=} maxCallStackDepth
*/
start: function(maxCallStackDepth)
{
this._enablementCount++;
if (this._enablementCount === 1)
TimelineAgent.start(maxCallStackDepth, this._started.bind(this));
},
stop: function()
{
if (!this._enablementCount) {
console.error("WebInspector.TimelineManager start/stop calls are unbalanced");
return;
}
this._enablementCount--;
if (!this._enablementCount)
TimelineAgent.stop(this._stopped.bind(this));
},
_started: function()
{
this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStarted);
},
_stopped: function()
{
this.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineStopped);
}
}
WebInspector.TimelineManager.prototype.__proto__ = WebInspector.Object.prototype;
/**
* @constructor
* @implements {TimelineAgent.Dispatcher}
*/
WebInspector.TimelineDispatcher = function(manager)
{
this._manager = manager;
InspectorBackend.registerTimelineDispatcher(this);
}
WebInspector.TimelineDispatcher.prototype = {
eventRecorded: function(record)
{
this._manager.dispatchEventToListeners(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded, record);
}
}
/**
* @type {WebInspector.TimelineManager}
*/
WebInspector.timelineManager;
/* UserAgentSupport.js */
/*
* Copyright (C) 2012 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
* met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the following disclaimer
* in the documentation and/or other materials provided with the
* distribution.
* * Neither the name of Google Inc. nor the names of its
* contributors may be used to endorse or promote products derived from
* this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
*/
WebInspector.UserAgentSupport = function()
{
if (WebInspector.settings.deviceMetrics.get())
this._deviceMetricsChanged();
WebInspector.settings.deviceMetrics.addChangeListener(this._deviceMetricsChanged, this);
WebInspector.settings.deviceFitWindow.addChangeListener(this._deviceMetricsChanged, this);
WebInspector.settings.geolocationOverride.addChangeListener(this._geolocationPositionChanged, this);
WebInspector.settings.deviceOrientationOverride.addChangeListener(this._deviceOrientationChanged, this);
}
/**
* @constructor
* @param {number} width
* @param {number} height
* @param {number} fontScaleFactor
*/
WebInspector.UserAgentSupport.DeviceMetrics = function(width, height, fontScaleFactor)
{
this.width = width;
this.height = height;
this.fontScaleFactor = fontScaleFactor;
}
/**
* @return {WebInspector.UserAgentSupport.DeviceMetrics}
*/
WebInspector.UserAgentSupport.DeviceMetrics.parseSetting = function(value)
{
if (value) {
var splitMetrics = value.split("x");
if (splitMetrics.length === 3)
return new WebInspector.UserAgentSupport.DeviceMetrics(parseInt(splitMetrics[0], 10), parseInt(splitMetrics[1], 10), parseFloat(splitMetrics[2]));
}
return new WebInspector.UserAgentSupport.DeviceMetrics(0, 0, 1);
}
/**
* @return {?WebInspector.UserAgentSupport.DeviceMetrics}
*/
WebInspector.UserAgentSupport.DeviceMetrics.parseUserInput = function(widthString, heightString, fontScaleFactorString)
{
function isUserInputValid(value, isInteger)
{
if (!value)
return true;
return isInteger ? /^[0]*[1-9][\d]*$/.test(value) : /^[0]*([1-9][\d]*(\.\d+)?|\.\d+)$/.test(value);
}
if (!widthString ^ !heightString)
return null;
var isWidthValid = isUserInputValid(widthString, true);
var isHeightValid = isUserInputValid(heightString, true);
var isFontScaleFactorValid = isUserInputValid(fontScaleFactorString, false);
if (!isWidthValid && !isHeightValid && !isFontScaleFactorValid)
return null;
var width = isWidthValid ? parseInt(widthString || "0", 10) : -1;
var height = isHeightValid ? parseInt(heightString || "0", 10) : -1;
var fontScaleFactor = isFontScaleFactorValid ? parseFloat(fontScaleFactorString) : -1;
return new WebInspector.UserAgentSupport.DeviceMetrics(width, height, fontScaleFactor);
}
WebInspector.UserAgentSupport.DeviceMetrics.prototype = {
/**
* @return {boolean}
*/
isValid: function()
{
return this.isWidthValid() && this.isHeightValid() && this.isFontScaleFactorValid();
},
/**
* @return {boolean}
*/
isWidthValid: function()
{
return this.width >= 0;
},
/**
* @return {boolean}
*/
isHeightValid: function()
{
return this.height >= 0;
},
/**
* @return {boolean}
*/
isFontScaleFactorValid: function()
{
return this.fontScaleFactor > 0;
},
/**
* @return {string}
*/
toSetting: function()
{
if (!this.isValid())
return "";
return this.width && this.height ? this.width + "x" + this.height + "x" + this.fontScaleFactor : "";
},
/**
* @return {string}
*/
widthToInput: function()
{
return this.isWidthValid() && this.width ? String(this.width) : "";
},
/**
* @return {string}
*/
heightToInput: function()
{
return this.isHeightValid() && this.height ? String(this.height) : "";
},
/**
* @return {string}
*/
fontScaleFactorToInput: function()
{
return this.isFontScaleFactorValid() && this.fontScaleFactor ? String(this.fontScaleFactor) : "";
}
}
/**
* @constructor
* @param {number} latitude
* @param {number} longitude
*/
WebInspector.UserAgentSupport.GeolocationPosition = function(latitude, longitude, error)
{
this.latitude = latitude;
this.longitude = longitude;
this.error = error;
}
WebInspector.UserAgentSupport.GeolocationPosition.prototype = {
/**
* @return {string}
*/
toSetting: function()
{
return (typeof this.latitude === "number" && typeof this.longitude === "number" && typeof this.error === "string") ? this.latitude + "@" + this.longitude + ":" + this.error : "";
}
}
/**
* @return {WebInspector.UserAgentSupport.GeolocationPosition}
*/
WebInspector.UserAgentSupport.GeolocationPosition.parseSetting = function(value)
{
if (value) {
var splitError = value.split(":");
if (splitError.length === 2) {
var splitPosition = splitError[0].split("@")
if (splitPosition.length === 2)
return new WebInspector.UserAgentSupport.GeolocationPosition(parseFloat(splitPosition[0]), parseFloat(splitPosition[1]), splitError[1]);
}
}
return new WebInspector.UserAgentSupport.GeolocationPosition(0, 0, "");
}
/**
* @return {?WebInspector.UserAgentSupport.GeolocationPosition}
*/
WebInspector.UserAgentSupport.GeolocationPosition.parseUserInput = function(latitudeString, longitudeString, errorStatus)
{
function isUserInputValid(value)
{
if (!value)
return true;
return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
}
if (!latitudeString ^ !latitudeString)
return null;
var isLatitudeValid = isUserInputValid(latitudeString);
var isLongitudeValid = isUserInputValid(longitudeString);
if (!isLatitudeValid && !isLongitudeValid)
return null;
var latitude = isLatitudeValid ? parseFloat(latitudeString) : -1;
var longitude = isLongitudeValid ? parseFloat(longitudeString) : -1;
return new WebInspector.UserAgentSupport.GeolocationPosition(latitude, longitude, errorStatus ? "PositionUnavailable" : "");
}
WebInspector.UserAgentSupport.GeolocationPosition.clearGeolocationOverride = function()
{
PageAgent.clearGeolocationOverride();
}
/**
* @constructor
* @param {number} alpha
* @param {number} beta
* @param {number} gamma
*/
WebInspector.UserAgentSupport.DeviceOrientation = function(alpha, beta, gamma)
{
this.alpha = alpha;
this.beta = beta;
this.gamma = gamma;
}
WebInspector.UserAgentSupport.DeviceOrientation.prototype = {
/**
* @return {string}
*/
toSetting: function()
{
return JSON.stringify(this);
}
}
/**
* @return {WebInspector.UserAgentSupport.DeviceOrientation}
*/
WebInspector.UserAgentSupport.DeviceOrientation.parseSetting = function(value)
{
if (value) {
var jsonObject = JSON.parse(value);
return new WebInspector.UserAgentSupport.DeviceOrientation(jsonObject.alpha, jsonObject.beta, jsonObject.gamma);
}
return new WebInspector.UserAgentSupport.DeviceOrientation(0, 0, 0);
}
/**
* @return {?WebInspector.UserAgentSupport.DeviceOrientation}
*/
WebInspector.UserAgentSupport.DeviceOrientation.parseUserInput = function(alphaString, betaString, gammaString)
{
function isUserInputValid(value)
{
if (!value)
return true;
return /^[-]?[0-9]*[.]?[0-9]*$/.test(value);
}
if (!alphaString ^ !betaString ^ !gammaString)
return null;
var isAlphaValid = isUserInputValid(alphaString);
var isBetaValid = isUserInputValid(betaString);
var isGammaValid = isUserInputValid(gammaString);
if (!isAlphaValid && !isBetaValid && !isGammaValid)
return null;
var alpha = isAlphaValid ? parseFloat(alphaString) : -1;
var beta = isBetaValid ? parseFloat(betaString) : -1;
var gamma = isGammaValid ? parseFloat(gammaString) : -1;
return new WebInspector.UserAgentSupport.DeviceOrientation(alpha, beta, gamma);
}
WebInspector.UserAgentSupport.DeviceOrientation.clearDeviceOrientationOverride = function()
{
PageAgent.clearDeviceOrientationOverride();
}
WebInspector.UserAgentSupport.prototype = {
_deviceMetricsChanged: function()
{
var metrics = WebInspector.UserAgentSupport.DeviceMetrics.parseSetting(WebInspector.settings.deviceMetrics.get());
if (metrics.isValid())
PageAgent.setDeviceMetricsOverride(metrics.width, metrics.height, metrics.fontScaleFactor, WebInspector.settings.deviceFitWindow.get());
},
_geolocationPositionChanged: function()
{
var geolocation = WebInspector.UserAgentSupport.GeolocationPosition.parseSetting(WebInspector.settings.geolocationOverride.get());
if (geolocation.error)
PageAgent.setGeolocationOverride();
else
PageAgent.setGeolocationOverride(geolocation.latitude, geolocation.longitude, 150);
},
/**
* @param {WebInspector.Event} event
*/
_deviceOrientationChanged: function(event)
{
var deviceOrientation = WebInspector.UserAgentSupport.DeviceOrientation.parseSetting(WebInspector.settings.deviceOrientationOverride.get());
PageAgent.setDeviceOrientationOverride(deviceOrientation.alpha, deviceOrientation.beta, deviceOrientation.gamma);
}
}
/* Database.js */
/*
* Copyright (C) 2007, 2008 Apple Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @param {WebInspector.DatabaseModel} model
*/
WebInspector.Database = function(model, id, domain, name, version)
{
this._model = model;
this._id = id;
this._domain = domain;
this._name = name;
this._version = version;
}
WebInspector.Database.prototype = {
/** @return {string} */
get id()
{
return this._id;
},
/** @return {string} */
get name()
{
return this._name;
},
set name(x)
{
this._name = x;
},
/** @return {string} */
get version()
{
return this._version;
},
set version(x)
{
this._version = x;
},
/** @return {string} */
get domain()
{
return this._domain;
},
set domain(x)
{
this._domain = x;
},
/**
* @param {function(Array.<string>)} callback
*/
getTableNames: function(callback)
{
function sortingCallback(error, names)
{
if (!error)
callback(names.sort());
}
DatabaseAgent.getDatabaseTableNames(this._id, sortingCallback);
},
/**
* @param {string} query
* @param {function(Array.<string>=, Array.<*>=)} onSuccess
* @param {function(string)} onError
*/
executeSql: function(query, onSuccess, onError)
{
/**
* @param {?Protocol.Error} error
* @param {Array.<string>=} columnNames
* @param {Array.<*>=} values
* @param {DatabaseAgent.Error=} errorObj
*/
function callback(error, columnNames, values, errorObj)
{
if (error) {
onError(error);
return;
}
if (errorObj) {
var message;
if (errorObj.message)
message = errorObj.message;
else if (errorObj.code == 2)
message = WebInspector.UIString("Database no longer has expected version.");
else
message = WebInspector.UIString("An unexpected error %s occurred.", errorObj.code);
onError(message);
return;
}
onSuccess(columnNames, values);
}
DatabaseAgent.executeSQL(this._id, query, callback.bind(this));
}
}
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.DatabaseModel = function()
{
this._databases = [];
InspectorBackend.registerDatabaseDispatcher(new WebInspector.DatabaseDispatcher(this));
DatabaseAgent.enable();
}
WebInspector.DatabaseModel.Events = {
DatabaseAdded: "DatabaseAdded"
}
WebInspector.DatabaseModel.prototype = {
/**
* @return {Array.<WebInspector.Database>}
*/
databases: function()
{
var result = [];
for (var databaseId in this._databases)
result.push(this._databases[databaseId]);
return result;
},
/**
* @param {DatabaseAgent.DatabaseId} databaseId
* @return {WebInspector.Database}
*/
databaseForId: function(databaseId)
{
return this._databases[databaseId];
},
/**
* @param {WebInspector.Database} database
*/
_addDatabase: function(database)
{
this._databases.push(database);
this.dispatchEventToListeners(WebInspector.DatabaseModel.Events.DatabaseAdded, database);
}
}
WebInspector.DatabaseModel.prototype.__proto__ = WebInspector.Object.prototype;
/**
* @constructor
* @implements {DatabaseAgent.Dispatcher}
* @param {WebInspector.DatabaseModel} model
*/
WebInspector.DatabaseDispatcher = function(model)
{
this._model = model;
}
WebInspector.DatabaseDispatcher.prototype = {
/**
* @param {DatabaseAgent.Database} payload
*/
addDatabase: function(payload)
{
this._model._addDatabase(new WebInspector.Database(
this._model,
payload.id,
payload.domain,
payload.name,
payload.version));
}
}
/**
* @type {WebInspector.DatabaseModel}
*/
WebInspector.databaseModel = null;
/* DOMStorage.js */
/*
* Copyright (C) 2008 Nokia Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of Apple Computer, Inc. ("Apple") nor the names of
* its contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED "AS IS" AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
*/
WebInspector.DOMStorage = function(id, domain, isLocalStorage)
{
this._id = id;
this._domain = domain;
this._isLocalStorage = isLocalStorage;
}
WebInspector.DOMStorage.prototype = {
/** @return {string} */
get id()
{
return this._id;
},
/** @return {string} */
get domain()
{
return this._domain;
},
/** @return {boolean} */
get isLocalStorage()
{
return this._isLocalStorage;
},
/**
* @param {function(?Protocol.Error, Array.<DOMStorageAgent.Entry>):void=} callback
*/
getEntries: function(callback)
{
DOMStorageAgent.getDOMStorageEntries(this._id, callback);
},
/**
* @param {string} key
* @param {string} value
* @param {function(?Protocol.Error, boolean):void=} callback
*/
setItem: function(key, value, callback)
{
DOMStorageAgent.setDOMStorageItem(this._id, key, value, callback);
},
/**
* @param {string} key
* @param {function(?Protocol.Error, boolean):void=} callback
*/
removeItem: function(key, callback)
{
DOMStorageAgent.removeDOMStorageItem(this._id, key, callback);
}
}
/**
* @constructor
* @extends {WebInspector.Object}
*/
WebInspector.DOMStorageModel = function()
{
this._storages = {};
InspectorBackend.registerDOMStorageDispatcher(new WebInspector.DOMStorageDispatcher(this));
DOMStorageAgent.enable();
}
WebInspector.DOMStorageModel.Events = {
DOMStorageAdded: "DOMStorageAdded",
DOMStorageUpdated: "DOMStorageUpdated"
}
WebInspector.DOMStorageModel.prototype = {
/**
* @param {WebInspector.DOMStorage} domStorage
*/
_addDOMStorage: function(domStorage)
{
this._storages[domStorage.id] = domStorage;
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageAdded, domStorage);
},
/**
* @param {DOMStorageAgent.StorageId} storageId
*/
_domStorageUpdated: function(storageId)
{
this.dispatchEventToListeners(WebInspector.DOMStorageModel.Events.DOMStorageUpdated, this._storages[storageId]);
},
/**
* @param {DOMStorageAgent.StorageId} storageId
* @return {WebInspector.DOMStorage}
*/
storageForId: function(storageId)
{
return this._storages[storageId];
},
/**
* @return {Array.<WebInspector.DOMStorage>}
*/
storages: function()
{
var result = [];
for (var storageId in this._storages)
result.push(this._storages[storageId]);
return result;
}
}
WebInspector.DOMStorageModel.prototype.__proto__ = WebInspector.Object.prototype;
/**
* @constructor
* @implements {DOMStorageAgent.Dispatcher}
* @param {WebInspector.DOMStorageModel} model
*/
WebInspector.DOMStorageDispatcher = function(model)
{
this._model = model;
}
WebInspector.DOMStorageDispatcher.prototype = {
/**
* @param {DOMStorageAgent.Entry} payload
*/
addDOMStorage: function(payload)
{
this._model._addDOMStorage(new WebInspector.DOMStorage(
payload.id,
payload.origin,
payload.isLocalStorage));
},
/**
* @param {string} storageId
*/
domStorageUpdated: function(storageId)
{
this._model._domStorageUpdated(storageId);
}
}
/**
* @type {WebInspector.DOMStorageModel}
*/
WebInspector.domStorageModel = null;
/* DataGrid.js */
/*
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
/**
* @constructor
* @extends {WebInspector.View}
* @param {function(WebInspector.DataGridNode, number, string, string)=} editCallback
* @param {function(WebInspector.DataGridNode)=} deleteCallback
*/
WebInspector.DataGrid = function(columns, editCallback, deleteCallback)
{
WebInspector.View.call(this);
this.registerRequiredCSS("dataGrid.css");
this.element.className = "data-grid";
this.element.tabIndex = 0;
this.element.addEventListener("keydown", this._keyDown.bind(this), false);
this._headerTable = document.createElement("table");
this._headerTable.className = "header";
this._headerTableHeaders = {};
this._dataTable = document.createElement("table");
this._dataTable.className = "data";
this._dataTable.addEventListener("mousedown", this._mouseDownInDataTable.bind(this), true);
this._dataTable.addEventListener("click", this._clickInDataTable.bind(this), true);
this._dataTable.addEventListener("contextmenu", this._contextMenuInDataTable.bind(this), true);
// FIXME: Add a createCallback which is different from editCallback and has different
// behavior when creating a new node.
if (editCallback) {
this._dataTable.addEventListener("dblclick", this._ondblclick.bind(this), false);
this._editCallback = editCallback;
}
if (deleteCallback)
this._deleteCallback = deleteCallback;
this.aligned = {};
this._scrollContainer = document.createElement("div");
this._scrollContainer.className = "data-container";
this._scrollContainer.appendChild(this._dataTable);
this.element.appendChild(this._headerTable);
this.element.appendChild(this._scrollContainer);
var headerRow = document.createElement("tr");
var columnGroup = document.createElement("colgroup");
this._columnCount = 0;
for (var columnIdentifier in columns) {
var column = columns[columnIdentifier];
if (column.disclosure)
this.disclosureColumnIdentifier = columnIdentifier;
var col = document.createElement("col");
if (column.width)
col.style.width = column.width;
column.element = col;
columnGroup.appendChild(col);
var cell = document.createElement("th");
cell.className = columnIdentifier + "-column";
cell.columnIdentifier = columnIdentifier;
this._headerTableHeaders[columnIdentifier] = cell;
var div = document.createElement("div");
if (column.titleDOMFragment)
div.appendChild(column.titleDOMFragment);
else
div.textContent = column.title;
cell.appendChild(div);
if (column.sort) {
cell.addStyleClass("sort-" + column.sort);
this._sortColumnCell = cell;
}
if (column.sortable) {
cell.addEventListener("click", this._clickInHeaderCell.bind(this), false);
cell.addStyleClass("sortable");
}
if (column.aligned)
this.aligned[columnIdentifier] = column.aligned;
headerRow.appendChild(cell);
++this._columnCount;
}
columnGroup.span = this._columnCount;
var cell = document.createElement("th");
cell.className = "corner";
headerRow.appendChild(cell);
this._headerTableColumnGroup = columnGroup;
this._headerTable.appendChild(this._headerTableColumnGroup);
this.headerTableBody.appendChild(headerRow);
var fillerRow = document.createElement("tr");
fillerRow.className = "filler";
for (var columnIdentifier in columns) {
var column = columns[columnIdentifier];
var td = document.createElement("td");
td.className = columnIdentifier + "-column";
fillerRow.appendChild(td);
}
this._dataTableColumnGroup = columnGroup.cloneNode(true);
this._dataTable.appendChild(this._dataTableColumnGroup);
this.dataTableBody.appendChild(fillerRow);
this.columns = columns || {};
this._columnsArray = [];
for (var columnIdentifier in columns) {
columns[columnIdentifier].ordinal = this._columnsArray.length;
columns[columnIdentifier].identifier = columnIdentifier;
this._columnsArray.push(columns[columnIdentifier]);
}
for (var i = 0; i < this._columnsArray.length; ++i)
this._columnsArray[i].bodyElement = this._dataTableColumnGroup.children[i];
this.selectedNode = null;
this.expandNodesWhenArrowing = false;
this.setRootNode(new WebInspector.DataGridNode());
this.indentWidth = 15;
this.resizers = [];
this._columnWidthsInitialized = false;
}
WebInspector.DataGrid.Events = {
SelectedNode: "SelectedNode",
DeselectedNode: "DeselectedNode"
}
/**
* @param {Array.<string>} columnNames
* @param {Array.<string>} values
*/
WebInspector.DataGrid.createSortableDataGrid = function(columnNames, values)
{
var numColumns = columnNames.length;
if (!numColumns)
return null;
var columns = {};
for (var i = 0; i < columnNames.length; ++i) {
var column = {};
column.width = columnNames[i].length;
column.title = columnNames[i];
column.sortable = true;
columns[columnNames[i]] = column;
}
var nodes = [];
for (var i = 0; i < values.length / numColumns; ++i) {
var data = {};
for (var j = 0; j < columnNames.length; ++j)
data[columnNames[j]] = values[numColumns * i + j];
var node = new WebInspector.DataGridNode(data, false);
node.selectable = false;
nodes.push(node);
}
var dataGrid = new WebInspector.DataGrid(columns);
var length = nodes.length;
for (var i = 0; i < length; ++i)
dataGrid.rootNode().appendChild(nodes[i]);
dataGrid.addEventListener("sorting changed", sortDataGrid, this);
function sortDataGrid()
{
var nodes = dataGrid._rootNode.children.slice();
var sortColumnIdentifier = dataGrid.sortColumnIdentifier;
var sortDirection = dataGrid.sortOrder === "ascending" ? 1 : -1;
var columnIsNumeric = true;
for (var i = 0; i < nodes.length; i++) {
if (isNaN(Number(nodes[i].data[sortColumnIdentifier])))
columnIsNumeric = false;
}
function comparator(dataGridNode1, dataGridNode2)
{
var item1 = dataGridNode1.data[sortColumnIdentifier];
var item2 = dataGridNode2.data[sortColumnIdentifier];
var comparison;
if (columnIsNumeric) {
// Sort numbers based on comparing their values rather than a lexicographical comparison.
var number1 = parseFloat(item1);
var number2 = parseFloat(item2);
comparison = number1 < number2 ? -1 : (number1 > number2 ? 1 : 0);
} else
comparison = item1 < item2 ? -1 : (item1 > item2 ? 1 : 0);
return sortDirection * comparison;
}
nodes.sort(comparator);
dataGrid.rootNode().removeChildren();
for (var i = 0; i < nodes.length; i++)
dataGrid._rootNode.appendChild(nodes[i]);
}
return dataGrid;
}
WebInspector.DataGrid.prototype = {
setRootNode: function(rootNode)
{
if (this._rootNode) {
this._rootNode.removeChildren();
this._rootNode.dataGrid = null;
this._rootNode._isRoot = false;
}
this._rootNode = rootNode;
rootNode._isRoot = true;
rootNode.hasChildren = false;
rootNode._expanded = true;
rootNode._revealed = true;
rootNode.dataGrid = this;
},
rootNode: function()
{
return this._rootNode;
},
get refreshCallback()
{
return this._refreshCallback;
},
set refreshCallback(refreshCallback)
{
this._refreshCallback = refreshCallback;
},
_ondblclick: function(event)
{
if (this._editing || this._editingNode)
return;
this._startEditing(event.target);
},
_startEditingColumnOfDataGridNode: function(node, column)
{
this._editing = true;
this._editingNode = node;
this._editingNode.select();
var element = this._editingNode._element.children[column];
WebInspector.startEditing(element, this._startEditingConfig(element));
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
_startEditing: function(target)
{
var element = target.enclosingNodeOrSelfWithNodeName("td");
if (!element)
return;
this._editingNode = this.dataGridNodeFromNode(target);
if (!this._editingNode) {
if (!this.creationNode)
return;
this._editingNode = this.creationNode;
}
// Force editing the 1st column when editing the creation node
if (this._editingNode.isCreationNode)
return this._startEditingColumnOfDataGridNode(this._editingNode, 0);
this._editing = true;
WebInspector.startEditing(element, this._startEditingConfig(element));
window.getSelection().setBaseAndExtent(element, 0, element, 1);
},
_startEditingConfig: function(element)
{
return new WebInspector.EditingConfig(this._editingCommitted.bind(this), this._editingCancelled.bind(this), element.textContent);
},
_editingCommitted: function(element, newText, oldText, context, moveDirection)
{
// FIXME: We need more column identifiers here throughout this function.
// Not needed yet since only editable DataGrid is DOM Storage, which is Key - Value.
// FIXME: Better way to do this than regular expressions?
var columnIdentifier = parseInt(element.className.match(/\b(\d+)-column\b/)[1], 10);
var textBeforeEditing = this._editingNode.data[columnIdentifier];
var currentEditingNode = this._editingNode;
function moveToNextIfNeeded(wasChange) {
if (!moveDirection)
return;
if (moveDirection === "forward") {
if (currentEditingNode.isCreationNode && columnIdentifier === 0 && !wasChange)
return;
if (columnIdentifier === 0)
return this._startEditingColumnOfDataGridNode(currentEditingNode, 1);
var nextDataGridNode = currentEditingNode.traverseNextNode(true, null, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, 0);
if (currentEditingNode.isCreationNode && wasChange) {
this.addCreationNode(false);
return this._startEditingColumnOfDataGridNode(this.creationNode, 0);
}
return;
}
if (moveDirection === "backward") {
if (columnIdentifier === 1)
return this._startEditingColumnOfDataGridNode(currentEditingNode, 0);
var nextDataGridNode = currentEditingNode.traversePreviousNode(true, null, true);
if (nextDataGridNode)
return this._startEditingColumnOfDataGridNode(nextDataGridNode, 1);
return;
}
}
if (textBeforeEditing == newText) {
this._editingCancelled(element);
moveToNextIfNeeded.call(this, false);
return;
}
// Update the text in the datagrid that we typed
this._editingNode.data[columnIdentifier] = newText;
// Make the callback - expects an editing node (table row), the column number that is being edited,
// the text that used to be there, and the new text.
this._editCallback(this._editingNode, columnIdentifier, textBeforeEditing, newText);
if (this._editingNode.isCreationNode)
this.addCreationNode(false);
this._editingCancelled(element);
moveToNextIfNeeded.call(this, true);
},
_editingCancelled: function(element)
{
delete this._editing;
this._editingNode = null;
},
/**
* @return {?string}
*/
get sortColumnIdentifier()
{
if (!this._sortColumnCell)
return null;
return this._sortColumnCell.columnIdentifier;
},
/**
* @return {?string}
*/
get sortOrder()
{
if (!this._sortColumnCell || this._sortColumnCell.hasStyleClass("sort-ascending"))
return "ascending";
if (this._sortColumnCell.hasStyleClass("sort-descending"))
return "descending";
return null;
},
get headerTableBody()
{
if ("_headerTableBody" in this)
return this._headerTableBody;
this._headerTableBody = this._headerTable.getElementsByTagName("tbody")[0];
if (!this._headerTableBody) {
this._headerTableBody = this.element.ownerDocument.createElement("tbody");
this._headerTable.insertBefore(this._headerTableBody, this._headerTable.tFoot);
}
return this._headerTableBody;
},
get dataTableBody()
{
if ("_dataTableBody" in this)
return this._dataTableBody;
this._dataTableBody = this._dataTable.getElementsByTagName("tbody")[0];
if (!this._dataTableBody) {
this._dataTableBody = this.element.ownerDocument.createElement("tbody");
this._dataTable.insertBefore(this._dataTableBody, this._dataTable.tFoot);
}
return this._dataTableBody;
},
/**
* @param {number=} maxDescentLevel
*/
autoSizeColumns: function(minPercent, maxPercent, maxDescentLevel)
{
if (minPercent)
minPercent = Math.min(minPercent, Math.floor(100 / this._columnCount));
var widths = {};
var columns = this.columns;
for (var columnIdentifier in columns)
widths[columnIdentifier] = (columns[columnIdentifier].title || "").length;
maxDescentLevel = maxDescentLevel || 0;
var children = this._enumerateChildren(this._rootNode, [], maxDescentLevel + 1);
for (var i = 0; i < children.length; ++i) {
var node = children[i];
for (var columnIdentifier in columns) {
var text = node.data[columnIdentifier] || "";
if (text.length > widths[columnIdentifier])
widths[columnIdentifier] = text.length;
}
}
var totalColumnWidths = 0;
for (var columnIdentifier in columns)
totalColumnWidths += widths[columnIdentifier];
var recoupPercent = 0;
for (var columnIdentifier in columns) {
var width = Math.round(100 * widths[columnIdentifier] / totalColumnWidths);
if (minPercent && width < minPercent) {
recoupPercent += (minPercent - width);
width = minPercent;
} else if (maxPercent && width > maxPercent) {
recoupPercent -= (width - maxPercent);
width = maxPercent;
}
widths[columnIdentifier] = width;
}
while (minPercent && recoupPercent > 0) {
for (var columnIdentifier in columns) {
if (widths[columnIdentifier] > minPercent) {
--widths[columnIdentifier];
--recoupPercent;
if (!recoupPercent)
break;
}
}
}
while (maxPercent && recoupPercent < 0) {
for (var columnIdentifier in columns) {
if (widths[columnIdentifier] < maxPercent) {
++widths[columnIdentifier];
++recoupPercent;
if (!recoupPercent)
break;
}
}
}
for (var columnIdentifier in columns)
columns[columnIdentifier].element.style.width = widths[columnIdentifier] + "%";
this._columnWidthsInitialized = false;
this.updateWidths();
},
_enumerateChildren: function(rootNode, result, maxLevel)
{
if (!rootNode._isRoot)
result.push(rootNode);
if (!maxLevel)
return;
for (var i = 0; i < rootNode.children.length; ++i)
this._enumerateChildren(rootNode.children[i], result, maxLevel - 1);
return result;
},
onResize: function()
{
this.updateWidths();
},
// Updates the widths of the table, including the positions of the column
// resizers.
//
// IMPORTANT: This function MUST be called once after the element of the
// DataGrid is attached to its parent element and every subsequent time the
// width of the parent element is changed in order to make it possible to
// resize the columns.
//
// If this function is not called after the DataGrid is attached to its
// parent element, then the DataGrid's columns will not be resizable.
updateWidths: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var tableWidth = this._dataTable.offsetWidth;
var numColumns = headerTableColumns.length;
if (!this._columnWidthsInitialized && this.element.offsetWidth) {
for (var i = 0; i < numColumns; i++) {
var columnWidth = this.headerTableBody.rows[0].cells[i].offsetWidth;
var percentWidth = ((columnWidth / tableWidth) * 100) + "%";
this._headerTableColumnGroup.children[i].style.width = percentWidth;
this._dataTableColumnGroup.children[i].style.width = percentWidth;
}
this._columnWidthsInitialized = true;
}
this._positionResizers();
this.dispatchEventToListeners("width changed");
},
columnWidthsMap: function()
{
var result = {};
for (var i = 0; i < this._columnsArray.length; ++i) {
var width = this._headerTableColumnGroup.children[i].style.width;
result[this._columnsArray[i].columnIdentifier] = parseFloat(width);
}
return result;
},
applyColumnWidthsMap: function(columnWidthsMap)
{
for (var columnIdentifier in this.columns) {
var column = this.columns[columnIdentifier];
var width = (columnWidthsMap[columnIdentifier] || 0) + "%";
this._headerTableColumnGroup.children[column.ordinal].style.width = width;
this._dataTableColumnGroup.children[column.ordinal].style.width = width;
}
delete this._columnWidthsInitialized;
this.updateWidths();
},
isColumnVisible: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
return !columnElement.hidden;
},
showColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (!columnElement.hidden)
return;
columnElement.hidden = false;
columnElement.removeStyleClass("hidden");
var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = false;
columnBodyElement.removeStyleClass("hidden");
},
hideColumn: function(columnIdentifier)
{
var column = this.columns[columnIdentifier];
var columnElement = column.element;
if (columnElement.hidden)
return;
var oldWidth = parseFloat(columnElement.style.width);
columnElement.hidden = true;
columnElement.addStyleClass("hidden");
columnElement.style.width = 0;
var columnBodyElement = column.bodyElement;
columnBodyElement.hidden = true;
columnBodyElement.addStyleClass("hidden");
columnBodyElement.style.width = 0;
this._columnWidthsInitialized = false;
},
get scrollContainer()
{
return this._scrollContainer;
},
isScrolledToLastRow: function()
{
return this._scrollContainer.isScrolledToBottom();
},
scrollToLastRow: function()
{
this._scrollContainer.scrollTop = this._scrollContainer.scrollHeight - this._scrollContainer.offsetHeight;
},
_positionResizers: function()
{
var headerTableColumns = this._headerTableColumnGroup.children;
var numColumns = headerTableColumns.length;
var left = 0;
var previousResizer = null;
for (var i = 0; i < numColumns - 1; i++) {
var resizer = this.resizers[i];
if (!resizer) {
resizer = document.createElement("div");
resizer.addStyleClass("data-grid-resizer");
WebInspector.installDragHandle(resizer, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "col-resize");
this.element.appendChild(resizer);
this.resizers[i] = resizer;
}
left += this.headerTableBody.rows[0].cells[i].offsetWidth;
var columnIsVisible = !this._headerTableColumnGroup.children[i].hidden;
if (columnIsVisible) {
resizer.style.removeProperty("display");
resizer.style.left = left + "px";
resizer.leftNeighboringColumnID = i;
if (previousResizer)
previousResizer.rightNeighboringColumnID = i;
previousResizer = resizer;
} else {
resizer.style.setProperty("display", "none");
resizer.leftNeighboringColumnID = 0;
resizer.rightNeighboringColumnID = 0;
}
}
if (previousResizer)
previousResizer.rightNeighboringColumnID = numColumns - 1;
},
addCreationNode: function(hasChildren)
{
if (this.creationNode)
this.creationNode.makeNormal();
var emptyData = {};
for (var column in this.columns)
emptyData[column] = '';
this.creationNode = new WebInspector.CreationDataGridNode(emptyData, hasChildren);
this.rootNode().appendChild(this.creationNode);
},
sortNodes: function(comparator, reverseMode)
{
function comparatorWrapper(a, b)
{
if (a._dataGridNode._data.summaryRow)
return 1;
if (b._dataGridNode._data.summaryRow)
return -1;
var aDataGirdNode = a._dataGridNode;
var bDataGirdNode = b._dataGridNode;
return reverseMode ? comparator(bDataGirdNode, aDataGirdNode) : comparator(aDataGirdNode, bDataGirdNode);
}
var tbody = this.dataTableBody;
var tbodyParent = tbody.parentElement;
tbodyParent.removeChild(tbody);
var childNodes = tbody.childNodes;
var fillerRow = childNodes[childNodes.length - 1];
var sortedRows = Array.prototype.slice.call(childNodes, 0, childNodes.length - 1);
sortedRows.sort(comparatorWrapper);
var sortedRowsLength = sortedRows.length;
tbody.removeChildren();
var previousSiblingNode = null;
for (var i = 0; i < sortedRowsLength; ++i) {
var row = sortedRows[i];
var node = row._dataGridNode;
node.previousSibling = previousSiblingNode;
if (previousSiblingNode)
previousSiblingNode.nextSibling = node;
tbody.appendChild(row);
previousSiblingNode = node;
}
if (previousSiblingNode)
previousSiblingNode.nextSibling = null;
tbody.appendChild(fillerRow);
tbodyParent.appendChild(tbody);
},
_keyDown: function(event)
{
if (!this.selectedNode || event.shiftKey || event.metaKey || event.ctrlKey || this._editing)
return;
var handled = false;
var nextSelectedNode;
if (event.keyIdentifier === "Up" && !event.altKey) {
nextSelectedNode = this.selectedNode.traversePreviousNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traversePreviousNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Down" && !event.altKey) {
nextSelectedNode = this.selectedNode.traverseNextNode(true);
while (nextSelectedNode && !nextSelectedNode.selectable)
nextSelectedNode = nextSelectedNode.traverseNextNode(true);
handled = nextSelectedNode ? true : false;
} else if (event.keyIdentifier === "Left") {
if (this.selectedNode.expanded) {
if (event.altKey)
this.selectedNode.collapseRecursively();
else
this.selectedNode.collapse();
handled = true;
} else if (this.selectedNode.parent && !this.selectedNode.parent._isRoot) {
handled = true;
if (this.selectedNode.parent.selectable) {
nextSelectedNode = this.selectedNode.parent;
handled = nextSelectedNode ? true : false;
} else if (this.selectedNode.parent)
this.selectedNode.parent.collapse();
}
} else if (event.keyIdentifier === "Right") {
if (!this.selectedNode.revealed) {
this.selectedNode.reveal();
handled = true;
} else if (this.selectedNode.hasChildren) {
handled = true;
if (this.selectedNode.expanded) {
nextSelectedNode = this.selectedNode.children[0];
handled = nextSelectedNode ? true : false;
} else {
if (event.altKey)
this.selectedNode.expandRecursively();
else
this.selectedNode.expand();
}
}
} else if (event.keyCode === 8 || event.keyCode === 46) {
if (this._deleteCallback) {
handled = true;
this._deleteCallback(this.selectedNode);
}
} else if (isEnterKey(event)) {
if (this._editCallback) {
handled = true;
this._startEditing(this.selectedNode._element.children[0]);
}
}
if (nextSelectedNode) {
nextSelectedNode.reveal();
nextSelectedNode.select();
}
if (handled)
event.consume(true);
},
dataGridNodeFromNode: function(target)
{
var rowElement = target.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},
dataGridNodeFromPoint: function(x, y)
{
var node = this._dataTable.ownerDocument.elementFromPoint(x, y);
var rowElement = node.enclosingNodeOrSelfWithNodeName("tr");
return rowElement && rowElement._dataGridNode;
},
_clickInHeaderCell: function(event)
{
var cell = event.target.enclosingNodeOrSelfWithNodeName("th");
if (!cell || !cell.columnIdentifier || !cell.hasStyleClass("sortable"))
return;
var sortOrder = this.sortOrder;
if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
if (cell == this._sortColumnCell) {
if (sortOrder === "ascending")
sortOrder = "descending";
else
sortOrder = "ascending";
}
this._sortColumnCell = cell;
cell.addStyleClass("sort-" + sortOrder);
this.dispatchEventToListeners("sorting changed");
},
markColumnAsSortedBy: function(columnIdentifier, sortOrder)
{
if (this._sortColumnCell)
this._sortColumnCell.removeMatchingStyleClasses("sort-\\w+");
this._sortColumnCell = this._headerTableHeaders[columnIdentifier];
this._sortColumnCell.addStyleClass("sort-" + sortOrder);
},
headerTableHeader: function(columnIdentifier)
{
return this._headerTableHeaders[columnIdentifier];
},
_mouseDownInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.selectable)
return;
if (gridNode.isEventWithinDisclosureTriangle(event))
return;
if (event.metaKey) {
if (gridNode.selected)
gridNode.deselect();
else
gridNode.select();
} else
gridNode.select();
},
_contextMenuInDataTable: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
var gridNode = this.dataGridNodeFromNode(event.target);
if (this._refreshCallback && (!gridNode || gridNode !== this.creationNode))
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._refreshCallback.bind(this));
if (gridNode && gridNode.selectable && !gridNode.isEventWithinDisclosureTriangle(event)) {
if (this._editCallback) {
if (gridNode === this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Add New"), this._startEditing.bind(this, event.target));
else
contextMenu.appendItem(WebInspector.UIString("Edit"), this._startEditing.bind(this, event.target));
}
if (this._deleteCallback && gridNode !== this.creationNode)
contextMenu.appendItem(WebInspector.UIString("Delete"), this._deleteCallback.bind(this, gridNode));
}
contextMenu.show(event);
},
_clickInDataTable: function(event)
{
var gridNode = this.dataGridNodeFromNode(event.target);
if (!gridNode || !gridNode.hasChildren)
return;
if (!gridNode.isEventWithinDisclosureTriangle(event))
return;
if (gridNode.expanded) {
if (event.altKey)
gridNode.collapseRecursively();
else
gridNode.collapse();
} else {
if (event.altKey)
gridNode.expandRecursively();
else
gridNode.expand();
}
},
get resizeMethod()
{
if (typeof this._resizeMethod === "undefined")
return WebInspector.DataGrid.ResizeMethod.Nearest;
return this._resizeMethod;
},
set resizeMethod(method)
{
this._resizeMethod = method;
},
_startResizerDragging: function(event)
{
this._currentResizer = event.target;
return !!this._currentResizer.rightNeighboringColumnID
},
_resizerDragging: function(event)
{
var resizer = this._currentResizer;
if (!resizer)
return;
var dragPoint = event.clientX - this.element.totalOffsetLeft();
var leftCellIndex = resizer.leftNeighboringColumnID;
var rightCellIndex = resizer.rightNeighboringColumnID;
var firstRowCells = this.headerTableBody.rows[0].cells;
var leftEdgeOfPreviousColumn = 0;
for (var i = 0; i < leftCellIndex; i++)
leftEdgeOfPreviousColumn += firstRowCells[i].offsetWidth;
if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.Last) {
rightCellIndex = this.resizers.length;
} else if (this.resizeMethod == WebInspector.DataGrid.ResizeMethod.First) {
leftEdgeOfPreviousColumn += firstRowCells[leftCellIndex].offsetWidth - firstRowCells[0].offsetWidth;
leftCellIndex = 0;
}
var rightEdgeOfNextColumn = leftEdgeOfPreviousColumn + firstRowCells[leftCellIndex].offsetWidth + firstRowCells[rightCellIndex].offsetWidth;
var leftMinimum = leftEdgeOfPreviousColumn + this.ColumnResizePadding;
var rightMaximum = rightEdgeOfNextColumn - this.ColumnResizePadding;
dragPoint = Number.constrain(dragPoint, leftMinimum, rightMaximum);
resizer.style.left = (dragPoint - this.CenterResizerOverBorderAdjustment) + "px";
var percentLeftColumn = (((dragPoint - leftEdgeOfPreviousColumn) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
this._dataTableColumnGroup.children[leftCellIndex].style.width = percentLeftColumn;
var percentRightColumn = (((rightEdgeOfNextColumn - dragPoint) / this._dataTable.offsetWidth) * 100) + "%";
this._headerTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;
this._dataTableColumnGroup.children[rightCellIndex].style.width = percentRightColumn;
this._positionResizers();
event.preventDefault();
this.dispatchEventToListeners("width changed");
},
_endResizerDragging: function(event)
{
this._currentResizer = null;
this.dispatchEventToListeners("width changed");
},
ColumnResizePadding: 10,
CenterResizerOverBorderAdjustment: 3,
}
WebInspector.DataGrid.ResizeMethod = {
Nearest: "nearest",
First: "first",
Last: "last"
}
WebInspector.DataGrid.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.DataGridNode = function(data, hasChildren)
{
this._expanded = false;
this._selected = false;
this._shouldRefreshChildren = true;
this._data = data || {};
this.hasChildren = hasChildren || false;
this.children = [];
this.dataGrid = null;
this.parent = null;
this.previousSibling = null;
this.nextSibling = null;
this.disclosureToggleWidth = 10;
}
WebInspector.DataGridNode.prototype = {
selectable: true,
_isRoot: false,
get element()
{
if (this._element)
return this._element;
if (!this.dataGrid)
return null;
this._element = document.createElement("tr");
this._element._dataGridNode = this;
if (this.hasChildren)
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
if (this.selected)
this._element.addStyleClass("selected");
if (this.revealed)
this._element.addStyleClass("revealed");
this.createCells();
return this._element;
},
createCells: function()
{
for (var columnIdentifier in this.dataGrid.columns) {
var cell = this.createCell(columnIdentifier);
this._element.appendChild(cell);
}
},
get data()
{
return this._data;
},
set data(x)
{
this._data = x || {};
this.refresh();
},
get revealed()
{
if ("_revealed" in this)
return this._revealed;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded) {
this._revealed = false;
return false;
}
currentAncestor = currentAncestor.parent;
}
this._revealed = true;
return true;
},
set hasChildren(x)
{
if (this._hasChildren === x)
return;
this._hasChildren = x;
if (!this._element)
return;
if (this._hasChildren)
{
this._element.addStyleClass("parent");
if (this.expanded)
this._element.addStyleClass("expanded");
}
else
{
this._element.removeStyleClass("parent");
this._element.removeStyleClass("expanded");
}
},
get hasChildren()
{
return this._hasChildren;
},
set revealed(x)
{
if (this._revealed === x)
return;
this._revealed = x;
if (this._element) {
if (this._revealed)
this._element.addStyleClass("revealed");
else
this._element.removeStyleClass("revealed");
}
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = x && this.expanded;
},
get depth()
{
if ("_depth" in this)
return this._depth;
if (this.parent && !this.parent._isRoot)
this._depth = this.parent.depth + 1;
else
this._depth = 0;
return this._depth;
},
get leftPadding()
{
if (typeof(this._leftPadding) === "number")
return this._leftPadding;
this._leftPadding = this.depth * this.dataGrid.indentWidth;
return this._leftPadding;
},
get shouldRefreshChildren()
{
return this._shouldRefreshChildren;
},
set shouldRefreshChildren(x)
{
this._shouldRefreshChildren = x;
if (x && this.expanded)
this.expand();
},
get selected()
{
return this._selected;
},
set selected(x)
{
if (x)
this.select();
else
this.deselect();
},
get expanded()
{
return this._expanded;
},
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
refresh: function()
{
if (!this._element || !this.dataGrid)
return;
this._element.removeChildren();
this.createCells();
},
createCell: function(columnIdentifier)
{
var cell = document.createElement("td");
cell.className = columnIdentifier + "-column";
var alignment = this.dataGrid.aligned[columnIdentifier];
if (alignment)
cell.addStyleClass(alignment);
var div = document.createElement("div");
div.textContent = this.data[columnIdentifier];
cell.appendChild(div);
if (columnIdentifier === this.dataGrid.disclosureColumnIdentifier) {
cell.addStyleClass("disclosure");
if (this.leftPadding)
cell.style.setProperty("padding-left", this.leftPadding + "px");
}
return cell;
},
nodeHeight: function()
{
var rowHeight = 16;
if (!this.revealed)
return 0;
if (!this.expanded)
return rowHeight;
var result = rowHeight;
for (var i = 0; i < this.children.length; i++)
result += this.children[i].nodeHeight();
return result;
},
appendChild: function(child)
{
this.insertChild(child, this.children.length);
},
insertChild: function(child, index)
{
if (!child)
throw("insertChild: Node can't be undefined or null.");
if (child.parent === this)
throw("insertChild: Node is already a child of this node.");
if (child.parent)
child.parent.removeChild(child);
this.children.splice(index, 0, child);
this.hasChildren = true;
child.parent = this;
child.dataGrid = this.dataGrid;
child._recalculateSiblings(index);
delete child._depth;
delete child._revealed;
delete child._attached;
child._shouldRefreshChildren = true;
var current = child.children[0];
while (current) {
current.dataGrid = this.dataGrid;
delete current._depth;
delete current._revealed;
delete current._attached;
current._shouldRefreshChildren = true;
current = current.traverseNextNode(false, child, true);
}
if (this.expanded)
child._attach();
if (!this.revealed)
child.revealed = false;
},
removeChild: function(child)
{
if (!child)
throw("removeChild: Node can't be undefined or null.");
if (child.parent !== this)
throw("removeChild: Node is not a child of this node.");
child.deselect();
child._detach();
this.children.remove(child, true);
if (child.previousSibling)
child.previousSibling.nextSibling = child.nextSibling;
if (child.nextSibling)
child.nextSibling.previousSibling = child.previousSibling;
child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
if (this.children.length <= 0)
this.hasChildren = false;
},
removeChildren: function()
{
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
child.deselect();
child._detach();
child.dataGrid = null;
child.parent = null;
child.nextSibling = null;
child.previousSibling = null;
}
this.children = [];
this.hasChildren = false;
},
_recalculateSiblings: function(myIndex)
{
if (!this.parent)
return;
var previousChild = (myIndex > 0 ? this.parent.children[myIndex - 1] : null);
if (previousChild) {
previousChild.nextSibling = this;
this.previousSibling = previousChild;
} else
this.previousSibling = null;
var nextChild = this.parent.children[myIndex + 1];
if (nextChild) {
nextChild.previousSibling = this;
this.nextSibling = nextChild;
} else
this.nextSibling = null;
},
collapse: function()
{
if (this._isRoot)
return;
if (this._element)
this._element.removeStyleClass("expanded");
this._expanded = false;
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = false;
this.dispatchEventToListeners("collapsed");
},
collapseRecursively: function()
{
var item = this;
while (item) {
if (item.expanded)
item.collapse();
item = item.traverseNextNode(false, this, true);
}
},
expand: function()
{
if (!this.hasChildren || this.expanded)
return;
if (this._isRoot)
return;
if (this.revealed && !this._shouldRefreshChildren)
for (var i = 0; i < this.children.length; ++i)
this.children[i].revealed = true;
if (this._shouldRefreshChildren) {
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();
this.dispatchEventToListeners("populate");
if (this._attached) {
for (var i = 0; i < this.children.length; ++i) {
var child = this.children[i];
if (this.revealed)
child.revealed = true;
child._attach();
}
}
delete this._shouldRefreshChildren;
}
if (this._element)
this._element.addStyleClass("expanded");
this._expanded = true;
this.dispatchEventToListeners("expanded");
},
expandRecursively: function()
{
var item = this;
while (item) {
item.expand();
item = item.traverseNextNode(false, this);
}
},
reveal: function()
{
if (this._isRoot)
return;
var currentAncestor = this.parent;
while (currentAncestor && !currentAncestor._isRoot) {
if (!currentAncestor.expanded)
currentAncestor.expand();
currentAncestor = currentAncestor.parent;
}
this.element.scrollIntoViewIfNeeded(false);
this.dispatchEventToListeners("revealed");
},
select: function(supressSelectedEvent)
{
if (!this.dataGrid || !this.selectable || this.selected)
return;
if (this.dataGrid.selectedNode)
this.dataGrid.selectedNode.deselect();
this._selected = true;
this.dataGrid.selectedNode = this;
if (this._element)
this._element.addStyleClass("selected");
if (!supressSelectedEvent) {
this.dispatchEventToListeners("selected");
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.SelectedNode);
}
},
revealAndSelect: function()
{
if (this._isRoot)
return;
this.reveal();
this.select();
},
deselect: function(supressDeselectedEvent)
{
if (!this.dataGrid || this.dataGrid.selectedNode !== this || !this.selected)
return;
this._selected = false;
this.dataGrid.selectedNode = null;
if (this._element)
this._element.removeStyleClass("selected");
if (!supressDeselectedEvent) {
this.dispatchEventToListeners("deselected");
this.dataGrid.dispatchEventToListeners(WebInspector.DataGrid.Events.DeselectedNode);
}
},
traverseNextNode: function(skipHidden, stayWithin, dontPopulate, info)
{
if (!dontPopulate && this.hasChildren)
this.dispatchEventToListeners("populate");
if (info)
info.depthChange = 0;
var node = (!skipHidden || this.revealed) ? this.children[0] : null;
if (node && (!skipHidden || this.expanded)) {
if (info)
info.depthChange = 1;
return node;
}
if (this === stayWithin)
return null;
node = (!skipHidden || this.revealed) ? this.nextSibling : null;
if (node)
return node;
node = this;
while (node && !node._isRoot && !((!skipHidden || node.revealed) ? node.nextSibling : null) && node.parent !== stayWithin) {
if (info)
info.depthChange -= 1;
node = node.parent;
}
if (!node)
return null;
return (!skipHidden || node.revealed) ? node.nextSibling : null;
},
traversePreviousNode: function(skipHidden, dontPopulate)
{
var node = (!skipHidden || this.revealed) ? this.previousSibling : null;
if (!dontPopulate && node && node.hasChildren)
node.dispatchEventToListeners("populate");
while (node && ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null)) {
if (!dontPopulate && node.hasChildren)
node.dispatchEventToListeners("populate");
node = ((!skipHidden || (node.revealed && node.expanded)) ? node.children[node.children.length - 1] : null);
}
if (node)
return node;
if (!this.parent || this.parent._isRoot)
return null;
return this.parent;
},
isEventWithinDisclosureTriangle: function(event)
{
if (!this.hasChildren)
return false;
var cell = event.target.enclosingNodeOrSelfWithNodeName("td");
if (!cell.hasStyleClass("disclosure"))
return false;
var left = cell.totalOffsetLeft() + this.leftPadding;
return event.pageX >= left && event.pageX <= left + this.disclosureToggleWidth;
},
_attach: function()
{
if (!this.dataGrid || this._attached)
return;
this._attached = true;
var nextNode = null;
var previousNode = this.traversePreviousNode(true, true);
if (previousNode && previousNode.element.parentNode && previousNode.element.nextSibling)
nextNode = previousNode.element.nextSibling;
if (!nextNode)
nextNode = this.dataGrid.dataTableBody.firstChild;
this.dataGrid.dataTableBody.insertBefore(this.element, nextNode);
if (this.expanded)
for (var i = 0; i < this.children.length; ++i)
this.children[i]._attach();
},
_detach: function()
{
if (!this._attached)
return;
this._attached = false;
if (this._element && this._element.parentNode)
this._element.parentNode.removeChild(this._element);
for (var i = 0; i < this.children.length; ++i)
this.children[i]._detach();
this.wasDetached();
},
wasDetached: function()
{
},
savePosition: function()
{
if (this._savedPosition)
return;
if (!this.parent)
throw("savePosition: Node must have a parent.");
this._savedPosition = {
parent: this.parent,
index: this.parent.children.indexOf(this)
};
},
restorePosition: function()
{
if (!this._savedPosition)
return;
if (this.parent !== this._savedPosition.parent)
this._savedPosition.parent.insertChild(this, this._savedPosition.index);
delete this._savedPosition;
}
}
WebInspector.DataGridNode.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.CreationDataGridNode = function(data, hasChildren)
{
WebInspector.DataGridNode.call(this, data, hasChildren);
this.isCreationNode = true;
}
WebInspector.CreationDataGridNode.prototype = {
makeNormal: function()
{
delete this.isCreationNode;
delete this.makeNormal;
}
}
WebInspector.CreationDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
WebInspector.ShowMoreDataGridNode = function(callback, startPosition, endPosition, chunkSize)
{
WebInspector.DataGridNode.call(this, {summaryRow:true}, false);
this._callback = callback;
this._startPosition = startPosition;
this._endPosition = endPosition;
this._chunkSize = chunkSize;
this.showNext = document.createElement("button");
this.showNext.setAttribute("type", "button");
this.showNext.addEventListener("click", this._showNextChunk.bind(this), false);
this.showNext.textContent = WebInspector.UIString("Show %d before", this._chunkSize);
this.showAll = document.createElement("button");
this.showAll.setAttribute("type", "button");
this.showAll.addEventListener("click", this._showAll.bind(this), false);
this.showLast = document.createElement("button");
this.showLast.setAttribute("type", "button");
this.showLast.addEventListener("click", this._showLastChunk.bind(this), false);
this.showLast.textContent = WebInspector.UIString("Show %d after", this._chunkSize);
this._updateLabels();
this.selectable = false;
}
WebInspector.ShowMoreDataGridNode.prototype = {
_showNextChunk: function()
{
this._callback(this._startPosition, this._startPosition + this._chunkSize);
},
_showAll: function()
{
this._callback(this._startPosition, this._endPosition);
},
_showLastChunk: function()
{
this._callback(this._endPosition - this._chunkSize, this._endPosition);
},
_updateLabels: function()
{
var totalSize = this._endPosition - this._startPosition;
if (totalSize > this._chunkSize) {
this.showNext.removeStyleClass("hidden");
this.showLast.removeStyleClass("hidden");
} else {
this.showNext.addStyleClass("hidden");
this.showLast.addStyleClass("hidden");
}
this.showAll.textContent = WebInspector.UIString("Show all %d", totalSize);
},
createCells: function()
{
var cell = document.createElement("td");
if (this.depth)
cell.style.setProperty("padding-left", (this.depth * this.dataGrid.indentWidth) + "px");
cell.appendChild(this.showNext);
cell.appendChild(this.showAll);
cell.appendChild(this.showLast);
this._element.appendChild(cell);
var columns = this.dataGrid.columns;
var count = 0;
for (var c in columns)
++count;
while (--count > 0) {
cell = document.createElement("td");
this._element.appendChild(cell);
}
},
setStartPosition: function(from)
{
this._startPosition = from;
this._updateLabels();
},
setEndPosition: function(to)
{
this._endPosition = to;
this._updateLabels();
},
nodeHeight: function()
{
return 32;
},
dispose: function()
{
}
};
WebInspector.ShowMoreDataGridNode.prototype.__proto__ = WebInspector.DataGridNode.prototype;
WebInspector.CookiesTable = function(cookieDomain, expandable, deleteCallback, refreshCallback)
{
WebInspector.View.call(this);
this.element.className = "fill";
this._cookieDomain = cookieDomain;
var columns = { 0: {}, 1: {}, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 7: {} };
columns[0].title = WebInspector.UIString("Name");
columns[0].sortable = true;
columns[0].disclosure = expandable;
columns[0].width = "24%";
columns[1].title = WebInspector.UIString("Value");
columns[1].sortable = true;
columns[1].width = "34%";
columns[2].title = WebInspector.UIString("Domain");
columns[2].sortable = true;
columns[2].width = "7%";
columns[3].title = WebInspector.UIString("Path");
columns[3].sortable = true;
columns[3].width = "7%";
columns[4].title = WebInspector.UIString("Expires");
columns[4].sortable = true;
columns[4].width = "7%";
columns[5].title = WebInspector.UIString("Size");
columns[5].aligned = "right";
columns[5].sortable = true;
columns[5].width = "7%";
columns[6].title = WebInspector.UIString("HTTP");
columns[6].aligned = "centered";
columns[6].sortable = true;
columns[6].width = "7%";
columns[7].title = WebInspector.UIString("Secure");
columns[7].aligned = "centered";
columns[7].sortable = true;
columns[7].width = "7%";
this._dataGrid = new WebInspector.DataGrid(columns, undefined, deleteCallback ? this._onDeleteFromGrid.bind(this, deleteCallback) : undefined);
this._dataGrid.addEventListener("sorting changed", this._rebuildTable, this);
this._dataGrid.refreshCallback = refreshCallback;
this._dataGrid.show(this.element);
this._data = [];
}
WebInspector.CookiesTable.prototype = {
updateWidths: function()
{
if (this._dataGrid)
this._dataGrid.updateWidths();
},
setCookies: function(cookies)
{
this._data = [{cookies: cookies}];
this._rebuildTable();
},
addCookiesFolder: function(folderName, cookies)
{
this._data.push({cookies: cookies, folderName: folderName});
this._rebuildTable();
},
get selectedCookie()
{
var node = this._dataGrid.selectedNode;
return node ? node.cookie : null;
},
_rebuildTable: function()
{
this._dataGrid.rootNode().removeChildren();
for (var i = 0; i < this._data.length; ++i) {
var item = this._data[i];
if (item.folderName) {
var groupData = [ item.folderName, "", "", "", "", this._totalSize(item.cookies), "", "" ];
var groupNode = new WebInspector.DataGridNode(groupData);
groupNode.selectable = true;
this._dataGrid.rootNode().appendChild(groupNode);
groupNode.element.addStyleClass("row-group");
this._populateNode(groupNode, item.cookies);
groupNode.expand();
} else
this._populateNode(this._dataGrid.rootNode(), item.cookies);
}
},
_populateNode: function(parentNode, cookies)
{
var selectedCookie = this.selectedCookie;
parentNode.removeChildren();
if (!cookies)
return;
this._sortCookies(cookies);
for (var i = 0; i < cookies.length; ++i) {
var cookieNode = this._createGridNode(cookies[i]);
parentNode.appendChild(cookieNode);
if (selectedCookie === cookies[i])
cookieNode.selected = true;
}
},
_totalSize: function(cookies)
{
var totalSize = 0;
for (var i = 0; cookies && i < cookies.length; ++i)
totalSize += cookies[i].size;
return totalSize;
},
_sortCookies: function(cookies)
{
var sortDirection = this._dataGrid.sortOrder === "ascending" ? 1 : -1;
function localeCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] + "").localeCompare(cookie2[field] + "")
}
function numberCompare(field, cookie1, cookie2)
{
return sortDirection * (cookie1[field] - cookie2[field]);
}
function expiresCompare(cookie1, cookie2)
{
if (cookie1.session !== cookie2.session)
return sortDirection * (cookie1.session ? 1 : -1);
if (cookie1.session)
return 0;
return sortDirection * (cookie1.expires - cookie2.expires);
}
var comparator;
switch (parseInt(this._dataGrid.sortColumnIdentifier, 10)) {
case 0: comparator = localeCompare.bind(this, "name"); break;
case 1: comparator = localeCompare.bind(this, "value"); break;
case 2: comparator = localeCompare.bind(this, "domain"); break;
case 3: comparator = localeCompare.bind(this, "path"); break;
case 4: comparator = expiresCompare; break;
case 5: comparator = numberCompare.bind(this, "size"); break;
case 6: comparator = localeCompare.bind(this, "httpOnly"); break;
case 7: comparator = localeCompare.bind(this, "secure"); break;
default: localeCompare.bind(this, "name");
}
cookies.sort(comparator);
},
_createGridNode: function(cookie)
{
var data = {};
data[0] = cookie.name;
data[1] = cookie.value;
data[2] = cookie.domain || "";
data[3] = cookie.path || "";
data[4] = cookie.type === WebInspector.Cookie.Type.Request ? "" :
(cookie.session ? WebInspector.UIString("Session") : new Date(cookie.expires).toGMTString());
data[5] = cookie.size;
const checkmark = "\u2713";
data[6] = (cookie.httpOnly ? checkmark : "");
data[7] = (cookie.secure ? checkmark : "");
var node = new WebInspector.DataGridNode(data);
node.cookie = cookie;
node.selectable = true;
return node;
},
_onDeleteFromGrid: function(deleteCallback, node)
{
deleteCallback(node.cookie);
}
}
WebInspector.CookiesTable.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.CookieItemsView = function(treeElement, cookieDomain)
{
WebInspector.View.call(this);
this.element.addStyleClass("storage-view");
this._deleteButton = new WebInspector.StatusBarButton(WebInspector.UIString("Delete"), "delete-storage-status-bar-item");
this._deleteButton.visible = false;
this._deleteButton.addEventListener("click", this._deleteButtonClicked, this);
this._refreshButton = new WebInspector.StatusBarButton(WebInspector.UIString("Refresh"), "refresh-storage-status-bar-item");
this._refreshButton.addEventListener("click", this._refreshButtonClicked, this);
this._treeElement = treeElement;
this._cookieDomain = cookieDomain;
this._emptyView = new WebInspector.EmptyView(WebInspector.UIString("This site has no cookies."));
this._emptyView.show(this.element);
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
}
WebInspector.CookieItemsView.prototype = {
get statusBarItems()
{
return [this._refreshButton.element, this._deleteButton.element];
},
wasShown: function()
{
this._update();
},
willHide: function()
{
this._deleteButton.visible = false;
},
_update: function()
{
WebInspector.Cookies.getCookiesAsync(this._updateWithCookies.bind(this));
},
_updateWithCookies: function(allCookies, isAdvanced)
{
this._cookies = isAdvanced ? this._filterCookiesForDomain(allCookies) : allCookies;
if (!this._cookies.length) {
this._emptyView.show(this.element);
this._deleteButton.visible = false;
if (this._cookiesTable)
this._cookiesTable.detach();
return;
}
if (!this._cookiesTable)
this._cookiesTable = isAdvanced ? new WebInspector.CookiesTable(this._cookieDomain, false, this._deleteCookie.bind(this), this._update.bind(this)) : new WebInspector.SimpleCookiesTable();
this._cookiesTable.setCookies(this._cookies);
this._emptyView.detach();
this._cookiesTable.show(this.element);
if (isAdvanced) {
this._treeElement.subtitle = String.sprintf(WebInspector.UIString("%d cookies (%s)"), this._cookies.length,
Number.bytesToString(this._totalSize));
this._deleteButton.visible = true;
}
},
_filterCookiesForDomain: function(allCookies)
{
var cookies = [];
var resourceURLsForDocumentURL = [];
this._totalSize = 0;
function populateResourcesForDocuments(resource)
{
var url = resource.documentURL.asParsedURL();
if (url && url.host == this._cookieDomain)
resourceURLsForDocumentURL.push(resource.url);
}
WebInspector.forAllResources(populateResourcesForDocuments.bind(this));
for (var i = 0; i < allCookies.length; ++i) {
var pushed = false;
var size = allCookies[i].size;
for (var j = 0; j < resourceURLsForDocumentURL.length; ++j) {
var resourceURL = resourceURLsForDocumentURL[j];
if (WebInspector.Cookies.cookieMatchesResourceURL(allCookies[i], resourceURL)) {
this._totalSize += size;
if (!pushed) {
pushed = true;
cookies.push(allCookies[i]);
}
}
}
}
return cookies;
},
_deleteCookie: function(cookie)
{
PageAgent.deleteCookie(cookie.name, this._cookieDomain);
this._update();
},
_deleteButtonClicked: function()
{
if (this._cookiesTable.selectedCookie)
this._deleteCookie(this._cookiesTable.selectedCookie);
},
_refreshButtonClicked: function(event)
{
this._update();
},
_contextMenu: function(event)
{
if (!this._cookies.length) {
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Refresh"), this._update.bind(this));
contextMenu.show(event);
}
}
}
WebInspector.CookieItemsView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.SimpleCookiesTable = function()
{
WebInspector.View.call(this);
var columns = {};
columns[0] = {};
columns[1] = {};
columns[0].title = WebInspector.UIString("Name");
columns[1].title = WebInspector.UIString("Value");
this._dataGrid = new WebInspector.DataGrid(columns);
this._dataGrid.autoSizeColumns(20, 80);
this._dataGrid.show(this.element);
}
WebInspector.SimpleCookiesTable.prototype = {
setCookies: function(cookies)
{
this._dataGrid.rootNode().removeChildren();
var addedCookies = {};
for (var i = 0; i < cookies.length; ++i) {
if (addedCookies[cookies[i].name])
continue;
addedCookies[cookies[i].name] = true;
var data = {};
data[0] = cookies[i].name;
data[1] = cookies[i].value;
var node = new WebInspector.DataGridNode(data, false);
node.selectable = true;
this._dataGrid.rootNode().appendChild(node);
}
this._dataGrid.rootNode().children[0].selected = true;
}
}
WebInspector.SimpleCookiesTable.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.Cookies = {}
WebInspector.Cookies.getCookiesAsync = function(callback)
{
function mycallback(error, cookies, cookiesString)
{
if (error)
return;
if (cookiesString)
callback(WebInspector.Cookies.buildCookiesFromString(cookiesString), false);
else
callback(cookies, true);
}
PageAgent.getCookies(mycallback);
}
WebInspector.Cookies.buildCookiesFromString = function(rawCookieString)
{
var rawCookies = rawCookieString.split(/;\s*/);
var cookies = [];
if (!(/^\s*$/.test(rawCookieString))) {
for (var i = 0; i < rawCookies.length; ++i) {
var cookie = rawCookies[i];
var delimIndex = cookie.indexOf("=");
var name = cookie.substring(0, delimIndex);
var value = cookie.substring(delimIndex + 1);
var size = name.length + value.length;
cookies.push({ name: name, value: value, size: size });
}
}
return cookies;
}
WebInspector.Cookies.cookieMatchesResourceURL = function(cookie, resourceURL)
{
var url = resourceURL.asParsedURL();
if (!url || !WebInspector.Cookies.cookieDomainMatchesResourceDomain(cookie.domain, url.host))
return false;
return (url.path.startsWith(cookie.path)
&& (!cookie.port || url.port == cookie.port)
&& (!cookie.secure || url.scheme === "https"));
}
WebInspector.Cookies.cookieDomainMatchesResourceDomain = function(cookieDomain, resourceDomain)
{
if (cookieDomain.charAt(0) !== '.')
return resourceDomain === cookieDomain;
return !!resourceDomain.match(new RegExp("^([^\\.]+\\.)?" + cookieDomain.substring(1).escapeForRegExp() + "$"), "i");
}
WebInspector.ApplicationCacheModel = function()
{
ApplicationCacheAgent.enable();
InspectorBackend.registerApplicationCacheDispatcher(new WebInspector.ApplicationCacheDispatcher(this));
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
this._statuses = {};
this._manifestURLsByFrame = {};
this._mainFrameNavigated();
this._onLine = true;
}
WebInspector.ApplicationCacheModel.EventTypes = {
FrameManifestStatusUpdated: "FrameManifestStatusUpdated",
FrameManifestAdded: "FrameManifestAdded",
FrameManifestRemoved: "FrameManifestRemoved",
NetworkStateChanged: "NetworkStateChanged"
}
WebInspector.ApplicationCacheModel.prototype = {
_frameNavigated: function(event)
{
var frame = event.data;
if (frame.isMainFrame()) {
this._mainFrameNavigated();
return;
}
ApplicationCacheAgent.getManifestForFrame(frame.id, this._manifestForFrameLoaded.bind(this, frame.id));
},
_frameDetached: function(event)
{
var frame = event.data;
this._frameManifestRemoved(frame.id);
},
_mainFrameNavigated: function()
{
ApplicationCacheAgent.getFramesWithManifests(this._framesWithManifestsLoaded.bind(this));
},
_manifestForFrameLoaded: function(frameId, error, manifestURL)
{
if (error) {
console.error(error);
return;
}
if (!manifestURL)
this._frameManifestRemoved(frameId);
},
_framesWithManifestsLoaded: function(error, framesWithManifests)
{
if (error) {
console.error(error);
return;
}
for (var i = 0; i < framesWithManifests.length; ++i)
this._frameManifestUpdated(framesWithManifests[i].frameId, framesWithManifests[i].manifestURL, framesWithManifests[i].status);
},
_frameManifestUpdated: function(frameId, manifestURL, status)
{
if (status === applicationCache.UNCACHED) {
this._frameManifestRemoved(frameId);
return;
}
if (!manifestURL)
return;
if (this._manifestURLsByFrame[frameId] && manifestURL !== this._manifestURLsByFrame[frameId])
this._frameManifestRemoved(frameId);
var statusChanged = this._statuses[frameId] !== status;
this._statuses[frameId] = status;
if (!this._manifestURLsByFrame[frameId]) {
this._manifestURLsByFrame[frameId] = manifestURL;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestAdded, frameId);
}
if (statusChanged)
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestStatusUpdated, frameId);
},
_frameManifestRemoved: function(frameId)
{
if (!this._manifestURLsByFrame[frameId])
return;
var manifestURL = this._manifestURLsByFrame[frameId];
delete this._manifestURLsByFrame[frameId];
delete this._statuses[frameId];
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.FrameManifestRemoved, frameId);
},
frameManifestURL: function(frameId)
{
return this._manifestURLsByFrame[frameId] || "";
},
frameManifestStatus: function(frameId)
{
return this._statuses[frameId] || applicationCache.UNCACHED;
},
get onLine()
{
return this._onLine;
},
_statusUpdated: function(frameId, manifestURL, status)
{
this._frameManifestUpdated(frameId, manifestURL, status);
},
requestApplicationCache: function(frameId, callback)
{
function callbackWrapper(error, applicationCache)
{
if (error) {
console.error(error);
callback(null);
return;
}
callback(applicationCache);
}
ApplicationCacheAgent.getApplicationCacheForFrame(frameId, callbackWrapper.bind(this));
},
_networkStateUpdated: function(isNowOnline)
{
this._onLine = isNowOnline;
this.dispatchEventToListeners(WebInspector.ApplicationCacheModel.EventTypes.NetworkStateChanged, isNowOnline);
}
}
WebInspector.ApplicationCacheModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.ApplicationCacheDispatcher = function(applicationCacheModel)
{
this._applicationCacheModel = applicationCacheModel;
}
WebInspector.ApplicationCacheDispatcher.prototype = {
applicationCacheStatusUpdated: function(frameId, manifestURL, status)
{
this._applicationCacheModel._statusUpdated(frameId, manifestURL, status);
},
networkStateUpdated: function(isNowOnline)
{
this._applicationCacheModel._networkStateUpdated(isNowOnline);
}
}
WebInspector.IndexedDBModel = function()
{
IndexedDBAgent.enable();
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameAdded, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameNavigated, this._frameNavigated, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.FrameDetached, this._frameDetached, this);
this._frames = {};
this._databases = new Map();
this._frameIdsBySecurityOrigin = {};
this._databaseNamesBySecurityOrigin = {};
this.refreshDatabaseNames();
}
WebInspector.IndexedDBModel.KeyTypes = {
NumberType: "number",
StringType: "string",
DateType: "date",
ArrayType: "array"
};
WebInspector.IndexedDBModel.KeyPathTypes = {
NullType: "null",
StringType: "string",
ArrayType: "array"
};
WebInspector.IndexedDBModel.idbKeyFromKey = function(key)
{
var idbKey;
switch (key.type) {
case WebInspector.IndexedDBModel.KeyTypes.NumberType:
idbKey = key.number;
break;
case WebInspector.IndexedDBModel.KeyTypes.StringType:
idbKey = key.string;
break;
case WebInspector.IndexedDBModel.KeyTypes.DateType:
idbKey = new Date(key.date);
break;
case WebInspector.IndexedDBModel.KeyTypes.ArrayType:
idbKey = [];
for (var i = 0; i < key.array.length; ++i)
idbKey.push(WebInspector.IndexedDBModel.idbKeyFromKey(key.array[i]));
break;
}
return idbKey;
}
WebInspector.IndexedDBModel.keyFromIDBKey = function(idbKey)
{
if (typeof(idbKey) === "undefined" || idbKey === null)
return null;
var key = {};
switch (typeof(idbKey)) {
case "number":
key.number = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.NumberType;
break;
case "string":
key.string = idbKey;
key.type = WebInspector.IndexedDBModel.KeyTypes.StringType;
break;
case "object":
if (idbKey instanceof Date) {
key.date = idbKey.getTime();
key.type = WebInspector.IndexedDBModel.KeyTypes.DateType;
} else if (idbKey instanceof Array) {
key.array = [];
for (var i = 0; i < idbKey.length; ++i)
key.array.push(WebInspector.IndexedDBModel.keyFromIDBKey(idbKey[i]));
key.type = WebInspector.IndexedDBModel.KeyTypes.ArrayType;
}
break;
default:
return null;
}
return key;
}
WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange = function(idbKeyRange)
{
var IDBKeyRange = window.IDBKeyRange || window.webkitIDBKeyRange;
if (typeof(idbKeyRange) === "undefined" || idbKeyRange === null)
return null;
var keyRange = {};
keyRange.lower = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.lower);
keyRange.upper = WebInspector.IndexedDBModel.keyFromIDBKey(idbKeyRange.upper);
keyRange.lowerOpen = idbKeyRange.lowerOpen;
keyRange.upperOpen = idbKeyRange.upperOpen;
return keyRange;
}
WebInspector.IndexedDBModel.idbKeyPathFromKeyPath = function(keyPath)
{
var idbKeyPath;
switch (keyPath.type) {
case WebInspector.IndexedDBModel.KeyPathTypes.NullType:
idbKeyPath = null;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.StringType:
idbKeyPath = keyPath.string;
break;
case WebInspector.IndexedDBModel.KeyPathTypes.ArrayType:
idbKeyPath = keyPath.array;
break;
}
return idbKeyPath;
}
WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath = function(idbKeyPath)
{
if (typeof idbKeyPath === "string")
return "\"" + idbKeyPath + "\"";
if (idbKeyPath instanceof Array)
return "[\"" + idbKeyPath.join("\", \"") + "\"]";
return null;
}
WebInspector.IndexedDBModel.EventTypes = {
DatabaseAdded: "DatabaseAdded",
DatabaseRemoved: "DatabaseRemoved",
DatabaseLoaded: "DatabaseLoaded"
}
WebInspector.IndexedDBModel.prototype = {
refreshDatabaseNames: function()
{
this._reset();
if (WebInspector.resourceTreeModel.mainFrame)
this._framesNavigatedRecursively(WebInspector.resourceTreeModel.mainFrame);
},
refreshDatabase: function(databaseId)
{
this._loadDatabase(databaseId);
},
_framesNavigatedRecursively: function(resourceTreeFrame)
{
this._processFrameNavigated(resourceTreeFrame);
for (var i = 0; i < resourceTreeFrame.childFrames.length; ++i)
this._framesNavigatedRecursively(resourceTreeFrame.childFrames[i]);
},
_frameNavigated: function(event)
{
var resourceTreeFrame = event.data;
this._processFrameNavigated(resourceTreeFrame);
},
_frameDetached: function(event)
{
var resourceTreeFrame = event.data;
this._originRemovedFromFrame(resourceTreeFrame.id);
},
_reset: function()
{
for (var frameId in this._frames)
this._originRemovedFromFrame(frameId);
},
_processFrameNavigated: function(resourceTreeFrame)
{
if (resourceTreeFrame.securityOrigin === "null")
return;
if (this._frameIdsBySecurityOrigin[resourceTreeFrame.securityOrigin])
this._originAddedToFrame(resourceTreeFrame.id, resourceTreeFrame.securityOrigin);
else
this._loadDatabaseNamesForFrame(resourceTreeFrame.id);
},
_originAddedToFrame: function(frameId, securityOrigin)
{
if (!this._frameIdsBySecurityOrigin[securityOrigin]) {
this._frameIdsBySecurityOrigin[securityOrigin] = [];
this._frameIdsBySecurityOrigin[securityOrigin].push(frameId);
this._databaseNamesBySecurityOrigin[securityOrigin] = [];
}
this._frames[frameId] = new WebInspector.IndexedDBModel.Frame(frameId, securityOrigin);
},
_originRemovedFromFrame: function(frameId)
{
var currentSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
if (!currentSecurityOrigin)
return;
delete this._frames[frameId];
var frameIdsForOrigin = this._frameIdsBySecurityOrigin[currentSecurityOrigin];
for (var i = 0; i < frameIdsForOrigin; ++i) {
if (frameIdsForOrigin[i] === frameId) {
frameIdsForOrigin.splice(i, 1);
break;
}
}
if (!frameIdsForOrigin.length)
this._originRemoved(currentSecurityOrigin);
},
_originRemoved: function(securityOrigin)
{
var frameIdsForOrigin = this._frameIdsBySecurityOrigin[securityOrigin];
for (var i = 0; i < frameIdsForOrigin; ++i)
delete this._frames[frameIdsForOrigin[i]];
delete this._frameIdsBySecurityOrigin[securityOrigin];
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
this._databaseRemoved(securityOrigin, this._databaseNamesBySecurityOrigin[securityOrigin][i]);
delete this._databaseNamesBySecurityOrigin[securityOrigin];
},
_updateOriginDatabaseNames: function(securityOrigin, databaseNames)
{
var newDatabaseNames = {};
for (var i = 0; i < databaseNames.length; ++i)
newDatabaseNames[databaseNames[i]] = true;
var oldDatabaseNames = {};
for (var i = 0; i < this._databaseNamesBySecurityOrigin[securityOrigin].length; ++i)
oldDatabaseNames[databaseNames[i]] = true;
this._databaseNamesBySecurityOrigin[securityOrigin] = databaseNames;
for (var databaseName in oldDatabaseNames) {
if (!newDatabaseNames[databaseName])
this._databaseRemoved(securityOrigin, databaseName);
}
for (var databaseName in newDatabaseNames) {
if (!oldDatabaseNames[databaseName])
this._databaseAdded(securityOrigin, databaseName);
}
if (!this._databaseNamesBySecurityOrigin[securityOrigin].length)
this._originRemoved(securityOrigin);
},
_databaseAdded: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseAdded, databaseId);
},
_databaseRemoved: function(securityOrigin, databaseName)
{
var databaseId = new WebInspector.IndexedDBModel.DatabaseId(securityOrigin, databaseName);
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseRemoved, databaseId);
},
_loadDatabaseNamesForFrame: function(frameId)
{
function callback(error, securityOriginWithDatabaseNames)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
var databaseNames = securityOriginWithDatabaseNames.databaseNames;
var oldSecurityOrigin = this._frames[frameId] ? this._frames[frameId].securityOrigin : null;
if (!oldSecurityOrigin || oldSecurityOrigin !== securityOriginWithDatabaseNames.securityOrigin) {
this._originRemovedFromFrame(frameId);
this._originAddedToFrame(frameId, securityOriginWithDatabaseNames.securityOrigin);
}
this._updateOriginDatabaseNames(securityOriginWithDatabaseNames.securityOrigin, securityOriginWithDatabaseNames.databaseNames);
}
IndexedDBAgent.requestDatabaseNamesForFrame(frameId, callback.bind(this));
},
_assertFrameId: function(databaseId)
{
var frameIds = this._frameIdsBySecurityOrigin[databaseId.securityOrigin];
if (!frameIds || !frameIds.length)
return null;
return frameIds[0];
},
_loadDatabase: function(databaseId)
{
var frameId = this._assertFrameId(databaseId);
if (!frameId)
return;
function callback(error, databaseWithObjectStores)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
if (!this._frames[frameId])
return;
var databaseModel = new WebInspector.IndexedDBModel.Database(databaseId, databaseWithObjectStores.version);
this._databases.put(databaseId, databaseModel);
for (var i = 0; i < databaseWithObjectStores.objectStores.length; ++i) {
var objectStore = databaseWithObjectStores.objectStores[i];
var objectStoreIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(objectStore.keyPath);
var objectStoreModel = new WebInspector.IndexedDBModel.ObjectStore(objectStore.name, objectStoreIDBKeyPath, objectStore.autoIncrement);
for (var j = 0; j < objectStore.indexes.length; ++j) {
var index = objectStore.indexes[j];
var indexIDBKeyPath = WebInspector.IndexedDBModel.idbKeyPathFromKeyPath(index.keyPath);
var indexModel = new WebInspector.IndexedDBModel.Index(index.name, indexIDBKeyPath, index.unique, index.multiEntry);
objectStoreModel.indexes[indexModel.name] = indexModel;
}
databaseModel.objectStores[objectStoreModel.name] = objectStoreModel;
}
this.dispatchEventToListeners(WebInspector.IndexedDBModel.EventTypes.DatabaseLoaded, databaseModel);
}
IndexedDBAgent.requestDatabase(frameId, databaseId.name, callback.bind(this));
},
loadObjectStoreData: function(databaseId, objectStoreName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, "", idbKeyRange, skipCount, pageSize, callback);
},
loadIndexData: function(databaseId, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
this._requestData(databaseId, databaseId.name, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback);
},
_requestData: function(databaseId, databaseName, objectStoreName, indexName, idbKeyRange, skipCount, pageSize, callback)
{
var frameId = this._assertFrameId(databaseId);
if (!frameId)
return;
function innerCallback(error, dataEntries, hasMore)
{
if (error) {
console.error("IndexedDBAgent error: " + error);
return;
}
if (!this._frames[frameId])
return;
var entries = [];
for (var i = 0; i < dataEntries.length; ++i) {
var key = WebInspector.IndexedDBModel.idbKeyFromKey(dataEntries[i].key);
var primaryKey = WebInspector.IndexedDBModel.idbKeyFromKey(dataEntries[i].primaryKey);
var value = WebInspector.RemoteObject.fromPayload(dataEntries[i].value);
entries.push(new WebInspector.IndexedDBModel.Entry(key, primaryKey, value));
}
callback(entries, hasMore);
}
var keyRange = WebInspector.IndexedDBModel.keyRangeFromIDBKeyRange(idbKeyRange);
IndexedDBAgent.requestData(frameId, databaseName, objectStoreName, indexName, skipCount, pageSize, keyRange ? keyRange : undefined, innerCallback.bind(this));
}
}
WebInspector.IndexedDBModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.IndexedDBModel.Entry = function(key, primaryKey, value)
{
this.key = key;
this.primaryKey = primaryKey;
this.value = value;
}
WebInspector.IndexedDBModel.Frame = function(frameId, securityOrigin)
{
this.frameId = frameId;
this.securityOrigin = securityOrigin;
this.databaseNames = {};
}
WebInspector.IndexedDBModel.DatabaseId = function(securityOrigin, name)
{
this.securityOrigin = securityOrigin;
this.name = name;
}
WebInspector.IndexedDBModel.DatabaseId.prototype = {
equals: function(databaseId)
{
return this.name === databaseId.name && this.securityOrigin === databaseId.securityOrigin;
},
}
WebInspector.IndexedDBModel.Database = function(databaseId, version)
{
this.databaseId = databaseId;
this.version = version;
this.objectStores = {};
}
WebInspector.IndexedDBModel.ObjectStore = function(name, keyPath, autoIncrement)
{
this.name = name;
this.keyPath = keyPath;
this.autoIncrement = autoIncrement;
this.indexes = {};
}
WebInspector.IndexedDBModel.ObjectStore.prototype = {
get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}
WebInspector.IndexedDBModel.Index = function(name, keyPath, unique, multiEntry)
{
this.name = name;
this.keyPath = keyPath;
this.unique = unique;
this.multiEntry = multiEntry;
}
WebInspector.IndexedDBModel.Index.prototype = {
get keyPathString()
{
return WebInspector.IndexedDBModel.keyPathStringFromIDBKeyPath(this.keyPath);
}
}
WebInspector.Spectrum = function()
{
this._popover = new WebInspector.Popover();
this._popover.setCanShrink(false);
this._popover.element.addEventListener("mousedown", consumeEvent, false);
this._containerElement = document.createElement('div');
this._containerElement.className = "spectrum-container";
this._containerElement.tabIndex = 0;
this._containerElement.addEventListener("keydown", this._onKeyDown.bind(this), false);
var topElement = this._containerElement.createChild("div", "spectrum-top");
topElement.createChild("div", "spectrum-fill");
var topInnerElement = topElement.createChild("div", "spectrum-top-inner fill");
this._draggerElement = topInnerElement.createChild("div", "spectrum-color");
this._dragHelperElement = this._draggerElement.createChild("div", "spectrum-sat fill").createChild("div", "spectrum-val fill").createChild("div", "spectrum-dragger");
this._sliderElement = topInnerElement.createChild("div", "spectrum-hue");
this.slideHelper = this._sliderElement.createChild("div", "spectrum-slider");
var rangeContainer = this._containerElement.createChild("div", "spectrum-range-container");
var alphaLabel = rangeContainer.createChild("label");
alphaLabel.textContent = WebInspector.UIString("\u03B1:");
this._alphaElement = rangeContainer.createChild("input", "spectrum-range");
this._alphaElement.setAttribute("type", "range");
this._alphaElement.setAttribute("min", "0");
this._alphaElement.setAttribute("max", "100");
this._alphaElement.addEventListener("change", alphaDrag.bind(this), false);
var swatchElement = document.createElement("span");
swatchElement.className = "swatch";
this._swatchInnerElement = swatchElement.createChild("span", "swatch-inner");
var displayContainer = this._containerElement.createChild("div");
displayContainer.appendChild(swatchElement);
this._displayElement = displayContainer.createChild("span", "source-code spectrum-display-value");
WebInspector.Spectrum.draggable(this._sliderElement, hueDrag.bind(this));
WebInspector.Spectrum.draggable(this._draggerElement, colorDrag.bind(this), colorDragStart.bind(this));
function hueDrag(element, dragX, dragY)
{
this.hsv[0] = (dragY / this.slideHeight);
this._onchange();
}
var initialHelperOffset;
function colorDragStart(element, dragX, dragY)
{
initialHelperOffset = { x: this._dragHelperElement.offsetLeft, y: this._dragHelperElement.offsetTop };
}
function colorDrag(element, dragX, dragY, event)
{
if (event.shiftKey) {
if (Math.abs(dragX - initialHelperOffset.x) >= Math.abs(dragY - initialHelperOffset.y))
dragY = initialHelperOffset.y;
else
dragX = initialHelperOffset.x;
}
this.hsv[1] = dragX / this.dragWidth;
this.hsv[2] = (this.dragHeight - dragY) / this.dragHeight;
this._onchange();
}
function alphaDrag()
{
this.hsv[3] = this._alphaElement.value / 100;
this._onchange();
}
this._hideProxy = this.hide.bind(this, true);
};
WebInspector.Spectrum.Events = {
ColorChanged: "ColorChanged",
Hidden: "Hidden"
};
WebInspector.Spectrum.hsvaToRGBA = function(h, s, v, a)
{
var r, g, b;
var i = Math.floor(h * 6);
var f = h * 6 - i;
var p = v * (1 - s);
var q = v * (1 - f * s);
var t = v * (1 - (1 - f) * s);
switch(i % 6) {
case 0:
r = v, g = t, b = p;
break;
case 1:
r = q, g = v, b = p;
break;
case 2:
r = p, g = v, b = t;
break;
case 3:
r = p, g = q, b = v;
break;
case 4:
r = t, g = p, b = v;
break;
case 5:
r = v, g = p, b = q;
break;
}
return [Math.round(r * 255), Math.round(g * 255), Math.round(b * 255), a];
};
WebInspector.Spectrum.rgbaToHSVA = function(r, g, b, a)
{
r = r / 255;
g = g / 255;
b = b / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var h;
var s;
var v = max;
var d = max - min;
s = max ? d / max : 0;
if(max === min) {
h = 0;
} else {
switch(max) {
case r:
h = (g - b) / d + (g < b ? 6 : 0);
break;
case g:
h = (b - r) / d + 2;
break;
case b:
h = (r - g) / d + 4;
break;
}
h /= 6;
}
return [h, s, v, a];
};
WebInspector.Spectrum.draggable = function(element, onmove, onstart, onstop) {
var doc = document;
var dragging;
var offset;
var scrollOffset;
var maxHeight;
var maxWidth;
function consume(e)
{
e.consume(true);
}
function move(e)
{
if (dragging) {
var dragX = Math.max(0, Math.min(e.pageX - offset.left + scrollOffset.left, maxWidth));
var dragY = Math.max(0, Math.min(e.pageY - offset.top + scrollOffset.top, maxHeight));
if (onmove)
onmove(element, dragX, dragY, e);
}
}
function start(e)
{
var rightClick = e.which ? (e.which === 3) : (e.button === 2);
if (!rightClick && !dragging) {
if (onstart)
onstart(element, e)
dragging = true;
maxHeight = element.clientHeight;
maxWidth = element.clientWidth;
scrollOffset = element.scrollOffset();
offset = element.totalOffset();
doc.addEventListener("selectstart", consume, false);
doc.addEventListener("dragstart", consume, false);
doc.addEventListener("mousemove", move, false);
doc.addEventListener("mouseup", stop, false);
move(e);
consume(e);
}
}
function stop(e)
{
if (dragging) {
doc.removeEventListener("selectstart", consume, false);
doc.removeEventListener("dragstart", consume, false);
doc.removeEventListener("mousemove", move, false);
doc.removeEventListener("mouseup", stop, false);
if (onstop)
onstop(element, e);
}
dragging = false;
}
element.addEventListener("mousedown", start, false);
};
WebInspector.Spectrum.prototype = {
set color(color)
{
var rgba = (color.rgba || color.rgb).slice(0);
if (rgba.length === 3)
rgba[3] = 1;
this.hsv = WebInspector.Spectrum.rgbaToHSVA(rgba[0], rgba[1], rgba[2], rgba[3]);
},
get color()
{
var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], this.hsv[1], this.hsv[2], this.hsv[3]);
var color;
if (rgba[3] === 1)
color = WebInspector.Color.fromRGB(rgba[0], rgba[1], rgba[2]);
else
color = WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
var colorValue = color.toString(this.outputColorFormat);
if (!colorValue)
colorValue = color.toString();
return new WebInspector.Color(colorValue);
},
get outputColorFormat()
{
var cf = WebInspector.Color.Format;
var format = this._originalFormat;
if (this.hsv[3] === 1) {
if (format === cf.RGBA)
format = cf.RGB;
else if (format === cf.HSLA)
format = cf.HSL;
} else {
if (format === cf.HSL || format === cf.HSLA)
format = cf.HSLA;
else
format = cf.RGBA;
}
return format;
},
get colorHueOnly()
{
var rgba = WebInspector.Spectrum.hsvaToRGBA(this.hsv[0], 1, 1, 1);
return WebInspector.Color.fromRGBA(rgba[0], rgba[1], rgba[2], rgba[3]);
},
set displayText(text)
{
this._displayElement.textContent = text;
},
get visible()
{
return this._popover.visible;
},
_onchange: function()
{
this._updateUI();
this.dispatchEventToListeners(WebInspector.Spectrum.Events.ColorChanged, this.color);
},
_updateHelperLocations: function()
{
var h = this.hsv[0];
var s = this.hsv[1];
var v = this.hsv[2];
var dragX = s * this.dragWidth;
var dragY = this.dragHeight - (v * this.dragHeight);
dragX = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragWidth - this._dragHelperElementHeight, dragX - this._dragHelperElementHeight));
dragY = Math.max(-this._dragHelperElementHeight,
Math.min(this.dragHeight - this._dragHelperElementHeight, dragY - this._dragHelperElementHeight));
this._dragHelperElement.positionAt(dragX, dragY);
var slideY = (h * this.slideHeight) - this.slideHelperHeight;
this.slideHelper.style.top = slideY + "px";
this._alphaElement.value = this.hsv[3] * 100;
},
_updateUI: function()
{
this._updateHelperLocations();
var rgb = (this.color.rgba || this.color.rgb).slice(0);
if (rgb.length === 3)
rgb[3] = 1;
var rgbHueOnly = this.colorHueOnly.rgb;
var flatColor = "rgb(" + rgbHueOnly[0] + ", " + rgbHueOnly[1] + ", " + rgbHueOnly[2] + ")";
var fullColor = "rgba(" + rgb[0] + ", " + rgb[1] + ", " + rgb[2] + ", " + rgb[3] + ")";
this._draggerElement.style.backgroundColor = flatColor;
this._swatchInnerElement.style.backgroundColor = fullColor;
this._alphaElement.value = this.hsv[3] * 100;
},
toggle: function(element, color, format)
{
if (this.visible)
this.hide(true);
else
this.show(element, color, format);
return this.visible;
},
show: function(element, color, format)
{
if (this.visible) {
if (this.anchorElement === element)
return false;
this.hide(true);
}
this.reposition(element);
this.anchorElement = element;
document.addEventListener("mousedown", this._hideProxy, false);
window.addEventListener("blur", this._hideProxy, false);
this.slideHeight = this._sliderElement.offsetHeight;
this.dragWidth = this._draggerElement.offsetWidth;
this.dragHeight = this._draggerElement.offsetHeight;
this._dragHelperElementHeight = this._dragHelperElement.offsetHeight / 2;
this.slideHelperHeight = this.slideHelper.offsetHeight / 2;
this.color = color;
this._originalFormat = format || color.format;
this._updateUI();
return true;
},
reposition: function(element)
{
if (!this._previousFocusElement)
this._previousFocusElement = WebInspector.currentFocusElement();
this._popover.show(this._containerElement, element);
WebInspector.setCurrentFocusElement(this._containerElement);
},
hide: function(commitEdit)
{
this._popover.hide();
document.removeEventListener("mousedown", this._hideProxy, false);
window.removeEventListener("blur", this._hideProxy, false);
this.dispatchEventToListeners(WebInspector.Spectrum.Events.Hidden, !!commitEdit);
WebInspector.setCurrentFocusElement(this._previousFocusElement);
delete this._previousFocusElement;
delete this.anchorElement;
},
_onKeyDown: function(event)
{
if (event.keyIdentifier === "Enter") {
this.hide(true);
event.consume(true);
return;
}
if (event.keyIdentifier === "U+001B") {
this.hide(false);
event.consume(true);
}
}
}
WebInspector.Spectrum.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.SidebarPane = function(title)
{
this.element = document.createElement("div");
this.element.className = "pane";
this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.titleElement.tabIndex = 0;
this.titleElement.addEventListener("click", this.toggleExpanded.bind(this), false);
this.titleElement.addEventListener("keydown", this._onTitleKeyDown.bind(this), false);
this.bodyElement = document.createElement("div");
this.bodyElement.className = "body";
this.element.appendChild(this.titleElement);
this.element.appendChild(this.bodyElement);
this.title = title;
this.growbarVisible = false;
this.expanded = false;
}
WebInspector.SidebarPane.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
this.titleElement.textContent = x;
},
get growbarVisible()
{
return this._growbarVisible;
},
set growbarVisible(x)
{
if (this._growbarVisible === x)
return;
this._growbarVisible = x;
if (x && !this._growbarElement) {
this._growbarElement = document.createElement("div");
this._growbarElement.className = "growbar";
this.element.appendChild(this._growbarElement);
} else if (!x && this._growbarElement) {
if (this._growbarElement.parentNode)
this._growbarElement.parentNode(this._growbarElement);
delete this._growbarElement;
}
},
get expanded()
{
return this._expanded;
},
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");
this.onexpand();
},
onexpand: function()
{
},
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},
toggleExpanded: function()
{
this.expanded = !this.expanded;
},
_onTitleKeyDown: function(event)
{
if (isEnterKey(event) || event.keyCode === WebInspector.KeyboardShortcut.Keys.Space.code)
this.toggleExpanded();
}
}
WebInspector.SidebarPane.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.ElementsTreeOutline = function(omitRootDOMNode, selectEnabled, showInElementsPanelEnabled, contextMenuCallback, setPseudoClassCallback)
{
this.element = document.createElement("ol");
this.element.addEventListener("mousedown", this._onmousedown.bind(this), false);
this.element.addEventListener("mousemove", this._onmousemove.bind(this), false);
this.element.addEventListener("mouseout", this._onmouseout.bind(this), false);
this.element.addEventListener("dragstart", this._ondragstart.bind(this), false);
this.element.addEventListener("dragover", this._ondragover.bind(this), false);
this.element.addEventListener("dragleave", this._ondragleave.bind(this), false);
this.element.addEventListener("drop", this._ondrop.bind(this), false);
this.element.addEventListener("dragend", this._ondragend.bind(this), false);
TreeOutline.call(this, this.element);
this._includeRootDOMNode = !omitRootDOMNode;
this._selectEnabled = selectEnabled;
this._showInElementsPanelEnabled = showInElementsPanelEnabled;
this._rootDOMNode = null;
this._selectDOMNode = null;
this._eventSupport = new WebInspector.Object();
this._editing = false;
this._visible = false;
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
this._contextMenuCallback = contextMenuCallback;
this._setPseudoClassCallback = setPseudoClassCallback;
this._createNodeDecorators();
}
WebInspector.ElementsTreeOutline.Events = {
SelectedNodeChanged: "SelectedNodeChanged"
}
WebInspector.ElementsTreeOutline.MappedCharToEntity = {
"\u00a0": "nbsp",
"\u2002": "ensp",
"\u2003": "emsp",
"\u2009": "thinsp",
"\u200b": "#8203",
"\u200c": "zwnj",
"\u200d": "zwj",
"\u200e": "lrm",
"\u200f": "rlm",
"\u202a": "#8234",
"\u202b": "#8235",
"\u202c": "#8236",
"\u202d": "#8237",
"\u202e": "#8238"
}
WebInspector.ElementsTreeOutline.prototype = {
_createNodeDecorators: function()
{
this._nodeDecorators = [];
this._nodeDecorators.push(new WebInspector.ElementsTreeOutline.PseudoStateDecorator());
},
wireToDomAgent: function()
{
this._elementsTreeUpdater = new WebInspector.ElementsTreeUpdater(this);
},
setVisible: function(visible)
{
this._visible = visible;
if (!this._visible)
return;
this._updateModifiedNodes();
if (this._selectedDOMNode)
this._revealAndSelectNode(this._selectedDOMNode, false);
},
addEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.addEventListener(eventType, listener, thisObject);
},
removeEventListener: function(eventType, listener, thisObject)
{
this._eventSupport.removeEventListener(eventType, listener, thisObject);
},
get rootDOMNode()
{
return this._rootDOMNode;
},
set rootDOMNode(x)
{
if (this._rootDOMNode === x)
return;
this._rootDOMNode = x;
this._isXMLMimeType = x && x.isXMLNode();
this.update();
},
get isXMLMimeType()
{
return this._isXMLMimeType;
},
selectedDOMNode: function()
{
return this._selectedDOMNode;
},
selectDOMNode: function(node, focus)
{
if (this._selectedDOMNode === node) {
this._revealAndSelectNode(node, !focus);
return;
}
this._selectedDOMNode = node;
this._revealAndSelectNode(node, !focus);
if (this._selectedDOMNode === node)
this._selectedNodeChanged();
},
get editing()
{
return this._editing;
},
update: function()
{
var selectedNode = this.selectedTreeElement ? this.selectedTreeElement.representedObject : null;
this.removeChildren();
if (!this.rootDOMNode)
return;
var treeElement;
if (this._includeRootDOMNode) {
treeElement = new WebInspector.ElementsTreeElement(this.rootDOMNode);
treeElement.selectable = this._selectEnabled;
this.appendChild(treeElement);
} else {
var node = this.rootDOMNode.firstChild;
while (node) {
treeElement = new WebInspector.ElementsTreeElement(node);
treeElement.selectable = this._selectEnabled;
this.appendChild(treeElement);
node = node.nextSibling;
}
}
if (selectedNode)
this._revealAndSelectNode(selectedNode, true);
},
updateSelection: function()
{
if (!this.selectedTreeElement)
return;
var element = this.treeOutline.selectedTreeElement;
element.updateSelection();
},
updateOpenCloseTags: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
treeElement.updateTitle();
var children = treeElement.children;
var closingTagElement = children[children.length - 1];
if (closingTagElement && closingTagElement._elementCloseTag)
closingTagElement.updateTitle();
},
_selectedNodeChanged: function()
{
this._eventSupport.dispatchEventToListeners(WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged, this._selectedDOMNode);
},
findTreeElement: function(node)
{
function isAncestorNode(ancestor, node)
{
return ancestor.isAncestor(node);
}
function parentNode(node)
{
return node.parentNode;
}
var treeElement = TreeOutline.prototype.findTreeElement.call(this, node, isAncestorNode, parentNode);
if (!treeElement && node.nodeType() === Node.TEXT_NODE) {
treeElement = TreeOutline.prototype.findTreeElement.call(this, node.parentNode, isAncestorNode, parentNode);
}
return treeElement;
},
createTreeElementFor: function(node)
{
var treeElement = this.findTreeElement(node);
if (treeElement)
return treeElement;
if (!node.parentNode)
return null;
treeElement = this.createTreeElementFor(node.parentNode);
if (treeElement && treeElement.showChild(node.index))
return treeElement.children[node.index];
return null;
},
set suppressRevealAndSelect(x)
{
if (this._suppressRevealAndSelect === x)
return;
this._suppressRevealAndSelect = x;
},
_revealAndSelectNode: function(node, omitFocus)
{
if (!node || this._suppressRevealAndSelect)
return;
var treeElement = this.createTreeElementFor(node);
if (!treeElement)
return;
treeElement.revealAndSelect(omitFocus);
},
_treeElementFromEvent: function(event)
{
var scrollContainer = this.element.parentElement;
var x = scrollContainer.totalOffsetLeft() + scrollContainer.offsetWidth - 36;
var y = event.pageY;
var elementUnderMouse = this.treeElementFromPoint(x, y);
var elementAboveMouse = this.treeElementFromPoint(x, y - 2);
var element;
if (elementUnderMouse === elementAboveMouse)
element = elementUnderMouse;
else
element = this.treeElementFromPoint(x, y + 2);
return element;
},
_onmousedown: function(event)
{
var element = this._treeElementFromEvent(event);
if (!element || element.isEventWithinDisclosureTriangle(event))
return;
element.select();
},
_onmousemove: function(event)
{
var element = this._treeElementFromEvent(event);
if (element && this._previousHoveredElement === element)
return;
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
if (element) {
element.hovered = true;
this._previousHoveredElement = element;
}
WebInspector.domAgent.highlightDOMNode(element ? element.representedObject.id : 0);
},
_onmouseout: function(event)
{
var nodeUnderMouse = document.elementFromPoint(event.pageX, event.pageY);
if (nodeUnderMouse && nodeUnderMouse.isDescendant(this.element))
return;
if (this._previousHoveredElement) {
this._previousHoveredElement.hovered = false;
delete this._previousHoveredElement;
}
WebInspector.domAgent.hideDOMNodeHighlight();
},
_ondragstart: function(event)
{
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return false;
if (!this._isValidDragSourceOrTarget(treeElement))
return false;
if (treeElement.representedObject.nodeName() === "BODY" || treeElement.representedObject.nodeName() === "HEAD")
return false;
event.dataTransfer.setData("text/plain", treeElement.listItemElement.textContent);
event.dataTransfer.effectAllowed = "copyMove";
this._treeElementBeingDragged = treeElement;
WebInspector.domAgent.hideDOMNodeHighlight();
return true;
},
_ondragover: function(event)
{
if (!this._treeElementBeingDragged)
return false;
var treeElement = this._treeElementFromEvent(event);
if (!this._isValidDragSourceOrTarget(treeElement))
return false;
var node = treeElement.representedObject;
while (node) {
if (node === this._treeElementBeingDragged.representedObject)
return false;
node = node.parentNode;
}
treeElement.updateSelection();
treeElement.listItemElement.addStyleClass("elements-drag-over");
this._dragOverTreeElement = treeElement;
event.preventDefault();
event.dataTransfer.dropEffect = 'move';
return false;
},
_ondragleave: function(event)
{
this._clearDragOverTreeElementMarker();
event.preventDefault();
return false;
},
_isValidDragSourceOrTarget: function(treeElement)
{
if (!treeElement)
return false;
var node = treeElement.representedObject;
if (!(node instanceof WebInspector.DOMNode))
return false;
if (!node.parentNode || node.parentNode.nodeType() !== Node.ELEMENT_NODE)
return false;
return true;
},
_ondrop: function(event)
{
event.preventDefault();
var treeElement = this._treeElementFromEvent(event);
if (treeElement)
this._doMove(treeElement);
},
_doMove: function(treeElement)
{
if (!this._treeElementBeingDragged)
return;
var parentNode;
var anchorNode;
if (treeElement._elementCloseTag) {
parentNode = treeElement.representedObject;
} else {
var dragTargetNode = treeElement.representedObject;
parentNode = dragTargetNode.parentNode;
anchorNode = dragTargetNode;
}
var wasExpanded = this._treeElementBeingDragged.expanded;
this._treeElementBeingDragged.representedObject.moveTo(parentNode, anchorNode, this._selectNodeAfterEdit.bind(this, null, wasExpanded));
delete this._treeElementBeingDragged;
},
_ondragend: function(event)
{
event.preventDefault();
this._clearDragOverTreeElementMarker();
delete this._treeElementBeingDragged;
},
_clearDragOverTreeElementMarker: function()
{
if (this._dragOverTreeElement) {
this._dragOverTreeElement.updateSelection();
this._dragOverTreeElement.listItemElement.removeStyleClass("elements-drag-over");
delete this._dragOverTreeElement;
}
},
_contextMenuEventFired: function(event)
{
if (!this._showInElementsPanelEnabled)
return;
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return;
function focusElement()
{
WebInspector.domAgent.inspectElement(treeElement.representedObject.id);
}
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString("Reveal in Elements Panel"), focusElement.bind(this));
contextMenu.show(event);
},
populateContextMenu: function(contextMenu, event)
{
var treeElement = this._treeElementFromEvent(event);
if (!treeElement)
return false;
var isTag = treeElement.representedObject.nodeType() === Node.ELEMENT_NODE;
var textNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode && textNode.hasStyleClass("bogus"))
textNode = null;
var commentNode = event.target.enclosingNodeOrSelfWithClass("webkit-html-comment");
contextMenu.appendApplicableItems(event.target);
if (textNode) {
contextMenu.appendSeparator();
treeElement._populateTextContextMenu(contextMenu, textNode);
} else if (isTag) {
contextMenu.appendSeparator();
treeElement._populateTagContextMenu(contextMenu, event);
} else if (commentNode) {
contextMenu.appendSeparator();
treeElement._populateNodeContextMenu(contextMenu, textNode);
}
},
adjustCollapsedRange: function()
{
},
_updateModifiedNodes: function()
{
if (this._elementsTreeUpdater)
this._elementsTreeUpdater._updateModifiedNodes();
},
_populateContextMenu: function(contextMenu, node)
{
if (this._contextMenuCallback)
this._contextMenuCallback(contextMenu, node);
},
handleShortcut: function(event)
{
var node = this.selectedDOMNode();
var treeElement = this.getCachedTreeElement(node);
if (!node || !treeElement)
return;
if (event.keyIdentifier === "F2") {
this._toggleEditAsHTML(node);
return;
}
if (WebInspector.KeyboardShortcut.eventHasCtrlOrMeta(event) && node.parentNode) {
if (event.keyIdentifier === "Up" && node.previousSibling) {
node.moveTo(node.parentNode, node.previousSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
return;
}
if (event.keyIdentifier === "Down" && node.nextSibling) {
node.moveTo(node.parentNode, node.nextSibling.nextSibling, this._selectNodeAfterEdit.bind(this, null, treeElement.expanded));
return;
}
}
},
_toggleEditAsHTML: function(node)
{
var treeElement = this.getCachedTreeElement(node);
if (!treeElement)
return;
if (treeElement._editing && treeElement._htmlEditElement && WebInspector.isBeingEdited(treeElement._htmlEditElement))
treeElement._editing.commit();
else
treeElement._editAsHTML();
},
_selectNodeAfterEdit: function(fallbackNode, wasExpanded, error, nodeId)
{
if (error)
return;
this._updateModifiedNodes();
var newNode = WebInspector.domAgent.nodeForId(nodeId) || fallbackNode;
if (!newNode)
return;
this.selectDOMNode(newNode, true);
var newTreeItem = this.findTreeElement(newNode);
if (wasExpanded) {
if (newTreeItem)
newTreeItem.expand();
}
return newTreeItem;
}
}
WebInspector.ElementsTreeOutline.prototype.__proto__ = TreeOutline.prototype;
WebInspector.ElementsTreeOutline.ElementDecorator = function()
{
}
WebInspector.ElementsTreeOutline.ElementDecorator.prototype = {
decorate: function(node)
{
},
decorateAncestor: function(node)
{
}
}
WebInspector.ElementsTreeOutline.PseudoStateDecorator = function()
{
WebInspector.ElementsTreeOutline.ElementDecorator.call(this);
}
WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName = "pseudoState";
WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype = {
decorate: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
var propertyValue = node.getUserProperty(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!propertyValue)
return null;
return WebInspector.UIString("Element state: %s", ":" + propertyValue.join(", :"));
},
decorateAncestor: function(node)
{
if (node.nodeType() !== Node.ELEMENT_NODE)
return null;
var descendantCount = node.descendantUserPropertyCount(WebInspector.ElementsTreeOutline.PseudoStateDecorator.PropertyName);
if (!descendantCount)
return null;
if (descendantCount === 1)
return WebInspector.UIString("%d descendant with forced state", descendantCount);
return WebInspector.UIString("%d descendants with forced state", descendantCount);
}
}
WebInspector.ElementsTreeOutline.PseudoStateDecorator.prototype.__proto__ = WebInspector.ElementsTreeOutline.ElementDecorator.prototype;
WebInspector.ElementsTreeElement = function(node, elementCloseTag)
{
this._elementCloseTag = elementCloseTag;
var hasChildrenOverride = !elementCloseTag && node.hasChildNodes() && !this._showInlineText(node);
TreeElement.call(this, "", node, hasChildrenOverride);
if (this.representedObject.nodeType() == Node.ELEMENT_NODE && !elementCloseTag)
this._canAddAttributes = true;
this._searchQuery = null;
this._expandedChildrenLimit = WebInspector.ElementsTreeElement.InitialChildrenLimit;
}
WebInspector.ElementsTreeElement.InitialChildrenLimit = 500;
WebInspector.ElementsTreeElement.ForbiddenClosingTagElements = [
"area", "base", "basefont", "br", "canvas", "col", "command", "embed", "frame",
"hr", "img", "input", "isindex", "keygen", "link", "meta", "param", "source"
].keySet();
WebInspector.ElementsTreeElement.EditTagBlacklist = [
"html", "head", "body"
].keySet();
WebInspector.ElementsTreeElement.prototype = {
highlightSearchResults: function(searchQuery)
{
if (this._searchQuery !== searchQuery) {
this._updateSearchHighlight(false);
delete this._highlightResult;
}
this._searchQuery = searchQuery;
this._searchHighlightsVisible = true;
this.updateTitle(true);
},
hideSearchHighlights: function()
{
delete this._searchHighlightsVisible;
this._updateSearchHighlight(false);
},
_updateSearchHighlight: function(show)
{
if (!this._highlightResult)
return;
function updateEntryShow(entry)
{
switch (entry.type) {
case "added":
entry.parent.insertBefore(entry.node, entry.nextSibling);
break;
case "changed":
entry.node.textContent = entry.newText;
break;
}
}
function updateEntryHide(entry)
{
switch (entry.type) {
case "added":
if (entry.node.parentElement)
entry.node.parentElement.removeChild(entry.node);
break;
case "changed":
entry.node.textContent = entry.oldText;
break;
}
}
if (show) {
for (var i = 0, size = this._highlightResult.length; i < size; ++i)
updateEntryShow(this._highlightResult[i]);
} else {
for (var i = (this._highlightResult.length - 1); i >= 0; --i)
updateEntryHide(this._highlightResult[i]);
}
},
get hovered()
{
return this._hovered;
},
set hovered(x)
{
if (this._hovered === x)
return;
this._hovered = x;
if (this.listItemElement) {
if (x) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
} else {
this.listItemElement.removeStyleClass("hovered");
}
}
},
get expandedChildrenLimit()
{
return this._expandedChildrenLimit;
},
set expandedChildrenLimit(x)
{
if (this._expandedChildrenLimit === x)
return;
this._expandedChildrenLimit = x;
if (this.treeOutline && !this._updateChildrenInProgress)
this._updateChildren(true);
},
get expandedChildCount()
{
var count = this.children.length;
if (count && this.children[count - 1]._elementCloseTag)
count--;
if (count && this.children[count - 1].expandAllButton)
count--;
return count;
},
showChild: function(index)
{
if (this._elementCloseTag)
return;
if (index >= this.expandedChildrenLimit) {
this._expandedChildrenLimit = index + 1;
this._updateChildren(true);
}
return this.expandedChildCount > index;
},
updateSelection: function()
{
var listItemElement = this.listItemElement;
if (!listItemElement)
return;
if (!this._readyToUpdateSelection) {
if (document.body.offsetWidth > 0)
this._readyToUpdateSelection = true;
else {
return;
}
}
if (!this.selectionElement) {
this.selectionElement = document.createElement("div");
this.selectionElement.className = "selection selected";
listItemElement.insertBefore(this.selectionElement, listItemElement.firstChild);
}
this.selectionElement.style.height = listItemElement.offsetHeight + "px";
},
onattach: function()
{
if (this._hovered) {
this.updateSelection();
this.listItemElement.addStyleClass("hovered");
}
this.updateTitle();
this._preventFollowingLinksOnDoubleClick();
this.listItemElement.draggable = true;
},
_preventFollowingLinksOnDoubleClick: function()
{
var links = this.listItemElement.querySelectorAll("li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-external-link, li > .webkit-html-tag > .webkit-html-attribute > .webkit-html-resource-link");
if (!links)
return;
for (var i = 0; i < links.length; ++i)
links[i].preventFollowOnDoubleClick = true;
},
onpopulate: function()
{
if (this.children.length || this._showInlineText(this.representedObject) || this._elementCloseTag)
return;
this.updateChildren();
},
updateChildren: function(fullRefresh)
{
if (this._elementCloseTag)
return;
this.representedObject.getChildNodes(this._updateChildren.bind(this, fullRefresh));
},
insertChildElement: function(child, index, closingTag)
{
var newElement = new WebInspector.ElementsTreeElement(child, closingTag);
newElement.selectable = this.treeOutline._selectEnabled;
this.insertChild(newElement, index);
return newElement;
},
moveChild: function(child, targetIndex)
{
var wasSelected = child.selected;
this.removeChild(child);
this.insertChild(child, targetIndex);
if (wasSelected)
child.select();
},
_updateChildren: function(fullRefresh)
{
if (this._updateChildrenInProgress || !this.treeOutline._visible)
return;
this._updateChildrenInProgress = true;
var selectedNode = this.treeOutline.selectedDOMNode();
var originalScrollTop = 0;
if (fullRefresh) {
var treeOutlineContainerElement = this.treeOutline.element.parentNode;
originalScrollTop = treeOutlineContainerElement.scrollTop;
var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && selectedTreeElement.hasAncestor(this))
this.select();
this.removeChildren();
}
var treeElement = this;
var treeChildIndex = 0;
var elementToSelect;
function updateChildrenOfNode(node)
{
var treeOutline = treeElement.treeOutline;
var child = node.firstChild;
while (child) {
var currentTreeElement = treeElement.children[treeChildIndex];
if (!currentTreeElement || currentTreeElement.representedObject !== child) {
var existingTreeElement = null;
for (var i = (treeChildIndex + 1), size = treeElement.expandedChildCount; i < size; ++i) {
if (treeElement.children[i].representedObject === child) {
existingTreeElement = treeElement.children[i];
break;
}
}
if (existingTreeElement && existingTreeElement.parent === treeElement) {
treeElement.moveChild(existingTreeElement, treeChildIndex);
} else {
if (treeChildIndex < treeElement.expandedChildrenLimit) {
var newElement = treeElement.insertChildElement(child, treeChildIndex);
if (child === selectedNode)
elementToSelect = newElement;
if (treeElement.expandedChildCount > treeElement.expandedChildrenLimit)
treeElement.expandedChildrenLimit++;
}
}
}
child = child.nextSibling;
++treeChildIndex;
}
}
for (var i = (this.children.length - 1); i >= 0; --i) {
var currentChild = this.children[i];
var currentNode = currentChild.representedObject;
var currentParentNode = currentNode.parentNode;
if (currentParentNode === this.representedObject)
continue;
var selectedTreeElement = this.treeOutline.selectedTreeElement;
if (selectedTreeElement && (selectedTreeElement === currentChild || selectedTreeElement.hasAncestor(currentChild)))
this.select();
this.removeChildAtIndex(i);
}
updateChildrenOfNode(this.representedObject);
this.adjustCollapsedRange();
var lastChild = this.children[this.children.length - 1];
if (this.representedObject.nodeType() == Node.ELEMENT_NODE && (!lastChild || !lastChild._elementCloseTag))
this.insertChildElement(this.representedObject, this.children.length, true);
if (fullRefresh && elementToSelect) {
elementToSelect.select();
if (treeOutlineContainerElement && originalScrollTop <= treeOutlineContainerElement.scrollHeight)
treeOutlineContainerElement.scrollTop = originalScrollTop;
}
delete this._updateChildrenInProgress;
},
adjustCollapsedRange: function()
{
if (this.expandAllButtonElement && this.expandAllButtonElement.__treeElement.parent)
this.removeChild(this.expandAllButtonElement.__treeElement);
const node = this.representedObject;
if (!node.children)
return;
const childNodeCount = node.children.length;
for (var i = this.expandedChildCount, limit = Math.min(this.expandedChildrenLimit, childNodeCount); i < limit; ++i)
this.insertChildElement(node.children[i], i);
const expandedChildCount = this.expandedChildCount;
if (childNodeCount > this.expandedChildCount) {
var targetButtonIndex = expandedChildCount;
if (!this.expandAllButtonElement) {
var button = document.createElement("button");
button.className = "show-all-nodes";
button.value = "";
var item = new TreeElement(button, null, false);
item.selectable = false;
item.expandAllButton = true;
this.insertChild(item, targetButtonIndex);
this.expandAllButtonElement = item.listItemElement.firstChild;
this.expandAllButtonElement.__treeElement = item;
this.expandAllButtonElement.addEventListener("click", this.handleLoadAllChildren.bind(this), false);
} else if (!this.expandAllButtonElement.__treeElement.parent)
this.insertChild(this.expandAllButtonElement.__treeElement, targetButtonIndex);
this.expandAllButtonElement.textContent = WebInspector.UIString("Show All Nodes (%d More)", childNodeCount - expandedChildCount);
} else if (this.expandAllButtonElement)
delete this.expandAllButtonElement;
},
handleLoadAllChildren: function()
{
this.expandedChildrenLimit = Math.max(this.representedObject._childNodeCount, this.expandedChildrenLimit + WebInspector.ElementsTreeElement.InitialChildrenLimit);
},
onexpand: function()
{
if (this._elementCloseTag)
return;
this.updateTitle();
this.treeOutline.updateSelection();
},
oncollapse: function()
{
if (this._elementCloseTag)
return;
this.updateTitle();
this.treeOutline.updateSelection();
},
onreveal: function()
{
if (this.listItemElement) {
var tagSpans = this.listItemElement.getElementsByClassName("webkit-html-tag-name");
if (tagSpans.length)
tagSpans[0].scrollIntoViewIfNeeded(false);
else
this.listItemElement.scrollIntoViewIfNeeded(false);
}
},
onselect: function(selectedByUser)
{
this.treeOutline.suppressRevealAndSelect = true;
this.treeOutline.selectDOMNode(this.representedObject, selectedByUser);
if (selectedByUser)
WebInspector.domAgent.highlightDOMNode(this.representedObject.id);
this.updateSelection();
this.treeOutline.suppressRevealAndSelect = false;
return true;
},
ondelete: function()
{
var startTagTreeElement = this.treeOutline.findTreeElement(this.representedObject);
startTagTreeElement ? startTagTreeElement.remove() : this.remove();
return true;
},
onenter: function()
{
if (this.treeOutline.editing)
return false;
this._startEditing();
return true;
},
selectOnMouseDown: function(event)
{
TreeElement.prototype.selectOnMouseDown.call(this, event);
if (this._editing)
return;
if (this.treeOutline._showInElementsPanelEnabled) {
WebInspector.showPanel("elements");
this.treeOutline.selectDOMNode(this.representedObject, true);
}
if (event.detail >= 2)
event.preventDefault();
},
ondblclick: function(event)
{
if (this._editing || this._elementCloseTag)
return;
if (this._startEditingTarget(event.target))
return;
if (this.hasChildren && !this.expanded)
this.expand();
},
_insertInLastAttributePosition: function(tag, node)
{
if (tag.getElementsByClassName("webkit-html-attribute").length > 0)
tag.insertBefore(node, tag.lastChild);
else {
var nodeName = tag.textContent.match(/^<(.*?)>$/)[1];
tag.textContent = '';
tag.appendChild(document.createTextNode('<'+nodeName));
tag.appendChild(node);
tag.appendChild(document.createTextNode('>'));
}
this.updateSelection();
},
_startEditingTarget: function(eventTarget)
{
if (this.treeOutline.selectedDOMNode() != this.representedObject)
return;
if (this.representedObject.nodeType() != Node.ELEMENT_NODE && this.representedObject.nodeType() != Node.TEXT_NODE)
return false;
var textNode = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (textNode)
return this._startEditingTextNode(textNode);
var attribute = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-attribute");
if (attribute)
return this._startEditingAttribute(attribute, eventTarget);
var tagName = eventTarget.enclosingNodeOrSelfWithClass("webkit-html-tag-name");
if (tagName)
return this._startEditingTagName(tagName);
var newAttribute = eventTarget.enclosingNodeOrSelfWithClass("add-attribute");
if (newAttribute)
return this._addNewAttribute();
return false;
},
_populateTagContextMenu: function(contextMenu, event)
{
var attribute = event.target.enclosingNodeOrSelfWithClass("webkit-html-attribute");
var newAttribute = event.target.enclosingNodeOrSelfWithClass("add-attribute");
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Add attribute" : "Add Attribute"), this._addNewAttribute.bind(this));
if (attribute && !newAttribute)
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit attribute" : "Edit Attribute"), this._startEditingAttribute.bind(this, attribute, event.target));
contextMenu.appendSeparator();
if (this.treeOutline._setPseudoClassCallback) {
var pseudoSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Force element state" : "Force Element State"));
this._populateForcedPseudoStateItems(pseudoSubMenu);
contextMenu.appendSeparator();
}
this._populateNodeContextMenu(contextMenu);
this.treeOutline._populateContextMenu(contextMenu, this.representedObject);
contextMenu.appendSeparator();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Scroll into view" : "Scroll Into View"), this._scrollIntoView.bind(this));
},
_populateForcedPseudoStateItems: function(subMenu)
{
const pseudoClasses = ["active", "hover", "focus", "visited"];
var node = this.representedObject;
var forcedPseudoState = (node ? node.getUserProperty("pseudoState") : null) || [];
for (var i = 0; i < pseudoClasses.length; ++i) {
var pseudoClassForced = forcedPseudoState.indexOf(pseudoClasses[i]) >= 0;
subMenu.appendCheckboxItem(":" + pseudoClasses[i], this.treeOutline._setPseudoClassCallback.bind(null, node.id, pseudoClasses[i], !pseudoClassForced), pseudoClassForced, false);
}
},
_populateTextContextMenu: function(contextMenu, textNode)
{
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Edit text" : "Edit Text"), this._startEditingTextNode.bind(this, textNode));
this._populateNodeContextMenu(contextMenu);
},
_populateNodeContextMenu: function(contextMenu)
{
contextMenu.appendItem(WebInspector.UIString("Edit as HTML"), this._editAsHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy as HTML"), this._copyHTML.bind(this));
contextMenu.appendItem(WebInspector.UIString("Copy XPath"), this._copyXPath.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Delete node" : "Delete Node"), this.remove.bind(this));
},
_startEditing: function()
{
if (this.treeOutline.selectedDOMNode() !== this.representedObject)
return;
var listItem = this._listItemNode;
if (this._canAddAttributes) {
var attribute = listItem.getElementsByClassName("webkit-html-attribute")[0];
if (attribute)
return this._startEditingAttribute(attribute, attribute.getElementsByClassName("webkit-html-attribute-value")[0]);
return this._addNewAttribute();
}
if (this.representedObject.nodeType() === Node.TEXT_NODE) {
var textNode = listItem.getElementsByClassName("webkit-html-text-node")[0];
if (textNode)
return this._startEditingTextNode(textNode);
return;
}
},
_addNewAttribute: function()
{
var container = document.createElement("span");
this._buildAttributeDOM(container, " ", "");
var attr = container.firstChild;
attr.style.marginLeft = "2px";
attr.style.marginRight = "2px";
var tag = this.listItemElement.getElementsByClassName("webkit-html-tag")[0];
this._insertInLastAttributePosition(tag, attr);
return this._startEditingAttribute(attr, attr);
},
_triggerEditAttribute: function(attributeName)
{
var attributeElements = this.listItemElement.getElementsByClassName("webkit-html-attribute-name");
for (var i = 0, len = attributeElements.length; i < len; ++i) {
if (attributeElements[i].textContent === attributeName) {
for (var elem = attributeElements[i].nextSibling; elem; elem = elem.nextSibling) {
if (elem.nodeType !== Node.ELEMENT_NODE)
continue;
if (elem.hasStyleClass("webkit-html-attribute-value"))
return this._startEditingAttribute(elem.parentNode, elem);
}
}
}
},
_startEditingAttribute: function(attribute, elementForSelection)
{
if (WebInspector.isBeingEdited(attribute))
return true;
var attributeNameElement = attribute.getElementsByClassName("webkit-html-attribute-name")[0];
if (!attributeNameElement)
return false;
var attributeName = attributeNameElement.textContent;
function removeZeroWidthSpaceRecursive(node)
{
if (node.nodeType === Node.TEXT_NODE) {
node.nodeValue = node.nodeValue.replace(/\u200B/g, "");
return;
}
if (node.nodeType !== Node.ELEMENT_NODE)
return;
for (var child = node.firstChild; child; child = child.nextSibling)
removeZeroWidthSpaceRecursive(child);
}
removeZeroWidthSpaceRecursive(attribute);
var config = new WebInspector.EditingConfig(this._attributeEditingCommitted.bind(this), this._editingCancelled.bind(this), attributeName);
function handleKeyDownEvents(event)
{
var isMetaOrCtrl = WebInspector.isMac() ?
event.metaKey && !event.shiftKey && !event.ctrlKey && !event.altKey :
event.ctrlKey && !event.shiftKey && !event.metaKey && !event.altKey;
if (isEnterKey(event) && (event.isMetaOrCtrlForTest || !config.multiline || isMetaOrCtrl))
return "commit";
else if (event.keyCode === WebInspector.KeyboardShortcut.Keys.Esc.code || event.keyIdentifier === "U+001B")
return "cancel";
else if (event.keyIdentifier === "U+0009")
return "move-" + (event.shiftKey ? "backward" : "forward");
else {
WebInspector.handleElementValueModifications(event, attribute);
return "";
}
}
config.customFinishHandler = handleKeyDownEvents.bind(this);
this._editing = WebInspector.startEditing(attribute, config);
window.getSelection().setBaseAndExtent(elementForSelection, 0, elementForSelection, 1);
return true;
},
_startEditingTextNode: function(textNode)
{
if (WebInspector.isBeingEdited(textNode))
return true;
var container = textNode.enclosingNodeOrSelfWithClass("webkit-html-text-node");
if (container)
container.innerText = textNode._originalContent;
var config = new WebInspector.EditingConfig(this._textNodeEditingCommitted.bind(this), this._editingCancelled.bind(this));
this._editing = WebInspector.startEditing(textNode, config);
window.getSelection().setBaseAndExtent(textNode, 0, textNode, 1);
return true;
},
_startEditingTagName: function(tagNameElement)
{
if (!tagNameElement) {
tagNameElement = this.listItemElement.getElementsByClassName("webkit-html-tag-name")[0];
if (!tagNameElement)
return false;
}
var tagName = tagNameElement.textContent;
if (WebInspector.ElementsTreeElement.EditTagBlacklist[tagName.toLowerCase()])
return false;
if (WebInspector.isBeingEdited(tagNameElement))
return true;
var closingTagElement = this._distinctClosingTagElement();
function keyupListener(event)
{
if (closingTagElement)
closingTagElement.textContent = "</" + tagNameElement.textContent + ">";
}
function editingComitted(element, newTagName)
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._tagNameEditingCommitted.apply(this, arguments);
}
function editingCancelled()
{
tagNameElement.removeEventListener('keyup', keyupListener, false);
this._editingCancelled.apply(this, arguments);
}
tagNameElement.addEventListener('keyup', keyupListener, false);
var config = new WebInspector.EditingConfig(editingComitted.bind(this), editingCancelled.bind(this), tagName);
this._editing = WebInspector.startEditing(tagNameElement, config);
window.getSelection().setBaseAndExtent(tagNameElement, 0, tagNameElement, 1);
return true;
},
_startEditingAsHTML: function(commitCallback, error, initialValue)
{
if (error)
return;
if (this._htmlEditElement && WebInspector.isBeingEdited(this._htmlEditElement))
return;
function consume(event)
{
if (event.eventPhase === Event.AT_TARGET)
event.consume(true);
}
this._htmlEditElement = document.createElement("div");
this._htmlEditElement.className = "source-code elements-tree-editor";
this._htmlEditElement.textContent = initialValue;
var child = this.listItemElement.firstChild;
while (child) {
child.style.display = "none";
child = child.nextSibling;
}
if (this._childrenListNode)
this._childrenListNode.style.display = "none";
this.listItemElement.appendChild(this._htmlEditElement);
this.treeOutline.childrenListElement.parentElement.addEventListener("mousedown", consume, false);
this.updateSelection();
function commit()
{
commitCallback(initialValue, this._htmlEditElement.textContent);
dispose.call(this);
}
function dispose()
{
this._editing = false;
this.listItemElement.removeChild(this._htmlEditElement);
delete this._htmlEditElement;
if (this._childrenListNode)
this._childrenListNode.style.removeProperty("display");
var child = this.listItemElement.firstChild;
while (child) {
child.style.removeProperty("display");
child = child.nextSibling;
}
this.treeOutline.childrenListElement.parentElement.removeEventListener("mousedown", consume, false);
this.updateSelection();
}
var config = new WebInspector.EditingConfig(commit.bind(this), dispose.bind(this));
config.setMultiline(true);
this._editing = WebInspector.startEditing(this._htmlEditElement, config);
},
_attributeEditingCommitted: function(element, newText, oldText, attributeName, moveDirection)
{
this._editing = false;
var treeOutline = this.treeOutline;
function moveToNextAttributeIfNeeded(error)
{
if (error)
this._editingCancelled(element, attributeName);
if (!moveDirection)
return;
treeOutline._updateModifiedNodes();
var attributes = this.representedObject.attributes();
for (var i = 0; i < attributes.length; ++i) {
if (attributes[i].name !== attributeName)
continue;
if (moveDirection === "backward") {
if (i === 0)
this._startEditingTagName();
else
this._triggerEditAttribute(attributes[i - 1].name);
} else {
if (i === attributes.length - 1)
this._addNewAttribute();
else
this._triggerEditAttribute(attributes[i + 1].name);
}
return;
}
if (moveDirection === "backward") {
if (newText === " ") {
if (attributes.length > 0)
this._triggerEditAttribute(attributes[attributes.length - 1].name);
} else {
if (attributes.length > 1)
this._triggerEditAttribute(attributes[attributes.length - 2].name);
}
} else if (moveDirection === "forward") {
if (!/^\s*$/.test(newText))
this._addNewAttribute();
else
this._startEditingTagName();
}
}
if (oldText !== newText)
this.representedObject.setAttribute(attributeName, newText, moveToNextAttributeIfNeeded.bind(this));
else
moveToNextAttributeIfNeeded.call(this);
},
_tagNameEditingCommitted: function(element, newText, oldText, tagName, moveDirection)
{
this._editing = false;
var self = this;
function cancel()
{
var closingTagElement = self._distinctClosingTagElement();
if (closingTagElement)
closingTagElement.textContent = "</" + tagName + ">";
self._editingCancelled(element, tagName);
moveToNextAttributeIfNeeded.call(self);
}
function moveToNextAttributeIfNeeded()
{
if (moveDirection !== "forward") {
this._addNewAttribute();
return;
}
var attributes = this.representedObject.attributes();
if (attributes.length > 0)
this._triggerEditAttribute(attributes[0].name);
else
this._addNewAttribute();
}
newText = newText.trim();
if (newText === oldText) {
cancel();
return;
}
var treeOutline = this.treeOutline;
var wasExpanded = this.expanded;
function changeTagNameCallback(error, nodeId)
{
if (error || !nodeId) {
cancel();
return;
}
var newTreeItem = treeOutline._selectNodeAfterEdit(null, wasExpanded, error, nodeId);
moveToNextAttributeIfNeeded.call(newTreeItem);
}
this.representedObject.setNodeName(newText, changeTagNameCallback);
},
_textNodeEditingCommitted: function(element, newText)
{
this._editing = false;
var textNode;
if (this.representedObject.nodeType() === Node.ELEMENT_NODE) {
textNode = this.representedObject.firstChild;
} else if (this.representedObject.nodeType() == Node.TEXT_NODE)
textNode = this.representedObject;
textNode.setNodeValue(newText, this.updateTitle.bind(this));
},
_editingCancelled: function(element, context)
{
this._editing = false;
this.updateTitle();
},
_distinctClosingTagElement: function()
{
if (this.expanded) {
var closers = this._childrenListNode.querySelectorAll(".close");
return closers[closers.length-1];
}
var tags = this.listItemElement.getElementsByClassName("webkit-html-tag");
return (tags.length === 1 ? null : tags[tags.length-1]);
},
updateTitle: function(onlySearchQueryChanged)
{
if (this._editing)
return;
if (onlySearchQueryChanged) {
if (this._highlightResult)
this._updateSearchHighlight(false);
} else {
var highlightElement = document.createElement("span");
highlightElement.className = "highlight";
highlightElement.appendChild(this._nodeTitleInfo(WebInspector.linkifyURLAsNode).titleDOM);
this.title = highlightElement;
this._updateDecorations();
delete this._highlightResult;
}
delete this.selectionElement;
if (this.selected)
this.updateSelection();
this._preventFollowingLinksOnDoubleClick();
this._highlightSearchResults();
},
_createDecoratorElement: function()
{
var node = this.representedObject;
var decoratorMessages = [];
var parentDecoratorMessages = [];
for (var i = 0; i < this.treeOutline._nodeDecorators.length; ++i) {
var decorator = this.treeOutline._nodeDecorators[i];
var message = decorator.decorate(node);
if (message) {
decoratorMessages.push(message);
continue;
}
if (this.expanded || this._elementCloseTag)
continue;
message = decorator.decorateAncestor(node);
if (message)
parentDecoratorMessages.push(message)
}
if (!decoratorMessages.length && !parentDecoratorMessages.length)
return null;
var decoratorElement = document.createElement("div");
decoratorElement.addStyleClass("elements-gutter-decoration");
if (!decoratorMessages.length)
decoratorElement.addStyleClass("elements-has-decorated-children");
decoratorElement.title = decoratorMessages.concat(parentDecoratorMessages).join("\n");
return decoratorElement;
},
_updateDecorations: function()
{
if (this._decoratorElement && this._decoratorElement.parentElement)
this._decoratorElement.parentElement.removeChild(this._decoratorElement);
this._decoratorElement = this._createDecoratorElement();
if (this._decoratorElement && this.listItemElement)
this.listItemElement.insertBefore(this._decoratorElement, this.listItemElement.firstChild);
},
_buildAttributeDOM: function(parentElement, name, value, node, linkify)
{
var hasText = (value.length > 0);
var attrSpanElement = parentElement.createChild("span", "webkit-html-attribute");
var attrNameElement = attrSpanElement.createChild("span", "webkit-html-attribute-name");
attrNameElement.textContent = name;
if (hasText)
attrSpanElement.appendChild(document.createTextNode("=\u200B\""));
if (linkify && (name === "src" || name === "href")) {
var rewrittenHref = node.resolveURL(value);
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
if (rewrittenHref === null) {
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
} else {
if (value.startsWith("data:"))
value = value.trimMiddle(60);
attrSpanElement.appendChild(linkify(rewrittenHref, value, "webkit-html-attribute-value", node.nodeName().toLowerCase() === "a"));
}
} else {
value = value.replace(/([\/;:\)\]\}])/g, "$1\u200B");
var attrValueElement = attrSpanElement.createChild("span", "webkit-html-attribute-value");
attrValueElement.textContent = value;
}
if (hasText)
attrSpanElement.appendChild(document.createTextNode("\""));
},
_buildTagDOM: function(parentElement, tagName, isClosingTag, isDistinctTreeElement, linkify)
{
var node = this.representedObject;
var classes = [ "webkit-html-tag" ];
if (isClosingTag && isDistinctTreeElement)
classes.push("close");
if (node.isInShadowTree())
classes.push("shadow");
var tagElement = parentElement.createChild("span", classes.join(" "));
tagElement.appendChild(document.createTextNode("<"));
var tagNameElement = tagElement.createChild("span", isClosingTag ? "" : "webkit-html-tag-name");
tagNameElement.textContent = (isClosingTag ? "/" : "") + tagName;
if (!isClosingTag && node.hasAttributes()) {
var attributes = node.attributes();
for (var i = 0; i < attributes.length; ++i) {
var attr = attributes[i];
tagElement.appendChild(document.createTextNode(" "));
this._buildAttributeDOM(tagElement, attr.name, attr.value, node, linkify);
}
}
tagElement.appendChild(document.createTextNode(">"));
parentElement.appendChild(document.createTextNode("\u200B"));
},
_convertWhitespaceToEntities: function(text)
{
var result = "";
var lastIndexAfterEntity = 0;
var charToEntity = WebInspector.ElementsTreeOutline.MappedCharToEntity;
for (var i = 0, size = text.length; i < size; ++i) {
var char = text.charAt(i);
if (charToEntity[char]) {
result += text.substring(lastIndexAfterEntity, i) + "&" + charToEntity[char] + ";";
lastIndexAfterEntity = i + 1;
}
}
if (result) {
result += text.substring(lastIndexAfterEntity);
return result;
}
return text;
},
_nodeTitleInfo: function(linkify)
{
var node = this.representedObject;
var info = {titleDOM: document.createDocumentFragment(), hasChildren: this.hasChildren};
switch (node.nodeType()) {
case Node.ATTRIBUTE_NODE:
var value = node.value || "\u200B";
this._buildAttributeDOM(info.titleDOM, node.name, value);
break;
case Node.ELEMENT_NODE:
var tagName = node.nodeNameInCorrectCase();
if (this._elementCloseTag) {
this._buildTagDOM(info.titleDOM, tagName, true, true);
info.hasChildren = false;
break;
}
this._buildTagDOM(info.titleDOM, tagName, false, false, linkify);
var textChild = this._singleTextChild(node);
var showInlineText = textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength;
if (!this.expanded && (!showInlineText && (this.treeOutline.isXMLMimeType || !WebInspector.ElementsTreeElement.ForbiddenClosingTagElements[tagName]))) {
if (this.hasChildren) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node bogus");
textNodeElement.textContent = "\u2026";
info.titleDOM.appendChild(document.createTextNode("\u200B"));
}
this._buildTagDOM(info.titleDOM, tagName, true, false);
}
if (showInlineText) {
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(textChild.nodeValue());
textNodeElement._originalContent = textChild.nodeValue();
info.titleDOM.appendChild(document.createTextNode("\u200B"));
this._buildTagDOM(info.titleDOM, tagName, true, false);
info.hasChildren = false;
}
break;
case Node.TEXT_NODE:
if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "script") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-js-node");
newNode.textContent = node.nodeValue();
var javascriptSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/javascript", true);
javascriptSyntaxHighlighter.syntaxHighlightNode(newNode);
} else if (node.parentNode && node.parentNode.nodeName().toLowerCase() === "style") {
var newNode = info.titleDOM.createChild("span", "webkit-html-text-node webkit-html-css-node");
newNode.textContent = node.nodeValue();
var cssSyntaxHighlighter = new WebInspector.DOMSyntaxHighlighter("text/css", true);
cssSyntaxHighlighter.syntaxHighlightNode(newNode);
} else {
info.titleDOM.appendChild(document.createTextNode("\""));
var textNodeElement = info.titleDOM.createChild("span", "webkit-html-text-node");
textNodeElement.textContent = this._convertWhitespaceToEntities(node.nodeValue());
textNodeElement._originalContent = node.nodeValue();
info.titleDOM.appendChild(document.createTextNode("\""));
}
break;
case Node.COMMENT_NODE:
var commentElement = info.titleDOM.createChild("span", "webkit-html-comment");
commentElement.appendChild(document.createTextNode("<!--" + node.nodeValue() + "-->"));
break;
case Node.DOCUMENT_TYPE_NODE:
var docTypeElement = info.titleDOM.createChild("span", "webkit-html-doctype");
docTypeElement.appendChild(document.createTextNode("<!DOCTYPE " + node.nodeName()));
if (node.publicId) {
docTypeElement.appendChild(document.createTextNode(" PUBLIC \"" + node.publicId + "\""));
if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" \"" + node.systemId + "\""));
} else if (node.systemId)
docTypeElement.appendChild(document.createTextNode(" SYSTEM \"" + node.systemId + "\""));
if (node.internalSubset)
docTypeElement.appendChild(document.createTextNode(" [" + node.internalSubset + "]"));
docTypeElement.appendChild(document.createTextNode(">"));
break;
case Node.CDATA_SECTION_NODE:
var cdataElement = info.titleDOM.createChild("span", "webkit-html-text-node");
cdataElement.appendChild(document.createTextNode("<![CDATA[" + node.nodeValue() + "]]>"));
break;
case Node.DOCUMENT_FRAGMENT_NODE:
var fragmentElement = info.titleDOM.createChild("span", "webkit-html-fragment");
fragmentElement.textContent = node.nodeNameInCorrectCase().collapseWhitespace();
if (node.isInShadowTree())
fragmentElement.addStyleClass("shadow");
break;
default:
info.titleDOM.appendChild(document.createTextNode(node.nodeNameInCorrectCase().collapseWhitespace()));
}
return info;
},
_singleTextChild: function(node)
{
if (!node)
return null;
var firstChild = node.firstChild;
if (!firstChild || firstChild.nodeType() !== Node.TEXT_NODE)
return null;
var sibling = firstChild.nextSibling;
return sibling ? null : firstChild;
},
_showInlineText: function(node)
{
if (node.nodeType() === Node.ELEMENT_NODE) {
var textChild = this._singleTextChild(node);
if (textChild && textChild.nodeValue().length < Preferences.maxInlineTextChildLength)
return true;
}
return false;
},
remove: function()
{
var parentElement = this.parent;
if (!parentElement)
return;
var self = this;
function removeNodeCallback(error, removedNodeId)
{
if (error)
return;
parentElement.removeChild(self);
parentElement.adjustCollapsedRange();
}
if (!this.representedObject.parentNode || this.representedObject.parentNode.nodeType() === Node.DOCUMENT_NODE)
return;
this.representedObject.removeNode(removeNodeCallback);
},
_editAsHTML: function()
{
var treeOutline = this.treeOutline;
var node = this.representedObject;
var parentNode = node.parentNode;
var index = node.index;
var wasExpanded = this.expanded;
function selectNode(error, nodeId)
{
if (error)
return;
treeOutline._updateModifiedNodes();
var newNode = parentNode ? parentNode.children[index] || parentNode : null;
if (!newNode)
return;
treeOutline.selectDOMNode(newNode, true);
if (wasExpanded) {
var newTreeItem = treeOutline.findTreeElement(newNode);
if (newTreeItem)
newTreeItem.expand();
}
}
function commitChange(initialValue, value)
{
if (initialValue !== value)
node.setOuterHTML(value, selectNode);
else
return;
}
node.getOuterHTML(this._startEditingAsHTML.bind(this, commitChange));
},
_copyHTML: function()
{
this.representedObject.copyNode();
},
_copyXPath: function()
{
this.representedObject.copyXPath(true);
},
_highlightSearchResults: function()
{
if (!this._searchQuery || !this._searchHighlightsVisible)
return;
if (this._highlightResult) {
this._updateSearchHighlight(true);
return;
}
var text = this.listItemElement.textContent;
var regexObject = createPlainTextSearchRegex(this._searchQuery, "gi");
var offset = 0;
var match = regexObject.exec(text);
var matchRanges = [];
while (match) {
matchRanges.push({ offset: match.index, length: match[0].length });
match = regexObject.exec(text);
}
if (!matchRanges.length)
matchRanges.push({ offset: 0, length: text.length });
this._highlightResult = [];
WebInspector.highlightSearchResults(this.listItemElement, matchRanges, this._highlightResult);
},
_scrollIntoView: function()
{
function scrollIntoViewCallback(object)
{
function scrollIntoView()
{
this.scrollIntoViewIfNeeded(true);
}
if (object)
object.callFunction(scrollIntoView);
}
var node = this.representedObject;
WebInspector.RemoteObject.resolveNode(node, "", scrollIntoViewCallback);
}
}
WebInspector.ElementsTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.ElementsTreeUpdater = function(treeOutline)
{
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeInserted, this._nodeInserted, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrModified, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.AttrRemoved, this._attributesUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.CharacterDataModified, this._characterDataModified, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.DocumentUpdated, this._documentUpdated, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.ChildNodeCountUpdated, this._childNodeCountUpdated, this);
this._treeOutline = treeOutline;
this._recentlyModifiedNodes = new Map();
}
WebInspector.ElementsTreeUpdater.prototype = {
_nodeModified: function(node, isUpdated, parentNode)
{
if (this._treeOutline._visible)
this._updateModifiedNodesSoon();
var entry = this._recentlyModifiedNodes.get(node);
if (!entry) {
entry = new WebInspector.ElementsTreeUpdater.UpdateEntry(isUpdated, parentNode);
this._recentlyModifiedNodes.put(node, entry);
return;
}
entry.isUpdated |= isUpdated;
if (parentNode)
entry.parent = parentNode;
},
_documentUpdated: function(event)
{
var inspectedRootDocument = event.data;
this._reset();
if (!inspectedRootDocument)
return;
this._treeOutline.rootDOMNode = inspectedRootDocument;
},
_attributesUpdated: function(event)
{
this._nodeModified(event.data.node, true);
},
_characterDataModified: function(event)
{
this._nodeModified(event.data, true);
},
_nodeInserted: function(event)
{
this._nodeModified(event.data, false, event.data.parentNode);
},
_nodeRemoved: function(event)
{
this._nodeModified(event.data.node, false, event.data.parent);
},
_childNodeCountUpdated: function(event)
{
var treeElement = this._treeOutline.findTreeElement(event.data);
if (treeElement)
treeElement.hasChildren = event.data.hasChildNodes();
},
_updateModifiedNodesSoon: function()
{
if (this._updateModifiedNodesTimeout)
return;
this._updateModifiedNodesTimeout = setTimeout(this._updateModifiedNodes.bind(this), 50);
},
_updateModifiedNodes: function()
{
if (this._updateModifiedNodesTimeout) {
clearTimeout(this._updateModifiedNodesTimeout);
delete this._updateModifiedNodesTimeout;
}
var updatedParentTreeElements = [];
var hidePanelWhileUpdating = this._recentlyModifiedNodes.size() > 10;
if (hidePanelWhileUpdating) {
var treeOutlineContainerElement = this._treeOutline.element.parentNode;
this._treeOutline.element.addStyleClass("hidden");
var originalScrollTop = treeOutlineContainerElement ? treeOutlineContainerElement.scrollTop : 0;
}
var keys = this._recentlyModifiedNodes.keys();
for (var i = 0, size = keys.length; i < size; ++i) {
var node = keys[i];
var entry = this._recentlyModifiedNodes.get(node);
var parent = entry.parent;
if (parent === this._treeOutline._rootDOMNode) {
this._treeOutline.update();
this._treeOutline.element.removeStyleClass("hidden");
return;
}
if (entry.isUpdated) {
var nodeItem = this._treeOutline.findTreeElement(node);
if (nodeItem)
nodeItem.updateTitle();
}
if (!parent)
continue;
var parentNodeItem = this._treeOutline.findTreeElement(parent);
if (parentNodeItem && !parentNodeItem.alreadyUpdatedChildren) {
parentNodeItem.updateChildren();
parentNodeItem.alreadyUpdatedChildren = true;
updatedParentTreeElements.push(parentNodeItem);
}
}
for (var i = 0; i < updatedParentTreeElements.length; ++i)
delete updatedParentTreeElements[i].alreadyUpdatedChildren;
if (hidePanelWhileUpdating) {
this._treeOutline.element.removeStyleClass("hidden");
if (originalScrollTop)
treeOutlineContainerElement.scrollTop = originalScrollTop;
this._treeOutline.updateSelection();
}
this._recentlyModifiedNodes.clear();
},
_reset: function()
{
this._treeOutline.rootDOMNode = null;
this._treeOutline.selectDOMNode(null, false);
WebInspector.domAgent.hideDOMNodeHighlight();
this._recentlyModifiedNodes.clear();
}
}
WebInspector.ElementsTreeUpdater.UpdateEntry = function(isUpdated, parent)
{
this.isUpdated = isUpdated;
if (parent)
this.parent = parent;
}
WebInspector.DOMPresentationUtils = {}
WebInspector.DOMPresentationUtils.decorateNodeLabel = function(node, parentElement)
{
var title = node.nodeNameInCorrectCase();
var nameElement = document.createElement("span");
nameElement.textContent = title;
parentElement.appendChild(nameElement);
var idAttribute = node.getAttribute("id");
if (idAttribute) {
var idElement = document.createElement("span");
parentElement.appendChild(idElement);
var part = "#" + idAttribute;
title += part;
idElement.appendChild(document.createTextNode(part));
nameElement.className = "extra";
}
var classAttribute = node.getAttribute("class");
if (classAttribute) {
var classes = classAttribute.split(/\s+/);
var foundClasses = {};
if (classes.length) {
var classesElement = document.createElement("span");
classesElement.className = "extra";
parentElement.appendChild(classesElement);
for (var i = 0; i < classes.length; ++i) {
var className = classes[i];
if (className && !(className in foundClasses)) {
var part = "." + className;
title += part;
classesElement.appendChild(document.createTextNode(part));
foundClasses[className] = true;
}
}
}
}
parentElement.title = title;
}
WebInspector.DOMPresentationUtils.linkifyNodeReference = function(node)
{
var link = document.createElement("span");
link.className = "node-link";
WebInspector.DOMPresentationUtils.decorateNodeLabel(node, link);
link.addEventListener("click", WebInspector.domAgent.inspectElement.bind(WebInspector.domAgent, node.id), false);
link.addEventListener("mouseover", WebInspector.domAgent.highlightDOMNode.bind(WebInspector.domAgent, node.id, ""), false);
link.addEventListener("mouseout", WebInspector.domAgent.hideDOMNodeHighlight.bind(WebInspector.domAgent), false);
return link;
}
WebInspector.DOMPresentationUtils.linkifyNodeById = function(nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return document.createTextNode(WebInspector.UIString("<node>"));
return WebInspector.DOMPresentationUtils.linkifyNodeReference(node);
}
WebInspector.DOMPresentationUtils.buildImagePreviewContents = function(imageURL, showDimensions, userCallback, precomputedDimensions)
{
var resource = WebInspector.resourceTreeModel.resourceForURL(imageURL);
if (!resource) {
userCallback();
return;
}
var imageElement = document.createElement("img");
imageElement.addEventListener("load", buildContent, false);
imageElement.addEventListener("error", errorCallback, false);
resource.populateImageSource(imageElement);
function errorCallback()
{
userCallback();
}
function buildContent()
{
var container = document.createElement("table");
container.className = "image-preview-container";
var naturalWidth = precomputedDimensions ? precomputedDimensions.naturalWidth : imageElement.naturalWidth;
var naturalHeight = precomputedDimensions ? precomputedDimensions.naturalHeight : imageElement.naturalHeight;
var offsetWidth = precomputedDimensions ? precomputedDimensions.offsetWidth : naturalWidth;
var offsetHeight = precomputedDimensions ? precomputedDimensions.offsetHeight : naturalHeight;
var description;
if (showDimensions) {
if (offsetHeight === naturalHeight && offsetWidth === naturalWidth)
description = WebInspector.UIString("%d \xd7 %d pixels", offsetWidth, offsetHeight);
else
description = WebInspector.UIString("%d \xd7 %d pixels (Natural: %d \xd7 %d pixels)", offsetWidth, offsetHeight, naturalWidth, naturalHeight);
}
container.createChild("tr").createChild("td", "image-container").appendChild(imageElement);
if (description)
container.createChild("tr").createChild("td").createChild("span", "description").textContent = description;
userCallback(container);
}
}
WebInspector.SidebarSectionTreeElement = function(title, representedObject, hasChildren)
{
TreeElement.call(this, title.escapeHTML(), representedObject || {}, hasChildren);
this.expand();
}
WebInspector.SidebarSectionTreeElement.prototype = {
selectable: false,
collapse: function()
{
},
get smallChildren()
{
return this._smallChildren;
},
set smallChildren(x)
{
if (this._smallChildren === x)
return;
this._smallChildren = x;
if (this._smallChildren)
this._childrenListNode.addStyleClass("small");
else
this._childrenListNode.removeStyleClass("small");
},
onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-section");
},
onreveal: function()
{
if (this.listItemElement)
this.listItemElement.scrollIntoViewIfNeeded(false);
}
}
WebInspector.SidebarSectionTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.SidebarTreeElement = function(className, title, subtitle, representedObject, hasChildren)
{
TreeElement.call(this, "", representedObject, hasChildren);
if (hasChildren) {
this.disclosureButton = document.createElement("button");
this.disclosureButton.className = "disclosure-button";
}
if (!this.iconElement) {
this.iconElement = document.createElement("img");
this.iconElement.className = "icon";
}
this.statusElement = document.createElement("div");
this.statusElement.className = "status";
this.titlesElement = document.createElement("div");
this.titlesElement.className = "titles";
this.titleElement = document.createElement("span");
this.titleElement.className = "title";
this.titlesElement.appendChild(this.titleElement);
this.subtitleElement = document.createElement("span");
this.subtitleElement.className = "subtitle";
this.titlesElement.appendChild(this.subtitleElement);
this.className = className;
this.mainTitle = title;
this.subtitle = subtitle;
}
WebInspector.SidebarTreeElement.prototype = {
get small()
{
return this._small;
},
set small(x)
{
this._small = x;
if (this._listItemNode) {
if (this._small)
this._listItemNode.addStyleClass("small");
else
this._listItemNode.removeStyleClass("small");
}
},
get mainTitle()
{
return this._mainTitle;
},
set mainTitle(x)
{
this._mainTitle = x;
this.refreshTitles();
},
get subtitle()
{
return this._subtitle;
},
set subtitle(x)
{
this._subtitle = x;
this.refreshTitles();
},
get bubbleText()
{
return this._bubbleText;
},
set bubbleText(x)
{
if (!this.bubbleElement) {
this.bubbleElement = document.createElement("div");
this.bubbleElement.className = "bubble";
this.statusElement.appendChild(this.bubbleElement);
}
this._bubbleText = x;
this.bubbleElement.textContent = x;
},
set wait(x)
{
if (x)
this._listItemNode.addStyleClass("wait");
else
this._listItemNode.removeStyleClass("wait");
},
refreshTitles: function()
{
var mainTitle = this.mainTitle;
if (this.titleElement.textContent !== mainTitle)
this.titleElement.textContent = mainTitle;
var subtitle = this.subtitle;
if (subtitle) {
if (this.subtitleElement.textContent !== subtitle)
this.subtitleElement.textContent = subtitle;
this.titlesElement.removeStyleClass("no-subtitle");
} else {
this.subtitleElement.textContent = "";
this.titlesElement.addStyleClass("no-subtitle");
}
},
isEventWithinDisclosureTriangle: function(event)
{
return event.target === this.disclosureButton;
},
onattach: function()
{
this._listItemNode.addStyleClass("sidebar-tree-item");
if (this.className)
this._listItemNode.addStyleClass(this.className);
if (this.small)
this._listItemNode.addStyleClass("small");
if (this.hasChildren && this.disclosureButton)
this._listItemNode.appendChild(this.disclosureButton);
this._listItemNode.appendChild(this.iconElement);
this._listItemNode.appendChild(this.statusElement);
this._listItemNode.appendChild(this.titlesElement);
},
onreveal: function()
{
if (this._listItemNode)
this._listItemNode.scrollIntoViewIfNeeded(false);
}
}
WebInspector.SidebarTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.Section = function(title, subtitle)
{
this.element = document.createElement("div");
this.element.className = "section";
this.element._section = this;
this.headerElement = document.createElement("div");
this.headerElement.className = "header";
this.titleElement = document.createElement("div");
this.titleElement.className = "title";
this.subtitleElement = document.createElement("div");
this.subtitleElement.className = "subtitle";
this.headerElement.appendChild(this.subtitleElement);
this.headerElement.appendChild(this.titleElement);
this.headerElement.addEventListener("click", this.handleClick.bind(this), false);
this.element.appendChild(this.headerElement);
this.title = title;
this.subtitle = subtitle;
this._expanded = false;
}
WebInspector.Section.prototype = {
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
if (x instanceof Node) {
this.titleElement.removeChildren();
this.titleElement.appendChild(x);
} else
this.titleElement.textContent = x;
},
get subtitle()
{
return this._subtitle;
},
set subtitle(x)
{
if (this._subtitle === x)
return;
this._subtitle = x;
this.subtitleElement.textContent = x;
},
get subtitleAsTextForTest()
{
var result = this.subtitleElement.textContent;
var child = this.subtitleElement.querySelector("[data-uncopyable]");
if (child) {
var linkData = child.getAttribute("data-uncopyable");
if (linkData)
result += linkData;
}
return result;
},
get expanded()
{
return this._expanded;
},
set expanded(x)
{
if (x)
this.expand();
else
this.collapse();
},
get populated()
{
return this._populated;
},
set populated(x)
{
this._populated = x;
if (!x && this._expanded) {
this.onpopulate();
this._populated = true;
}
},
onpopulate: function()
{
},
get firstSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;
var childElement = parent.firstChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.nextSibling;
}
return null;
},
get lastSibling()
{
var parent = this.element.parentElement;
if (!parent)
return null;
var childElement = parent.lastChild;
while (childElement) {
if (childElement._section)
return childElement._section;
childElement = childElement.previousSibling;
}
return null;
},
get nextSibling()
{
var curElement = this.element;
do {
curElement = curElement.nextSibling;
} while (curElement && !curElement._section);
return curElement ? curElement._section : null;
},
get previousSibling()
{
var curElement = this.element;
do {
curElement = curElement.previousSibling;
} while (curElement && !curElement._section);
return curElement ? curElement._section : null;
},
expand: function()
{
if (this._expanded)
return;
this._expanded = true;
this.element.addStyleClass("expanded");
if (!this._populated) {
this.onpopulate();
this._populated = true;
}
},
collapse: function()
{
if (!this._expanded)
return;
this._expanded = false;
this.element.removeStyleClass("expanded");
},
toggleExpanded: function()
{
this.expanded = !this.expanded;
},
handleClick: function(event)
{
this.toggleExpanded();
event.consume();
}
}
WebInspector.PropertiesSection = function(title, subtitle)
{
WebInspector.Section.call(this, title, subtitle);
this.headerElement.addStyleClass("monospace");
this.propertiesElement = document.createElement("ol");
this.propertiesElement.className = "properties properties-tree monospace";
this.propertiesTreeOutline = new TreeOutline(this.propertiesElement, true);
this.propertiesTreeOutline.setFocusable(false);
this.propertiesTreeOutline.section = this;
this.element.appendChild(this.propertiesElement);
}
WebInspector.PropertiesSection.prototype.__proto__ = WebInspector.Section.prototype;
WebInspector.RemoteObject = function(objectId, type, subtype, value, description, preview)
{
this._type = type;
this._subtype = subtype;
if (objectId) {
this._objectId = objectId;
this._description = description;
this._hasChildren = true;
this._preview = preview;
} else {
console.assert(type !== "object" || value === null);
this._description = description || (value + "");
this._hasChildren = false;
this.value = value;
}
}
WebInspector.RemoteObject.fromPrimitiveValue = function(value)
{
return new WebInspector.RemoteObject(undefined, typeof value, undefined, value);
}
WebInspector.RemoteObject.fromLocalObject = function(value)
{
return new WebInspector.LocalJSONObject(value);
}
WebInspector.RemoteObject.resolveNode = function(node, objectGroup, callback)
{
function mycallback(error, object)
{
if (!callback)
return;
if (error || !object)
callback(null);
else
callback(WebInspector.RemoteObject.fromPayload(object));
}
DOMAgent.resolveNode(node.id, objectGroup, mycallback);
}
WebInspector.RemoteObject.fromPayload = function(payload)
{
console.assert(typeof payload === "object", "Remote object payload should only be an object");
return new WebInspector.RemoteObject(payload.objectId, payload.type, payload.subtype, payload.value, payload.description, payload.preview);
}
WebInspector.RemoteObject.type = function(remoteObject)
{
if (remoteObject === null)
return "null";
var type = typeof remoteObject;
if (type !== "object" && type !== "function")
return type;
return remoteObject.type;
}
WebInspector.RemoteObject.prototype = {
get objectId()
{
return this._objectId;
},
get type()
{
return this._type;
},
get subtype()
{
return this._subtype;
},
get description()
{
return this._description;
},
get hasChildren()
{
return this._hasChildren;
},
get preview()
{
return this._preview;
},
getOwnProperties: function(callback)
{
this._getProperties(true, callback);
},
getAllProperties: function(callback)
{
this._getProperties(false, callback);
},
_getProperties: function(ownProperties, callback)
{
if (!this._objectId) {
callback([]);
return;
}
function remoteObjectBinder(error, properties)
{
if (error) {
callback(null);
return;
}
var result = [];
for (var i = 0; properties && i < properties.length; ++i) {
var property = properties[i];
if (property.get || property.set) {
if (property.get)
result.push(new WebInspector.RemoteObjectProperty("get " + property.name, WebInspector.RemoteObject.fromPayload(property.get), property));
if (property.set)
result.push(new WebInspector.RemoteObjectProperty("set " + property.name, WebInspector.RemoteObject.fromPayload(property.set), property));
} else
result.push(new WebInspector.RemoteObjectProperty(property.name, WebInspector.RemoteObject.fromPayload(property.value), property));
}
callback(result);
}
RuntimeAgent.getProperties(this._objectId, ownProperties, remoteObjectBinder);
},
setPropertyValue: function(name, value, callback)
{
if (!this._objectId) {
callback("Can't set a property of non-object.");
return;
}
RuntimeAgent.evaluate.invoke({expression:value, doNotPauseOnExceptionsAndMuteConsole:true}, evaluatedCallback.bind(this));
function evaluatedCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
function setPropertyValue(propertyName, propertyValue)
{
this[propertyName] = propertyValue;
}
delete result.description;
RuntimeAgent.callFunctionOn(this._objectId, setPropertyValue.toString(), [{ value:name }, result], true, undefined, propertySetCallback.bind(this));
if (result._objectId)
RuntimeAgent.releaseObject(result._objectId);
}
function propertySetCallback(error, result, wasThrown)
{
if (error || wasThrown) {
callback(error || result.description);
return;
}
callback();
}
},
pushNodeToFrontend: function(callback)
{
if (this._objectId)
WebInspector.domAgent.pushNodeToFrontend(this._objectId, callback);
else
callback(0);
},
callFunction: function(functionDeclaration, args, callback)
{
function mycallback(error, result, wasThrown)
{
if (!callback)
return;
callback((error || wasThrown) ? null : WebInspector.RemoteObject.fromPayload(result));
}
RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, undefined, mycallback);
},
callFunctionJSON: function(functionDeclaration, args, callback)
{
function mycallback(error, result, wasThrown)
{
callback((error || wasThrown) ? null : result.value);
}
RuntimeAgent.callFunctionOn(this._objectId, functionDeclaration.toString(), args, true, true, mycallback);
},
release: function()
{
RuntimeAgent.releaseObject(this._objectId);
},
arrayLength: function()
{
if (this.subtype !== "array")
return 0;
var matches = this._description.match(/\[([0-9]+)\]/);
if (!matches)
return 0;
return parseInt(matches[1], 10);
}
}
WebInspector.RemoteObjectProperty = function(name, value, descriptor)
{
this.name = name;
this.value = value;
this.enumerable = descriptor ? !!descriptor.enumerable : true;
this.writable = descriptor ? !!descriptor.writable : true;
if (descriptor && descriptor.wasThrown)
this.wasThrown = true;
}
WebInspector.RemoteObjectProperty.fromPrimitiveValue = function(name, value)
{
return new WebInspector.RemoteObjectProperty(name, WebInspector.RemoteObject.fromPrimitiveValue(value));
}
WebInspector.RemoteObjectProperty.fromScopeValue = function(name, value)
{
var result = new WebInspector.RemoteObjectProperty(name, value);
result.writable = false;
return result;
}
WebInspector.LocalJSONObject = function(value)
{
this._value = value;
}
WebInspector.LocalJSONObject.prototype = {
get description()
{
if (this._cachedDescription)
return this._cachedDescription;
if (this.type === "object") {
switch (this.subtype) {
case "array":
function formatArrayItem(property)
{
return property.value.description;
}
this._cachedDescription = this._concatenate("[", "]", formatArrayItem);
break;
case "date":
this._cachedDescription = "" + this._value;
break;
case "null":
this._cachedDescription = "null";
break;
default:
function formatObjectItem(property)
{
return property.name + ":" + property.value.description;
}
this._cachedDescription = this._concatenate("{", "}", formatObjectItem);
}
} else
this._cachedDescription = String(this._value);
return this._cachedDescription;
},
_concatenate: function(prefix, suffix, formatProperty)
{
const previewChars = 100;
var buffer = prefix;
var children = this._children();
for (var i = 0; i < children.length; ++i) {
var itemDescription = formatProperty(children[i]);
if (buffer.length + itemDescription.length > previewChars) {
buffer += ",\u2026";
break;
}
if (i)
buffer += ", ";
buffer += itemDescription;
}
buffer += suffix;
return buffer;
},
get type()
{
return typeof this._value;
},
get subtype()
{
if (this._value === null)
return "null";
if (this._value instanceof Array)
return "array";
if (this._value instanceof Date)
return "date";
return undefined;
},
get hasChildren()
{
return typeof this._value === "object" && this._value !== null && !!Object.keys(this._value).length;
},
getOwnProperties: function(callback)
{
callback(this._children());
},
getAllProperties: function(callback)
{
callback(this._children());
},
_children: function()
{
if (!this.hasChildren)
return [];
function buildProperty(propName)
{
return new WebInspector.RemoteObjectProperty(propName, new WebInspector.LocalJSONObject(this._value[propName]));
}
if (!this._cachedChildren)
this._cachedChildren = Object.keys(this._value || {}).map(buildProperty.bind(this));
return this._cachedChildren;
},
isError: function()
{
return false;
},
arrayLength: function()
{
return this._value instanceof Array ? this._value.length : 0;
}
}
WebInspector.ObjectPropertiesSection = function(object, title, subtitle, emptyPlaceholder, ignoreHasOwnProperty, extraProperties, treeElementConstructor)
{
this.emptyPlaceholder = (emptyPlaceholder || WebInspector.UIString("No Properties"));
this.object = object;
this.ignoreHasOwnProperty = ignoreHasOwnProperty;
this.extraProperties = extraProperties;
this.treeElementConstructor = treeElementConstructor || WebInspector.ObjectPropertyTreeElement;
this.editable = true;
this.skipProto = false;
WebInspector.PropertiesSection.call(this, title || "", subtitle);
}
WebInspector.ObjectPropertiesSection._arrayLoadThreshold = 100;
WebInspector.ObjectPropertiesSection.prototype = {
enableContextMenu: function()
{
this.element.addEventListener("contextmenu", this._contextMenuEventFired.bind(this), true);
},
_contextMenuEventFired: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendApplicableItems(this.object);
contextMenu.show(event);
},
onpopulate: function()
{
this.update();
},
update: function()
{
if (this.object.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
this.propertiesTreeOutline.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(this.propertiesTreeOutline, this.object, 0, this.object.arrayLength() - 1);
return;
}
function callback(properties)
{
if (!properties)
return;
this.updateProperties(properties);
}
if (this.ignoreHasOwnProperty)
this.object.getAllProperties(callback.bind(this));
else
this.object.getOwnProperties(callback.bind(this));
},
updateProperties: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
if (!rootTreeElementConstructor)
rootTreeElementConstructor = this.treeElementConstructor;
if (!rootPropertyComparer)
rootPropertyComparer = WebInspector.ObjectPropertiesSection.CompareProperties;
if (this.extraProperties)
for (var i = 0; i < this.extraProperties.length; ++i)
properties.push(this.extraProperties[i]);
properties.sort(rootPropertyComparer);
this.propertiesTreeOutline.removeChildren();
for (var i = 0; i < properties.length; ++i) {
if (this.skipProto && properties[i].name === "__proto__")
continue;
properties[i].parentObject = this.object;
}
this.propertiesForTest = properties;
for (var i = 0; i < properties.length; ++i)
this.propertiesTreeOutline.appendChild(new rootTreeElementConstructor(properties[i]));
if (!this.propertiesTreeOutline.children.length) {
var title = document.createElement("div");
title.className = "info";
title.textContent = this.emptyPlaceholder;
var infoElement = new TreeElement(title, null, false);
this.propertiesTreeOutline.appendChild(infoElement);
}
}
}
WebInspector.ObjectPropertiesSection.prototype.__proto__ = WebInspector.PropertiesSection.prototype;
WebInspector.ObjectPropertiesSection.CompareProperties = function(propertyA, propertyB)
{
var a = propertyA.name;
var b = propertyB.name;
if (a === "__proto__")
return 1;
if (b === "__proto__")
return -1;
var diff = 0;
var chunk = /^\d+|^\D+/;
var chunka, chunkb, anum, bnum;
while (diff === 0) {
if (!a && b)
return -1;
if (!b && a)
return 1;
chunka = a.match(chunk)[0];
chunkb = b.match(chunk)[0];
anum = !isNaN(chunka);
bnum = !isNaN(chunkb);
if (anum && !bnum)
return -1;
if (bnum && !anum)
return 1;
if (anum && bnum) {
diff = chunka - chunkb;
if (diff === 0 && chunka.length !== chunkb.length) {
if (!+chunka && !+chunkb)
return chunka.length - chunkb.length;
else
return chunkb.length - chunka.length;
}
} else if (chunka !== chunkb)
return (chunka < chunkb) ? -1 : 1;
a = a.substring(chunka.length);
b = b.substring(chunkb.length);
}
return diff;
}
WebInspector.ObjectPropertyTreeElement = function(property)
{
this.property = property;
TreeElement.call(this, "", null, false);
this.toggleOnClick = true;
this.selectable = false;
}
WebInspector.ObjectPropertyTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this.property.value);
},
ondblclick: function(event)
{
if (this.property.writable)
this.startEditing(event);
},
onattach: function()
{
this.update();
},
update: function()
{
this.nameElement = document.createElement("span");
this.nameElement.className = "name";
this.nameElement.textContent = this.property.name;
if (!this.property.enumerable)
this.nameElement.addStyleClass("dimmed");
var separatorElement = document.createElement("span");
separatorElement.className = "separator";
separatorElement.textContent = ": ";
this.valueElement = document.createElement("span");
this.valueElement.className = "value";
var description = this.property.value.description;
if (this.property.wasThrown)
this.valueElement.textContent = "[Exception: " + description + "]";
else if (this.property.value.type === "string" && typeof description === "string") {
this.valueElement.textContent = "\"" + description.replace(/\n/g, "\u21B5") + "\"";
this.valueElement._originalTextContent = "\"" + description + "\"";
} else if (this.property.value.type === "function" && typeof description === "string") {
this.valueElement.textContent = /.*/.exec(description)[0].replace(/ +$/g, "");
this.valueElement._originalTextContent = description;
} else
this.valueElement.textContent = description;
if (this.property.wasThrown)
this.valueElement.addStyleClass("error");
if (this.property.value.subtype)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.subtype);
else if (this.property.value.type)
this.valueElement.addStyleClass("console-formatted-" + this.property.value.type);
this.valueElement.addEventListener("contextmenu", this._contextMenuFired.bind(this, this.property.value), false);
this.valueElement.title = description || "";
this.listItemElement.removeChildren();
this.listItemElement.appendChild(this.nameElement);
this.listItemElement.appendChild(separatorElement);
this.listItemElement.appendChild(this.valueElement);
this.hasChildren = this.property.value.hasChildren && !this.property.wasThrown;
},
_contextMenuFired: function(value, event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendApplicableItems(value);
contextMenu.show(event);
},
updateSiblings: function()
{
if (this.parent.root)
this.treeOutline.section.update();
else
this.parent.shouldRefreshChildren = true;
},
renderPromptAsBlock: function()
{
return false;
},
elementAndValueToEdit: function(event)
{
return [this.valueElement, (typeof this.valueElement._originalTextContent === "string") ? this.valueElement._originalTextContent : undefined];
},
startEditing: function(event)
{
var elementAndValueToEdit = this.elementAndValueToEdit(event);
var elementToEdit = elementAndValueToEdit[0];
var valueToEdit = elementAndValueToEdit[1];
if (WebInspector.isBeingEdited(elementToEdit) || !this.treeOutline.section.editable || this._readOnly)
return;
if (typeof valueToEdit !== "undefined")
elementToEdit.textContent = valueToEdit;
var context = { expanded: this.expanded, elementToEdit: elementToEdit, previousContent: elementToEdit.textContent };
this.hasChildren = false;
this.listItemElement.addStyleClass("editing-sub-part");
this._prompt = new WebInspector.ObjectPropertyPrompt(this.editingCommitted.bind(this, null, elementToEdit.textContent, context.previousContent, context), this.editingCancelled.bind(this, null, context), this.renderPromptAsBlock());
function blurListener()
{
this.editingCommitted(null, elementToEdit.textContent, context.previousContent, context);
}
var proxyElement = this._prompt.attachAndStartEditing(elementToEdit, blurListener.bind(this));
window.getSelection().setBaseAndExtent(elementToEdit, 0, elementToEdit, 1);
proxyElement.addEventListener("keydown", this._promptKeyDown.bind(this, context), false);
},
editingEnded: function(context)
{
this._prompt.detach();
delete this._prompt;
this.listItemElement.scrollLeft = 0;
this.listItemElement.removeStyleClass("editing-sub-part");
if (context.expanded)
this.expand();
},
editingCancelled: function(element, context)
{
this.editingEnded(context);
this.update();
},
editingCommitted: function(element, userInput, previousContent, context)
{
if (userInput === previousContent)
return this.editingCancelled(element, context);
this.editingEnded(context);
this.applyExpression(userInput, true);
},
_promptKeyDown: function(context, event)
{
if (isEnterKey(event)) {
event.consume(true);
return this.editingCommitted(null, context.elementToEdit.textContent, context.previousContent, context);
}
if (event.keyIdentifier === "U+001B") {
event.consume();
return this.editingCancelled(null, context);
}
},
applyExpression: function(expression, updateInterface)
{
expression = expression.trim();
var expressionLength = expression.length;
function callback(error)
{
if (!updateInterface)
return;
if (error)
this.update();
if (!expressionLength) {
this.parent.removeChild(this);
} else {
this.updateSiblings();
}
};
this.property.parentObject.setPropertyValue(this.property.name, expression.trim(), callback.bind(this));
}
}
WebInspector.ObjectPropertyTreeElement.populate = function(treeElement, value) {
if (treeElement.children.length && !treeElement.shouldRefreshChildren)
return;
if (value.arrayLength() > WebInspector.ObjectPropertiesSection._arrayLoadThreshold) {
treeElement.removeChildren();
WebInspector.ArrayGroupingTreeElement._populateArray(treeElement, value, 0, value.arrayLength() - 1);
return;
}
function callback(properties)
{
treeElement.removeChildren();
if (!properties)
return;
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
if (treeElement.treeOutline.section.skipProto && properties[i].name === "__proto__")
continue;
properties[i].parentObject = value;
treeElement.appendChild(new treeElement.treeOutline.section.treeElementConstructor(properties[i]));
}
if (value.type === "function")
treeElement.appendChild(new WebInspector.FunctionScopeMainTreeElement(value));
}
value.getOwnProperties(callback);
}
WebInspector.ObjectPropertyTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.FunctionScopeMainTreeElement = function(remoteObject)
{
TreeElement.call(this, "<function scope>", null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}
WebInspector.FunctionScopeMainTreeElement.prototype = {
onpopulate: function()
{
if (this.children.length && !this.shouldRefreshChildren)
return;
function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
this.removeChildren();
var scopeChain = response.scopeChain;
for (var i = 0; i < scopeChain.length; ++i) {
var scope = scopeChain[i];
var title = null;
var isTrueObject;
switch (scope.type) {
case "local":
title = WebInspector.UIString("Local");
isTrueObject = false;
break;
case "closure":
title = WebInspector.UIString("Closure");
isTrueObject = false;
break;
case "catch":
title = WebInspector.UIString("Catch");
isTrueObject = false;
break;
case "with":
title = WebInspector.UIString("With Block");
isTrueObject = true;
break;
case "global":
title = WebInspector.UIString("Global");
isTrueObject = true;
break;
}
var remoteObject = WebInspector.RemoteObject.fromPayload(scope.object);
if (isTrueObject) {
var property = WebInspector.RemoteObjectProperty.fromScopeValue(title, remoteObject);
property.parentObject = null;
this.appendChild(new this.treeOutline.section.treeElementConstructor(property));
} else {
var scopeTreeElement = new WebInspector.ScopeTreeElement(title, null, remoteObject);
this.appendChild(scopeTreeElement);
}
}
}
DebuggerAgent.getFunctionDetails(this._remoteObject.objectId, didGetDetails.bind(this));
}
};
WebInspector.FunctionScopeMainTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.ScopeTreeElement = function(title, subtitle, remoteObject)
{
TreeElement.call(this, title, null, false);
this.toggleOnClick = true;
this.selectable = false;
this._remoteObject = remoteObject;
this.hasChildren = true;
}
WebInspector.ScopeTreeElement.prototype = {
onpopulate: function()
{
return WebInspector.ObjectPropertyTreeElement.populate(this, this._remoteObject);
}
};
WebInspector.ScopeTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.ArrayGroupingTreeElement = function(object, fromIndex, toIndex, propertyCount)
{
TreeElement.call(this, String.sprintf("[%d \u2026 %d]", fromIndex, toIndex), undefined, true);
this._fromIndex = fromIndex;
this._toIndex = toIndex;
this._object = object;
this._readOnly = true;
this._propertyCount = propertyCount;
this._populated = false;
}
WebInspector.ArrayGroupingTreeElement._bucketThreshold = 100;
WebInspector.ArrayGroupingTreeElement._populateArray = function(treeElement, object, fromIndex, toIndex)
{
WebInspector.ArrayGroupingTreeElement._populateRanges(treeElement, object, fromIndex, toIndex, true);
}
WebInspector.ArrayGroupingTreeElement._populateRanges = function(treeElement, object, fromIndex, toIndex, topLevel)
{
object.callFunctionJSON(packRanges, [{value: fromIndex}, {value: toIndex}, {value: WebInspector.ArrayGroupingTreeElement._bucketThreshold}], callback.bind(this));
function packRanges(fromIndex, toIndex, bucketThreshold)
{
var count = 0;
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value !== "undefined")
++count;
}
var bucketSize = count;
if (count <= bucketThreshold)
bucketSize = count;
else
bucketSize = Math.pow(bucketThreshold, Math.floor(Math.log(count) / Math.log(bucketThreshold)));
var ranges = [];
count = 0;
var groupStart = -1;
var groupEnd = 0;
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value === "undefined")
continue;
if (groupStart === -1)
groupStart = i;
groupEnd = i;
if (++count === bucketSize) {
ranges.push([groupStart, groupEnd, count]);
count = 0;
groupStart = -1;
}
}
if (count > 0)
ranges.push([groupStart, groupEnd, count]);
return ranges;
}
function callback(ranges)
{
if (ranges.length == 1)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, ranges[0][0], ranges[0][1]);
else {
for (var i = 0; i < ranges.length; ++i) {
var fromIndex = ranges[i][0];
var toIndex = ranges[i][1];
var count = ranges[i][2];
if (fromIndex == toIndex)
WebInspector.ArrayGroupingTreeElement._populateAsFragment(treeElement, object, fromIndex, toIndex);
else
treeElement.appendChild(new WebInspector.ArrayGroupingTreeElement(object, fromIndex, toIndex, count));
}
}
if (topLevel)
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties(treeElement, object);
}
}
WebInspector.ArrayGroupingTreeElement._populateAsFragment = function(treeElement, object, fromIndex, toIndex)
{
object.callFunction(buildArrayFragment, [{value: fromIndex}, {value: toIndex}], processArrayFragment.bind(this));
function buildArrayFragment(fromIndex, toIndex)
{
var result = Object.create(null);
for (var i = fromIndex; i <= toIndex; ++i) {
var value = this[i];
if (typeof value !== "undefined")
result[i] = value;
}
return result;
}
function processArrayFragment(arrayFragment)
{
arrayFragment.getAllProperties(processProperties.bind(this));
}
function processProperties(properties)
{
if (!properties)
return;
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}
WebInspector.ArrayGroupingTreeElement._populateNonIndexProperties = function(treeElement, object)
{
object.callFunction(buildObjectFragment, undefined, processObjectFragment.bind(this));
function buildObjectFragment()
{
var result = Object.create(this.__proto__);
var names = Object.getOwnPropertyNames(this);
for (var i = 0; i < names.length; ++i) {
var name = names[i];
if (!isNaN(name))
continue;
var descriptor = Object.getOwnPropertyDescriptor(this, name);
if (descriptor)
Object.defineProperty(result, name, descriptor);
}
return result;
}
function processObjectFragment(arrayFragment)
{
arrayFragment.getOwnProperties(processProperties.bind(this));
}
function processProperties(properties)
{
if (!properties)
return;
properties.sort(WebInspector.ObjectPropertiesSection.CompareProperties);
for (var i = 0; i < properties.length; ++i) {
properties[i].parentObject = this._object;
var childTreeElement = new treeElement.treeOutline.section.treeElementConstructor(properties[i]);
childTreeElement._readOnly = true;
treeElement.appendChild(childTreeElement);
}
}
}
WebInspector.ArrayGroupingTreeElement.prototype = {
onpopulate: function()
{
if (this._populated)
return;
this._populated = true;
if (this._propertyCount >= WebInspector.ArrayGroupingTreeElement._bucketThreshold) {
WebInspector.ArrayGroupingTreeElement._populateRanges(this, this._object, this._fromIndex, this._toIndex, false);
return;
}
WebInspector.ArrayGroupingTreeElement._populateAsFragment(this, this._object, this._fromIndex, this._toIndex);
},
onattach: function()
{
this.listItemElement.addStyleClass("name");
}
}
WebInspector.ArrayGroupingTreeElement.prototype.__proto__ = TreeElement.prototype;
WebInspector.ObjectPropertyPrompt = function(commitHandler, cancelHandler, renderAsBlock)
{
const ExpressionStopCharacters = " =:[({;,!+-*/&|^<>.";
WebInspector.TextPrompt.call(this, WebInspector.consoleView.completionsForTextPrompt.bind(WebInspector.consoleView), ExpressionStopCharacters);
this.setSuggestBoxEnabled("generic-suggest");
if (renderAsBlock)
this.renderAsBlock();
}
WebInspector.ObjectPropertyPrompt.prototype.__proto__ = WebInspector.TextPrompt.prototype;
WebInspector.ObjectPopoverHelper = function(panelElement, getAnchor, queryObject, onHide, disableOnClick)
{
WebInspector.PopoverHelper.call(this, panelElement, getAnchor, this._showObjectPopover.bind(this), this._onHideObjectPopover.bind(this), disableOnClick);
this._queryObject = queryObject;
this._onHideCallback = onHide;
this._popoverObjectGroup = "popover";
panelElement.addEventListener("scroll", this.hidePopover.bind(this), true);
};
WebInspector.ObjectPopoverHelper.prototype = {
_showObjectPopover: function(element, popover)
{
function showObjectPopover(result, wasThrown, anchorOverride)
{
if (popover.disposed)
return;
if (wasThrown) {
this.hidePopover();
return;
}
var anchorElement = anchorOverride || element;
var popoverContentElement = null;
if (result.type !== "object") {
popoverContentElement = document.createElement("span");
popoverContentElement.className = "monospace console-formatted-" + result.type;
popoverContentElement.style.whiteSpace = "pre";
popoverContentElement.textContent = result.description;
if (result.type === "function") {
function didGetDetails(error, response)
{
if (error) {
console.error(error);
return;
}
var container = document.createElement("div");
container.style.display = "inline-block";
var title = container.createChild("div", "function-popover-title source-code");
var functionName = title.createChild("span", "function-name");
functionName.textContent = response.name || response.inferredName || response.displayName || WebInspector.UIString("(anonymous function)");
this._linkifier = new WebInspector.Linkifier();
var rawLocation = response.location;
var link = this._linkifier.linkifyRawLocation(rawLocation, "function-location-link");
if (link)
title.appendChild(link);
container.appendChild(popoverContentElement);
popover.show(container, anchorElement);
}
DebuggerAgent.getFunctionDetails(result.objectId, didGetDetails.bind(this));
return;
}
if (result.type === "string")
popoverContentElement.textContent = "\"" + popoverContentElement.textContent + "\"";
popover.show(popoverContentElement, anchorElement);
} else {
popoverContentElement = document.createElement("div");
this._titleElement = document.createElement("div");
this._titleElement.className = "source-frame-popover-title monospace";
this._titleElement.textContent = result.description;
popoverContentElement.appendChild(this._titleElement);
var section = new WebInspector.ObjectPropertiesSection(result);
if (result.description.substr(0, 4) === "HTML") {
this._sectionUpdateProperties = section.updateProperties.bind(section);
section.updateProperties = this._updateHTMLId.bind(this);
}
section.expanded = true;
section.element.addStyleClass("source-frame-popover-tree");
section.headerElement.addStyleClass("hidden");
popoverContentElement.appendChild(section.element);
const popoverWidth = 300;
const popoverHeight = 250;
popover.show(popoverContentElement, anchorElement, popoverWidth, popoverHeight);
}
}
this._queryObject(element, showObjectPopover.bind(this), this._popoverObjectGroup);
},
_onHideObjectPopover: function()
{
if (this._linkifier) {
this._linkifier.reset();
delete this._linkifier;
}
if (this._onHideCallback)
this._onHideCallback();
RuntimeAgent.releaseObjectGroup(this._popoverObjectGroup);
},
_updateHTMLId: function(properties, rootTreeElementConstructor, rootPropertyComparer)
{
for (var i = 0; i < properties.length; ++i) {
if (properties[i].name === "id") {
if (properties[i].value.description)
this._titleElement.textContent += "#" + properties[i].value.description;
break;
}
}
this._sectionUpdateProperties(properties, rootTreeElementConstructor, rootPropertyComparer);
}
}
WebInspector.ObjectPopoverHelper.prototype.__proto__ = WebInspector.PopoverHelper.prototype;
WebInspector.NativeBreakpointsSidebarPane = function(title)
{
WebInspector.SidebarPane.call(this, title);
this.listElement = document.createElement("ol");
this.listElement.className = "breakpoint-list";
this.emptyElement = document.createElement("div");
this.emptyElement.className = "info";
this.emptyElement.textContent = WebInspector.UIString("No Breakpoints");
this.bodyElement.appendChild(this.emptyElement);
}
WebInspector.NativeBreakpointsSidebarPane.prototype = {
_addListElement: function(element, beforeElement)
{
if (beforeElement)
this.listElement.insertBefore(element, beforeElement);
else {
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.emptyElement);
this.bodyElement.appendChild(this.listElement);
}
this.listElement.appendChild(element);
}
},
_removeListElement: function(element)
{
this.listElement.removeChild(element);
if (!this.listElement.firstChild) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
},
_reset: function()
{
this.listElement.removeChildren();
if (this.listElement.parentElement) {
this.bodyElement.removeChild(this.listElement);
this.bodyElement.appendChild(this.emptyElement);
}
}
}
WebInspector.NativeBreakpointsSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
WebInspector.DOMBreakpointsSidebarPane = function()
{
WebInspector.NativeBreakpointsSidebarPane.call(this, WebInspector.UIString("DOM Breakpoints"));
this._breakpointElements = {};
this._breakpointTypes = {
SubtreeModified: "subtree-modified",
AttributeModified: "attribute-modified",
NodeRemoved: "node-removed"
};
this._breakpointTypeLabels = {};
this._breakpointTypeLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString("Subtree Modified");
this._breakpointTypeLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString("Attribute Modified");
this._breakpointTypeLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString("Node Removed");
this._contextMenuLabels = {};
this._contextMenuLabels[this._breakpointTypes.SubtreeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Subtree modifications" : "Subtree Modifications");
this._contextMenuLabels[this._breakpointTypes.AttributeModified] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Attributes modifications" : "Attributes Modifications");
this._contextMenuLabels[this._breakpointTypes.NodeRemoved] = WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Node removal" : "Node Removal");
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged, this._inspectedURLChanged, this);
WebInspector.domAgent.addEventListener(WebInspector.DOMAgent.Events.NodeRemoved, this._nodeRemoved, this);
}
WebInspector.DOMBreakpointsSidebarPane.prototype = {
_inspectedURLChanged: function(event)
{
this._breakpointElements = {};
this._reset();
var url = event.data;
this._inspectedURL = url.removeURLFragment();
},
populateNodeContextMenu: function(node, contextMenu)
{
var nodeBreakpoints = {};
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
nodeBreakpoints[element._type] = true;
}
function toggleBreakpoint(type)
{
if (!nodeBreakpoints[type])
this._setBreakpoint(node, type, true);
else
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
var breakPointSubMenu = contextMenu.appendSubMenuItem(WebInspector.UIString("Break on..."));
for (var key in this._breakpointTypes) {
var type = this._breakpointTypes[key];
var label = this._contextMenuLabels[type];
breakPointSubMenu.appendCheckboxItem(label, toggleBreakpoint.bind(this, type), nodeBreakpoints[type]);
}
},
createBreakpointHitStatusMessage: function(auxData, callback)
{
if (auxData.type === this._breakpointTypes.SubtreeModified) {
var targetNodeObject = WebInspector.RemoteObject.fromPayload(auxData["targetNode"]);
function didPushNodeToFrontend(targetNodeId)
{
if (targetNodeId)
targetNodeObject.release();
this._doCreateBreakpointHitStatusMessage(auxData, targetNodeId, callback);
}
targetNodeObject.pushNodeToFrontend(didPushNodeToFrontend.bind(this));
} else
this._doCreateBreakpointHitStatusMessage(auxData, null, callback);
},
_doCreateBreakpointHitStatusMessage: function (auxData, targetNodeId, callback)
{
var message;
var typeLabel = this._breakpointTypeLabels[auxData.type];
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(auxData.nodeId);
var substitutions = [typeLabel, linkifiedNode];
var targetNode = "";
if (targetNodeId)
targetNode = WebInspector.DOMPresentationUtils.linkifyNodeById(targetNodeId);
if (auxData.type === this._breakpointTypes.SubtreeModified) {
if (auxData.insertion) {
if (targetNodeId !== auxData.nodeId) {
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to its descendant %s.";
substitutions.push(targetNode);
} else
message = "Paused on a \"%s\" breakpoint set on %s, because a new child was added to that node.";
} else {
message = "Paused on a \"%s\" breakpoint set on %s, because its descendant %s was removed.";
substitutions.push(targetNode);
}
} else
message = "Paused on a \"%s\" breakpoint set on %s.";
var element = document.createElement("span");
var formatters = {
s: function(substitution)
{
return substitution;
}
};
function append(a, b)
{
if (typeof b === "string")
b = document.createTextNode(b);
element.appendChild(b);
}
WebInspector.formatLocalized(message, substitutions, formatters, "", append);
callback(element);
},
_nodeRemoved: function(event)
{
var node = event.data.node;
this._removeBreakpointsForNode(event.data.node);
if (!node.children)
return;
for (var i = 0; i < node.children.length; ++i)
this._removeBreakpointsForNode(node.children[i]);
this._saveBreakpoints();
},
_removeBreakpointsForNode: function(node)
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
if (element._node === node)
this._removeBreakpoint(element._node, element._type);
}
},
_setBreakpoint: function(node, type, enabled)
{
var breakpointId = this._createBreakpointId(node.id, type);
if (breakpointId in this._breakpointElements)
return;
var element = document.createElement("li");
element._node = node;
element._type = type;
element.addEventListener("contextmenu", this._contextMenu.bind(this, node, type), true);
var checkboxElement = document.createElement("input");
checkboxElement.className = "checkbox-elem";
checkboxElement.type = "checkbox";
checkboxElement.checked = enabled;
checkboxElement.addEventListener("click", this._checkboxClicked.bind(this, node, type), false);
element._checkboxElement = checkboxElement;
element.appendChild(checkboxElement);
var labelElement = document.createElement("span");
element.appendChild(labelElement);
var linkifiedNode = WebInspector.DOMPresentationUtils.linkifyNodeById(node.id);
linkifiedNode.addStyleClass("monospace");
labelElement.appendChild(linkifiedNode);
var description = document.createElement("div");
description.className = "source-text";
description.textContent = this._breakpointTypeLabels[type];
labelElement.appendChild(description);
var currentElement = this.listElement.firstChild;
while (currentElement) {
if (currentElement._type && currentElement._type < element._type)
break;
currentElement = currentElement.nextSibling;
}
this._addListElement(element, currentElement);
this._breakpointElements[breakpointId] = element;
if (enabled)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
},
_removeAllBreakpoints: function()
{
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
this._removeBreakpoint(element._node, element._type);
}
this._saveBreakpoints();
},
_removeBreakpoint: function(node, type)
{
var breakpointId = this._createBreakpointId(node.id, type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this._removeListElement(element);
delete this._breakpointElements[breakpointId];
if (element._checkboxElement.checked)
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
},
_contextMenu: function(node, type, event)
{
var contextMenu = new WebInspector.ContextMenu();
function removeBreakpoint()
{
this._removeBreakpoint(node, type);
this._saveBreakpoints();
}
contextMenu.appendItem(WebInspector.UIString("Remove Breakpoint"), removeBreakpoint.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Remove all DOM breakpoints" : "Remove All DOM Breakpoints"), this._removeAllBreakpoints.bind(this));
contextMenu.show(event);
},
_checkboxClicked: function(node, type, event)
{
if (event.target.checked)
DOMDebuggerAgent.setDOMBreakpoint(node.id, type);
else
DOMDebuggerAgent.removeDOMBreakpoint(node.id, type);
this._saveBreakpoints();
},
highlightBreakpoint: function(auxData)
{
var breakpointId = this._createBreakpointId(auxData.nodeId, auxData.type);
var element = this._breakpointElements[breakpointId];
if (!element)
return;
this.expanded = true;
element.addStyleClass("breakpoint-hit");
this._highlightedElement = element;
},
clearBreakpointHighlight: function()
{
if (this._highlightedElement) {
this._highlightedElement.removeStyleClass("breakpoint-hit");
delete this._highlightedElement;
}
},
_createBreakpointId: function(nodeId, type)
{
return nodeId + ":" + type;
},
_saveBreakpoints: function()
{
var breakpoints = [];
var storedBreakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < storedBreakpoints.length; ++i) {
var breakpoint = storedBreakpoints[i];
if (breakpoint.url !== this._inspectedURL)
breakpoints.push(breakpoint);
}
for (var id in this._breakpointElements) {
var element = this._breakpointElements[id];
breakpoints.push({ url: this._inspectedURL, path: element._node.path(), type: element._type, enabled: element._checkboxElement.checked });
}
WebInspector.settings.domBreakpoints.set(breakpoints);
},
restoreBreakpoints: function()
{
var pathToBreakpoints = {};
function didPushNodeByPathToFrontend(path, nodeId)
{
var node = WebInspector.domAgent.nodeForId(nodeId);
if (!node)
return;
var breakpoints = pathToBreakpoints[path];
for (var i = 0; i < breakpoints.length; ++i)
this._setBreakpoint(node, breakpoints[i].type, breakpoints[i].enabled);
}
var breakpoints = WebInspector.settings.domBreakpoints.get();
for (var i = 0; i < breakpoints.length; ++i) {
var breakpoint = breakpoints[i];
if (breakpoint.url !== this._inspectedURL)
continue;
var path = breakpoint.path;
if (!pathToBreakpoints[path]) {
pathToBreakpoints[path] = [];
WebInspector.domAgent.pushNodeByPathToFrontend(path, didPushNodeByPathToFrontend.bind(this, path));
}
pathToBreakpoints[path].push(breakpoint);
}
}
}
WebInspector.DOMBreakpointsSidebarPane.prototype.__proto__ = WebInspector.NativeBreakpointsSidebarPane.prototype;
WebInspector.Color = function(str)
{
this.value = str;
this._parse();
}
WebInspector.Color.fromRGBA = function(r, g, b, a)
{
return new WebInspector.Color("rgba(" + r + "," + g + "," + b + "," + (typeof a === "undefined" ? 1 : a) + ")");
}
WebInspector.Color.fromRGB = function(r, g, b)
{
return new WebInspector.Color("rgb(" + r + "," + g + "," + b + ")");
}
WebInspector.Color.prototype = {
get shorthex()
{
if ("_short" in this)
return this._short;
if (!this.simple)
return "";
var hex = this.hex;
if (hex.charAt(0) === hex.charAt(1) && hex.charAt(2) === hex.charAt(3) && hex.charAt(4) === hex.charAt(5))
this._short = hex.charAt(0) + hex.charAt(2) + hex.charAt(4);
else
this._short = hex;
return this._short;
},
get hex()
{
if (!this.simple)
return "";
return this._hex;
},
set hex(x)
{
this._hex = x;
},
get rgb()
{
if (this._rgb)
return this._rgb;
if (this.simple)
this._rgb = this._hexToRGB(this.hex);
else {
var rgba = this.rgba;
this._rgb = [rgba[0], rgba[1], rgba[2]];
}
return this._rgb;
},
set rgb(x)
{
this._rgb = x;
},
get hsl()
{
if (this._hsl)
return this._hsl;
this._hsl = this._rgbToHSL(this.rgb);
return this._hsl;
},
set hsl(x)
{
this._hsl = x;
},
get nickname()
{
if (typeof this._nickname !== "undefined")
return this._nickname;
else
return "";
},
set nickname(x)
{
this._nickname = x;
},
get rgba()
{
return this._rgba;
},
set rgba(x)
{
this._rgba = x;
},
get hsla()
{
return this._hsla;
},
set hsla(x)
{
this._hsla = x;
},
hasShortHex: function()
{
var shorthex = this.shorthex;
return (!!shorthex && shorthex.length === 3);
},
toString: function(format)
{
if (!format)
format = this.format;
switch (format) {
case "original":
return this.value;
case "rgb":
return "rgb(" + this.rgb.join(", ") + ")";
case "rgba":
return "rgba(" + this.rgba.join(", ") + ")";
case "hsl":
var hsl = this.hsl;
return "hsl(" + hsl[0] + ", " + hsl[1] + "%, " + hsl[2] + "%)";
case "hsla":
var hsla = this.hsla;
return "hsla(" + hsla[0] + ", " + hsla[1] + "%, " + hsla[2] + "%, " + hsla[3] + ")";
case "hex":
return "#" + this.hex;
case "shorthex":
return "#" + this.shorthex;
case "nickname":
return this.nickname;
}
throw "invalid color format";
},
toProtocolRGBA: function()
{
if (this._protocolRGBA)
return this._protocolRGBA;
var components = this.rgba;
if (components)
this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]), a: Number(components[3]) };
else {
components = this.rgb;
this._protocolRGBA = { r: Number(components[0]), g: Number(components[1]), b: Number(components[2]) };
}
return this._protocolRGBA;
},
_clamp: function(value, min, max)
{
if (value < min)
return min;
if (value > max)
return max;
return value;
},
_individualRGBValueToFloatValue: function(rgbValue)
{
if (typeof rgbValue === "number")
return this._clamp(rgbValue, 0, 255);
if (rgbValue.indexOf("%") === -1) {
var intValue = parseInt(rgbValue, 10);
return this._clamp(intValue, 0, 255);
}
var percentValue = parseFloat(rgbValue);
return this._clamp(percentValue, 0, 100) * 2.55;
},
_individualRGBValueToHexValue: function(rgbValue)
{
var floatValue = this._individualRGBValueToFloatValue(rgbValue);
var hex = Math.round(floatValue).toString(16);
if (hex.length === 1)
hex = "0" + hex;
return hex;
},
_rgbStringsToHex: function(rgb)
{
var r = this._individualRGBValueToHexValue(rgb[0]);
var g = this._individualRGBValueToHexValue(rgb[1]);
var b = this._individualRGBValueToHexValue(rgb[2]);
return (r + g + b).toUpperCase();
},
_rgbToHex: function(rgb)
{
var r = this._individualRGBValueToHexValue(rgb[0]);
var g = this._individualRGBValueToHexValue(rgb[1]);
var b = this._individualRGBValueToHexValue(rgb[2]);
return (r + g + b).toUpperCase();
},
_hexToRGB: function(hex)
{
var r = parseInt(hex.substring(0,2), 16);
var g = parseInt(hex.substring(2,4), 16);
var b = parseInt(hex.substring(4,6), 16);
return [r, g, b];
},
_rgbToHSL: function(rgb)
{
var r = this._individualRGBValueToFloatValue(rgb[0]) / 255;
var g = this._individualRGBValueToFloatValue(rgb[1]) / 255;
var b = this._individualRGBValueToFloatValue(rgb[2]) / 255;
var max = Math.max(r, g, b);
var min = Math.min(r, g, b);
var diff = max - min;
var add = max + min;
if (min === max)
var h = 0;
else if (r === max)
var h = ((60 * (g - b) / diff) + 360) % 360;
else if (g === max)
var h = (60 * (b - r) / diff) + 120;
else
var h = (60 * (r - g) / diff) + 240;
var l = 0.5 * add;
if (l === 0)
var s = 0;
else if (l === 1)
var s = 1;
else if (l <= 0.5)
var s = diff / add;
else
var s = diff / (2 - add);
h = Math.round(h);
s = Math.round(s*100);
l = Math.round(l*100);
return [h, s, l];
},
_hslToRGB: function(hsl)
{
var h = parseFloat(hsl[0]) / 360;
var s = parseFloat(hsl[1]) / 100;
var l = parseFloat(hsl[2]) / 100;
if (s < 0)
s = 0;
if (l <= 0.5)
var q = l * (1 + s);
else
var q = l + s - (l * s);
var p = 2 * l - q;
var tr = h + (1 / 3);
var tg = h;
var tb = h - (1 / 3);
var r = Math.round(hueToRGB(p, q, tr) * 255);
var g = Math.round(hueToRGB(p, q, tg) * 255);
var b = Math.round(hueToRGB(p, q, tb) * 255);
return [r, g, b];
function hueToRGB(p, q, h) {
if (h < 0)
h += 1;
else if (h > 1)
h -= 1;
if ((h * 6) < 1)
return p + (q - p) * h * 6;
else if ((h * 2) < 1)
return q;
else if ((h * 3) < 2)
return p + (q - p) * ((2 / 3) - h) * 6;
else
return p;
}
},
_rgbaToHSLA: function(rgba, alpha)
{
var hsl = this._rgbToHSL(rgba)
hsl.push(alpha);
return hsl;
},
_hslaToRGBA: function(hsla, alpha)
{
var rgb = this._hslToRGB(hsla);
rgb.push(alpha);
return rgb;
},
_parse: function()
{
var value = this.value.toLowerCase().replace(/%|\s+/g, "");
if (value in WebInspector.Color.AdvancedNickNames) {
this.format = "nickname";
var set = WebInspector.Color.AdvancedNickNames[value];
this.simple = false;
this.rgba = set[0];
this.hsla = set[1];
this.nickname = set[2];
this.alpha = set[0][3];
return;
}
var simple = /^(?:#([0-9a-f]{3,6})|rgb\(([^)]+)\)|(\w+)|hsl\(([^)]+)\))$/i;
var match = this.value.match(simple);
if (match) {
this.simple = true;
if (match[1]) {
var hex = match[1].toUpperCase();
if (hex.length === 3) {
this.format = "shorthex";
this.hex = hex.charAt(0) + hex.charAt(0) + hex.charAt(1) + hex.charAt(1) + hex.charAt(2) + hex.charAt(2);
} else {
this.format = "hex";
this.hex = hex;
}
} else if (match[2]) {
this.format = "rgb";
var rgb = match[2].split(/\s*,\s*/);
this.rgb = rgb;
this.hex = this._rgbStringsToHex(rgb);
} else if (match[3]) {
var nickname = match[3].toLowerCase();
if (nickname in WebInspector.Color.Nicknames) {
this.format = "nickname";
this.hex = WebInspector.Color.Nicknames[nickname];
} else
throw "unknown color name";
} else if (match[4]) {
this.format = "hsl";
var hsl = match[4].replace(/%/g, "").split(/\s*,\s*/);
this.hsl = hsl;
this.rgb = this._hslToRGB(hsl);
this.hex = this._rgbToHex(this.rgb);
}
var hex = this.hex;
if (hex && hex in WebInspector.Color.HexTable) {
var set = WebInspector.Color.HexTable[hex];
this.rgb = set[0];
this.hsl = set[1];
this.nickname = set[2];
}
return;
}
var advanced = /^(?:rgba\(([^)]+)\)|hsla\(([^)]+)\))$/;
match = this.value.match(advanced);
if (match) {
this.simple = false;
if (match[1]) {
this.format = "rgba";
this.rgba = match[1].split(/\s*,\s*/);
this.rgba[3] = this.alpha = this._clamp(this.rgba[3], 0, 1);
this.hsla = this._rgbaToHSLA(this.rgba, this.alpha);
} else if (match[2]) {
this.format = "hsla";
this.hsla = match[2].replace(/%/g, "").split(/\s*,\s*/);
this.hsla[3] = this.alpha = this._clamp(this.hsla[3], 0, 1);
this.rgba = this._hslaToRGBA(this.hsla, this.alpha);
}
return;
}
throw "could not parse color";
}
}
WebInspector.Color.HexTable = {
"000000": [[0, 0, 0], [0, 0, 0], "black"],
"000080": [[0, 0, 128], [240, 100, 25], "navy"],
"00008B": [[0, 0, 139], [240, 100, 27], "darkBlue"],
"0000CD": [[0, 0, 205], [240, 100, 40], "mediumBlue"],
"0000FF": [[0, 0, 255], [240, 100, 50], "blue"],
"006400": [[0, 100, 0], [120, 100, 20], "darkGreen"],
"008000": [[0, 128, 0], [120, 100, 25], "green"],
"008080": [[0, 128, 128], [180, 100, 25], "teal"],
"008B8B": [[0, 139, 139], [180, 100, 27], "darkCyan"],
"00BFFF": [[0, 191, 255], [195, 100, 50], "deepSkyBlue"],
"00CED1": [[0, 206, 209], [181, 100, 41], "darkTurquoise"],
"00FA9A": [[0, 250, 154], [157, 100, 49], "mediumSpringGreen"],
"00FF00": [[0, 255, 0], [120, 100, 50], "lime"],
"00FF7F": [[0, 255, 127], [150, 100, 50], "springGreen"],
"00FFFF": [[0, 255, 255], [180, 100, 50], "cyan"],
"191970": [[25, 25, 112], [240, 64, 27], "midnightBlue"],
"1E90FF": [[30, 144, 255], [210, 100, 56], "dodgerBlue"],
"20B2AA": [[32, 178, 170], [177, 70, 41], "lightSeaGreen"],
"228B22": [[34, 139, 34], [120, 61, 34], "forestGreen"],
"2E8B57": [[46, 139, 87], [146, 50, 36], "seaGreen"],
"2F4F4F": [[47, 79, 79], [180, 25, 25], "darkSlateGray"],
"32CD32": [[50, 205, 50], [120, 61, 50], "limeGreen"],
"3CB371": [[60, 179, 113], [147, 50, 47], "mediumSeaGreen"],
"40E0D0": [[64, 224, 208], [174, 72, 56], "turquoise"],
"4169E1": [[65, 105, 225], [225, 73, 57], "royalBlue"],
"4682B4": [[70, 130, 180], [207, 44, 49], "steelBlue"],
"483D8B": [[72, 61, 139], [248, 39, 39], "darkSlateBlue"],
"48D1CC": [[72, 209, 204], [178, 60, 55], "mediumTurquoise"],
"4B0082": [[75, 0, 130], [275, 100, 25], "indigo"],
"556B2F": [[85, 107, 47], [82, 39, 30], "darkOliveGreen"],
"5F9EA0": [[95, 158, 160], [182, 25, 50], "cadetBlue"],
"6495ED": [[100, 149, 237], [219, 79, 66], "cornflowerBlue"],
"66CDAA": [[102, 205, 170], [160, 51, 60], "mediumAquaMarine"],
"696969": [[105, 105, 105], [0, 0, 41], "dimGray"],
"6A5ACD": [[106, 90, 205], [248, 53, 58], "slateBlue"],
"6B8E23": [[107, 142, 35], [80, 60, 35], "oliveDrab"],
"708090": [[112, 128, 144], [210, 13, 50], "slateGray"],
"778899": [[119, 136, 153], [210, 14, 53], "lightSlateGray"],
"7B68EE": [[123, 104, 238], [249, 80, 67], "mediumSlateBlue"],
"7CFC00": [[124, 252, 0], [90, 100, 49], "lawnGreen"],
"7FFF00": [[127, 255, 0], [90, 100, 50], "chartreuse"],
"7FFFD4": [[127, 255, 212], [160, 100, 75], "aquamarine"],
"800000": [[128, 0, 0], [0, 100, 25], "maroon"],
"800080": [[128, 0, 128], [300, 100, 25], "purple"],
"808000": [[128, 128, 0], [60, 100, 25], "olive"],
"808080": [[128, 128, 128], [0, 0, 50], "gray"],
"87CEEB": [[135, 206, 235], [197, 71, 73], "skyBlue"],
"87CEFA": [[135, 206, 250], [203, 92, 75], "lightSkyBlue"],
"8A2BE2": [[138, 43, 226], [271, 76, 53], "blueViolet"],
"8B0000": [[139, 0, 0], [0, 100, 27], "darkRed"],
"8B008B": [[139, 0, 139], [300, 100, 27], "darkMagenta"],
"8B4513": [[139, 69, 19], [25, 76, 31], "saddleBrown"],
"8FBC8F": [[143, 188, 143], [120, 25, 65], "darkSeaGreen"],
"90EE90": [[144, 238, 144], [120, 73, 75], "lightGreen"],
"9370D8": [[147, 112, 219], [260, 60, 65], "mediumPurple"],
"9400D3": [[148, 0, 211], [282, 100, 41], "darkViolet"],
"98FB98": [[152, 251, 152], [120, 93, 79], "paleGreen"],
"9932CC": [[153, 50, 204], [280, 61, 50], "darkOrchid"],
"9ACD32": [[154, 205, 50], [80, 61, 50], "yellowGreen"],
"A0522D": [[160, 82, 45], [19, 56, 40], "sienna"],
"A52A2A": [[165, 42, 42], [0, 59, 41], "brown"],
"A9A9A9": [[169, 169, 169], [0, 0, 66], "darkGray"],
"ADD8E6": [[173, 216, 230], [195, 53, 79], "lightBlue"],
"ADFF2F": [[173, 255, 47], [84, 100, 59], "greenYellow"],
"AFEEEE": [[175, 238, 238], [180, 65, 81], "paleTurquoise"],
"B0C4DE": [[176, 196, 222], [214, 41, 78], "lightSteelBlue"],
"B0E0E6": [[176, 224, 230], [187, 52, 80], "powderBlue"],
"B22222": [[178, 34, 34], [0, 68, 42], "fireBrick"],
"B8860B": [[184, 134, 11], [43, 89, 38], "darkGoldenrod"],
"BA55D3": [[186, 85, 211], [288, 59, 58], "mediumOrchid"],
"BC8F8F": [[188, 143, 143], [0, 25, 65], "rosyBrown"],
"BDB76B": [[189, 183, 107], [56, 38, 58], "darkKhaki"],
"C0C0C0": [[192, 192, 192], [0, 0, 75], "silver"],
"C71585": [[199, 21, 133], [322, 81, 43], "mediumVioletRed"],
"CD5C5C": [[205, 92, 92], [0, 53, 58], "indianRed"],
"CD853F": [[205, 133, 63], [30, 59, 53], "peru"],
"D2691E": [[210, 105, 30], [25, 75, 47], "chocolate"],
"D2B48C": [[210, 180, 140], [34, 44, 69], "tan"],
"D3D3D3": [[211, 211, 211], [0, 0, 83], "lightGrey"],
"D87093": [[219, 112, 147], [340, 60, 65], "paleVioletRed"],
"D8BFD8": [[216, 191, 216], [300, 24, 80], "thistle"],
"DA70D6": [[218, 112, 214], [302, 59, 65], "orchid"],
"DAA520": [[218, 165, 32], [43, 74, 49], "goldenrod"],
"DC143C": [[237, 164, 61], [35, 83, 58], "crimson"],
"DCDCDC": [[220, 220, 220], [0, 0, 86], "gainsboro"],
"DDA0DD": [[221, 160, 221], [300, 47, 75], "plum"],
"DEB887": [[222, 184, 135], [34, 57, 70], "burlyWood"],
"E0FFFF": [[224, 255, 255], [180, 100, 94], "lightCyan"],
"E6E6FA": [[230, 230, 250], [240, 67, 94], "lavender"],
"E9967A": [[233, 150, 122], [15, 72, 70], "darkSalmon"],
"EE82EE": [[238, 130, 238], [300, 76, 72], "violet"],
"EEE8AA": [[238, 232, 170], [55, 67, 80], "paleGoldenrod"],
"F08080": [[240, 128, 128], [0, 79, 72], "lightCoral"],
"F0E68C": [[240, 230, 140], [54, 77, 75], "khaki"],
"F0F8FF": [[240, 248, 255], [208, 100, 97], "aliceBlue"],
"F0FFF0": [[240, 255, 240], [120, 100, 97], "honeyDew"],
"F0FFFF": [[240, 255, 255], [180, 100, 97], "azure"],
"F4A460": [[244, 164, 96], [28, 87, 67], "sandyBrown"],
"F5DEB3": [[245, 222, 179], [39, 77, 83], "wheat"],
"F5F5DC": [[245, 245, 220], [60, 56, 91], "beige"],
"F5F5F5": [[245, 245, 245], [0, 0, 96], "whiteSmoke"],
"F5FFFA": [[245, 255, 250], [150, 100, 98], "mintCream"],
"F8F8FF": [[248, 248, 255], [240, 100, 99], "ghostWhite"],
"FA8072": [[250, 128, 114], [6, 93, 71], "salmon"],
"FAEBD7": [[250, 235, 215], [34, 78, 91], "antiqueWhite"],
"FAF0E6": [[250, 240, 230], [30, 67, 94], "linen"],
"FAFAD2": [[250, 250, 210], [60, 80, 90], "lightGoldenrodYellow"],
"FDF5E6": [[253, 245, 230], [39, 85, 95], "oldLace"],
"FF0000": [[255, 0, 0], [0, 100, 50], "red"],
"FF00FF": [[255, 0, 255], [300, 100, 50], "magenta"],
"FF1493": [[255, 20, 147], [328, 100, 54], "deepPink"],
"FF4500": [[255, 69, 0], [16, 100, 50], "orangeRed"],
"FF6347": [[255, 99, 71], [9, 100, 64], "tomato"],
"FF69B4": [[255, 105, 180], [330, 100, 71], "hotPink"],
"FF7F50": [[255, 127, 80], [16, 100, 66], "coral"],
"FF8C00": [[255, 140, 0], [33, 100, 50], "darkOrange"],
"FFA07A": [[255, 160, 122], [17, 100, 74], "lightSalmon"],
"FFA500": [[255, 165, 0], [39, 100, 50], "orange"],
"FFB6C1": [[255, 182, 193], [351, 100, 86], "lightPink"],
"FFC0CB": [[255, 192, 203], [350, 100, 88], "pink"],
"FFD700": [[255, 215, 0], [51, 100, 50], "gold"],
"FFDAB9": [[255, 218, 185], [28, 100, 86], "peachPuff"],
"FFDEAD": [[255, 222, 173], [36, 100, 84], "navajoWhite"],
"FFE4B5": [[255, 228, 181], [38, 100, 85], "moccasin"],
"FFE4C4": [[255, 228, 196], [33, 100, 88], "bisque"],
"FFE4E1": [[255, 228, 225], [6, 100, 94], "mistyRose"],
"FFEBCD": [[255, 235, 205], [36, 100, 90], "blanchedAlmond"],
"FFEFD5": [[255, 239, 213], [37, 100, 92], "papayaWhip"],
"FFF0F5": [[255, 240, 245], [340, 100, 97], "lavenderBlush"],
"FFF5EE": [[255, 245, 238], [25, 100, 97], "seaShell"],
"FFF8DC": [[255, 248, 220], [48, 100, 93], "cornsilk"],
"FFFACD": [[255, 250, 205], [54, 100, 90], "lemonChiffon"],
"FFFAF0": [[255, 250, 240], [40, 100, 97], "floralWhite"],
"FFFAFA": [[255, 250, 250], [0, 100, 99], "snow"],
"FFFF00": [[255, 255, 0], [60, 100, 50], "yellow"],
"FFFFE0": [[255, 255, 224], [60, 100, 94], "lightYellow"],
"FFFFF0": [[255, 255, 240], [60, 100, 97], "ivory"],
"FFFFFF": [[255, 255, 255], [0, 100, 100], "white"]
};
WebInspector.Color.Nicknames = {
"aliceblue": "F0F8FF",
"antiquewhite": "FAEBD7",
"aqua": "00FFFF",
"aquamarine": "7FFFD4",
"azure": "F0FFFF",
"beige": "F5F5DC",
"bisque": "FFE4C4",
"black": "000000",
"blanchedalmond": "FFEBCD",
"blue": "0000FF",
"blueviolet": "8A2BE2",
"brown": "A52A2A",
"burlywood": "DEB887",
"cadetblue": "5F9EA0",
"chartreuse": "7FFF00",
"chocolate": "D2691E",
"coral": "FF7F50",
"cornflowerblue": "6495ED",
"cornsilk": "FFF8DC",
"crimson": "DC143C",
"cyan": "00FFFF",
"darkblue": "00008B",
"darkcyan": "008B8B",
"darkgoldenrod": "B8860B",
"darkgray": "A9A9A9",
"darkgreen": "006400",
"darkkhaki": "BDB76B",
"darkmagenta": "8B008B",
"darkolivegreen": "556B2F",
"darkorange": "FF8C00",
"darkorchid": "9932CC",
"darkred": "8B0000",
"darksalmon": "E9967A",
"darkseagreen": "8FBC8F",
"darkslateblue": "483D8B",
"darkslategray": "2F4F4F",
"darkturquoise": "00CED1",
"darkviolet": "9400D3",
"deeppink": "FF1493",
"deepskyblue": "00BFFF",
"dimgray": "696969",
"dodgerblue": "1E90FF",
"firebrick": "B22222",
"floralwhite": "FFFAF0",
"forestgreen": "228B22",
"fuchsia": "FF00FF",
"gainsboro": "DCDCDC",
"ghostwhite": "F8F8FF",
"gold": "FFD700",
"goldenrod": "DAA520",
"gray": "808080",
"green": "008000",
"greenyellow": "ADFF2F",
"honeydew": "F0FFF0",
"hotpink": "FF69B4",
"indianred": "CD5C5C",
"indigo": "4B0082",
"ivory": "FFFFF0",
"khaki": "F0E68C",
"lavender": "E6E6FA",
"lavenderblush": "FFF0F5",
"lawngreen": "7CFC00",
"lemonchiffon": "FFFACD",
"lightblue": "ADD8E6",
"lightcoral": "F08080",
"lightcyan": "E0FFFF",
"lightgoldenrodyellow": "FAFAD2",
"lightgreen": "90EE90",
"lightgrey": "D3D3D3",
"lightpink": "FFB6C1",
"lightsalmon": "FFA07A",
"lightseagreen": "20B2AA",
"lightskyblue": "87CEFA",
"lightslategray": "778899",
"lightsteelblue": "B0C4DE",
"lightyellow": "FFFFE0",
"lime": "00FF00",
"limegreen": "32CD32",
"linen": "FAF0E6",
"magenta": "FF00FF",
"maroon": "800000",
"mediumaquamarine": "66CDAA",
"mediumblue": "0000CD",
"mediumorchid": "BA55D3",
"mediumpurple": "9370DB",
"mediumseagreen": "3CB371",
"mediumslateblue": "7B68EE",
"mediumspringgreen": "00FA9A",
"mediumturquoise": "48D1CC",
"mediumvioletred": "C71585",
"midnightblue": "191970",
"mintcream": "F5FFFA",
"mistyrose": "FFE4E1",
"moccasin": "FFE4B5",
"navajowhite": "FFDEAD",
"navy": "000080",
"oldlace": "FDF5E6",
"olive": "808000",
"olivedrab": "6B8E23",
"orange": "FFA500",
"orangered": "FF4500",
"orchid": "DA70D6",
"palegoldenrod": "EEE8AA",
"palegreen": "98FB98",
"paleturquoise": "AFEEEE",
"palevioletred": "DB7093",
"papayawhip": "FFEFD5",
"peachpuff": "FFDAB9",
"peru": "CD853F",
"pink": "FFC0CB",
"plum": "DDA0DD",
"powderblue": "B0E0E6",
"purple": "800080",
"red": "FF0000",
"rosybrown": "BC8F8F",
"royalblue": "4169E1",
"saddlebrown": "8B4513",
"salmon": "FA8072",
"sandybrown": "F4A460",
"seagreen": "2E8B57",
"seashell": "FFF5EE",
"sienna": "A0522D",
"silver": "C0C0C0",
"skyblue": "87CEEB",
"slateblue": "6A5ACD",
"slategray": "708090",
"snow": "FFFAFA",
"springgreen": "00FF7F",
"steelblue": "4682B4",
"tan": "D2B48C",
"teal": "008080",
"thistle": "D8BFD8",
"tomato": "FF6347",
"turquoise": "40E0D0",
"violet": "EE82EE",
"wheat": "F5DEB3",
"white": "FFFFFF",
"whitesmoke": "F5F5F5",
"yellow": "FFFF00",
"yellowgreen": "9ACD32"
};
WebInspector.Color.AdvancedNickNames = {
"transparent": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"rgba(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
"hsla(0,0,0,0)": [[0, 0, 0, 0], [0, 0, 0, 0], "transparent"],
};
WebInspector.Color.PageHighlight = {
Content: WebInspector.Color.fromRGBA(111, 168, 220, .66),
ContentLight: WebInspector.Color.fromRGBA(111, 168, 220, .5),
ContentOutline: WebInspector.Color.fromRGBA(9, 83, 148),
Padding: WebInspector.Color.fromRGBA(147, 196, 125, .55),
PaddingLight: WebInspector.Color.fromRGBA(147, 196, 125, .4),
Border: WebInspector.Color.fromRGBA(255, 229, 153, .66),
BorderLight: WebInspector.Color.fromRGBA(255, 229, 153, .5),
Margin: WebInspector.Color.fromRGBA(246, 178, 107, .66),
MarginLight: WebInspector.Color.fromRGBA(246, 178, 107, .5)
}
WebInspector.Color.Format = {
Original: "original",
Nickname: "nickname",
HEX: "hex",
ShortHEX: "shorthex",
RGB: "rgb",
RGBA: "rgba",
HSL: "hsl",
HSLA: "hsla"
}
WebInspector.CSSCompletions = function(properties, acceptEmptyPrefix)
{
this._values = [];
this._longhands = {};
this._shorthands = {};
for (var i = 0; i < properties.length; ++i) {
var property = properties[i];
if (typeof property === "string") {
this._values.push(property);
continue;
}
var propertyName = property.name;
this._values.push(propertyName);
var longhands = properties[i].longhands;
if (longhands) {
this._longhands[propertyName] = longhands;
for (var j = 0; j < longhands.length; ++j) {
var longhandName = longhands[j];
var shorthands = this._shorthands[longhandName];
if (!shorthands) {
shorthands = [];
this._shorthands[longhandName] = shorthands;
}
shorthands.push(propertyName);
}
}
}
this._values.sort();
this._acceptEmptyPrefix = acceptEmptyPrefix;
}
WebInspector.CSSCompletions.cssPropertiesMetainfo = null;
WebInspector.CSSCompletions.requestCSSNameCompletions = function()
{
function propertyNamesCallback(error, properties)
{
if (!error)
WebInspector.CSSCompletions.cssPropertiesMetainfo = new WebInspector.CSSCompletions(properties, false);
}
CSSAgent.getSupportedCSSProperties(propertyNamesCallback);
}
WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet = function()
{
if (!WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet)
WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet = WebInspector.CSSCompletions.cssPropertiesMetainfo.keySet();
return WebInspector.CSSCompletions._cssPropertiesMetainfoKeySet;
}
WebInspector.CSSCompletions.prototype = {
startsWith: function(prefix)
{
var firstIndex = this._firstIndexOfPrefix(prefix);
if (firstIndex === -1)
return [];
var results = [];
while (firstIndex < this._values.length && this._values[firstIndex].startsWith(prefix))
results.push(this._values[firstIndex++]);
return results;
},
firstStartsWith: function(prefix)
{
var foundIndex = this._firstIndexOfPrefix(prefix);
return (foundIndex === -1 ? "" : this._values[foundIndex]);
},
_firstIndexOfPrefix: function(prefix)
{
if (!this._values.length)
return -1;
if (!prefix)
return this._acceptEmptyPrefix ? 0 : -1;
var maxIndex = this._values.length - 1;
var minIndex = 0;
var foundIndex;
do {
var middleIndex = (maxIndex + minIndex) >> 1;
if (this._values[middleIndex].startsWith(prefix)) {
foundIndex = middleIndex;
break;
}
if (this._values[middleIndex] < prefix)
minIndex = middleIndex + 1;
else
maxIndex = middleIndex - 1;
} while (minIndex <= maxIndex);
if (foundIndex === undefined)
return -1;
while (foundIndex && this._values[foundIndex - 1].startsWith(prefix))
foundIndex--;
return foundIndex;
},
keySet: function()
{
if (!this._keySet)
this._keySet = this._values.keySet();
return this._keySet;
},
next: function(str, prefix)
{
return this._closest(str, prefix, 1);
},
previous: function(str, prefix)
{
return this._closest(str, prefix, -1);
},
_closest: function(str, prefix, shift)
{
if (!str)
return "";
var index = this._values.indexOf(str);
if (index === -1)
return "";
if (!prefix) {
index = (index + this._values.length + shift) % this._values.length;
return this._values[index];
}
var propertiesWithPrefix = this.startsWith(prefix);
var j = propertiesWithPrefix.indexOf(str);
j = (j + propertiesWithPrefix.length + shift) % propertiesWithPrefix.length;
return propertiesWithPrefix[j];
},
longhands: function(shorthand)
{
return this._longhands[shorthand];
},
shorthands: function(longhand)
{
return this._shorthands[longhand];
}
}
WebInspector.CSSKeywordCompletions = {}
WebInspector.CSSKeywordCompletions.forProperty = function(propertyName)
{
var acceptedKeywords = ["initial"];
if (propertyName in WebInspector.CSSKeywordCompletions._propertyKeywordMap)
acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._propertyKeywordMap[propertyName]);
if (propertyName in WebInspector.CSSKeywordCompletions._colorAwareProperties)
acceptedKeywords = acceptedKeywords.concat(WebInspector.CSSKeywordCompletions._colors);
if (propertyName in WebInspector.CSSKeywordCompletions.InheritedProperties)
acceptedKeywords.push("inherit");
return new WebInspector.CSSCompletions(acceptedKeywords, true);
}
WebInspector.CSSKeywordCompletions.isColorAwareProperty = function(propertyName)
{
return WebInspector.CSSKeywordCompletions._colorAwareProperties[propertyName] === true;
}
WebInspector.CSSKeywordCompletions.colors = function()
{
if (!WebInspector.CSSKeywordCompletions._colorsKeySet)
WebInspector.CSSKeywordCompletions._colorsKeySet = WebInspector.CSSKeywordCompletions._colors.keySet();
return WebInspector.CSSKeywordCompletions._colorsKeySet;
}
WebInspector.CSSKeywordCompletions.InheritedProperties = [
"azimuth", "border-collapse", "border-spacing", "caption-side", "color", "cursor", "direction", "elevation",
"empty-cells", "font-family", "font-size", "font-style", "font-variant", "font-weight", "font", "letter-spacing",
"line-height", "list-style-image", "list-style-position", "list-style-type", "list-style", "orphans", "pitch-range",
"pitch", "quotes", "richness", "speak-header", "speak-numeral", "speak-punctuation", "speak", "speech-rate", "stress",
"text-align", "text-indent", "text-transform", "text-shadow", "visibility", "voice-family", "volume", "white-space", "widows", "word-spacing"
].keySet();
WebInspector.CSSKeywordCompletions._colors = [
"aqua", "black", "blue", "fuchsia", "gray", "green", "lime", "maroon", "navy", "olive", "orange", "purple", "red",
"silver", "teal", "white", "yellow", "transparent", "currentcolor", "grey", "aliceblue", "antiquewhite",
"aquamarine", "azure", "beige", "bisque", "blanchedalmond", "blueviolet", "brown", "burlywood", "cadetblue",
"chartreuse", "chocolate", "coral", "cornflowerblue", "cornsilk", "crimson", "cyan", "darkblue", "darkcyan",
"darkgoldenrod", "darkgray", "darkgreen", "darkgrey", "darkkhaki", "darkmagenta", "darkolivegreen", "darkorange",
"darkorchid", "darkred", "darksalmon", "darkseagreen", "darkslateblue", "darkslategray", "darkslategrey",
"darkturquoise", "darkviolet", "deeppink", "deepskyblue", "dimgray", "dimgrey", "dodgerblue", "firebrick",
"floralwhite", "forestgreen", "gainsboro", "ghostwhite", "gold", "goldenrod", "greenyellow", "honeydew", "hotpink",
"indianred", "indigo", "ivory", "khaki", "lavender", "lavenderblush", "lawngreen", "lemonchiffon", "lightblue",
"lightcoral", "lightcyan", "lightgoldenrodyellow", "lightgray", "lightgreen", "lightgrey", "lightpink",
"lightsalmon", "lightseagreen", "lightskyblue", "lightslategray", "lightslategrey", "lightsteelblue", "lightyellow",
"limegreen", "linen", "magenta", "mediumaquamarine", "mediumblue", "mediumorchid", "mediumpurple", "mediumseagreen",
"mediumslateblue", "mediumspringgreen", "mediumturquoise", "mediumvioletred", "midnightblue", "mintcream",
"mistyrose", "moccasin", "navajowhite", "oldlace", "olivedrab", "orangered", "orchid", "palegoldenrod", "palegreen",
"paleturquoise", "palevioletred", "papayawhip", "peachpuff", "peru", "pink", "plum", "powderblue", "rosybrown",
"royalblue", "saddlebrown", "salmon", "sandybrown", "seagreen", "seashell", "sienna", "skyblue", "slateblue",
"slategray", "slategrey", "snow", "springgreen", "steelblue", "tan", "thistle", "tomato", "turquoise", "violet",
"wheat", "whitesmoke", "yellowgreen"
];
WebInspector.CSSKeywordCompletions._colorAwareProperties = [
"background", "background-color", "background-image", "border", "border-color", "border-top", "border-right", "border-bottom",
"border-left", "border-top-color", "border-right-color", "border-bottom-color", "border-left-color", "box-shadow", "color",
"fill", "outline", "outline-color", "stroke", "text-line-through", "text-line-through-color", "text-overline", "text-overline-color",
"text-shadow", "text-underline", "text-underline-color", "-webkit-box-shadow", "-webkit-text-emphasis", "-webkit-text-emphasis-color"
].keySet();
WebInspector.CSSKeywordCompletions._propertyKeywordMap = {
"table-layout": [
"auto", "fixed"
],
"visibility": [
"hidden", "visible", "collapse"
],
"background-repeat": [
"repeat", "repeat-x", "repeat-y", "no-repeat", "space", "round"
],
"text-underline": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"content": [
"list-item", "close-quote", "no-close-quote", "no-open-quote", "open-quote"
],
"list-style-image": [
"none"
],
"clear": [
"none", "left", "right", "both"
],
"text-underline-mode": [
"continuous", "skip-white-space"
],
"overflow-x": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"stroke-linejoin": [
"round", "miter", "bevel"
],
"baseline-shift": [
"baseline", "sub", "super"
],
"border-bottom-width": [
"medium", "thick", "thin"
],
"marquee-speed": [
"normal", "slow", "fast"
],
"margin-top-collapse": [
"collapse", "separate", "discard"
],
"max-height": [
"none"
],
"box-orient": [
"horizontal", "vertical", "inline-axis", "block-axis"
],
"font-stretch": [
"normal", "wider", "narrower", "ultra-condensed", "extra-condensed", "condensed", "semi-condensed",
"semi-expanded", "expanded", "extra-expanded", "ultra-expanded"
],
"-webkit-color-correction": [
"default", "srgb"
],
"text-underline-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"text-overline-mode": [
"continuous", "skip-white-space"
],
"-webkit-background-composite": [
"highlight", "clear", "copy", "source-over", "source-in", "source-out", "source-atop", "destination-over",
"destination-in", "destination-out", "destination-atop", "xor", "plus-darker", "plus-lighter"
],
"border-left-width": [
"medium", "thick", "thin"
],
"-webkit-writing-mode": [
"lr", "rl", "tb", "lr-tb", "rl-tb", "tb-rl", "horizontal-tb", "vertical-rl", "vertical-lr", "horizontal-bt"
],
"text-line-through-mode": [
"continuous", "skip-white-space"
],
"border-collapse": [
"collapse", "separate"
],
"page-break-inside": [
"auto", "avoid"
],
"border-top-width": [
"medium", "thick", "thin"
],
"outline-color": [
"invert"
],
"text-line-through-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"outline-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"cursor": [
"none", "copy", "auto", "crosshair", "default", "pointer", "move", "vertical-text", "cell", "context-menu",
"alias", "progress", "no-drop", "not-allowed", "-webkit-zoom-in", "-webkit-zoom-out", "e-resize", "ne-resize",
"nw-resize", "n-resize", "se-resize", "sw-resize", "s-resize", "w-resize", "ew-resize", "ns-resize",
"nesw-resize", "nwse-resize", "col-resize", "row-resize", "text", "wait", "help", "all-scroll", "-webkit-grab",
"-webkit-grabbing"
],
"border-width": [
"medium", "thick", "thin"
],
"size": [
"a3", "a4", "a5", "b4", "b5", "landscape", "ledger", "legal", "letter", "portrait"
],
"background-size": [
"contain", "cover"
],
"direction": [
"ltr", "rtl"
],
"marquee-direction": [
"left", "right", "auto", "reverse", "forwards", "backwards", "ahead", "up", "down"
],
"enable-background": [
"accumulate", "new"
],
"float": [
"none", "left", "right"
],
"overflow-y": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"margin-bottom-collapse": [
"collapse", "separate", "discard"
],
"box-reflect": [
"left", "right", "above", "below"
],
"overflow": [
"hidden", "auto", "visible", "overlay", "scroll"
],
"text-rendering": [
"auto", "optimizeSpeed", "optimizeLegibility", "geometricPrecision"
],
"text-align": [
"-webkit-auto", "left", "right", "center", "justify", "-webkit-left", "-webkit-right", "-webkit-center"
],
"list-style-position": [
"outside", "inside"
],
"margin-bottom": [
"auto"
],
"color-interpolation": [
"linearrgb"
],
"background-origin": [
"border-box", "content-box", "padding-box"
],
"word-wrap": [
"normal", "break-word"
],
"font-weight": [
"normal", "bold", "bolder", "lighter", "100", "200", "300", "400", "500", "600", "700", "800", "900"
],
"margin-before-collapse": [
"collapse", "separate", "discard"
],
"text-overline-width": [
"normal", "medium", "auto", "thick", "thin"
],
"text-transform": [
"none", "capitalize", "uppercase", "lowercase"
],
"border-right-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"border-left-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"-webkit-text-emphasis": [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
],
"font-style": [
"italic", "oblique", "normal"
],
"speak": [
"none", "normal", "spell-out", "digits", "literal-punctuation", "no-punctuation"
],
"text-line-through": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave", "continuous",
"skip-white-space"
],
"color-rendering": [
"auto", "optimizeSpeed", "optimizeQuality"
],
"list-style-type": [
"none", "disc", "circle", "square", "decimal", "decimal-leading-zero", "arabic-indic", "binary", "bengali",
"cambodian", "khmer", "devanagari", "gujarati", "gurmukhi", "kannada", "lower-hexadecimal", "lao", "malayalam",
"mongolian", "myanmar", "octal", "oriya", "persian", "urdu", "telugu", "tibetan", "thai", "upper-hexadecimal",
"lower-roman", "upper-roman", "lower-greek", "lower-alpha", "lower-latin", "upper-alpha", "upper-latin", "afar",
"ethiopic-halehame-aa-et", "ethiopic-halehame-aa-er", "amharic", "ethiopic-halehame-am-et", "amharic-abegede",
"ethiopic-abegede-am-et", "cjk-earthly-branch", "cjk-heavenly-stem", "ethiopic", "ethiopic-halehame-gez",
"ethiopic-abegede", "ethiopic-abegede-gez", "hangul-consonant", "hangul", "lower-norwegian", "oromo",
"ethiopic-halehame-om-et", "sidama", "ethiopic-halehame-sid-et", "somali", "ethiopic-halehame-so-et", "tigre",
"ethiopic-halehame-tig", "tigrinya-er", "ethiopic-halehame-ti-er", "tigrinya-er-abegede",
"ethiopic-abegede-ti-er", "tigrinya-et", "ethiopic-halehame-ti-et", "tigrinya-et-abegede",
"ethiopic-abegede-ti-et", "upper-greek", "upper-norwegian", "asterisks", "footnotes", "hebrew", "armenian",
"lower-armenian", "upper-armenian", "georgian", "cjk-ideographic", "hiragana", "katakana", "hiragana-iroha",
"katakana-iroha"
],
"-webkit-text-combine": [
"none", "horizontal"
],
"outline": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"font": [
"caption", "icon", "menu", "message-box", "small-caption", "-webkit-mini-control", "-webkit-small-control",
"-webkit-control", "status-bar", "italic", "oblique", "small-caps", "normal", "bold", "bolder", "lighter",
"100", "200", "300", "400", "500", "600", "700", "800", "900", "xx-small", "x-small", "small", "medium",
"large", "x-large", "xx-large", "-webkit-xxx-large", "smaller", "larger", "serif", "sans-serif", "cursive",
"fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
],
"dominant-baseline": [
"middle", "auto", "central", "text-before-edge", "text-after-edge", "ideographic", "alphabetic", "hanging",
"mathematical", "use-script", "no-change", "reset-size"
],
"display": [
"none", "inline", "block", "list-item", "run-in", "compact", "inline-block", "table", "inline-table",
"table-row-group", "table-header-group", "table-footer-group", "table-row", "table-column-group",
"table-column", "table-cell", "table-caption", "-webkit-box", "-webkit-inline-box", "-wap-marquee"
],
"-webkit-text-emphasis-position": [
"over", "under"
],
"image-rendering": [
"auto", "optimizeSpeed", "optimizeQuality"
],
"alignment-baseline": [
"baseline", "middle", "auto", "before-edge", "after-edge", "central", "text-before-edge", "text-after-edge",
"ideographic", "alphabetic", "hanging", "mathematical"
],
"outline-width": [
"medium", "thick", "thin"
],
"text-line-through-width": [
"normal", "medium", "auto", "thick", "thin"
],
"box-align": [
"baseline", "center", "stretch", "start", "end"
],
"border-right-width": [
"medium", "thick", "thin"
],
"border-top-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"line-height": [
"normal"
],
"text-overflow": [
"clip", "ellipsis"
],
"box-direction": [
"normal", "reverse"
],
"margin-after-collapse": [
"collapse", "separate", "discard"
],
"page-break-before": [
"left", "right", "auto", "always", "avoid"
],
"-webkit-hyphens": [
"none", "auto", "manual"
],
"border-image": [
"repeat", "stretch"
],
"text-decoration": [
"blink", "line-through", "overline", "underline"
],
"position": [
"absolute", "fixed", "relative", "static"
],
"font-family": [
"serif", "sans-serif", "cursive", "fantasy", "monospace", "-webkit-body", "-webkit-pictograph"
],
"text-overflow-mode": [
"clip", "ellipsis"
],
"border-bottom-style": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"unicode-bidi": [
"normal", "bidi-override", "embed"
],
"clip-rule": [
"nonzero", "evenodd"
],
"margin-left": [
"auto"
],
"margin-top": [
"auto"
],
"zoom": [
"document", "reset"
],
"text-overline-style": [
"none", "dotted", "dashed", "solid", "double", "dot-dash", "dot-dot-dash", "wave"
],
"max-width": [
"none"
],
"empty-cells": [
"hide", "show"
],
"pointer-events": [
"none", "all", "auto", "visible", "visiblepainted", "visiblefill", "visiblestroke", "painted", "fill", "stroke"
],
"letter-spacing": [
"normal"
],
"background-clip": [
"border-box", "content-box", "padding-box"
],
"-webkit-font-smoothing": [
"none", "auto", "antialiased", "subpixel-antialiased"
],
"border": [
"none", "hidden", "inset", "groove", "ridge", "outset", "dotted", "dashed", "solid", "double"
],
"font-size": [
"xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large", "-webkit-xxx-large", "smaller",
"larger"
],
"font-variant": [
"small-caps", "normal"
],
"vertical-align": [
"baseline", "middle", "sub", "super", "text-top", "text-bottom", "top", "bottom", "-webkit-baseline-middle"
],
"marquee-style": [
"none", "scroll", "slide", "alternate"
],
"white-space": [
"normal", "nowrap", "pre", "pre-line", "pre-wrap"
],
"text-underline-width": [
"normal", "medium", "auto", "thick", "thin"
],
"box-lines": [
"single", "multiple"
],
"page-break-after": [
"left", "right", "auto", "always", "avoid"
],
"clip-path": [
"none"
],
"margin": [
"auto"
],
"marquee-repetition": [
"infinite"
],
"margin-right": [
"auto"
],
"-webkit-text-emphasis-style": [
"circle", "filled", "open", "dot", "double-circle", "triangle", "sesame"
],
"-webkit-transform": [
"scale", "scaleX", "scaleY", "scale3d", "rotate", "rotateX", "rotateY", "rotateZ", "rotate3d", "skew", "skewX", "skewY",
"translate", "translateX", "translateY", "translateZ", "translate3d", "matrix", "matrix3d", "perspective"
]
}
WebInspector.PanelEnablerView = function(identifier, headingText, disclaimerText, buttonTitle)
{
WebInspector.View.call(this);
this.registerRequiredCSS("panelEnablerView.css");
this.element.addStyleClass("panel-enabler-view");
this.element.addStyleClass(identifier);
this.contentElement = document.createElement("div");
this.contentElement.className = "panel-enabler-view-content";
this.element.appendChild(this.contentElement);
this.imageElement = document.createElement("img");
this.contentElement.appendChild(this.imageElement);
this.choicesForm = document.createElement("form");
this.contentElement.appendChild(this.choicesForm);
this.headerElement = document.createElement("h1");
this.headerElement.textContent = headingText;
this.choicesForm.appendChild(this.headerElement);
var self = this;
function enableOption(text, checked) {
var label = document.createElement("label");
var option = document.createElement("input");
option.type = "radio";
option.name = "enable-option";
if (checked)
option.checked = true;
label.appendChild(option);
label.appendChild(document.createTextNode(text));
self.choicesForm.appendChild(label);
return option;
};
this.enabledForSession = enableOption(WebInspector.UIString("Only enable for this session"), true);
this.enabledAlways = enableOption(WebInspector.UIString("Always enable"), false);
this.disclaimerElement = document.createElement("div");
this.disclaimerElement.className = "panel-enabler-disclaimer";
this.disclaimerElement.textContent = disclaimerText;
this.choicesForm.appendChild(this.disclaimerElement);
this.enableButton = document.createElement("button");
this.enableButton.setAttribute("type", "button");
this.enableButton.textContent = buttonTitle;
this.enableButton.addEventListener("click", this._enableButtonCicked.bind(this), false);
this.choicesForm.appendChild(this.enableButton);
}
WebInspector.PanelEnablerView.prototype = {
_enableButtonCicked: function()
{
this.dispatchEventToListeners("enable clicked");
},
onResize: function()
{
this.imageElement.removeStyleClass("hidden");
if (this.element.offsetWidth < (this.choicesForm.offsetWidth + this.imageElement.offsetWidth))
this.imageElement.addStyleClass("hidden");
},
get alwaysEnabled() {
return this.enabledAlways.checked;
}
}
WebInspector.PanelEnablerView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.StatusBarButton = function(title, className, states)
{
this.element = document.createElement("button");
this.element.className = className + " status-bar-item";
this.element.addEventListener("click", this._clicked.bind(this), false);
this.glyph = document.createElement("div");
this.glyph.className = "glyph";
this.element.appendChild(this.glyph);
this.glyphShadow = document.createElement("div");
this.glyphShadow.className = "glyph shadow";
this.element.appendChild(this.glyphShadow);
this.states = states;
if (!states)
this.states = 2;
if (states == 2)
this._state = false;
else
this._state = 0;
this.title = title;
this.disabled = false;
this._visible = true;
}
WebInspector.StatusBarButton.width = 31;
WebInspector.StatusBarButton.prototype = {
_clicked: function()
{
this.dispatchEventToListeners("click");
if (this._showOptionsTimer)
clearTimeout(this._showOptionsTimer);
},
get disabled()
{
return this._disabled;
},
set disabled(x)
{
if (this._disabled === x)
return;
this._disabled = x;
this.element.disabled = x;
},
get title()
{
return this._title;
},
set title(x)
{
if (this._title === x)
return;
this._title = x;
this.element.title = x;
},
get state()
{
return this._state;
},
set state(x)
{
if (this._state === x)
return;
if (this.states === 2) {
if (x)
this.element.addStyleClass("toggled-on");
else
this.element.removeStyleClass("toggled-on");
} else {
if (x !== 0) {
this.element.removeStyleClass("toggled-" + this._state);
this.element.addStyleClass("toggled-" + x);
} else
this.element.removeStyleClass("toggled-" + this._state);
}
this._state = x;
},
get toggled()
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
return this.state;
},
set toggled(x)
{
if (this.states !== 2)
throw("Only used toggled when there are 2 states, otherwise, use state");
this.state = x;
},
get visible()
{
return this._visible;
},
set visible(x)
{
if (this._visible === x)
return;
if (x)
this.element.removeStyleClass("hidden");
else
this.element.addStyleClass("hidden");
this._visible = x;
},
makeLongClickEnabled: function(buttonsProvider)
{
this.longClickGlyph = document.createElement("div");
this.longClickGlyph.className = "fill long-click-glyph";
this.element.appendChild(this.longClickGlyph);
this.longClickGlyphShadow = document.createElement("div");
this.longClickGlyphShadow.className = "fill long-click-glyph shadow";
this.element.appendChild(this.longClickGlyphShadow);
this.element.addEventListener("mousedown", mouseDown.bind(this), false);
this.element.addEventListener("mouseout", mouseUp.bind(this), false);
this.element.addEventListener("mouseup", mouseUp.bind(this), false);
function mouseDown(e)
{
if (e.which !== 1)
return;
this._showOptionsTimer = setTimeout(this._showOptions.bind(this, buttonsProvider), 200);
}
function mouseUp(e)
{
if (e.which !== 1)
return;
if (this._showOptionsTimer)
clearTimeout(this._showOptionsTimer);
}
},
_showOptions: function(buttonsProvider)
{
var buttons = buttonsProvider();
var mouseUpListener = mouseUp.bind(this);
document.documentElement.addEventListener("mouseup", mouseUpListener, false);
var optionsGlassPane = new WebInspector.GlassPane();
var optionsBarElement = optionsGlassPane.element.createChild("div", "alternate-status-bar-buttons-bar");
const buttonHeight = 24;
optionsBarElement.style.height = (buttonHeight * buttons.length) + "px";
optionsBarElement.style.left = (this.element.offsetLeft + 1) + "px";
var boundMouseOver = mouseOver.bind(this);
var boundMouseOut = mouseOut.bind(this);
for (var i = 0; i < buttons.length; ++i) {
buttons[i].element.addEventListener("mousemove", boundMouseOver.bind(this), false);
buttons[i].element.addEventListener("mouseout", boundMouseOut.bind(this), false);
optionsBarElement.appendChild(buttons[i].element);
}
buttons[buttons.length - 1].element.addStyleClass("emulate-active");
function mouseOver(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.addStyleClass("emulate-active");
}
function mouseOut(e)
{
if (e.which !== 1)
return;
var buttonElement = e.target.enclosingNodeOrSelfWithClass("status-bar-item");
buttonElement.removeStyleClass("emulate-active");
}
function mouseUp(e)
{
if (e.which !== 1)
return;
optionsGlassPane.dispose();
document.documentElement.removeEventListener("mouseup", mouseUpListener, false);
for (var i = 0; i < buttons.length; ++i) {
if (buttons[i].element.hasStyleClass("emulate-active"))
buttons[i]._clicked();
}
}
}
}
WebInspector.StatusBarButton.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.StatusBarComboBox = function(changeHandler, className)
{
this.element = document.createElement("span");
this.element.className = "status-bar-select-container";
this._selectElement = this.element.createChild("select", "status-bar-item");
if (changeHandler)
this._selectElement.addEventListener("change", changeHandler, false);
if (className)
this._selectElement.addStyleClass(className);
}
WebInspector.StatusBarComboBox.prototype = {
addOption: function(option)
{
this._selectElement.appendChild(option);
},
removeOption: function(option)
{
this._selectElement.removeChild(option);
},
removeOptions: function()
{
this._selectElement.removeChildren();
},
selectedOption: function()
{
if (this._selectElement.selectedIndex >= 0)
return this._selectElement[this._selectElement.selectedIndex];
return null;
},
select: function(option)
{
this._selectElement.selectedIndex = Array.prototype.indexOf.call(this._selectElement, option);
}
}
WebInspector.TextEditor = function() { };
WebInspector.TextEditor.Events = {
GutterClick: "gutterClick"
};
WebInspector.TextEditor.prototype = {
set mimeType(mimeType) { },
setReadOnly: function(readOnly) { },
readOnly: function() { },
defaultFocusedElement: function() { },
revealLine: function(lineNumber) { },
addBreakpoint: function(lineNumber, disabled, conditional) { },
removeBreakpoint: function(lineNumber) { },
setExecutionLine: function(lineNumber) { },
clearExecutionLine: function() { },
addDecoration: function(lineNumber, element) { },
removeDecoration: function(lineNumber, element) { },
markAndRevealRange: function(range) { },
highlightLine: function(lineNumber) { },
clearLineHighlight: function() { },
elementsToRestoreScrollPositionsFor: function() { },
inheritScrollPositions: function(textEditor) { },
beginUpdates: function() { },
endUpdates: function() { },
onResize: function() { },
editRange: function(range, text) { },
scrollToLine: function(lineNumber) { },
selection: function(textRange) { },
lastSelection: function() { },
setSelection: function(textRange) { },
setText: function(text) { },
text: function() { },
range: function() { },
line: function(lineNumber) { },
get linesCount() { },
setAttribute: function(line, name, value) { },
getAttribute: function(line, name) { },
removeAttribute: function(line, name) { },
wasShown: function() { },
willHide: function() { }
}
WebInspector.TextEditorDelegate = function()
{
}
WebInspector.TextEditorDelegate.prototype = {
onTextChanged: function(oldRange, newRange) { },
selectionChanged: function(textRange) { },
scrollChanged: function(lineNumber) { },
populateLineGutterContextMenu: function(contextMenu, lineNumber) { },
populateTextAreaContextMenu: function(contextMenu, lineNumber) { },
createLink: function(hrefValue, isExternal) { }
}
WebInspector.DefaultTextEditor = function(url, delegate)
{
WebInspector.View.call(this);
this._delegate = delegate;
this._url = url;
this.registerRequiredCSS("textEditor.css");
this.element.className = "text-editor monospace";
this._textModel = new WebInspector.TextEditorModel();
this._textModel.addEventListener(WebInspector.TextEditorModel.Events.TextChanged, this._textChanged, this);
this._textModel.resetUndoStack();
var enterTextChangeMode = this._enterInternalTextChangeMode.bind(this);
var exitTextChangeMode = this._exitInternalTextChangeMode.bind(this);
var syncScrollListener = this._syncScroll.bind(this);
var syncDecorationsForLineListener = this._syncDecorationsForLine.bind(this);
var syncLineHeightListener = this._syncLineHeight.bind(this);
this._mainPanel = new WebInspector.TextEditorMainPanel(this._delegate, this._textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode);
this._gutterPanel = new WebInspector.TextEditorGutterPanel(this._textModel, syncDecorationsForLineListener, syncLineHeightListener);
this._mainPanel.element.addEventListener("scroll", this._handleScrollChanged.bind(this), false);
this._mainPanel._container.addEventListener("focus", this._handleFocused.bind(this), false);
this._gutterPanel.element.addEventListener("mousedown", this._onMouseDown.bind(this), true);
this.element.appendChild(this._mainPanel.element);
this.element.appendChild(this._gutterPanel.element);
function forwardWheelEvent(event)
{
var clone = document.createEvent("WheelEvent");
clone.initWebKitWheelEvent(event.wheelDeltaX, event.wheelDeltaY,
event.view,
event.screenX, event.screenY,
event.clientX, event.clientY,
event.ctrlKey, event.altKey, event.shiftKey, event.metaKey);
this._mainPanel.element.dispatchEvent(clone);
}
this._gutterPanel.element.addEventListener("mousewheel", forwardWheelEvent.bind(this), false);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
this.element.addEventListener("contextmenu", this._contextMenu.bind(this), true);
this._registerShortcuts();
}
WebInspector.DefaultTextEditor.prototype = {
set mimeType(mimeType)
{
this._mainPanel.mimeType = mimeType;
},
setReadOnly: function(readOnly)
{
if (this._mainPanel.readOnly() === readOnly)
return;
this._mainPanel.setReadOnly(readOnly, this.isShowing());
WebInspector.markBeingEdited(this.element, !readOnly);
},
readOnly: function()
{
return this._mainPanel.readOnly();
},
get textModel()
{
return this._textModel;
},
defaultFocusedElement: function()
{
return this._mainPanel.defaultFocusedElement();
},
revealLine: function(lineNumber)
{
this._mainPanel.revealLine(lineNumber);
},
_onMouseDown: function(event)
{
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (!target)
return;
this.dispatchEventToListeners(WebInspector.TextEditor.Events.GutterClick, { lineNumber: target.lineNumber, event: event });
},
addBreakpoint: function(lineNumber, disabled, conditional)
{
this.beginUpdates();
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint");
if (disabled)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-disabled");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
if (conditional)
this._gutterPanel.addDecoration(lineNumber, "webkit-breakpoint-conditional");
else
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},
removeBreakpoint: function(lineNumber)
{
this.beginUpdates();
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-disabled");
this._gutterPanel.removeDecoration(lineNumber, "webkit-breakpoint-conditional");
this.endUpdates();
},
setExecutionLine: function(lineNumber)
{
this._executionLineNumber = lineNumber;
this._mainPanel.addDecoration(lineNumber, "webkit-execution-line");
this._gutterPanel.addDecoration(lineNumber, "webkit-execution-line");
},
clearExecutionLine: function()
{
if (typeof this._executionLineNumber === "number") {
this._mainPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
this._gutterPanel.removeDecoration(this._executionLineNumber, "webkit-execution-line");
}
delete this._executionLineNumber;
},
addDecoration: function(lineNumber, element)
{
this._mainPanel.addDecoration(lineNumber, element);
this._gutterPanel.addDecoration(lineNumber, element);
},
removeDecoration: function(lineNumber, element)
{
this._mainPanel.removeDecoration(lineNumber, element);
this._gutterPanel.removeDecoration(lineNumber, element);
},
markAndRevealRange: function(range)
{
if (range)
this.setSelection(range);
this._mainPanel.markAndRevealRange(range);
},
highlightLine: function(lineNumber)
{
if (typeof lineNumber !== "number" || lineNumber < 0)
return;
lineNumber = Math.min(lineNumber, this._textModel.linesCount - 1);
this._mainPanel.highlightLine(lineNumber);
},
clearLineHighlight: function()
{
this._mainPanel.clearLineHighlight();
},
_freeCachedElements: function()
{
this._mainPanel._freeCachedElements();
this._gutterPanel._freeCachedElements();
},
elementsToRestoreScrollPositionsFor: function()
{
return [this._mainPanel.element];
},
inheritScrollPositions: function(textEditor)
{
this._mainPanel.element._scrollTop = textEditor._mainPanel.element.scrollTop;
this._mainPanel.element._scrollLeft = textEditor._mainPanel.element.scrollLeft;
},
beginUpdates: function()
{
this._mainPanel.beginUpdates();
this._gutterPanel.beginUpdates();
},
endUpdates: function()
{
this._mainPanel.endUpdates();
this._gutterPanel.endUpdates();
this._updatePanelOffsets();
},
onResize: function()
{
this._mainPanel.resize();
this._gutterPanel.resize();
this._updatePanelOffsets();
},
_textChanged: function(event)
{
if (!this._internalTextChangeMode)
this._textModel.resetUndoStack();
this._mainPanel.textChanged(event.data.oldRange, event.data.newRange);
this._gutterPanel.textChanged(event.data.oldRange, event.data.newRange);
this._updatePanelOffsets();
},
editRange: function(range, text)
{
this._enterInternalTextChangeMode();
this._textModel.markUndoableState();
var newRange = this._textModel.editRange(range, text);
this._exitInternalTextChangeMode(range, newRange);
return newRange;
},
_enterInternalTextChangeMode: function()
{
this._internalTextChangeMode = true;
},
_exitInternalTextChangeMode: function(oldRange, newRange)
{
this._internalTextChangeMode = false;
this._delegate.onTextChanged(oldRange, newRange);
},
_updatePanelOffsets: function()
{
var lineNumbersWidth = this._gutterPanel.element.offsetWidth;
if (lineNumbersWidth)
this._mainPanel.element.style.setProperty("left", (lineNumbersWidth + 2) + "px");
else
this._mainPanel.element.style.removeProperty("left");
},
_syncScroll: function()
{
var mainElement = this._mainPanel.element;
var gutterElement = this._gutterPanel.element;
this._gutterPanel.syncClientHeight(mainElement.clientHeight);
gutterElement.scrollTop = mainElement.scrollTop;
},
_syncDecorationsForLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;
var mainChunk = this._mainPanel.chunkForLine(lineNumber);
if (mainChunk.linesCount === 1 && mainChunk.decorated) {
var gutterChunk = this._gutterPanel.makeLineAChunk(lineNumber);
var height = mainChunk.height;
if (height)
gutterChunk.element.style.setProperty("height", height + "px");
else
gutterChunk.element.style.removeProperty("height");
} else {
var gutterChunk = this._gutterPanel.chunkForLine(lineNumber);
if (gutterChunk.linesCount === 1)
gutterChunk.element.style.removeProperty("height");
}
},
_syncLineHeight: function(gutterRow)
{
if (this._lineHeightSynced)
return;
if (gutterRow && gutterRow.offsetHeight) {
this.element.style.setProperty("line-height", gutterRow.offsetHeight + "px");
this._lineHeightSynced = true;
}
},
_registerShortcuts: function()
{
var keys = WebInspector.KeyboardShortcut.Keys;
var modifiers = WebInspector.KeyboardShortcut.Modifiers;
this._shortcuts = {};
var handleEnterKey = this._mainPanel.handleEnterKey.bind(this._mainPanel);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Enter.code, WebInspector.KeyboardShortcut.Modifiers.None)] = handleEnterKey;
var handleUndo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, false);
var handleRedo = this._mainPanel.handleUndoRedo.bind(this._mainPanel, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.CtrlOrMeta)] = handleUndo;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("z", modifiers.Shift | modifiers.CtrlOrMeta)] = handleRedo;
var handleTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, false);
var handleShiftTabKey = this._mainPanel.handleTabKeyPress.bind(this._mainPanel, true);
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code)] = handleTabKey;
this._shortcuts[WebInspector.KeyboardShortcut.makeKey(keys.Tab.code, modifiers.Shift)] = handleShiftTabKey;
},
_handleKeyDown: function(e)
{
if (this.readOnly())
return;
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},
_contextMenu: function(event)
{
var anchor = event.target.enclosingNodeOrSelfWithNodeName("a");
if (anchor)
return;
var contextMenu = new WebInspector.ContextMenu();
var target = event.target.enclosingNodeOrSelfWithClass("webkit-line-number");
if (target)
this._delegate.populateLineGutterContextMenu(contextMenu, target.lineNumber);
else {
target = this._mainPanel._enclosingLineRowOrSelf(event.target);
this._delegate.populateTextAreaContextMenu(contextMenu, target && target.lineNumber);
}
contextMenu.show(event);
},
_handleScrollChanged: function(event)
{
var visibleFrom = this._mainPanel.element.scrollTop;
var firstVisibleLineNumber = this._mainPanel._findFirstVisibleLineNumber(visibleFrom);
this._delegate.scrollChanged(firstVisibleLineNumber);
},
scrollToLine: function(lineNumber)
{
this._mainPanel.scrollToLine(lineNumber);
},
_handleSelectionChange: function(event)
{
var textRange = this._mainPanel._getSelection();
if (textRange) {
this._lastSelection = WebInspector.TextRange.createFromLocation(textRange.endLine, textRange.endColumn);
}
this._delegate.selectionChanged(textRange);
},
selection: function(textRange)
{
return this._mainPanel._getSelection();
},
lastSelection: function()
{
return this._lastSelection;
},
setSelection: function(textRange)
{
this._lastSelection = textRange;
if (this.element.isAncestor(document.activeElement))
this._mainPanel._restoreSelection(textRange);
},
setText: function(text)
{
this._textModel.setText(text);
},
text: function()
{
return this._textModel.text();
},
range: function()
{
return this._textModel.range();
},
line: function(lineNumber)
{
return this._textModel.line(lineNumber);
},
get linesCount()
{
return this._textModel.linesCount;
},
setAttribute: function(line, name, value)
{
this._textModel.setAttribute(line, name, value);
},
getAttribute: function(line, name)
{
return this._textModel.getAttribute(line, name);
},
removeAttribute: function(line, name)
{
this._textModel.removeAttribute(line, name);
},
wasShown: function()
{
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, true);
this._boundSelectionChangeListener = this._handleSelectionChange.bind(this);
document.addEventListener("selectionchange", this._boundSelectionChangeListener, false);
},
_handleFocused: function()
{
if (this._lastSelection)
this.setSelection(this._lastSelection);
},
willHide: function()
{
document.removeEventListener("selectionchange", this._boundSelectionChangeListener, false);
delete this._boundSelectionChangeListener;
if (!this.readOnly())
WebInspector.markBeingEdited(this.element, false);
this._freeCachedElements();
}
}
WebInspector.DefaultTextEditor.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.TextEditorChunkedPanel = function(textModel)
{
this._textModel = textModel;
this._defaultChunkSize = 50;
this._paintCoalescingLevel = 0;
this._domUpdateCoalescingLevel = 0;
}
WebInspector.TextEditorChunkedPanel.prototype = {
get textModel()
{
return this._textModel;
},
scrollToLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;
var chunk = this.makeLineAChunk(lineNumber);
this.element.scrollTop = chunk.offsetTop;
},
revealLine: function(lineNumber)
{
if (lineNumber >= this._textModel.linesCount)
return;
var chunk = this.makeLineAChunk(lineNumber);
chunk.element.scrollIntoViewIfNeeded();
},
addDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;
var chunk = this.makeLineAChunk(lineNumber);
chunk.addDecoration(decoration);
},
removeDecoration: function(lineNumber, decoration)
{
if (lineNumber >= this._textModel.linesCount)
return;
var chunk = this.chunkForLine(lineNumber);
chunk.removeDecoration(decoration);
},
_buildChunks: function()
{
this.beginDomUpdates();
this._container.removeChildren();
this._textChunks = [];
for (var i = 0; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}
this._repaintAll();
this.endDomUpdates();
},
makeLineAChunk: function(lineNumber)
{
var chunkNumber = this._chunkNumberForLine(lineNumber);
var oldChunk = this._textChunks[chunkNumber];
if (!oldChunk) {
console.error("No chunk for line number: " + lineNumber);
return;
}
if (oldChunk.linesCount === 1)
return oldChunk;
return this._splitChunkOnALine(lineNumber, chunkNumber, true);
},
_splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
this.beginDomUpdates();
var oldChunk = this._textChunks[chunkNumber];
var wasExpanded = oldChunk.expanded;
oldChunk.expanded = false;
var insertIndex = chunkNumber + 1;
if (lineNumber > oldChunk.startLine) {
var prefixChunk = this._createNewChunk(oldChunk.startLine, lineNumber);
prefixChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex++, 0, prefixChunk);
this._container.insertBefore(prefixChunk.element, oldChunk.element);
}
var endLine = createSuffixChunk ? lineNumber + 1 : oldChunk.startLine + oldChunk.linesCount;
var lineChunk = this._createNewChunk(lineNumber, endLine);
lineChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex++, 0, lineChunk);
this._container.insertBefore(lineChunk.element, oldChunk.element);
if (oldChunk.startLine + oldChunk.linesCount > endLine) {
var suffixChunk = this._createNewChunk(endLine, oldChunk.startLine + oldChunk.linesCount);
suffixChunk.readOnly = oldChunk.readOnly;
this._textChunks.splice(insertIndex, 0, suffixChunk);
this._container.insertBefore(suffixChunk.element, oldChunk.element);
}
this._textChunks.splice(chunkNumber, 1);
this._container.removeChild(oldChunk.element);
if (wasExpanded) {
if (prefixChunk)
prefixChunk.expanded = true;
lineChunk.expanded = true;
if (suffixChunk)
suffixChunk.expanded = true;
}
this.endDomUpdates();
return lineChunk;
},
_scroll: function()
{
this._scheduleRepaintAll();
if (this._syncScrollListener)
this._syncScrollListener();
},
_scheduleRepaintAll: function()
{
if (this._repaintAllTimer)
clearTimeout(this._repaintAllTimer);
this._repaintAllTimer = setTimeout(this._repaintAll.bind(this), 50);
},
beginUpdates: function()
{
this._paintCoalescingLevel++;
},
endUpdates: function()
{
this._paintCoalescingLevel--;
if (!this._paintCoalescingLevel)
this._repaintAll();
},
beginDomUpdates: function()
{
this._domUpdateCoalescingLevel++;
},
endDomUpdates: function()
{
this._domUpdateCoalescingLevel--;
},
_chunkNumberForLine: function(lineNumber)
{
function compareLineNumbers(value, chunk)
{
return value < chunk.startLine ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(lineNumber, this._textChunks, compareLineNumbers);
return insertBefore - 1;
},
chunkForLine: function(lineNumber)
{
return this._textChunks[this._chunkNumberForLine(lineNumber)];
},
_findFirstVisibleChunkNumber: function(visibleFrom)
{
function compareOffsetTops(value, chunk)
{
return value < chunk.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, this._textChunks, compareOffsetTops);
return insertBefore - 1;
},
_findVisibleChunks: function(visibleFrom, visibleTo)
{
var from = this._findFirstVisibleChunkNumber(visibleFrom);
for (var to = from + 1; to < this._textChunks.length; ++to) {
if (this._textChunks[to].offsetTop >= visibleTo)
break;
}
return { start: from, end: to };
},
_findFirstVisibleLineNumber: function(visibleFrom)
{
var chunk = this._textChunks[this._findFirstVisibleChunkNumber(visibleFrom)];
if (!chunk.expanded)
return chunk.startLine;
var lineNumbers = [];
for (var i = 0; i < chunk.linesCount; ++i) {
lineNumbers.push(chunk.startLine + i);
}
function compareLineRowOffsetTops(value, lineNumber)
{
var lineRow = chunk.getExpandedLineRow(lineNumber);
return value < lineRow.offsetTop ? -1 : 1;
}
var insertBefore = insertionIndexForObjectInListSortedByFunction(visibleFrom, lineNumbers, compareLineRowOffsetTops);
return lineNumbers[insertBefore - 1];
},
_repaintAll: function()
{
delete this._repaintAllTimer;
if (this._paintCoalescingLevel || this._dirtyLines)
return;
var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;
if (visibleTo) {
var result = this._findVisibleChunks(visibleFrom, visibleTo);
this._expandChunks(result.start, result.end);
}
},
_expandChunks: function(fromIndex, toIndex)
{
for (var i = 0; i < fromIndex; ++i)
this._textChunks[i].expanded = false;
for (var i = toIndex; i < this._textChunks.length; ++i)
this._textChunks[i].expanded = false;
for (var i = fromIndex; i < toIndex; ++i)
this._textChunks[i].expanded = true;
},
_totalHeight: function(firstElement, lastElement)
{
lastElement = (lastElement || firstElement).nextElementSibling;
if (lastElement)
return lastElement.offsetTop - firstElement.offsetTop;
var offsetParent = firstElement.offsetParent;
if (offsetParent && offsetParent.scrollHeight > offsetParent.clientHeight)
return offsetParent.scrollHeight - firstElement.offsetTop;
var total = 0;
while (firstElement && firstElement !== lastElement) {
total += firstElement.offsetHeight;
firstElement = firstElement.nextElementSibling;
}
return total;
},
resize: function()
{
this._repaintAll();
}
}
WebInspector.TextEditorGutterPanel = function(textModel, syncDecorationsForLineListener, syncLineHeightListener)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);
this._syncDecorationsForLineListener = syncDecorationsForLineListener;
this._syncLineHeightListener = syncLineHeightListener;
this.element = document.createElement("div");
this.element.className = "text-editor-lines";
this._container = document.createElement("div");
this._container.className = "inner-container";
this.element.appendChild(this._container);
this.element.addEventListener("scroll", this._scroll.bind(this), false);
this._freeCachedElements();
this._buildChunks();
this._decorations = {};
}
WebInspector.TextEditorGutterPanel.prototype = {
_freeCachedElements: function()
{
this._cachedRows = [];
},
_createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorGutterChunk(this, startLine, endLine);
},
textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();
var linesDiff = newRange.linesCount - oldRange.linesCount;
if (linesDiff) {
for (var chunkNumber = this._textChunks.length - 1; chunkNumber >= 0 ; --chunkNumber) {
var chunk = this._textChunks[chunkNumber];
if (chunk.startLine + chunk.linesCount <= this._textModel.linesCount)
break;
chunk.expanded = false;
this._container.removeChild(chunk.element);
}
this._textChunks.length = chunkNumber + 1;
var totalLines = 0;
if (this._textChunks.length) {
var lastChunk = this._textChunks[this._textChunks.length - 1];
totalLines = lastChunk.startLine + lastChunk.linesCount;
}
for (var i = totalLines; i < this._textModel.linesCount; i += this._defaultChunkSize) {
var chunk = this._createNewChunk(i, i + this._defaultChunkSize);
this._textChunks.push(chunk);
this._container.appendChild(chunk.element);
}
for (var lineNumber in this._decorations) {
lineNumber = parseInt(lineNumber, 10);
if (lineNumber < oldRange.startLine)
continue;
if (lineNumber === oldRange.startLine && oldRange.startColumn)
continue;
var lineDecorationsCopy = this._decorations[lineNumber].slice();
for (var i = 0; i < lineDecorationsCopy.length; ++i) {
var decoration = lineDecorationsCopy[i];
this.removeDecoration(lineNumber, decoration);
if (lineNumber < oldRange.endLine)
continue;
this.addDecoration(lineNumber + linesDiff, decoration);
}
}
this._repaintAll();
} else {
var chunkNumber = this._chunkNumberForLine(newRange.startLine);
var chunk = this._textChunks[chunkNumber];
while (chunk && chunk.startLine <= newRange.endLine) {
if (chunk.linesCount === 1)
this._syncDecorationsForLineListener(chunk.startLine);
chunk = this._textChunks[++chunkNumber];
}
}
this.endDomUpdates();
},
syncClientHeight: function(clientHeight)
{
if (this.element.offsetHeight > clientHeight)
this._container.style.setProperty("padding-bottom", (this.element.offsetHeight - clientHeight) + "px");
else
this._container.style.removeProperty("padding-bottom");
},
addDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.addDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (!decorations) {
decorations = [];
this._decorations[lineNumber] = decorations;
}
decorations.push(decoration);
},
removeDecoration: function(lineNumber, decoration)
{
WebInspector.TextEditorChunkedPanel.prototype.removeDecoration.call(this, lineNumber, decoration);
var decorations = this._decorations[lineNumber];
if (decorations) {
decorations.remove(decoration);
if (!decorations.length)
delete this._decorations[lineNumber];
}
}
}
WebInspector.TextEditorGutterPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;
WebInspector.TextEditorGutterChunk = function(textEditor, startLine, endLine)
{
this._textEditor = textEditor;
this._textModel = textEditor._textModel;
this.startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;
this._expanded = false;
this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-number";
if (this.linesCount === 1) {
var innerSpan = document.createElement("span");
innerSpan.className = "webkit-line-number-inner";
innerSpan.textContent = startLine + 1;
var outerSpan = document.createElement("div");
outerSpan.className = "webkit-line-number-outer";
outerSpan.appendChild(innerSpan);
this.element.appendChild(outerSpan);
} else {
var lineNumbers = [];
for (var i = startLine; i < endLine; ++i)
lineNumbers.push(i + 1);
this.element.textContent = lineNumbers.join("\n");
}
}
WebInspector.TextEditorGutterChunk.prototype = {
addDecoration: function(decoration)
{
this._textEditor.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
this._textEditor.endDomUpdates();
},
removeDecoration: function(decoration)
{
this._textEditor.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
this._textEditor.endDomUpdates();
},
get expanded()
{
return this._expanded;
},
set expanded(expanded)
{
if (this.linesCount === 1)
this._textEditor._syncDecorationsForLineListener(this.startLine);
if (this._expanded === expanded)
return;
this._expanded = expanded;
if (this.linesCount === 1)
return;
this._textEditor.beginDomUpdates();
if (expanded) {
this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._textEditor._syncLineHeightListener(this._expandedLineRows[0]);
} else {
var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._textEditor._cachedRows.push(lineRow);
}
delete this._expandedLineRows;
}
this._textEditor.endDomUpdates();
},
get height()
{
if (!this._expandedLineRows)
return this._textEditor._totalHeight(this.element);
return this._textEditor._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},
get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},
_createRow: function(lineNumber)
{
var lineRow = this._textEditor._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-number";
lineRow.textContent = lineNumber + 1;
return lineRow;
}
}
WebInspector.TextEditorMainPanel = function(delegate, textModel, url, syncScrollListener, syncDecorationsForLineListener, enterTextChangeMode, exitTextChangeMode)
{
WebInspector.TextEditorChunkedPanel.call(this, textModel);
this._delegate = delegate;
this._syncScrollListener = syncScrollListener;
this._syncDecorationsForLineListener = syncDecorationsForLineListener;
this._enterTextChangeMode = enterTextChangeMode;
this._exitTextChangeMode = exitTextChangeMode;
this._url = url;
this._highlighter = new WebInspector.TextEditorHighlighter(textModel, this._highlightDataReady.bind(this));
this._readOnly = true;
this.element = document.createElement("div");
this.element.className = "text-editor-contents";
this.element.tabIndex = 0;
this._container = document.createElement("div");
this._container.className = "inner-container";
this._container.tabIndex = 0;
this.element.appendChild(this._container);
this.element.addEventListener("scroll", this._scroll.bind(this), false);
this.element.addEventListener("focus", this._handleElementFocus.bind(this), false);
this._handleDOMUpdatesCallback = this._handleDOMUpdates.bind(this);
this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
this._freeCachedElements();
this._buildChunks();
}
WebInspector.TextEditorMainPanel.prototype = {
set mimeType(mimeType)
{
this._highlighter.mimeType = mimeType;
},
setReadOnly: function(readOnly, requestFocus)
{
if (this._readOnly === readOnly)
return;
this.beginDomUpdates();
this._readOnly = readOnly;
if (this._readOnly)
this._container.removeStyleClass("text-editor-editable");
else {
this._container.addStyleClass("text-editor-editable");
if (requestFocus)
this._updateSelectionOnStartEditing();
}
this.endDomUpdates();
},
readOnly: function()
{
return this._readOnly;
},
_handleElementFocus: function()
{
if (!this._readOnly)
this._container.focus();
},
defaultFocusedElement: function()
{
if (this._readOnly)
return this.element;
return this._container;
},
_updateSelectionOnStartEditing: function()
{
this._container.focus();
var selection = window.getSelection();
if (selection.rangeCount) {
var commonAncestorContainer = selection.getRangeAt(0).commonAncestorContainer;
if (this._container.isSelfOrAncestor(commonAncestorContainer))
return;
}
selection.removeAllRanges();
var range = document.createRange();
range.setStart(this._container, 0);
range.setEnd(this._container, 0);
selection.addRange(range);
},
setEditableRange: function(startLine, endLine)
{
this.beginDomUpdates();
var firstChunkNumber = this._chunkNumberForLine(startLine);
var firstChunk = this._textChunks[firstChunkNumber];
if (firstChunk.startLine !== startLine) {
this._splitChunkOnALine(startLine, firstChunkNumber);
firstChunkNumber += 1;
}
var lastChunkNumber = this._textChunks.length;
if (endLine !== this._textModel.linesCount) {
lastChunkNumber = this._chunkNumberForLine(endLine);
var lastChunk = this._textChunks[lastChunkNumber];
if (lastChunk && lastChunk.startLine !== endLine) {
this._splitChunkOnALine(endLine, lastChunkNumber);
lastChunkNumber += 1;
}
}
for (var chunkNumber = 0; chunkNumber < firstChunkNumber; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = true;
for (var chunkNumber = firstChunkNumber; chunkNumber < lastChunkNumber; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = false;
for (var chunkNumber = lastChunkNumber; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = true;
this.endDomUpdates();
},
clearEditableRange: function()
{
for (var chunkNumber = 0; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].readOnly = false;
},
markAndRevealRange: function(range)
{
if (this._rangeToMark) {
var markedLine = this._rangeToMark.startLine;
delete this._rangeToMark;
if (!this._dirtyLines) {
this.beginDomUpdates();
var chunk = this.chunkForLine(markedLine);
var wasExpanded = chunk.expanded;
chunk.expanded = false;
chunk.updateCollapsedLineRow();
chunk.expanded = wasExpanded;
this.endDomUpdates();
} else
this._paintLines(markedLine, markedLine + 1);
}
if (range) {
this._rangeToMark = range;
this.revealLine(range.startLine);
var chunk = this.makeLineAChunk(range.startLine);
this._paintLine(chunk.element);
if (this._markedRangeElement)
this._markedRangeElement.scrollIntoViewIfNeeded();
}
delete this._markedRangeElement;
},
highlightLine: function(lineNumber)
{
this.clearLineHighlight();
this._highlightedLine = lineNumber;
this.revealLine(lineNumber);
if (!this._readOnly)
this._restoreSelection(WebInspector.TextRange.createFromLocation(lineNumber, 0), false);
this.addDecoration(lineNumber, "webkit-highlighted-line");
},
clearLineHighlight: function()
{
if (typeof this._highlightedLine === "number") {
this.removeDecoration(this._highlightedLine, "webkit-highlighted-line");
delete this._highlightedLine;
}
},
_freeCachedElements: function()
{
this._cachedSpans = [];
this._cachedTextNodes = [];
this._cachedRows = [];
},
handleUndoRedo: function(redo)
{
if (this._dirtyLines)
return false;
this.beginUpdates();
function before()
{
this._enterTextChangeMode();
}
function after(oldRange, newRange)
{
this._exitTextChangeMode(oldRange, newRange);
}
var range = redo ? this._textModel.redo(before.bind(this), after.bind(this)) : this._textModel.undo(before.bind(this), after.bind(this));
this.endUpdates();
if (range)
this._restoreSelection(range, true);
return true;
},
handleTabKeyPress: function(shiftKey)
{
if (this._dirtyLines)
return false;
var selection = this._getSelection();
if (!selection)
return false;
var range = selection.normalize();
this.beginUpdates();
this._enterTextChangeMode();
var newRange;
var rangeWasEmpty = range.isEmpty();
if (shiftKey)
newRange = this._unindentLines(range);
else {
if (rangeWasEmpty)
newRange = this._editRange(range, WebInspector.settings.textEditorIndent.get());
else
newRange = this._indentLines(range);
}
this._exitTextChangeMode(range, newRange);
this.endUpdates();
if (rangeWasEmpty)
newRange.startColumn = newRange.endColumn;
this._restoreSelection(newRange, true);
return true;
},
_indentLines: function(range)
{
var indent = WebInspector.settings.textEditorIndent.get();
if (this._lastEditedRange)
this._textModel.markUndoableState();
var newRange = range.clone();
if (range.startColumn)
newRange.startColumn += indent.length;
var indentEndLine = range.endLine;
if (range.endColumn)
newRange.endColumn += indent.length;
else
indentEndLine--;
for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++)
this._textModel.editRange(WebInspector.TextRange.createFromLocation(lineNumber, 0), indent);
this._lastEditedRange = newRange;
return newRange;
},
_unindentLines: function(range)
{
if (this._lastEditedRange)
this._textModel.markUndoableState();
var indent = WebInspector.settings.textEditorIndent.get();
var indentLength = indent === WebInspector.TextEditorModel.Indent.TabCharacter ? 4 : indent.length;
var lineIndentRegex = new RegExp("^ {1," + indentLength + "}");
var newRange = range.clone();
var indentEndLine = range.endLine;
if (!range.endColumn)
indentEndLine--;
for (var lineNumber = range.startLine; lineNumber <= indentEndLine; lineNumber++) {
var line = this._textModel.line(lineNumber);
var firstCharacter = line.charAt(0);
var lineIndentLength;
if (firstCharacter === " ")
lineIndentLength = line.match(lineIndentRegex)[0].length;
else if (firstCharacter === "\t")
lineIndentLength = 1;
else
continue;
this._textModel.editRange(new WebInspector.TextRange(lineNumber, 0, lineNumber, lineIndentLength), "");
if (lineNumber === range.startLine)
newRange.startColumn = Math.max(0, newRange.startColumn - lineIndentLength);
}
if (lineIndentLength)
newRange.endColumn = Math.max(0, newRange.endColumn - lineIndentLength);
this._lastEditedRange = newRange;
return newRange;
},
handleEnterKey: function()
{
if (this._dirtyLines)
return false;
var range = this._getSelection();
if (!range)
return false;
range = range.normalize();
if (range.endColumn === 0)
return false;
var line = this._textModel.line(range.startLine);
var linePrefix = line.substring(0, range.startColumn);
var indentMatch = linePrefix.match(/^\s+/);
var currentIndent = indentMatch ? indentMatch[0] : "";
var textEditorIndent = WebInspector.settings.textEditorIndent.get();
var indent = WebInspector.TextEditorModel.endsWithBracketRegex.test(linePrefix) ? currentIndent + textEditorIndent : currentIndent;
if (!indent)
return false;
this.beginUpdates();
this._enterTextChangeMode();
var lineBreak = this._textModel.lineBreak;
var newRange;
if (range.isEmpty() && line.substr(range.endColumn - 1, 2) === '{}') {
newRange = this._editRange(range, lineBreak + indent + lineBreak + currentIndent);
newRange.endLine--;
newRange.endColumn += textEditorIndent.length;
} else
newRange = this._editRange(range, lineBreak + indent);
this._exitTextChangeMode(range, newRange);
this.endUpdates();
this._restoreSelection(newRange.collapseToEnd(), true);
return true;
},
_splitChunkOnALine: function(lineNumber, chunkNumber, createSuffixChunk)
{
var selection = this._getSelection();
var chunk = WebInspector.TextEditorChunkedPanel.prototype._splitChunkOnALine.call(this, lineNumber, chunkNumber, createSuffixChunk);
this._restoreSelection(selection);
return chunk;
},
beginDomUpdates: function()
{
WebInspector.TextEditorChunkedPanel.prototype.beginDomUpdates.call(this);
if (this._domUpdateCoalescingLevel === 1) {
this._container.removeEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.removeEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.removeEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
}
},
endDomUpdates: function()
{
WebInspector.TextEditorChunkedPanel.prototype.endDomUpdates.call(this);
if (this._domUpdateCoalescingLevel === 0) {
this._container.addEventListener("DOMCharacterDataModified", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMNodeInserted", this._handleDOMUpdatesCallback, false);
this._container.addEventListener("DOMSubtreeModified", this._handleDOMUpdatesCallback, false);
}
},
_buildChunks: function()
{
for (var i = 0; i < this._textModel.linesCount; ++i)
this._textModel.removeAttribute(i, "highlight");
WebInspector.TextEditorChunkedPanel.prototype._buildChunks.call(this);
},
_createNewChunk: function(startLine, endLine)
{
return new WebInspector.TextEditorMainChunk(this, startLine, endLine);
},
_expandChunks: function(fromIndex, toIndex)
{
var lastChunk = this._textChunks[toIndex - 1];
var lastVisibleLine = lastChunk.startLine + lastChunk.linesCount;
var selection = this._getSelection();
this._muteHighlightListener = true;
this._highlighter.highlight(lastVisibleLine);
delete this._muteHighlightListener;
this._restorePaintLinesOperationsCredit();
WebInspector.TextEditorChunkedPanel.prototype._expandChunks.call(this, fromIndex, toIndex);
this._adjustPaintLinesOperationsRefreshValue();
this._restoreSelection(selection);
},
_highlightDataReady: function(fromLine, toLine)
{
if (this._muteHighlightListener)
return;
this._restorePaintLinesOperationsCredit();
this._paintLines(fromLine, toLine, true );
},
_schedulePaintLines: function(startLine, endLine)
{
if (startLine >= endLine)
return;
if (!this._scheduledPaintLines) {
this._scheduledPaintLines = [ { startLine: startLine, endLine: endLine } ];
this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 0);
} else {
for (var i = 0; i < this._scheduledPaintLines.length; ++i) {
var chunk = this._scheduledPaintLines[i];
if (chunk.startLine <= endLine && chunk.endLine >= startLine) {
chunk.startLine = Math.min(chunk.startLine, startLine);
chunk.endLine = Math.max(chunk.endLine, endLine);
return;
}
if (chunk.startLine > endLine) {
this._scheduledPaintLines.splice(i, 0, { startLine: startLine, endLine: endLine });
return;
}
}
this._scheduledPaintLines.push({ startLine: startLine, endLine: endLine });
}
},
_paintScheduledLines: function(skipRestoreSelection)
{
if (this._paintScheduledLinesTimer)
clearTimeout(this._paintScheduledLinesTimer);
delete this._paintScheduledLinesTimer;
if (!this._scheduledPaintLines)
return;
if (this._dirtyLines || this._repaintAllTimer) {
this._paintScheduledLinesTimer = setTimeout(this._paintScheduledLines.bind(this), 50);
return;
}
var scheduledPaintLines = this._scheduledPaintLines;
delete this._scheduledPaintLines;
this._restorePaintLinesOperationsCredit();
this._paintLineChunks(scheduledPaintLines, !skipRestoreSelection);
this._adjustPaintLinesOperationsRefreshValue();
},
_restorePaintLinesOperationsCredit: function()
{
if (!this._paintLinesOperationsRefreshValue)
this._paintLinesOperationsRefreshValue = 250;
this._paintLinesOperationsCredit = this._paintLinesOperationsRefreshValue;
this._paintLinesOperationsLastRefresh = Date.now();
},
_adjustPaintLinesOperationsRefreshValue: function()
{
var operationsDone = this._paintLinesOperationsRefreshValue - this._paintLinesOperationsCredit;
if (operationsDone <= 0)
return;
var timePast = Date.now() - this._paintLinesOperationsLastRefresh;
if (timePast <= 0)
return;
var value = Math.floor(operationsDone / timePast * 50);
this._paintLinesOperationsRefreshValue = Number.constrain(value, 150, 1500);
},
_paintLines: function(fromLine, toLine, restoreSelection)
{
this._paintLineChunks([ { startLine: fromLine, endLine: toLine } ], restoreSelection);
},
_paintLineChunks: function(lineChunks, restoreSelection)
{
var visibleFrom = this.element.scrollTop;
var firstVisibleLineNumber = this._findFirstVisibleLineNumber(visibleFrom);
var chunk;
var selection;
var invisibleLineRows = [];
for (var i = 0; i < lineChunks.length; ++i) {
var lineChunk = lineChunks[i];
if (this._dirtyLines || this._scheduledPaintLines) {
this._schedulePaintLines(lineChunk.startLine, lineChunk.endLine);
continue;
}
for (var lineNumber = lineChunk.startLine; lineNumber < lineChunk.endLine; ++lineNumber) {
if (!chunk || lineNumber < chunk.startLine || lineNumber >= chunk.startLine + chunk.linesCount)
chunk = this.chunkForLine(lineNumber);
var lineRow = chunk.getExpandedLineRow(lineNumber);
if (!lineRow)
continue;
if (lineNumber < firstVisibleLineNumber) {
invisibleLineRows.push(lineRow);
continue;
}
if (restoreSelection && !selection)
selection = this._getSelection();
this._paintLine(lineRow);
if (this._paintLinesOperationsCredit < 0) {
this._schedulePaintLines(lineNumber + 1, lineChunk.endLine);
break;
}
}
}
for (var i = 0; i < invisibleLineRows.length; ++i) {
if (restoreSelection && !selection)
selection = this._getSelection();
this._paintLine(invisibleLineRows[i]);
}
if (restoreSelection)
this._restoreSelection(selection);
},
_paintLine: function(lineRow)
{
var lineNumber = lineRow.lineNumber;
if (this._dirtyLines) {
this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}
this.beginDomUpdates();
try {
if (this._scheduledPaintLines || this._paintLinesOperationsCredit < 0) {
this._schedulePaintLines(lineNumber, lineNumber + 1);
return;
}
var highlight = this._textModel.getAttribute(lineNumber, "highlight");
if (!highlight)
return;
lineRow.removeChildren();
var line = this._textModel.line(lineNumber);
if (!line)
lineRow.appendChild(document.createElement("br"));
var plainTextStart = -1;
for (var j = 0; j < line.length;) {
if (j > 1000) {
if (plainTextStart === -1)
plainTextStart = j;
break;
}
var attribute = highlight[j];
if (!attribute || !attribute.tokenType) {
if (plainTextStart === -1)
plainTextStart = j;
j++;
} else {
if (plainTextStart !== -1) {
this._appendTextNode(lineRow, line.substring(plainTextStart, j));
plainTextStart = -1;
--this._paintLinesOperationsCredit;
}
this._appendSpan(lineRow, line.substring(j, j + attribute.length), attribute.tokenType);
j += attribute.length;
--this._paintLinesOperationsCredit;
}
}
if (plainTextStart !== -1) {
this._appendTextNode(lineRow, line.substring(plainTextStart, line.length));
--this._paintLinesOperationsCredit;
}
if (lineRow.decorationsElement)
lineRow.appendChild(lineRow.decorationsElement);
} finally {
if (this._rangeToMark && this._rangeToMark.startLine === lineNumber)
this._markedRangeElement = WebInspector.highlightSearchResult(lineRow, this._rangeToMark.startColumn, this._rangeToMark.endColumn - this._rangeToMark.startColumn);
this.endDomUpdates();
}
},
_releaseLinesHighlight: function(lineRow)
{
if (!lineRow)
return;
if ("spans" in lineRow) {
var spans = lineRow.spans;
for (var j = 0; j < spans.length; ++j)
this._cachedSpans.push(spans[j]);
delete lineRow.spans;
}
if ("textNodes" in lineRow) {
var textNodes = lineRow.textNodes;
for (var j = 0; j < textNodes.length; ++j)
this._cachedTextNodes.push(textNodes[j]);
delete lineRow.textNodes;
}
this._cachedRows.push(lineRow);
},
_getSelection: function()
{
var selection = window.getSelection();
if (!selection.rangeCount)
return null;
if (!this._container.isAncestor(selection.anchorNode) || !this._container.isAncestor(selection.focusNode))
return null;
var start = this._selectionToPosition(selection.anchorNode, selection.anchorOffset);
var end = selection.isCollapsed ? start : this._selectionToPosition(selection.focusNode, selection.focusOffset);
return new WebInspector.TextRange(start.line, start.column, end.line, end.column);
},
_restoreSelection: function(range, scrollIntoView)
{
if (!range)
return;
var start = this._positionToSelection(range.startLine, range.startColumn);
var end = range.isEmpty() ? start : this._positionToSelection(range.endLine, range.endColumn);
window.getSelection().setBaseAndExtent(start.container, start.offset, end.container, end.offset);
if (scrollIntoView) {
for (var node = end.container; node; node = node.parentElement) {
if (node.scrollIntoViewIfNeeded) {
node.scrollIntoViewIfNeeded();
break;
}
}
}
},
_selectionToPosition: function(container, offset)
{
if (container === this._container && offset === 0)
return { line: 0, column: 0 };
if (container === this._container && offset === 1)
return { line: this._textModel.linesCount - 1, column: this._textModel.lineLength(this._textModel.linesCount - 1) };
var lineRow = this._enclosingLineRowOrSelf(container);
var lineNumber = lineRow.lineNumber;
if (container === lineRow && offset === 0)
return { line: lineNumber, column: 0 };
var column = 0;
var node = lineRow.nodeType === Node.TEXT_NODE ? lineRow : lineRow.traverseNextTextNode(lineRow);
while (node && node !== container) {
var text = node.textContent;
for (var i = 0; i < text.length; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
node = node.traverseNextTextNode(lineRow);
}
if (node === container && offset) {
var text = node.textContent;
for (var i = 0; i < offset; ++i) {
if (text.charAt(i) === "\n") {
lineNumber++;
column = 0;
} else
column++;
}
}
return { line: lineNumber, column: column };
},
_positionToSelection: function(line, column)
{
var chunk = this.chunkForLine(line);
var lineRow = chunk.linesCount === 1 ? chunk.element : chunk.getExpandedLineRow(line);
if (lineRow)
var rangeBoundary = lineRow.rangeBoundaryForOffset(column);
else {
var offset = column;
for (var i = chunk.startLine; i < line; ++i)
offset += this._textModel.lineLength(i) + 1;
lineRow = chunk.element;
if (lineRow.firstChild)
var rangeBoundary = { container: lineRow.firstChild, offset: offset };
else
var rangeBoundary = { container: lineRow, offset: 0 };
}
return rangeBoundary;
},
_enclosingLineRowOrSelf: function(element)
{
var lineRow = element.enclosingNodeOrSelfWithClass("webkit-line-content");
if (lineRow)
return lineRow;
for (lineRow = element; lineRow; lineRow = lineRow.parentElement) {
if (lineRow.parentElement === this._container)
return lineRow;
}
return null;
},
_appendSpan: function(element, content, className)
{
if (className === "html-resource-link" || className === "html-external-link") {
element.appendChild(this._createLink(content, className === "html-external-link"));
return;
}
var span = this._cachedSpans.pop() || document.createElement("span");
span.className = "webkit-" + className;
span.textContent = content;
element.appendChild(span);
if (!("spans" in element))
element.spans = [];
element.spans.push(span);
},
_appendTextNode: function(element, text)
{
var textNode = this._cachedTextNodes.pop();
if (textNode)
textNode.nodeValue = text;
else
textNode = document.createTextNode(text);
element.appendChild(textNode);
if (!("textNodes" in element))
element.textNodes = [];
element.textNodes.push(textNode);
},
_createLink: function(content, isExternal)
{
var quote = content.charAt(0);
if (content.length > 1 && (quote === "\"" || quote === "'"))
content = content.substring(1, content.length - 1);
else
quote = null;
var span = document.createElement("span");
span.className = "webkit-html-attribute-value";
if (quote)
span.appendChild(document.createTextNode(quote));
span.appendChild(this._delegate.createLink(content, isExternal));
if (quote)
span.appendChild(document.createTextNode(quote));
return span;
},
_handleDOMUpdates: function(e)
{
if (this._domUpdateCoalescingLevel)
return;
var target = e.target;
if (target === this._container)
return;
var lineRow = this._enclosingLineRowOrSelf(target);
if (!lineRow)
return;
if (lineRow.decorationsElement && lineRow.decorationsElement.isSelfOrAncestor(target)) {
if (this._syncDecorationsForLineListener)
this._syncDecorationsForLineListener(lineRow.lineNumber);
return;
}
if (this._readOnly)
return;
if (target === lineRow && e.type === "DOMNodeInserted") {
delete lineRow.lineNumber;
}
var startLine = 0;
for (var row = lineRow; row; row = row.previousSibling) {
if (typeof row.lineNumber === "number") {
startLine = row.lineNumber;
break;
}
}
var endLine = startLine + 1;
for (var row = lineRow.nextSibling; row; row = row.nextSibling) {
if (typeof row.lineNumber === "number" && row.lineNumber > startLine) {
endLine = row.lineNumber;
break;
}
}
if (this._dirtyLines) {
this._dirtyLines.start = Math.min(this._dirtyLines.start, startLine);
this._dirtyLines.end = Math.max(this._dirtyLines.end, endLine);
} else {
this._dirtyLines = { start: startLine, end: endLine };
setTimeout(this._applyDomUpdates.bind(this), 0);
this.markAndRevealRange(null);
}
},
_applyDomUpdates: function()
{
if (!this._dirtyLines)
return;
if (this._readOnly) {
delete this._dirtyLines;
return;
}
var dirtyLines = this._dirtyLines;
var firstChunkNumber = this._chunkNumberForLine(dirtyLines.start);
var startLine = this._textChunks[firstChunkNumber].startLine;
var endLine = this._textModel.linesCount;
var firstLineRow;
if (firstChunkNumber) {
var chunk = this._textChunks[firstChunkNumber - 1];
firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
firstLineRow = firstLineRow.nextSibling;
} else
firstLineRow = this._container.firstChild;
var lines = [];
for (var lineRow = firstLineRow; lineRow; lineRow = lineRow.nextSibling) {
if (typeof lineRow.lineNumber === "number" && lineRow.lineNumber >= dirtyLines.end) {
endLine = lineRow.lineNumber;
break;
}
lineRow.lineNumber = startLine + lines.length;
this._collectLinesFromDiv(lines, lineRow);
}
var startOffset = 0;
while (startLine < dirtyLines.start && startOffset < lines.length) {
if (this._textModel.line(startLine) !== lines[startOffset])
break;
++startOffset;
++startLine;
}
var endOffset = lines.length;
while (endLine > dirtyLines.end && endOffset > startOffset) {
if (this._textModel.line(endLine - 1) !== lines[endOffset - 1])
break;
--endOffset;
--endLine;
}
lines = lines.slice(startOffset, endOffset);
var startColumn = 0;
var endColumn = this._textModel.lineLength(endLine - 1);
if (lines.length > 0) {
var line1 = this._textModel.line(startLine);
var line2 = lines[0];
while (line1[startColumn] && line1[startColumn] === line2[startColumn])
++startColumn;
lines[0] = line2.substring(startColumn);
line1 = this._textModel.line(endLine - 1);
line2 = lines[lines.length - 1];
for (var i = 0; i < endColumn && i < line2.length; ++i) {
if (startLine === endLine - 1 && endColumn - i <= startColumn)
break;
if (line1[endColumn - i - 1] !== line2[line2.length - i - 1])
break;
}
if (i) {
endColumn -= i;
lines[lines.length - 1] = line2.substring(0, line2.length - i);
}
}
var selection = this._getSelection();
if (lines.length === 0 && endLine < this._textModel.linesCount)
var oldRange = new WebInspector.TextRange(startLine, 0, endLine, 0);
else if (lines.length === 0 && startLine > 0)
var oldRange = new WebInspector.TextRange(startLine - 1, this._textModel.lineLength(startLine - 1), endLine - 1, this._textModel.lineLength(endLine - 1));
else
var oldRange = new WebInspector.TextRange(startLine, startColumn, endLine - 1, endColumn);
var newContent = lines.join("\n");
if (this._textModel.copyRange(oldRange) === newContent) {
delete this._dirtyLines;
return;
}
if (lines.length === 1 && lines[0] === "}" && oldRange.isEmpty() && selection.isEmpty() && !this._textModel.line(oldRange.endLine).trim())
this._unindentAfterBlock(oldRange, selection);
this._enterTextChangeMode();
delete this._dirtyLines;
var newRange = this._editRange(oldRange, newContent);
this._paintScheduledLines(true);
this._restoreSelection(selection);
this._exitTextChangeMode(oldRange, newRange);
},
_unindentAfterBlock: function(oldRange, selection)
{
var nestingLevel = 1;
for (var i = oldRange.endLine; i >= 0; --i) {
var attribute = this._textModel.getAttribute(i, "highlight");
if (!attribute)
continue;
var columnNumbers = Object.keys(attribute).reverse();
for (var j = 0; j < columnNumbers.length; ++j) {
var column = columnNumbers[j];
if (attribute[column].tokenType === "block-start") {
if (!(--nestingLevel)) {
var lineContent = this._textModel.line(i);
var blockOffset = lineContent.length - lineContent.trimLeft().length;
if (blockOffset < oldRange.startColumn) {
oldRange.startColumn = blockOffset;
selection.startColumn = blockOffset + 1;
selection.endColumn = blockOffset + 1;
}
return;
}
}
if (attribute[column].tokenType === "block-end")
++nestingLevel;
}
}
},
textChanged: function(oldRange, newRange)
{
this.beginDomUpdates();
this._removeDecorationsInRange(oldRange);
this._updateChunksForRanges(oldRange, newRange);
this._updateHighlightsForRange(newRange);
this.endDomUpdates();
},
_editRange: function(range, text)
{
if (this._lastEditedRange && (!text || text.indexOf("\n") !== -1 || this._lastEditedRange.endLine !== range.startLine || this._lastEditedRange.endColumn !== range.startColumn))
this._textModel.markUndoableState();
var newRange = this._textModel.editRange(range, text);
this._lastEditedRange = newRange;
return newRange;
},
_removeDecorationsInRange: function(range)
{
for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i) {
var chunk = this._textChunks[i];
if (chunk.startLine > range.endLine)
break;
chunk.removeAllDecorations();
}
},
_updateChunksForRanges: function(oldRange, newRange)
{
var firstChunkNumber = this._chunkNumberForLine(oldRange.startLine);
var lastChunkNumber = firstChunkNumber;
while (lastChunkNumber + 1 < this._textChunks.length) {
if (this._textChunks[lastChunkNumber + 1].startLine > oldRange.endLine)
break;
++lastChunkNumber;
}
var startLine = this._textChunks[firstChunkNumber].startLine;
var linesCount = this._textChunks[lastChunkNumber].startLine + this._textChunks[lastChunkNumber].linesCount - startLine;
var linesDiff = newRange.linesCount - oldRange.linesCount;
linesCount += linesDiff;
if (linesDiff) {
for (var chunkNumber = lastChunkNumber + 1; chunkNumber < this._textChunks.length; ++chunkNumber)
this._textChunks[chunkNumber].startLine += linesDiff;
}
var firstLineRow;
if (firstChunkNumber) {
var chunk = this._textChunks[firstChunkNumber - 1];
firstLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine + chunk.linesCount - 1) : chunk.element;
firstLineRow = firstLineRow.nextSibling;
} else
firstLineRow = this._container.firstChild;
for (var chunkNumber = firstChunkNumber; chunkNumber <= lastChunkNumber; ++chunkNumber) {
var chunk = this._textChunks[chunkNumber];
if (chunk.startLine + chunk.linesCount > this._textModel.linesCount)
break;
var lineNumber = chunk.startLine;
for (var lineRow = firstLineRow; lineRow && lineNumber < chunk.startLine + chunk.linesCount; lineRow = lineRow.nextSibling) {
if (lineRow.lineNumber !== lineNumber || lineRow !== chunk.getExpandedLineRow(lineNumber) || lineRow.textContent !== this._textModel.line(lineNumber) || !lineRow.firstChild)
break;
++lineNumber;
}
if (lineNumber < chunk.startLine + chunk.linesCount)
break;
chunk.updateCollapsedLineRow();
++firstChunkNumber;
firstLineRow = lineRow;
startLine += chunk.linesCount;
linesCount -= chunk.linesCount;
}
if (firstChunkNumber > lastChunkNumber && linesCount === 0)
return;
var chunk = this._textChunks[lastChunkNumber + 1];
var linesInLastChunk = linesCount % this._defaultChunkSize;
if (chunk && !chunk.decorated && linesInLastChunk > 0 && linesInLastChunk + chunk.linesCount <= this._defaultChunkSize) {
++lastChunkNumber;
linesCount += chunk.linesCount;
}
var scrollTop = this.element.scrollTop;
var scrollLeft = this.element.scrollLeft;
var firstUnmodifiedLineRow = null;
chunk = this._textChunks[lastChunkNumber + 1];
if (chunk)
firstUnmodifiedLineRow = chunk.expanded ? chunk.getExpandedLineRow(chunk.startLine) : chunk.element;
while (firstLineRow && firstLineRow !== firstUnmodifiedLineRow) {
var lineRow = firstLineRow;
firstLineRow = firstLineRow.nextSibling;
this._container.removeChild(lineRow);
}
for (var chunkNumber = firstChunkNumber; linesCount > 0; ++chunkNumber) {
var chunkLinesCount = Math.min(this._defaultChunkSize, linesCount);
var newChunk = this._createNewChunk(startLine, startLine + chunkLinesCount);
this._container.insertBefore(newChunk.element, firstUnmodifiedLineRow);
if (chunkNumber <= lastChunkNumber)
this._textChunks[chunkNumber] = newChunk;
else
this._textChunks.splice(chunkNumber, 0, newChunk);
startLine += chunkLinesCount;
linesCount -= chunkLinesCount;
}
if (chunkNumber <= lastChunkNumber)
this._textChunks.splice(chunkNumber, lastChunkNumber - chunkNumber + 1);
this.element.scrollTop = scrollTop;
this.element.scrollLeft = scrollLeft;
},
_updateHighlightsForRange: function(range)
{
var visibleFrom = this.element.scrollTop;
var visibleTo = this.element.scrollTop + this.element.clientHeight;
var result = this._findVisibleChunks(visibleFrom, visibleTo);
var chunk = this._textChunks[result.end - 1];
var lastVisibleLine = chunk.startLine + chunk.linesCount;
lastVisibleLine = Math.max(lastVisibleLine, range.endLine + 1);
lastVisibleLine = Math.min(lastVisibleLine, this._textModel.linesCount);
var updated = this._highlighter.updateHighlight(range.startLine, lastVisibleLine);
if (!updated) {
for (var i = this._chunkNumberForLine(range.startLine); i < this._textChunks.length; ++i)
this._textChunks[i].expanded = false;
}
this._repaintAll();
},
_collectLinesFromDiv: function(lines, element)
{
var textContents = [];
var node = element.nodeType === Node.TEXT_NODE ? element : element.traverseNextNode(element);
while (node) {
if (element.decorationsElement === node) {
node = node.nextSibling;
continue;
}
if (node.nodeName.toLowerCase() === "br")
textContents.push("\n");
else if (node.nodeType === Node.TEXT_NODE)
textContents.push(node.textContent);
node = node.traverseNextNode(element);
}
var textContent = textContents.join("");
textContent = textContent.replace(/\n$/, "");
textContents = textContent.split("\n");
for (var i = 0; i < textContents.length; ++i)
lines.push(textContents[i]);
}
}
WebInspector.TextEditorMainPanel.prototype.__proto__ = WebInspector.TextEditorChunkedPanel.prototype;
WebInspector.TextEditorMainChunk = function(chunkedPanel, startLine, endLine)
{
this._chunkedPanel = chunkedPanel;
this._textModel = chunkedPanel._textModel;
this.element = document.createElement("div");
this.element.lineNumber = startLine;
this.element.className = "webkit-line-content";
this._startLine = startLine;
endLine = Math.min(this._textModel.linesCount, endLine);
this.linesCount = endLine - startLine;
this._expanded = false;
this._readOnly = false;
this.updateCollapsedLineRow();
}
WebInspector.TextEditorMainChunk.prototype = {
addDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.addStyleClass(decoration);
else {
if (!this.element.decorationsElement) {
this.element.decorationsElement = document.createElement("div");
this.element.decorationsElement.className = "webkit-line-decorations";
this.element.appendChild(this.element.decorationsElement);
}
this.element.decorationsElement.appendChild(decoration);
}
this._chunkedPanel.endDomUpdates();
},
removeDecoration: function(decoration)
{
this._chunkedPanel.beginDomUpdates();
if (typeof decoration === "string")
this.element.removeStyleClass(decoration);
else if (this.element.decorationsElement)
this.element.decorationsElement.removeChild(decoration);
this._chunkedPanel.endDomUpdates();
},
removeAllDecorations: function()
{
this._chunkedPanel.beginDomUpdates();
this.element.className = "webkit-line-content";
if (this.element.decorationsElement) {
this.element.removeChild(this.element.decorationsElement);
delete this.element.decorationsElement;
}
this._chunkedPanel.endDomUpdates();
},
get decorated()
{
return this.element.className !== "webkit-line-content" || !!(this.element.decorationsElement && this.element.decorationsElement.firstChild);
},
get startLine()
{
return this._startLine;
},
set startLine(startLine)
{
this._startLine = startLine;
this.element.lineNumber = startLine;
if (this._expandedLineRows) {
for (var i = 0; i < this._expandedLineRows.length; ++i)
this._expandedLineRows[i].lineNumber = startLine + i;
}
},
get expanded()
{
return this._expanded;
},
set expanded(expanded)
{
if (this._expanded === expanded)
return;
this._expanded = expanded;
if (this.linesCount === 1) {
if (expanded)
this._chunkedPanel._paintLine(this.element);
return;
}
this._chunkedPanel.beginDomUpdates();
if (expanded) {
this._expandedLineRows = [];
var parentElement = this.element.parentElement;
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i) {
var lineRow = this._createRow(i);
this._updateElementReadOnlyState(lineRow);
parentElement.insertBefore(lineRow, this.element);
this._expandedLineRows.push(lineRow);
}
parentElement.removeChild(this.element);
this._chunkedPanel._paintLines(this.startLine, this.startLine + this.linesCount);
} else {
var elementInserted = false;
for (var i = 0; i < this._expandedLineRows.length; ++i) {
var lineRow = this._expandedLineRows[i];
var parentElement = lineRow.parentElement;
if (parentElement) {
if (!elementInserted) {
elementInserted = true;
parentElement.insertBefore(this.element, lineRow);
}
parentElement.removeChild(lineRow);
}
this._chunkedPanel._releaseLinesHighlight(lineRow);
}
delete this._expandedLineRows;
}
this._chunkedPanel.endDomUpdates();
},
set readOnly(readOnly)
{
if (this._readOnly === readOnly)
return;
this._readOnly = readOnly;
this._updateElementReadOnlyState(this.element);
if (this._expandedLineRows) {
for (var i = 0; i < this._expandedLineRows.length; ++i)
this._updateElementReadOnlyState(this._expandedLineRows[i]);
}
},
get readOnly()
{
return this._readOnly;
},
_updateElementReadOnlyState: function(element)
{
if (this._readOnly)
element.addStyleClass("text-editor-read-only");
else
element.removeStyleClass("text-editor-read-only");
},
get height()
{
if (!this._expandedLineRows)
return this._chunkedPanel._totalHeight(this.element);
return this._chunkedPanel._totalHeight(this._expandedLineRows[0], this._expandedLineRows[this._expandedLineRows.length - 1]);
},
get offsetTop()
{
return (this._expandedLineRows && this._expandedLineRows.length) ? this._expandedLineRows[0].offsetTop : this.element.offsetTop;
},
_createRow: function(lineNumber)
{
var lineRow = this._chunkedPanel._cachedRows.pop() || document.createElement("div");
lineRow.lineNumber = lineNumber;
lineRow.className = "webkit-line-content";
lineRow.textContent = this._textModel.line(lineNumber);
if (!lineRow.textContent)
lineRow.appendChild(document.createElement("br"));
return lineRow;
},
getExpandedLineRow: function(lineNumber)
{
if (!this._expanded || lineNumber < this.startLine || lineNumber >= this.startLine + this.linesCount)
return null;
if (!this._expandedLineRows)
return this.element;
return this._expandedLineRows[lineNumber - this.startLine];
},
updateCollapsedLineRow: function()
{
if (this.linesCount === 1 && this._expanded)
return;
var lines = [];
for (var i = this.startLine; i < this.startLine + this.linesCount; ++i)
lines.push(this._textModel.line(i));
this.element.removeChildren();
this.element.textContent = lines.join("\n");
if (!lines[lines.length - 1])
this.element.appendChild(document.createElement("br"));
}
}
WebInspector.SourceFrame = function(contentProvider)
{
WebInspector.View.call(this);
this.element.addStyleClass("script-view");
this._url = contentProvider.contentURL();
this._contentProvider = contentProvider;
var textEditorDelegate = new WebInspector.TextEditorDelegateForSourceFrame(this);
if (WebInspector.experimentsSettings.codemirror.isEnabled()) {
importScript("CodeMirrorTextEditor.js");
this._textEditor = new WebInspector.CodeMirrorTextEditor(this._url, textEditorDelegate);
} else
this._textEditor = new WebInspector.DefaultTextEditor(this._url, textEditorDelegate);
this._currentSearchResultIndex = -1;
this._searchResults = [];
this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
this._textEditor.setReadOnly(!this.canEditSource());
this._shortcuts = {};
this._shortcuts[WebInspector.KeyboardShortcut.makeKey("s", WebInspector.KeyboardShortcut.Modifiers.CtrlOrMeta)] = this._commitEditing.bind(this);
this.element.addEventListener("keydown", this._handleKeyDown.bind(this), false);
}
WebInspector.SourceFrame.createSearchRegex = function(query, modifiers)
{
var regex;
modifiers = modifiers || "";
try {
if (/^\/.*\/$/.test(query))
regex = new RegExp(query.substring(1, query.length - 1), modifiers);
} catch (e) {
}
if (!regex)
regex = createPlainTextSearchRegex(query, "i" + modifiers);
return regex;
}
WebInspector.SourceFrame.Events = {
ScrollChanged: "ScrollChanged",
SelectionChanged: "SelectionChanged"
}
WebInspector.SourceFrame.prototype = {
wasShown: function()
{
this._ensureContentLoaded();
this._textEditor.show(this.element);
this._wasShownOrLoaded();
},
willHide: function()
{
WebInspector.View.prototype.willHide.call(this);
this._clearLineHighlight();
this._clearLineToReveal();
},
statusBarItems: function()
{
return [];
},
defaultFocusedElement: function()
{
return this._textEditor.defaultFocusedElement();
},
get loaded()
{
return this._loaded;
},
hasContent: function()
{
return true;
},
get textEditor()
{
return this._textEditor;
},
_ensureContentLoaded: function()
{
if (!this._contentRequested) {
this._contentRequested = true;
this._contentProvider.requestContent(this.setContent.bind(this));
}
},
addMessage: function(msg)
{
this._messages.push(msg);
if (this.loaded)
this.addMessageToSource(msg.line - 1, msg);
},
clearMessages: function()
{
for (var line in this._messageBubbles) {
var bubble = this._messageBubbles[line];
bubble.parentNode.removeChild(bubble);
}
this._messages = [];
this._rowMessages = {};
this._messageBubbles = {};
this._textEditor.doResize();
},
canHighlightLine: function(line)
{
return true;
},
highlightLine: function(line)
{
this._clearLineToReveal();
this._clearLineToScrollTo();
this._lineToHighlight = line;
this._innerHighlightLineIfNeeded();
this._textEditor.setSelection(WebInspector.TextRange.createFromLocation(line, 0));
},
_innerHighlightLineIfNeeded: function()
{
if (typeof this._lineToHighlight === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.highlightLine(this._lineToHighlight);
delete this._lineToHighlight
}
}
},
_clearLineHighlight: function()
{
this._textEditor.clearLineHighlight();
delete this._lineToHighlight;
},
revealLine: function(line)
{
this._clearLineHighlight();
this._clearLineToScrollTo();
this._lineToReveal = line;
this._innerRevealLineIfNeeded();
},
_innerRevealLineIfNeeded: function()
{
if (typeof this._lineToReveal === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.revealLine(this._lineToReveal);
delete this._lineToReveal
}
}
},
_clearLineToReveal: function()
{
delete this._lineToReveal;
},
scrollToLine: function(line)
{
this._clearLineHighlight();
this._clearLineToReveal();
this._lineToScrollTo = line;
this._innerScrollToLineIfNeeded();
},
_innerScrollToLineIfNeeded: function()
{
if (typeof this._lineToScrollTo === "number") {
if (this.loaded && this._textEditor.isShowing()) {
this._textEditor.scrollToLine(this._lineToScrollTo);
delete this._lineToScrollTo
}
}
},
_clearLineToScrollTo: function()
{
delete this._lineToScrollTo;
},
setSelection: function(textRange)
{
this._selectionToSet = textRange;
this._innerSetSelectionIfNeeded();
},
_innerSetSelectionIfNeeded: function()
{
if (this._selectionToSet && this.loaded && this._textEditor.isShowing()) {
this._textEditor.setSelection(this._selectionToSet);
delete this._selectionToSet;
}
},
_wasShownOrLoaded: function()
{
this._innerHighlightLineIfNeeded();
this._innerRevealLineIfNeeded();
this._innerScrollToLineIfNeeded();
this._innerSetSelectionIfNeeded();
},
onTextChanged: function(oldRange, newRange)
{
if (!this._isReplacing)
WebInspector.searchController.cancelSearch();
this.clearMessages();
},
setContent: function(content, contentEncoded, mimeType)
{
this._textEditor.mimeType = mimeType;
this._loaded = true;
this._textEditor.setText(content || "");
this._textEditor.beginUpdates();
this._setTextEditorDecorations();
this._wasShownOrLoaded();
if (this._delayedFindSearchMatches) {
this._delayedFindSearchMatches();
delete this._delayedFindSearchMatches;
}
this.onTextEditorContentLoaded();
this._textEditor.endUpdates();
},
onTextEditorContentLoaded: function() {},
_setTextEditorDecorations: function()
{
this._rowMessages = {};
this._messageBubbles = {};
this._textEditor.beginUpdates();
this._addExistingMessagesToSource();
this._textEditor.doResize();
this._textEditor.endUpdates();
},
performSearch: function(query, callback)
{
this.searchCanceled();
function doFindSearchMatches(query)
{
this._currentSearchResultIndex = -1;
this._searchResults = [];
var regex = WebInspector.SourceFrame.createSearchRegex(query);
this._searchResults = this._collectRegexMatches(regex);
var shiftToIndex = 0;
var selection = this._textEditor.lastSelection();
for (var i = 0; selection && i < this._searchResults.length; ++i) {
if (this._searchResults[i].compareTo(selection) >= 0) {
shiftToIndex = i;
break;
}
}
if (shiftToIndex)
this._searchResults = this._searchResults.rotate(shiftToIndex);
callback(this, this._searchResults.length);
}
if (this.loaded)
doFindSearchMatches.call(this, query);
else
this._delayedFindSearchMatches = doFindSearchMatches.bind(this, query);
this._ensureContentLoaded();
},
searchCanceled: function()
{
delete this._delayedFindSearchMatches;
if (!this.loaded)
return;
this._currentSearchResultIndex = -1;
this._searchResults = [];
this._textEditor.markAndRevealRange(null);
},
hasSearchResults: function()
{
return this._searchResults.length > 0;
},
jumpToFirstSearchResult: function()
{
this.jumpToSearchResult(0);
},
jumpToLastSearchResult: function()
{
this.jumpToSearchResult(this._searchResults.length - 1);
},
jumpToNextSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex + 1);
},
jumpToPreviousSearchResult: function()
{
this.jumpToSearchResult(this._currentSearchResultIndex - 1);
},
showingFirstSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === 0;
},
showingLastSearchResult: function()
{
return this._searchResults.length && this._currentSearchResultIndex === (this._searchResults.length - 1);
},
get currentSearchResultIndex()
{
return this._currentSearchResultIndex;
},
jumpToSearchResult: function(index)
{
if (!this.loaded || !this._searchResults.length)
return;
this._currentSearchResultIndex = (index + this._searchResults.length) % this._searchResults.length;
this._textEditor.markAndRevealRange(this._searchResults[this._currentSearchResultIndex]);
},
replaceSearchMatchWith: function(text)
{
var range = this._searchResults[this._currentSearchResultIndex];
if (!range)
return;
this._textEditor.markAndRevealRange(null);
this._isReplacing = true;
var newRange = this._textEditor.editRange(range, text);
delete this._isReplacing;
this._textEditor.setSelection(newRange.collapseToEnd());
},
replaceAllWith: function(query, replacement)
{
this._textEditor.markAndRevealRange(null);
var text = this._textEditor.text();
var range = this._textEditor.range();
text = text.replace(WebInspector.SourceFrame.createSearchRegex(query, "g"), replacement);
this._isReplacing = true;
this._textEditor.editRange(range, text);
delete this._isReplacing;
},
_collectRegexMatches: function(regexObject)
{
var ranges = [];
for (var i = 0; i < this._textEditor.linesCount; ++i) {
var line = this._textEditor.line(i);
var offset = 0;
do {
var match = regexObject.exec(line);
if (match) {
if (match[0].length)
ranges.push(new WebInspector.TextRange(i, offset + match.index, i, offset + match.index + match[0].length));
offset += match.index + 1;
line = line.substring(match.index + 1);
}
} while (match && line);
}
return ranges;
},
_addExistingMessagesToSource: function()
{
var length = this._messages.length;
for (var i = 0; i < length; ++i)
this.addMessageToSource(this._messages[i].line - 1, this._messages[i]);
},
addMessageToSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;
var messageBubbleElement = this._messageBubbles[lineNumber];
if (!messageBubbleElement || messageBubbleElement.nodeType !== Node.ELEMENT_NODE || !messageBubbleElement.hasStyleClass("webkit-html-message-bubble")) {
messageBubbleElement = document.createElement("div");
messageBubbleElement.className = "webkit-html-message-bubble";
this._messageBubbles[lineNumber] = messageBubbleElement;
this._textEditor.addDecoration(lineNumber, messageBubbleElement);
}
var rowMessages = this._rowMessages[lineNumber];
if (!rowMessages) {
rowMessages = [];
this._rowMessages[lineNumber] = rowMessages;
}
for (var i = 0; i < rowMessages.length; ++i) {
if (rowMessages[i].consoleMessage.isEqual(msg)) {
rowMessages[i].repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessages[i]);
return;
}
}
var rowMessage = { consoleMessage: msg };
rowMessages.push(rowMessage);
var imageURL;
switch (msg.level) {
case WebInspector.ConsoleMessage.MessageLevel.Error:
messageBubbleElement.addStyleClass("webkit-html-error-message");
imageURL = "Images/errorIcon.png";
break;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
messageBubbleElement.addStyleClass("webkit-html-warning-message");
imageURL = "Images/warningIcon.png";
break;
}
var messageLineElement = document.createElement("div");
messageLineElement.className = "webkit-html-message-line";
messageBubbleElement.appendChild(messageLineElement);
var image = document.createElement("img");
image.src = imageURL;
image.className = "webkit-html-message-icon";
messageLineElement.appendChild(image);
messageLineElement.appendChild(document.createTextNode(msg.message));
rowMessage.element = messageLineElement;
rowMessage.repeatCount = msg.totalRepeatCount;
this._updateMessageRepeatCount(rowMessage);
},
_updateMessageRepeatCount: function(rowMessage)
{
if (rowMessage.repeatCount < 2)
return;
if (!rowMessage.repeatCountElement) {
var repeatCountElement = document.createElement("span");
rowMessage.element.appendChild(repeatCountElement);
rowMessage.repeatCountElement = repeatCountElement;
}
rowMessage.repeatCountElement.textContent = WebInspector.UIString(" (repeated %d times)", rowMessage.repeatCount);
},
removeMessageFromSource: function(lineNumber, msg)
{
if (lineNumber >= this._textEditor.linesCount)
lineNumber = this._textEditor.linesCount - 1;
if (lineNumber < 0)
lineNumber = 0;
var rowMessages = this._rowMessages[lineNumber];
for (var i = 0; rowMessages && i < rowMessages.length; ++i) {
var rowMessage = rowMessages[i];
if (rowMessage.consoleMessage !== msg)
continue;
var messageLineElement = rowMessage.element;
var messageBubbleElement = messageLineElement.parentElement;
messageBubbleElement.removeChild(messageLineElement);
rowMessages.remove(rowMessage);
if (!rowMessages.length)
delete this._rowMessages[lineNumber];
if (!messageBubbleElement.childElementCount) {
this._textEditor.removeDecoration(lineNumber, messageBubbleElement);
delete this._messageBubbles[lineNumber];
}
break;
}
},
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
},
populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
},
inheritScrollPositions: function(sourceFrame)
{
this._textEditor.inheritScrollPositions(sourceFrame._textEditor);
},
canEditSource: function()
{
return false;
},
commitEditing: function(text)
{
},
selectionChanged: function(textRange)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.SelectionChanged, textRange);
},
scrollChanged: function(lineNumber)
{
this.dispatchEventToListeners(WebInspector.SourceFrame.Events.ScrollChanged, lineNumber);
},
_handleKeyDown: function(e)
{
var shortcutKey = WebInspector.KeyboardShortcut.makeKeyFromEvent(e);
var handler = this._shortcuts[shortcutKey];
if (handler && handler())
e.consume(true);
},
_commitEditing: function()
{
if (this._textEditor.readOnly())
return false;
var content = this._textEditor.text();
this.commitEditing(content);
if (this._url && WebInspector.fileManager.isURLSaved(this._url))
WebInspector.fileManager.save(this._url, content, false);
return true;
}
}
WebInspector.SourceFrame.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.TextEditorDelegateForSourceFrame = function(sourceFrame)
{
this._sourceFrame = sourceFrame;
}
WebInspector.TextEditorDelegateForSourceFrame.prototype = {
onTextChanged: function(oldRange, newRange)
{
this._sourceFrame.onTextChanged(oldRange, newRange);
},
selectionChanged: function(textRange)
{
this._sourceFrame.selectionChanged(textRange);
},
scrollChanged: function(lineNumber)
{
this._sourceFrame.scrollChanged(lineNumber);
},
populateLineGutterContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateLineGutterContextMenu(contextMenu, lineNumber);
},
populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
this._sourceFrame.populateTextAreaContextMenu(contextMenu, lineNumber);
},
createLink: function(hrefValue, isExternal)
{
var targetLocation = WebInspector.ParsedURL.completeURL(this._sourceFrame._url, hrefValue);
return WebInspector.linkifyURLAsNode(targetLocation || hrefValue, hrefValue, undefined, isExternal);
}
}
WebInspector.TextEditorDelegateForSourceFrame.prototype.__proto__ = WebInspector.TextEditorDelegate.prototype;
WebInspector.ResourceView = function(resource)
{
WebInspector.View.call(this);
this.registerRequiredCSS("resourceView.css");
this.element.addStyleClass("resource-view");
this.resource = resource;
}
WebInspector.ResourceView.prototype = {
hasContent: function()
{
return false;
}
}
WebInspector.ResourceView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ResourceView.hasTextContent = function(resource)
{
if (resource.type.isTextType())
return true;
if (resource.type === WebInspector.resourceTypes.Other)
return resource.content && !resource.contentEncoded;
return false;
}
WebInspector.ResourceView.nonSourceViewForResource = function(resource)
{
switch (resource.type) {
case WebInspector.resourceTypes.Image:
return new WebInspector.ImageView(resource);
case WebInspector.resourceTypes.Font:
return new WebInspector.FontView(resource);
default:
return new WebInspector.ResourceView(resource);
}
}
WebInspector.ResourceSourceFrame = function(resource)
{
this._resource = resource;
WebInspector.SourceFrame.call(this, resource);
}
WebInspector.ResourceSourceFrame.prototype = {
get resource()
{
return this._resource;
},
populateTextAreaContextMenu: function(contextMenu, lineNumber)
{
contextMenu.appendApplicableItems(this._resource);
if (this._resource.request)
contextMenu.appendApplicableItems(this._resource.request);
}
}
WebInspector.ResourceSourceFrame.prototype.__proto__ = WebInspector.SourceFrame.prototype;
WebInspector.FontView = function(resource)
{
WebInspector.ResourceView.call(this, resource);
this.element.addStyleClass("font");
}
WebInspector.FontView._fontPreviewLines = [ "ABCDEFGHIJKLM", "NOPQRSTUVWXYZ", "abcdefghijklm", "nopqrstuvwxyz", "1234567890" ];
WebInspector.FontView._fontId = 0;
WebInspector.FontView._measureFontSize = 50;
WebInspector.FontView.prototype = {
hasContent: function()
{
return true;
},
_createContentIfNeeded: function()
{
if (this.fontPreviewElement)
return;
var uniqueFontName = "WebInspectorFontPreview" + (++WebInspector.FontView._fontId);
this.fontStyleElement = document.createElement("style");
this.fontStyleElement.textContent = "@font-face { font-family: \"" + uniqueFontName + "\"; src: url(" + this.resource.url + "); }";
document.head.appendChild(this.fontStyleElement);
var fontPreview = document.createElement("div");
for (var i = 0; i < WebInspector.FontView._fontPreviewLines.length; ++i) {
if (i > 0)
fontPreview.appendChild(document.createElement("br"));
fontPreview.appendChild(document.createTextNode(WebInspector.FontView._fontPreviewLines[i]));
}
this.fontPreviewElement = fontPreview.cloneNode(true);
this.fontPreviewElement.style.setProperty("font-family", uniqueFontName);
this.fontPreviewElement.style.setProperty("visibility", "hidden");
this._dummyElement = fontPreview;
this._dummyElement.style.visibility = "hidden";
this._dummyElement.style.zIndex = "-1";
this._dummyElement.style.display = "inline";
this._dummyElement.style.position = "absolute";
this._dummyElement.style.setProperty("font-family", uniqueFontName);
this._dummyElement.style.setProperty("font-size", WebInspector.FontView._measureFontSize + "px");
this.element.appendChild(this.fontPreviewElement);
},
wasShown: function()
{
this._createContentIfNeeded();
this.updateFontPreviewSize();
},
onResize: function()
{
if (this._inResize)
return;
this._inResize = true;
try {
this.updateFontPreviewSize();
} finally {
delete this._inResize;
}
},
_measureElement: function()
{
this.element.appendChild(this._dummyElement);
var result = { width: this._dummyElement.offsetWidth, height: this._dummyElement.offsetHeight };
this.element.removeChild(this._dummyElement);
return result;
},
updateFontPreviewSize: function()
{
if (!this.fontPreviewElement || !this.isShowing())
return;
this.fontPreviewElement.style.removeProperty("visibility");
var dimension = this._measureElement();
const height = dimension.height;
const width = dimension.width;
const containerWidth = this.element.offsetWidth - 50;
const containerHeight = this.element.offsetHeight - 30;
if (!height || !width || !containerWidth || !containerHeight) {
this.fontPreviewElement.style.removeProperty("font-size");
return;
}
var widthRatio = containerWidth / width;
var heightRatio = containerHeight / height;
var finalFontSize = Math.floor(WebInspector.FontView._measureFontSize * Math.min(widthRatio, heightRatio)) - 2;
this.fontPreviewElement.style.setProperty("font-size", finalFontSize + "px", null);
}
}
WebInspector.FontView.prototype.__proto__ = WebInspector.ResourceView.prototype;
WebInspector.ImageView = function(resource)
{
WebInspector.ResourceView.call(this, resource);
this.element.addStyleClass("image");
}
WebInspector.ImageView.prototype = {
hasContent: function()
{
return true;
},
wasShown: function()
{
this._createContentIfNeeded();
},
_createContentIfNeeded: function()
{
if (this._container)
return;
var imageContainer = document.createElement("div");
imageContainer.className = "image";
this.element.appendChild(imageContainer);
var imagePreviewElement = document.createElement("img");
imagePreviewElement.addStyleClass("resource-image-view");
imageContainer.appendChild(imagePreviewElement);
imagePreviewElement.addEventListener("contextmenu", this._contextMenu.bind(this), true);
this._container = document.createElement("div");
this._container.className = "info";
this.element.appendChild(this._container);
var imageNameElement = document.createElement("h1");
imageNameElement.className = "title";
imageNameElement.textContent = this.resource.displayName;
this._container.appendChild(imageNameElement);
var infoListElement = document.createElement("dl");
infoListElement.className = "infoList";
this.resource.populateImageSource(imagePreviewElement);
function onImageLoad()
{
var content = this.resource.content;
if (content)
var resourceSize = this._base64ToSize(content);
else
var resourceSize = this.resource.resourceSize;
var imageProperties = [
{ name: WebInspector.UIString("Dimensions"), value: WebInspector.UIString("%d × %d", imagePreviewElement.naturalWidth, imagePreviewElement.naturalHeight) },
{ name: WebInspector.UIString("File size"), value: Number.bytesToString(resourceSize) },
{ name: WebInspector.UIString("MIME type"), value: this.resource.mimeType }
];
infoListElement.removeChildren();
for (var i = 0; i < imageProperties.length; ++i) {
var dt = document.createElement("dt");
dt.textContent = imageProperties[i].name;
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
dd.textContent = imageProperties[i].value;
infoListElement.appendChild(dd);
}
var dt = document.createElement("dt");
dt.textContent = WebInspector.UIString("URL");
infoListElement.appendChild(dt);
var dd = document.createElement("dd");
var externalResource = true;
dd.appendChild(WebInspector.linkifyURLAsNode(this.resource.url, undefined, undefined, externalResource));
infoListElement.appendChild(dd);
this._container.appendChild(infoListElement);
}
imagePreviewElement.addEventListener("load", onImageLoad.bind(this), false);
},
_base64ToSize: function(content)
{
if (!content.length)
return 0;
var size = (content.length || 0) * 3 / 4;
if (content.length > 0 && content[content.length - 1] === "=")
size--;
if (content.length > 1 && content[content.length - 2] === "=")
size--;
return size;
},
_contextMenu: function(event)
{
var contextMenu = new WebInspector.ContextMenu();
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Copy image URL" : "Copy Image URL"), this._copyImageURL.bind(this));
contextMenu.appendItem(WebInspector.UIString(WebInspector.useLowerCaseMenuTitles() ? "Open image in new tab" : "Open Image in New Tab"), this._openInNewTab.bind(this));
contextMenu.show(event);
},
_copyImageURL: function(event)
{
InspectorFrontendHost.copyText(this.resource.url);
},
_openInNewTab: function(event)
{
InspectorFrontendHost.openInNewTab(this.resource.url);
}
}
WebInspector.ImageView.prototype.__proto__ = WebInspector.ResourceView.prototype;
WebInspector.SplitView = function(sidebarPosition, sidebarWidthSettingName, defaultSidebarWidth)
{
WebInspector.View.call(this);
this.registerRequiredCSS("splitView.css");
this.element.className = "split-view";
this._leftElement = document.createElement("div");
this._leftElement.className = "split-view-contents";
this.element.appendChild(this._leftElement);
this._rightElement = document.createElement("div");
this._rightElement.className = "split-view-contents";
this.element.appendChild(this._rightElement);
this.sidebarResizerElement = document.createElement("div");
this.sidebarResizerElement.className = "split-view-resizer";
this.installResizer(this.sidebarResizerElement);
this._resizable = true;
this.element.appendChild(this.sidebarResizerElement);
defaultSidebarWidth = defaultSidebarWidth || 200;
this._savedSidebarWidth = defaultSidebarWidth;
this._sidebarWidthSettingName = sidebarWidthSettingName;
if (this._sidebarWidthSettingName)
WebInspector.settings[this._sidebarWidthSettingName] = WebInspector.settings.createSetting(this._sidebarWidthSettingName, undefined);
this._minimalSidebarWidth = Preferences.minSidebarWidth;
this._minimalMainWidth = 0;
this._minimalSidebarWidthPercent = 0;
this._minimalMainWidthPercent = 50;
this._mainElementHidden = false;
this._sidebarElementHidden = false;
this._innerSetSidebarPosition(sidebarPosition || WebInspector.SplitView.SidebarPosition.Left);
}
WebInspector.SplitView.EventTypes = {
Resized: "Resized"
}
WebInspector.SplitView.SidebarPosition = {
Left: "Left",
Right: "Right"
}
WebInspector.SplitView.prototype = {
get hasLeftSidebar()
{
return this._sidebarPosition === WebInspector.SplitView.SidebarPosition.Left;
},
get mainElement()
{
return this.hasLeftSidebar ? this._rightElement : this._leftElement;
},
get sidebarElement()
{
return this.hasLeftSidebar ? this._leftElement : this._rightElement;
},
get resizable()
{
return this._resizable && !this._mainElementHidden && !this._sidebarElementHidden;
},
set resizable(resizable)
{
if (this._resizable === resizable)
return;
this._resizable = resizable;
this._updateResizer(resizable);
},
_updateResizer: function()
{
if (this.resizable)
this.sidebarResizerElement.removeStyleClass("hidden");
else
this.sidebarResizerElement.addStyleClass("hidden");
},
set sidebarPosition(sidebarPosition)
{
if (this._sidebarPosition === sidebarPosition)
return;
this._innerSetSidebarPosition(sidebarPosition);
this._restoreSidebarWidth();
},
_innerSetSidebarPosition: function(sidebarPosition)
{
this._sidebarPosition = sidebarPosition;
this._leftElement.style.left = 0;
this._rightElement.style.right = 0;
if (this.hasLeftSidebar) {
this._leftElement.addStyleClass("split-view-sidebar-left");
this._rightElement.removeStyleClass("split-view-sidebar-right");
this._leftElement.style.removeProperty("right");
this._rightElement.style.removeProperty("width");
this.sidebarResizerElement.style.removeProperty("right");
} else {
this._rightElement.addStyleClass("split-view-sidebar-right");
this._leftElement.removeStyleClass("split-view-sidebar-left");
this._leftElement.style.removeProperty("width");
this._rightElement.style.removeProperty("left");
this.sidebarResizerElement.style.removeProperty("left");
}
},
set minimalSidebarWidth(width)
{
this._minimalSidebarWidth = width;
},
set minimalMainWidth(width)
{
this._minimalMainWidth = width;
},
set minimalSidebarWidthPercent(widthPercent)
{
this._minimalSidebarWidthPercent = widthPercent;
},
set minimalMainWidthPercent(widthPercent)
{
this._minimalMainWidthPercent = widthPercent;
},
setMainWidth: function(width)
{
this.setSidebarWidth(this._totalWidth - width);
},
setSidebarWidth: function(width)
{
if (this._sidebarWidth === width)
return;
this._innerSetSidebarWidth(width);
this.saveSidebarWidth();
},
sidebarWidth: function()
{
return this._sidebarWidth;
},
_innerSetSidebarWidth: function(width)
{
if (this.hasLeftSidebar)
this._innerSetLeftSidebarWidth(width);
else
this._innerSetRightSidebarWidth(width);
this._sidebarWidth = width;
this.doResize();
this.dispatchEventToListeners(WebInspector.SplitView.EventTypes.Resized, this._sidebarWidth);
},
_innerSetLeftSidebarWidth: function(width)
{
this._leftElement.style.width = width + "px";
this._rightElement.style.left = width + "px";
this.sidebarResizerElement.style.left = (width - 3) + "px";
},
_innerSetRightSidebarWidth: function(width)
{
this._rightElement.style.width = width + "px";
this._leftElement.style.right = width + "px";
this.sidebarResizerElement.style.right = (width - 3) + "px";
},
_setSidebarWidthEnsuringConstraints: function(width)
{
var minWidth = Math.max(this._minimalSidebarWidth, this._totalWidth * this._minimalSidebarWidthPercent);
var maxWidth = Math.min(this._totalWidth - this._minimalMainWidth, this._totalWidth * (100 - this._minimalMainWidthPercent) / 100 );
width = Number.constrain(width, minWidth, maxWidth);
this.setSidebarWidth(width);
},
hideMainElement: function()
{
if (this._mainElementHidden)
return;
if (this._sidebarElementHidden)
this.showSidebarElement();
this.mainElement.addStyleClass("hidden");
this.sidebarElement.addStyleClass("maximized");
if (this.hasLeftSidebar)
this.sidebarElement.style.right = "0px";
else
this.sidebarElement.style.left = "0px";
this._mainElementHidden = true;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},
showMainElement: function()
{
if (!this._mainElementHidden)
return;
this.mainElement.removeStyleClass("hidden");
this.sidebarElement.removeStyleClass("maximized");
if (this.hasLeftSidebar)
this.sidebarElement.style.right = "";
else
this.sidebarElement.style.left = "";
this._mainElementHidden = false;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},
hideSidebarElement: function()
{
if (this._sidebarElementHidden)
return;
if (this._mainElementHidden)
this.showMainElement();
this.sidebarElement.addStyleClass("hidden");
this._sidebarElementHidden = true;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},
showSidebarElement: function()
{
if (!this._sidebarElementHidden)
return;
this.sidebarElement.removeStyleClass("hidden");
this._sidebarElementHidden = false;
this._updateResizer();
this._restoreSidebarWidth();
this.doResize();
},
wasShown: function()
{
this._totalWidth = this.element.offsetWidth;
this._restoreSidebarWidth();
},
onResize: function()
{
this._totalWidth = this.element.offsetWidth;
if (this._mainElementHidden)
this._sidebarWidth = this._totalWidth;
},
_startResizerDragging: function(event)
{
if (!this._resizable)
return false;
var leftWidth = this.hasLeftSidebar ? this._sidebarWidth : this._totalWidth - this._sidebarWidth;
this._dragOffset = leftWidth - event.pageX;
return true;
},
_resizerDragging: function(event)
{
var leftWidth = event.pageX + this._dragOffset;
var rightWidth = this._totalWidth - leftWidth;
var sidebarWidth = this.hasLeftSidebar ? leftWidth : rightWidth;
this._setSidebarWidthEnsuringConstraints(sidebarWidth);
event.preventDefault();
},
_endResizerDragging: function(event)
{
delete this._dragOffset;
},
installResizer: function(resizerElement)
{
WebInspector.installDragHandle(resizerElement, this._startResizerDragging.bind(this), this._resizerDragging.bind(this), this._endResizerDragging.bind(this), "ew-resize");
},
preferredSidebarWidth: function()
{
if (!this._sidebarWidthSettingName)
return this._savedSidebarWidth;
return WebInspector.settings[this._sidebarWidthSettingName].get() || this._savedSidebarWidth;
},
_restoreSidebarWidth: function()
{
if (this._mainElementHidden) {
this.sidebarElement.style.width = "";
this._sidebarWidth = this._totalWidth;
return;
}
if (this._sidebarElementHidden) {
this._innerSetSidebarWidth(0);
return;
}
this._setSidebarWidthEnsuringConstraints(this.preferredSidebarWidth());
},
saveSidebarWidth: function()
{
this._savedSidebarWidth = this._sidebarWidth;
if (!this._sidebarWidthSettingName)
return;
WebInspector.settings[this._sidebarWidthSettingName].set(this._sidebarWidth);
},
elementsToRestoreScrollPositionsFor: function()
{
return [ this.mainElement, this.sidebarElement ];
}
}
WebInspector.SplitView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ConsolePanel = function()
{
WebInspector.Panel.call(this, "console");
WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.EntryAdded, this._consoleMessageAdded, this);
WebInspector.consoleView.addEventListener(WebInspector.ConsoleView.Events.ConsoleCleared, this._consoleCleared, this);
this._view = WebInspector.consoleView;
}
WebInspector.ConsolePanel.prototype = {
get statusBarItems()
{
return this._view.statusBarItems;
},
wasShown: function()
{
WebInspector.Panel.prototype.wasShown.call(this);
if (WebInspector.drawer.visible) {
WebInspector.drawer.hide(WebInspector.Drawer.AnimationType.Immediately);
this._drawerWasVisible = true;
}
this._view.show(this.element);
},
willHide: function()
{
if (this._drawerWasVisible) {
WebInspector.drawer.show(this._view, WebInspector.Drawer.AnimationType.Immediately);
delete this._drawerWasVisible;
}
WebInspector.Panel.prototype.willHide.call(this);
},
searchCanceled: function()
{
this._clearCurrentSearchResultHighlight();
delete this._searchResults;
delete this._searchRegex;
},
performSearch: function(query)
{
WebInspector.searchController.updateSearchMatchesCount(0, this);
this.searchCanceled();
this._searchRegex = createPlainTextSearchRegex(query, "gi");
this._searchResults = [];
var messages = WebInspector.consoleView.messages;
for (var i = 0; i < messages.length; i++) {
if (messages[i].matchesRegex(this._searchRegex)) {
this._searchResults.push(messages[i]);
this._searchRegex.lastIndex = 0;
}
}
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
this._currentSearchResultIndex = -1;
if (this._searchResults.length)
this._jumpToSearchResult(0);
},
jumpToNextSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
this._jumpToSearchResult((this._currentSearchResultIndex + 1) % this._searchResults.length);
},
jumpToPreviousSearchResult: function()
{
if (!this._searchResults || !this._searchResults.length)
return;
var index = this._currentSearchResultIndex - 1;
if (index === -1)
index = this._searchResults.length - 1;
this._jumpToSearchResult(index);
return true;
},
_clearCurrentSearchResultHighlight: function()
{
if (!this._searchResults)
return;
var highlightedMessage = this._searchResults[this._currentSearchResultIndex];
if (highlightedMessage)
highlightedMessage.clearHighlight();
this._currentSearchResultIndex = -1;
},
_jumpToSearchResult: function(index)
{
this._clearCurrentSearchResultHighlight();
this._currentSearchResultIndex = index;
WebInspector.searchController.updateCurrentMatchIndex(this._currentSearchResultIndex, this);
this._searchResults[index].highlightSearchResults(this._searchRegex);
},
_consoleMessageAdded: function(event)
{
if (!this._searchRegex || !this.isShowing())
return;
var message = event.data;
this._searchRegex.lastIndex = 0;
if (message.matchesRegex(this._searchRegex)) {
this._searchResults.push(message);
WebInspector.searchController.updateSearchMatchesCount(this._searchResults.length, this);
}
},
_consoleCleared: function()
{
if (!this._searchResults)
return;
this._clearCurrentSearchResultHighlight();
this._searchResults.length = 0;
if (this.isShowing())
WebInspector.searchController.updateSearchMatchesCount(0, this);
}
}
WebInspector.ConsolePanel.prototype.__proto__ = WebInspector.Panel.prototype;
function defineCommonExtensionSymbols(apiPrivate)
{
if (!apiPrivate.audits)
apiPrivate.audits = {};
apiPrivate.audits.Severity = {
Info: "info",
Warning: "warning",
Severe: "severe"
};
if (!apiPrivate.console)
apiPrivate.console = {};
apiPrivate.console.Severity = {
Tip: "tip",
Debug: "debug",
Log: "log",
Warning: "warning",
Error: "error"
};
if (!apiPrivate.panels)
apiPrivate.panels = {};
apiPrivate.panels.SearchAction = {
CancelSearch: "cancelSearch",
PerformSearch: "performSearch",
NextSearchResult: "nextSearchResult",
PreviousSearchResult: "previousSearchResult"
};
apiPrivate.Events = {
AuditStarted: "audit-started-",
ButtonClicked: "button-clicked-",
ConsoleMessageAdded: "console-message-added",
ElementsPanelObjectSelected: "panel-objectSelected-elements",
NetworkRequestFinished: "network-request-finished",
Reset: "reset",
OpenResource: "open-resource",
PanelSearch: "panel-search-",
Reload: "Reload",
ResourceAdded: "resource-added",
ResourceContentCommitted: "resource-content-committed",
TimelineEventRecorded: "timeline-event-recorded",
ViewShown: "view-shown-",
ViewHidden: "view-hidden-"
};
apiPrivate.Commands = {
AddAuditCategory: "addAuditCategory",
AddAuditResult: "addAuditResult",
AddConsoleMessage: "addConsoleMessage",
AddRequestHeaders: "addRequestHeaders",
CreatePanel: "createPanel",
CreateSidebarPane: "createSidebarPane",
CreateStatusBarButton: "createStatusBarButton",
EvaluateOnInspectedPage: "evaluateOnInspectedPage",
GetConsoleMessages: "getConsoleMessages",
GetHAR: "getHAR",
GetPageResources: "getPageResources",
GetRequestContent: "getRequestContent",
GetResourceContent: "getResourceContent",
Subscribe: "subscribe",
SetOpenResourceHandler: "setOpenResourceHandler",
SetResourceContent: "setResourceContent",
SetSidebarContent: "setSidebarContent",
SetSidebarHeight: "setSidebarHeight",
SetSidebarPage: "setSidebarPage",
ShowPanel: "showPanel",
StopAuditCategoryRun: "stopAuditCategoryRun",
Unsubscribe: "unsubscribe",
UpdateAuditProgress: "updateAuditProgress",
UpdateButton: "updateButton",
InspectedURLChanged: "inspectedURLChanged"
};
}
function injectedExtensionAPI(injectedScriptId)
{
var apiPrivate = {};
defineCommonExtensionSymbols(apiPrivate);
var commands = apiPrivate.Commands;
var events = apiPrivate.Events;
var userAction = false;
function EventSinkImpl(type, customDispatch)
{
this._type = type;
this._listeners = [];
this._customDispatch = customDispatch;
}
EventSinkImpl.prototype = {
addListener: function(callback)
{
if (typeof callback !== "function")
throw "addListener: callback is not a function";
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Subscribe, type: this._type });
this._listeners.push(callback);
extensionServer.registerHandler("notify-" + this._type, this._dispatch.bind(this));
},
removeListener: function(callback)
{
var listeners = this._listeners;
for (var i = 0; i < listeners.length; ++i) {
if (listeners[i] === callback) {
listeners.splice(i, 1);
break;
}
}
if (this._listeners.length === 0)
extensionServer.sendRequest({ command: commands.Unsubscribe, type: this._type });
},
_fire: function()
{
var listeners = this._listeners.slice();
for (var i = 0; i < listeners.length; ++i)
listeners[i].apply(null, arguments);
},
_dispatch: function(request)
{
if (this._customDispatch)
this._customDispatch.call(this, request);
else
this._fire.apply(this, request.arguments);
}
}
function InspectorExtensionAPI()
{
this.audits = new Audits();
this.inspectedWindow = new InspectedWindow();
this.panels = new Panels();
this.network = new Network();
defineDeprecatedProperty(this, "webInspector", "resources", "network");
this.timeline = new Timeline();
this.console = new ConsoleAPI();
this.onReset = new EventSink(events.Reset);
}
InspectorExtensionAPI.prototype = {
log: function(message)
{
extensionServer.sendRequest({ command: commands.Log, message: message });
}
}
function ConsoleAPI()
{
this.onMessageAdded = new EventSink(events.ConsoleMessageAdded);
}
ConsoleAPI.prototype = {
getMessages: function(callback)
{
extensionServer.sendRequest({ command: commands.GetConsoleMessages }, callback);
},
addMessage: function(severity, text, url, line)
{
extensionServer.sendRequest({ command: commands.AddConsoleMessage, severity: severity, text: text, url: url, line: line });
},
get Severity()
{
return apiPrivate.console.Severity;
}
}
function Network()
{
function dispatchRequestEvent(message)
{
var request = message.arguments[1];
request.__proto__ = new Request(message.arguments[0]);
this._fire(request);
}
this.onRequestFinished = new EventSink(events.NetworkRequestFinished, dispatchRequestEvent);
defineDeprecatedProperty(this, "network", "onFinished", "onRequestFinished");
this.onNavigated = new EventSink(events.InspectedURLChanged);
}
Network.prototype = {
getHAR: function(callback)
{
function callbackWrapper(result)
{
var entries = (result && result.entries) || [];
for (var i = 0; i < entries.length; ++i) {
entries[i].__proto__ = new Request(entries[i]._requestId);
delete entries[i]._requestId;
}
callback(result);
}
return extensionServer.sendRequest({ command: commands.GetHAR }, callback && callbackWrapper);
},
addRequestHeaders: function(headers)
{
return extensionServer.sendRequest({ command: commands.AddRequestHeaders, headers: headers, extensionId: window.location.hostname });
}
}
function RequestImpl(id)
{
this._id = id;
}
RequestImpl.prototype = {
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
extensionServer.sendRequest({ command: commands.GetRequestContent, id: this._id }, callback && callbackWrapper);
}
}
function Panels()
{
var panels = {
elements: new ElementsPanel()
};
function panelGetter(name)
{
return panels[name];
}
for (var panel in panels)
this.__defineGetter__(panel, panelGetter.bind(null, panel));
}
Panels.prototype = {
create: function(title, icon, page, callback)
{
var id = "extension-panel-" + extensionServer.nextObjectId();
var request = {
command: commands.CreatePanel,
id: id,
title: title,
icon: icon,
page: page
};
extensionServer.sendRequest(request, callback && callback.bind(this, new ExtensionPanel(id)));
},
setOpenResourceHandler: function(callback)
{
var hadHandler = extensionServer.hasHandler(events.OpenResource);
if (!callback)
extensionServer.unregisterHandler(events.OpenResource);
else {
function callbackWrapper(message)
{
userAction = true;
try {
callback.call(null, new Resource(message.resource), message.lineNumber);
} finally {
userAction = false;
}
}
extensionServer.registerHandler(events.OpenResource, callbackWrapper);
}
if (hadHandler === !callback)
extensionServer.sendRequest({ command: commands.SetOpenResourceHandler, "handlerPresent": !!callback });
},
get SearchAction()
{
return apiPrivate.panels.SearchAction;
}
}
function ExtensionViewImpl(id)
{
this._id = id;
function dispatchShowEvent(message)
{
var frameIndex = message.arguments[0];
this._fire(window.parent.frames[frameIndex]);
}
this.onShown = new EventSink(events.ViewShown + id, dispatchShowEvent);
this.onHidden = new EventSink(events.ViewHidden + id);
}
function PanelWithSidebarImpl(id)
{
this._id = id;
}
PanelWithSidebarImpl.prototype = {
createSidebarPane: function(title, callback)
{
var id = "extension-sidebar-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateSidebarPane,
panel: this._id,
id: id,
title: title
};
function callbackWrapper()
{
callback(new ExtensionSidebarPane(id));
}
extensionServer.sendRequest(request, callback && callbackWrapper);
}
}
PanelWithSidebarImpl.prototype.__proto__ = ExtensionViewImpl.prototype;
function ElementsPanel()
{
var id = "elements";
PanelWithSidebar.call(this, id);
this.onSelectionChanged = new EventSink(events.ElementsPanelObjectSelected);
}
function ExtensionPanelImpl(id)
{
ExtensionViewImpl.call(this, id);
this.onSearch = new EventSink(events.PanelSearch + id);
}
ExtensionPanelImpl.prototype = {
createStatusBarButton: function(iconPath, tooltipText, disabled)
{
var id = "button-" + extensionServer.nextObjectId();
var request = {
command: commands.CreateStatusBarButton,
panel: this._id,
id: id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
return new Button(id);
},
show: function()
{
if (!userAction)
return;
var request = {
command: commands.ShowPanel,
id: this._id
};
extensionServer.sendRequest(request);
}
};
ExtensionPanelImpl.prototype.__proto__ = ExtensionViewImpl.prototype;
function ExtensionSidebarPaneImpl(id)
{
ExtensionViewImpl.call(this, id);
}
ExtensionSidebarPaneImpl.prototype = {
setHeight: function(height)
{
extensionServer.sendRequest({ command: commands.SetSidebarHeight, id: this._id, height: height });
},
setExpression: function(expression, rootTitle, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
var request = {
command: commands.SetSidebarContent,
id: this._id,
expression: expression,
rootTitle: rootTitle,
evaluateOnPage: true,
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
extensionServer.sendRequest(request, callback);
},
setObject: function(jsonObject, rootTitle, callback)
{
extensionServer.sendRequest({ command: commands.SetSidebarContent, id: this._id, expression: jsonObject, rootTitle: rootTitle }, callback);
},
setPage: function(page)
{
extensionServer.sendRequest({ command: commands.SetSidebarPage, id: this._id, page: page });
}
}
function ButtonImpl(id)
{
this._id = id;
this.onClicked = new EventSink(events.ButtonClicked + id);
}
ButtonImpl.prototype = {
update: function(iconPath, tooltipText, disabled)
{
var request = {
command: commands.UpdateButton,
id: this._id,
icon: iconPath,
tooltip: tooltipText,
disabled: !!disabled
};
extensionServer.sendRequest(request);
}
};
function Audits()
{
}
Audits.prototype = {
addCategory: function(displayName, resultCount)
{
var id = "extension-audit-category-" + extensionServer.nextObjectId();
if (typeof resultCount !== "undefined")
console.warn("Passing resultCount to audits.addCategory() is deprecated. Use AuditResult.updateProgress() instead.");
extensionServer.sendRequest({ command: commands.AddAuditCategory, id: id, displayName: displayName, resultCount: resultCount });
return new AuditCategory(id);
}
}
function AuditCategoryImpl(id)
{
function dispatchAuditEvent(request)
{
var auditResult = new AuditResult(request.arguments[0]);
try {
this._fire(auditResult);
} catch (e) {
console.error("Uncaught exception in extension audit event handler: " + e);
auditResult.done();
}
}
this._id = id;
this.onAuditStarted = new EventSink(events.AuditStarted + id, dispatchAuditEvent);
}
function AuditResultImpl(id)
{
this._id = id;
this.createURL = this._nodeFactory.bind(null, "url");
this.createSnippet = this._nodeFactory.bind(null, "snippet");
this.createText = this._nodeFactory.bind(null, "text");
this.createObject = this._nodeFactory.bind(null, "object");
this.createNode = this._nodeFactory.bind(null, "node");
}
AuditResultImpl.prototype = {
addResult: function(displayName, description, severity, details)
{
if (details && !(details instanceof AuditResultNode))
details = new AuditResultNode(details instanceof Array ? details : [details]);
var request = {
command: commands.AddAuditResult,
resultId: this._id,
displayName: displayName,
description: description,
severity: severity,
details: details
};
extensionServer.sendRequest(request);
},
createResult: function()
{
return new AuditResultNode(Array.prototype.slice.call(arguments));
},
updateProgress: function(worked, totalWork)
{
extensionServer.sendRequest({ command: commands.UpdateAuditProgress, resultId: this._id, progress: worked / totalWork });
},
done: function()
{
extensionServer.sendRequest({ command: commands.StopAuditCategoryRun, resultId: this._id });
},
get Severity()
{
return apiPrivate.audits.Severity;
},
createResourceLink: function(url, lineNumber)
{
return {
type: "resourceLink",
arguments: [url, lineNumber && lineNumber - 1]
};
},
_nodeFactory: function(type)
{
return {
type: type,
arguments: Array.prototype.slice.call(arguments, 1)
};
}
}
function AuditResultNode(contents)
{
this.contents = contents;
this.children = [];
this.expanded = false;
}
AuditResultNode.prototype = {
addChild: function()
{
var node = new AuditResultNode(Array.prototype.slice.call(arguments));
this.children.push(node);
return node;
}
};
function InspectedWindow()
{
function dispatchResourceEvent(message)
{
this._fire(new Resource(message.arguments[0]));
}
function dispatchResourceContentEvent(message)
{
this._fire(new Resource(message.arguments[0]), message.arguments[1]);
}
this.onResourceAdded = new EventSink(events.ResourceAdded, dispatchResourceEvent);
this.onResourceContentCommitted = new EventSink(events.ResourceContentCommitted, dispatchResourceContentEvent);
}
InspectedWindow.prototype = {
reload: function(optionsOrUserAgent)
{
var options = null;
if (typeof optionsOrUserAgent === "object")
options = optionsOrUserAgent;
else if (typeof optionsOrUserAgent === "string") {
options = { userAgent: optionsOrUserAgent };
console.warn("Passing userAgent as string parameter to inspectedWindow.reload() is deprecated. " +
"Use inspectedWindow.reload({ userAgent: value}) instead.");
}
return extensionServer.sendRequest({ command: commands.Reload, options: options });
},
eval: function(expression, evaluateOptions)
{
var callback = extractCallbackArgument(arguments);
function callbackWrapper(result)
{
callback(result.value, result.isException);
}
var request = {
command: commands.EvaluateOnInspectedPage,
expression: expression
};
if (typeof evaluateOptions === "object")
request.evaluateOptions = evaluateOptions;
return extensionServer.sendRequest(request, callback && callbackWrapper);
},
getResources: function(callback)
{
function wrapResource(resourceData)
{
return new Resource(resourceData);
}
function callbackWrapper(resources)
{
callback(resources.map(wrapResource));
}
return extensionServer.sendRequest({ command: commands.GetPageResources }, callback && callbackWrapper);
}
}
function ResourceImpl(resourceData)
{
this._url = resourceData.url
this._type = resourceData.type;
}
ResourceImpl.prototype = {
get url()
{
return this._url;
},
get type()
{
return this._type;
},
getContent: function(callback)
{
function callbackWrapper(response)
{
callback(response.content, response.encoding);
}
return extensionServer.sendRequest({ command: commands.GetResourceContent, url: this._url }, callback && callbackWrapper);
},
setContent: function(content, commit, callback)
{
return extensionServer.sendRequest({ command: commands.SetResourceContent, url: this._url, content: content, commit: commit }, callback);
}
}
function TimelineImpl()
{
this.onEventRecorded = new EventSink(events.TimelineEventRecorded);
}
function ExtensionServerClient()
{
this._callbacks = {};
this._handlers = {};
this._lastRequestId = 0;
this._lastObjectId = 0;
this.registerHandler("callback", this._onCallback.bind(this));
var channel = new MessageChannel();
this._port = channel.port1;
this._port.addEventListener("message", this._onMessage.bind(this), false);
this._port.start();
window.parent.postMessage("registerExtension", [ channel.port2 ], "*");
}
ExtensionServerClient.prototype = {
sendRequest: function(message, callback)
{
if (typeof callback === "function")
message.requestId = this._registerCallback(callback);
return this._port.postMessage(message);
},
hasHandler: function(command)
{
return !!this._handlers[command];
},
registerHandler: function(command, handler)
{
this._handlers[command] = handler;
},
unregisterHandler: function(command)
{
delete this._handlers[command];
},
nextObjectId: function()
{
return injectedScriptId + "_" + ++this._lastObjectId;
},
_registerCallback: function(callback)
{
var id = ++this._lastRequestId;
this._callbacks[id] = callback;
return id;
},
_onCallback: function(request)
{
if (request.requestId in this._callbacks) {
var callback = this._callbacks[request.requestId];
delete this._callbacks[request.requestId];
callback(request.result);
}
},
_onMessage: function(event)
{
var request = event.data;
var handler = this._handlers[request.command];
if (handler)
handler.call(this, request);
}
}
function populateInterfaceClass(interface, implementation)
{
for (var member in implementation) {
if (member.charAt(0) === "_")
continue;
var descriptor = null;
for (var owner = implementation; owner && !descriptor; owner = owner.__proto__)
descriptor = Object.getOwnPropertyDescriptor(owner, member);
if (!descriptor)
continue;
if (typeof descriptor.value === "function")
interface[member] = descriptor.value.bind(implementation);
else if (typeof descriptor.get === "function")
interface.__defineGetter__(member, descriptor.get.bind(implementation));
else
Object.defineProperty(interface, member, descriptor);
}
}
function declareInterfaceClass(implConstructor)
{
return function()
{
var impl = { __proto__: implConstructor.prototype };
implConstructor.apply(impl, arguments);
populateInterfaceClass(this, impl);
}
}
function defineDeprecatedProperty(object, className, oldName, newName)
{
var warningGiven = false;
function getter()
{
if (!warningGiven) {
console.warn(className + "." + oldName + " is deprecated. Use " + className + "." + newName + " instead");
warningGiven = true;
}
return object[newName];
}
object.__defineGetter__(oldName, getter);
}
function extractCallbackArgument(args)
{
var lastArgument = args[args.length - 1];
return typeof lastArgument === "function" ? lastArgument : undefined;
}
var AuditCategory = declareInterfaceClass(AuditCategoryImpl);
var AuditResult = declareInterfaceClass(AuditResultImpl);
var Button = declareInterfaceClass(ButtonImpl);
var EventSink = declareInterfaceClass(EventSinkImpl);
var ExtensionPanel = declareInterfaceClass(ExtensionPanelImpl);
var ExtensionSidebarPane = declareInterfaceClass(ExtensionSidebarPaneImpl);
var PanelWithSidebar = declareInterfaceClass(PanelWithSidebarImpl);
var Request = declareInterfaceClass(RequestImpl);
var Resource = declareInterfaceClass(ResourceImpl);
var Timeline = declareInterfaceClass(TimelineImpl);
var extensionServer = new ExtensionServerClient();
return new InspectorExtensionAPI();
}
function buildPlatformExtensionAPI(extensionInfo)
{
function platformExtensionAPI(coreAPI)
{
window.webInspector = coreAPI;
}
return platformExtensionAPI.toString();
}
function buildExtensionAPIInjectedScript(extensionInfo)
{
return "(function(injectedScriptHost, inspectedWindow, injectedScriptId){ " +
defineCommonExtensionSymbols.toString() + ";" +
injectedExtensionAPI.toString() + ";" +
buildPlatformExtensionAPI(extensionInfo) + ";" +
"platformExtensionAPI(injectedExtensionAPI(injectedScriptId));" +
"return {};" +
"})";
}
WebInspector.ExtensionAuditCategory = function(extensionOrigin, id, displayName, ruleCount)
{
this._extensionOrigin = extensionOrigin;
this._id = id;
this._displayName = displayName;
this._ruleCount = ruleCount;
}
WebInspector.ExtensionAuditCategory.prototype = {
get id()
{
return this._id;
},
get displayName()
{
return this._displayName;
},
run: function(requests, ruleResultCallback, categoryDoneCallback, progress)
{
var results = new WebInspector.ExtensionAuditCategoryResults(this, ruleResultCallback, categoryDoneCallback, progress);
WebInspector.extensionServer.startAuditRun(this, results);
}
}
WebInspector.ExtensionAuditCategoryResults = function(category, ruleResultCallback, categoryDoneCallback, progress)
{
this._category = category;
this._ruleResultCallback = ruleResultCallback;
this._categoryDoneCallback = categoryDoneCallback;
this._progress = progress;
this._progress.setTotalWork(1);
this._expectedResults = category._ruleCount;
this._actualResults = 0;
this.id = category.id + "-" + ++WebInspector.ExtensionAuditCategoryResults._lastId;
}
WebInspector.ExtensionAuditCategoryResults.prototype = {
done: function()
{
WebInspector.extensionServer.stopAuditRun(this);
this._progress.done();
this._categoryDoneCallback();
},
addResult: function(displayName, description, severity, details)
{
var result = new WebInspector.AuditRuleResult(displayName);
result.addChild(description);
result.severity = severity;
if (details)
this._addNode(result, details);
this._addResult(result);
},
_addNode: function(parent, node)
{
var contents = WebInspector.auditFormatters.partiallyApply(WebInspector.ExtensionAuditFormatters, this, node.contents);
var addedNode = parent.addChild(contents, node.expanded);
if (node.children) {
for (var i = 0; i < node.children.length; ++i)
this._addNode(addedNode, node.children[i]);
}
},
_addResult: function(result)
{
this._ruleResultCallback(result);
++this._actualResults;
if (typeof this._expectedResults === "number") {
this._progress.setWorked(this._actualResults / this._expectedResults);
if (this._actualResults === this._expectedResults)
this.done();
}
},
updateProgress: function(progress)
{
this._progress.setWorked(progress);
},
evaluate: function(expression, evaluateOptions, callback)
{
function onEvaluate(error, result, wasThrown)
{
if (wasThrown)
return;
var object = WebInspector.RemoteObject.fromPayload(result);
callback(object);
}
WebInspector.extensionServer.evaluate(expression, false, false, evaluateOptions, this._category._extensionOrigin, onEvaluate);
}
}
WebInspector.ExtensionAuditFormatters = {
object: function(expression, title, evaluateOptions)
{
var parentElement = document.createElement("div");
function onEvaluate(remoteObject)
{
var section = new WebInspector.ObjectPropertiesSection(remoteObject, title);
section.expanded = true;
section.editable = false;
parentElement.appendChild(section.element);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
},
node: function(expression, evaluateOptions)
{
var parentElement = document.createElement("div");
function onNodeAvailable(nodeId)
{
if (!nodeId)
return;
var treeOutline = new WebInspector.ElementsTreeOutline(false, false, true);
treeOutline.rootDOMNode = WebInspector.domAgent.nodeForId(nodeId);
treeOutline.element.addStyleClass("outline-disclosure");
treeOutline.setVisible(true);
parentElement.appendChild(treeOutline.element);
}
function onEvaluate(remoteObject)
{
remoteObject.pushNodeToFrontend(onNodeAvailable);
}
this.evaluate(expression, evaluateOptions, onEvaluate);
return parentElement;
}
}
WebInspector.ExtensionAuditCategoryResults._lastId = 0;
WebInspector.ExtensionServer = function()
{
this._clientObjects = {};
this._handlers = {};
this._subscribers = {};
this._subscriptionStartHandlers = {};
this._subscriptionStopHandlers = {};
this._extraHeaders = {};
this._requests = {};
this._lastRequestId = 0;
this._registeredExtensions = {};
this._status = new WebInspector.ExtensionStatus();
var commands = WebInspector.extensionAPI.Commands;
this._registerHandler(commands.AddAuditCategory, this._onAddAuditCategory.bind(this));
this._registerHandler(commands.AddAuditResult, this._onAddAuditResult.bind(this));
this._registerHandler(commands.AddConsoleMessage, this._onAddConsoleMessage.bind(this));
this._registerHandler(commands.AddRequestHeaders, this._onAddRequestHeaders.bind(this));
this._registerHandler(commands.CreatePanel, this._onCreatePanel.bind(this));
this._registerHandler(commands.CreateSidebarPane, this._onCreateSidebarPane.bind(this));
this._registerHandler(commands.CreateStatusBarButton, this._onCreateStatusBarButton.bind(this));
this._registerHandler(commands.EvaluateOnInspectedPage, this._onEvaluateOnInspectedPage.bind(this));
this._registerHandler(commands.GetHAR, this._onGetHAR.bind(this));
this._registerHandler(commands.GetConsoleMessages, this._onGetConsoleMessages.bind(this));
this._registerHandler(commands.GetPageResources, this._onGetPageResources.bind(this));
this._registerHandler(commands.GetRequestContent, this._onGetRequestContent.bind(this));
this._registerHandler(commands.GetResourceContent, this._onGetResourceContent.bind(this));
this._registerHandler(commands.Log, this._onLog.bind(this));
this._registerHandler(commands.Reload, this._onReload.bind(this));
this._registerHandler(commands.SetOpenResourceHandler, this._onSetOpenResourceHandler.bind(this));
this._registerHandler(commands.SetResourceContent, this._onSetResourceContent.bind(this));
this._registerHandler(commands.SetSidebarHeight, this._onSetSidebarHeight.bind(this));
this._registerHandler(commands.SetSidebarContent, this._onSetSidebarContent.bind(this));
this._registerHandler(commands.SetSidebarPage, this._onSetSidebarPage.bind(this));
this._registerHandler(commands.ShowPanel, this._onShowPanel.bind(this));
this._registerHandler(commands.StopAuditCategoryRun, this._onStopAuditCategoryRun.bind(this));
this._registerHandler(commands.Subscribe, this._onSubscribe.bind(this));
this._registerHandler(commands.Unsubscribe, this._onUnsubscribe.bind(this));
this._registerHandler(commands.UpdateButton, this._onUpdateButton.bind(this));
this._registerHandler(commands.UpdateAuditProgress, this._onUpdateAuditProgress.bind(this));
window.addEventListener("message", this._onWindowMessage.bind(this), false);
}
WebInspector.ExtensionServer.prototype = {
hasExtensions: function()
{
return !!Object.keys(this._registeredExtensions).length;
},
notifySearchAction: function(panelId, action, searchString)
{
this._postNotification(WebInspector.extensionAPI.Events.PanelSearch + panelId, action, searchString);
},
notifyViewShown: function(identifier, frameIndex)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewShown + identifier, frameIndex);
},
notifyViewHidden: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ViewHidden + identifier);
},
notifyButtonClicked: function(identifier)
{
this._postNotification(WebInspector.extensionAPI.Events.ButtonClicked + identifier);
},
_inspectedURLChanged: function(event)
{
this._requests = {};
var url = event.data;
this._postNotification(WebInspector.extensionAPI.Events.InspectedURLChanged, url);
},
_mainFrameNavigated: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.Reset);
},
startAuditRun: function(category, auditRun)
{
this._clientObjects[auditRun.id] = auditRun;
this._postNotification("audit-started-" + category.id, auditRun.id);
},
stopAuditRun: function(auditRun)
{
delete this._clientObjects[auditRun.id];
},
_postNotification: function(type, vararg)
{
var subscribers = this._subscribers[type];
if (!subscribers)
return;
var message = {
command: "notify-" + type,
arguments: Array.prototype.slice.call(arguments, 1)
};
for (var i = 0; i < subscribers.length; ++i)
subscribers[i].postMessage(message);
},
_onSubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (subscribers)
subscribers.push(port);
else {
this._subscribers[message.type] = [ port ];
if (this._subscriptionStartHandlers[message.type])
this._subscriptionStartHandlers[message.type]();
}
},
_onUnsubscribe: function(message, port)
{
var subscribers = this._subscribers[message.type];
if (!subscribers)
return;
subscribers.remove(port);
if (!subscribers.length) {
delete this._subscribers[message.type];
if (this._subscriptionStopHandlers[message.type])
this._subscriptionStopHandlers[message.type]();
}
},
_onAddRequestHeaders: function(message)
{
var id = message.extensionId;
if (typeof id !== "string")
return this._status.E_BADARGTYPE("extensionId", typeof id, "string");
var extensionHeaders = this._extraHeaders[id];
if (!extensionHeaders) {
extensionHeaders = {};
this._extraHeaders[id] = extensionHeaders;
}
for (var name in message.headers)
extensionHeaders[name] = message.headers[name];
var allHeaders = {};
for (var extension in this._extraHeaders) {
var headers = this._extraHeaders[extension];
for (name in headers) {
if (typeof headers[name] === "string")
allHeaders[name] = headers[name];
}
}
NetworkAgent.setExtraHTTPHeaders(allHeaders);
},
_onCreatePanel: function(message, port)
{
var id = message.id;
if (id in this._clientObjects || id in WebInspector.panels)
return this._status.E_EXISTS(id);
var page = this._expandResourcePath(port._extensionOrigin, message.page);
var panelDescriptor = new WebInspector.PanelDescriptor(id, message.title, undefined, undefined, new WebInspector.ExtensionPanel(id, page));
panelDescriptor.setIconURL(this._expandResourcePath(port._extensionOrigin, message.icon));
this._clientObjects[id] = panelDescriptor.panel();
WebInspector.inspectorView.addPanel(panelDescriptor);
return this._status.OK();
},
_onShowPanel: function(message)
{
WebInspector.showPanel(message.id);
},
_onCreateStatusBarButton: function(message, port)
{
var panel = this._clientObjects[message.panel];
if (!panel || !(panel instanceof WebInspector.ExtensionPanel))
return this._status.E_NOTFOUND(message.panel);
var button = new WebInspector.ExtensionButton(message.id, this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
this._clientObjects[message.id] = button;
panel.addStatusBarItem(button.element);
return this._status.OK();
},
_onUpdateButton: function(message, port)
{
var button = this._clientObjects[message.id];
if (!button || !(button instanceof WebInspector.ExtensionButton))
return this._status.E_NOTFOUND(message.id);
button.update(this._expandResourcePath(port._extensionOrigin, message.icon), message.tooltip, message.disabled);
return this._status.OK();
},
_onCreateSidebarPane: function(message)
{
var panel = WebInspector.panel(message.panel);
if (!panel)
return this._status.E_NOTFOUND(message.panel);
if (!panel.sidebarElement || !panel.sidebarPanes)
return this._status.E_NOTSUPPORTED();
var id = message.id;
var sidebar = new WebInspector.ExtensionSidebarPane(message.title, message.id);
this._clientObjects[id] = sidebar;
panel.sidebarPanes[id] = sidebar;
panel.sidebarElement.appendChild(sidebar.element);
return this._status.OK();
},
_onSetSidebarHeight: function(message)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setHeight(message.height);
return this._status.OK();
},
_onSetSidebarContent: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
function callback(error)
{
var result = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, result);
}
if (message.evaluateOnPage)
return sidebar.setExpression(message.expression, message.rootTitle, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
sidebar.setObject(message.expression, message.rootTitle, callback.bind(this));
},
_onSetSidebarPage: function(message, port)
{
var sidebar = this._clientObjects[message.id];
if (!sidebar)
return this._status.E_NOTFOUND(message.id);
sidebar.setPage(this._expandResourcePath(port._extensionOrigin, message.page));
},
_onSetOpenResourceHandler: function(message, port)
{
var name = this._registeredExtensions[port._extensionOrigin].name || ("Extension " + port._extensionOrigin);
if (message.handlerPresent)
WebInspector.openAnchorLocationRegistry.registerHandler(name, this._handleOpenURL.bind(this, port));
else
WebInspector.openAnchorLocationRegistry.unregisterHandler(name);
},
_handleOpenURL: function(port, details)
{
var url = details.url;
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return false;
var lineNumber = details.lineNumber;
if (typeof lineNumber === "number")
lineNumber += 1;
port.postMessage({
command: "open-resource",
resource: this._makeResource(contentProvider),
lineNumber: lineNumber
});
return true;
},
_onLog: function(message)
{
WebInspector.log(message.message);
},
_onReload: function(message)
{
var options = (message.options || {});
NetworkAgent.setUserAgentOverride(typeof options.userAgent === "string" ? options.userAgent : "");
var injectedScript;
if (options.injectedScript) {
injectedScript = "((function(){" + options.injectedScript + "})(),function(){return {}})";
}
PageAgent.reload(!!options.ignoreCache, injectedScript);
return this._status.OK();
},
_onEvaluateOnInspectedPage: function(message, port)
{
function callback(error, resultPayload, wasThrown)
{
var result = {};
if (error) {
result.isException = true;
result.value = error.toString();
} else
result.value = resultPayload.value;
if (wasThrown)
result.isException = true;
this._dispatchCallback(message.requestId, port, result);
}
return this.evaluate(message.expression, true, true, message.evaluateOptions, port._extensionOrigin, callback.bind(this));
},
_onGetConsoleMessages: function()
{
return WebInspector.console.messages.map(this._makeConsoleMessage);
},
_onAddConsoleMessage: function(message)
{
function convertSeverity(level)
{
switch (level) {
case WebInspector.extensionAPI.console.Severity.Tip:
return WebInspector.ConsoleMessage.MessageLevel.Tip;
case WebInspector.extensionAPI.console.Severity.Log:
return WebInspector.ConsoleMessage.MessageLevel.Log;
case WebInspector.extensionAPI.console.Severity.Warning:
return WebInspector.ConsoleMessage.MessageLevel.Warning;
case WebInspector.extensionAPI.console.Severity.Error:
return WebInspector.ConsoleMessage.MessageLevel.Error;
case WebInspector.extensionAPI.console.Severity.Debug:
return WebInspector.ConsoleMessage.MessageLevel.Debug;
}
}
var level = convertSeverity(message.severity);
if (!level)
return this._status.E_BADARG("message.severity", message.severity);
var consoleMessage = WebInspector.ConsoleMessage.create(
WebInspector.ConsoleMessage.MessageSource.JS,
level,
message.text,
WebInspector.ConsoleMessage.MessageType.Log,
message.url,
message.line);
WebInspector.console.addMessage(consoleMessage);
},
_makeConsoleMessage: function(message)
{
function convertLevel(level)
{
if (!level)
return;
switch (level) {
case WebInspector.ConsoleMessage.MessageLevel.Tip:
return WebInspector.extensionAPI.console.Severity.Tip;
case WebInspector.ConsoleMessage.MessageLevel.Log:
return WebInspector.extensionAPI.console.Severity.Log;
case WebInspector.ConsoleMessage.MessageLevel.Warning:
return WebInspector.extensionAPI.console.Severity.Warning;
case WebInspector.ConsoleMessage.MessageLevel.Error:
return WebInspector.extensionAPI.console.Severity.Error;
case WebInspector.ConsoleMessage.MessageLevel.Debug:
return WebInspector.extensionAPI.console.Severity.Debug;
default:
return WebInspector.extensionAPI.console.Severity.Log;
}
}
var result = {
severity: convertLevel(message.level),
text: message.text,
};
if (message.url)
result.url = message.url;
if (message.line)
result.line = message.line;
return result;
},
_onGetHAR: function()
{
var requests = WebInspector.networkLog.requests;
var harLog = (new WebInspector.HARLog(requests)).build();
for (var i = 0; i < harLog.entries.length; ++i)
harLog.entries[i]._requestId = this._requestId(requests[i]);
return harLog;
},
_makeResource: function(contentProvider)
{
return {
url: contentProvider.contentURL(),
type: contentProvider.contentType().name()
};
},
_onGetPageResources: function()
{
var resources = {};
function pushResourceData(contentProvider)
{
if (!resources[contentProvider.contentURL()])
resources[contentProvider.contentURL()] = this._makeResource(contentProvider);
}
WebInspector.workspace.uiSourceCodes().forEach(pushResourceData.bind(this));
WebInspector.resourceTreeModel.forAllResources(pushResourceData.bind(this));
return Object.values(resources);
},
_getResourceContent: function(contentProvider, message, port)
{
function onContentAvailable(content, contentEncoded, mimeType)
{
var response = {
encoding: contentEncoded ? "base64" : "",
content: content
};
this._dispatchCallback(message.requestId, port, response);
}
contentProvider.requestContent(onContentAvailable.bind(this));
},
_onGetRequestContent: function(message, port)
{
var request = this._requestById(message.id);
if (!request)
return this._status.E_NOTFOUND(message.id);
this._getResourceContent(request, message, port);
},
_onGetResourceContent: function(message, port)
{
var url = message.url;
var contentProvider = WebInspector.workspace.uiSourceCodeForURL(url) || WebInspector.resourceForURL(url);
if (!contentProvider)
return this._status.E_NOTFOUND(url);
this._getResourceContent(contentProvider, message, port);
},
_onSetResourceContent: function(message, port)
{
function callbackWrapper(error)
{
var response = error ? this._status.E_FAILED(error) : this._status.OK();
this._dispatchCallback(message.requestId, port, response);
}
var url = message.url;
var uiSourceCode = WebInspector.workspace.uiSourceCodeForURL(url);
if (!uiSourceCode) {
var resource = WebInspector.resourceTreeModel.resourceForURL(url);
if (!resource)
return this._status.E_NOTFOUND(url);
return this._status.E_NOTSUPPORTED("Resource is not editable")
}
uiSourceCode.setWorkingCopy(message.content);
if (message.commit)
uiSourceCode.commitWorkingCopy(callbackWrapper.bind(this));
else
callbackWrapper.call(this, null);
},
_requestId: function(request)
{
if (!request._extensionRequestId) {
request._extensionRequestId = ++this._lastRequestId;
this._requests[request._extensionRequestId] = request;
}
return request._extensionRequestId;
},
_requestById: function(id)
{
return this._requests[id];
},
_onAddAuditCategory: function(message, port)
{
var category = new WebInspector.ExtensionAuditCategory(port._extensionOrigin, message.id, message.displayName, message.resultCount);
if (WebInspector.panel("audits").getCategory(category.id))
return this._status.E_EXISTS(category.id);
this._clientObjects[message.id] = category;
WebInspector.panel("audits").addCategory(category);
},
_onAddAuditResult: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
try {
auditResult.addResult(message.displayName, message.description, message.severity, message.details);
} catch (e) {
return e;
}
return this._status.OK();
},
_onUpdateAuditProgress: function(message)
{
var auditResult = this._clientObjects[message.resultId];
if (!auditResult)
return this._status.E_NOTFOUND(message.resultId);
auditResult.updateProgress(Math.min(Math.max(0, message.progress), 1));
},
_onStopAuditCategoryRun: function(message)
{
var auditRun = this._clientObjects[message.resultId];
if (!auditRun)
return this._status.E_NOTFOUND(message.resultId);
auditRun.done();
},
_dispatchCallback: function(requestId, port, result)
{
if (requestId)
port.postMessage({ command: "callback", requestId: requestId, result: result });
},
initExtensions: function()
{
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ConsoleMessageAdded,
WebInspector.console, WebInspector.ConsoleModel.Events.MessageAdded, this._notifyConsoleMessageAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.NetworkRequestFinished,
WebInspector.networkManager, WebInspector.NetworkManager.EventTypes.RequestFinished, this._notifyRequestFinished);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceAdded,
WebInspector.workspace,
WebInspector.UISourceCodeProvider.Events.UISourceCodeAdded,
this._notifyResourceAdded);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected,
WebInspector.notifications,
WebInspector.ElementsTreeOutline.Events.SelectedNodeChanged,
this._notifyElementsSelectionChanged);
this._registerAutosubscriptionHandler(WebInspector.extensionAPI.Events.ResourceContentCommitted,
WebInspector.workspace,
WebInspector.Workspace.Events.UISourceCodeContentCommitted,
this._notifyUISourceCodeContentCommitted);
function onTimelineSubscriptionStarted()
{
WebInspector.timelineManager.addEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
WebInspector.timelineManager.start();
}
function onTimelineSubscriptionStopped()
{
WebInspector.timelineManager.stop();
WebInspector.timelineManager.removeEventListener(WebInspector.TimelineManager.EventTypes.TimelineEventRecorded,
this._notifyTimelineEventRecorded, this);
}
this._registerSubscriptionHandler(WebInspector.extensionAPI.Events.TimelineEventRecorded,
onTimelineSubscriptionStarted.bind(this), onTimelineSubscriptionStopped.bind(this));
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.InspectedURLChanged,
this._inspectedURLChanged, this);
WebInspector.resourceTreeModel.addEventListener(WebInspector.ResourceTreeModel.EventTypes.MainFrameNavigated, this._mainFrameNavigated, this);
this._initDone = true;
if (this._pendingExtensions) {
this._pendingExtensions.forEach(this._innerAddExtension, this);
delete this._pendingExtensions;
}
InspectorExtensionRegistry.getExtensionsAsync();
},
_notifyConsoleMessageAdded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.ConsoleMessageAdded, this._makeConsoleMessage(event.data));
},
_notifyResourceAdded: function(event)
{
var uiSourceCode = event.data;
this._postNotification(WebInspector.extensionAPI.Events.ResourceAdded, this._makeResource(uiSourceCode));
},
_notifyUISourceCodeContentCommitted: function(event)
{
var uiSourceCode = event.data.uiSourceCode;
var content = event.data.content;
this._postNotification(WebInspector.extensionAPI.Events.ResourceContentCommitted, this._makeResource(uiSourceCode), content);
},
_notifyRequestFinished: function(event)
{
var request = event.data;
this._postNotification(WebInspector.extensionAPI.Events.NetworkRequestFinished, this._requestId(request), (new WebInspector.HAREntry(request)).build());
},
_notifyElementsSelectionChanged: function()
{
this._postNotification(WebInspector.extensionAPI.Events.ElementsPanelObjectSelected);
},
_notifyTimelineEventRecorded: function(event)
{
this._postNotification(WebInspector.extensionAPI.Events.TimelineEventRecorded, event.data);
},
_addExtensions: function(extensions)
{
extensions.forEach(this._addExtension, this);
},
_addExtension: function(extensionInfo)
{
if (this._initDone) {
this._innerAddExtension(extensionInfo);
return;
}
if (this._pendingExtensions)
this._pendingExtensions.push(extensionInfo);
else
this._pendingExtensions = [extensionInfo];
},
_innerAddExtension: function(extensionInfo)
{
const urlOriginRegExp = new RegExp("([^:]+:\/\/[^/]*)\/");
var startPage = extensionInfo.startPage;
var name = extensionInfo.name;
try {
var originMatch = urlOriginRegExp.exec(startPage);
if (!originMatch) {
console.error("Skipping extension with invalid URL: " + startPage);
return false;
}
var extensionOrigin = originMatch[1];
if (!this._registeredExtensions[extensionOrigin]) {
InspectorFrontendHost.setInjectedScriptForOrigin(extensionOrigin, buildExtensionAPIInjectedScript(extensionInfo));
this._registeredExtensions[extensionOrigin] = { name: name };
}
var iframe = document.createElement("iframe");
iframe.src = startPage;
iframe.style.display = "none";
document.body.appendChild(iframe);
} catch (e) {
console.error("Failed to initialize extension " + startPage + ":" + e);
return false;
}
return true;
},
_onWindowMessage: function(event)
{
if (event.data === "registerExtension")
this._registerExtension(event.origin, event.ports[0]);
},
_registerExtension: function(origin, port)
{
if (!this._registeredExtensions.hasOwnProperty(origin)) {
if (origin !== window.location.origin)
console.error("Ignoring unauthorized client request from " + origin);
return;
}
port._extensionOrigin = origin;
port.addEventListener("message", this._onmessage.bind(this), false);
port.start();
},
_onmessage: function(event)
{
var message = event.data;
var result;
if (message.command in this._handlers)
result = this._handlers[message.command](message, event.target);
else
result = this._status.E_NOTSUPPORTED(message.command);
if (result && message.requestId)
this._dispatchCallback(message.requestId, event.target, result);
},
_registerHandler: function(command, callback)
{
this._handlers[command] = callback;
},
_registerSubscriptionHandler: function(eventTopic, onSubscribeFirst, onUnsubscribeLast)
{
this._subscriptionStartHandlers[eventTopic] = onSubscribeFirst;
this._subscriptionStopHandlers[eventTopic] = onUnsubscribeLast;
},
_registerAutosubscriptionHandler: function(eventTopic, eventTarget, frontendEventType, handler)
{
this._registerSubscriptionHandler(eventTopic,
eventTarget.addEventListener.bind(eventTarget, frontendEventType, handler, this),
eventTarget.removeEventListener.bind(eventTarget, frontendEventType, handler, this));
},
_expandResourcePath: function(extensionPath, resourcePath)
{
if (!resourcePath)
return;
return extensionPath + this._normalizePath(resourcePath);
},
_normalizePath: function(path)
{
var source = path.split("/");
var result = [];
for (var i = 0; i < source.length; ++i) {
if (source[i] === ".")
continue;
if (source[i] === "")
continue;
if (source[i] === "..")
result.pop();
else
result.push(source[i]);
}
return "/" + result.join("/");
},
evaluate: function(expression, exposeCommandLineAPI, returnByValue, options, securityOrigin, callback)
{
var contextId;
if (typeof options === "object" && options["useContentScriptContext"]) {
var mainFrame = WebInspector.resourceTreeModel.mainFrame;
if (!mainFrame)
return this._status.E_FAILED("main frame not available yet");
var context = WebInspector.runtimeModel.contextByFrameAndSecurityOrigin(mainFrame, securityOrigin);
if (!context)
return this._status.E_NOTFOUND(securityOrigin);
contextId = context.id;
}
RuntimeAgent.evaluate(expression, "extension", exposeCommandLineAPI, true, contextId, returnByValue, callback);
}
}
WebInspector.ExtensionStatus = function()
{
function makeStatus(code, description)
{
var details = Array.prototype.slice.call(arguments, 2);
var status = { code: code, description: description, details: details };
if (code !== "OK") {
status.isError = true;
console.log("Extension server error: " + String.vsprintf(description, details));
}
return status;
}
this.OK = makeStatus.bind(null, "OK", "OK");
this.E_EXISTS = makeStatus.bind(null, "E_EXISTS", "Object already exists: %s");
this.E_BADARG = makeStatus.bind(null, "E_BADARG", "Invalid argument %s: %s");
this.E_BADARGTYPE = makeStatus.bind(null, "E_BADARGTYPE", "Invalid type for argument %s: got %s, expected %s");
this.E_NOTFOUND = makeStatus.bind(null, "E_NOTFOUND", "Object not found: %s");
this.E_NOTSUPPORTED = makeStatus.bind(null, "E_NOTSUPPORTED", "Object does not support requested operation: %s");
this.E_FAILED = makeStatus.bind(null, "E_FAILED", "Operation failed: %s");
}
WebInspector.addExtensions = function(extensions)
{
WebInspector.extensionServer._addExtensions(extensions);
}
WebInspector.extensionAPI = {};
defineCommonExtensionSymbols(WebInspector.extensionAPI);
WebInspector.extensionServer = new WebInspector.ExtensionServer();
window.addExtension = function(page, name)
{
WebInspector.extensionServer._addExtension({
startPage: page,
name: name,
});
}
WebInspector.ExtensionView = function(id, src, className)
{
WebInspector.View.call(this);
this.element.className = "fill";
this._id = id;
this._iframe = document.createElement("iframe");
this._iframe.addEventListener("load", this._onLoad.bind(this), false);
this._iframe.src = src;
this._iframe.className = className;
this.setDefaultFocusedElement(this._iframe);
this.element.appendChild(this._iframe);
}
WebInspector.ExtensionView.prototype = {
wasShown: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
},
willHide: function()
{
if (typeof this._frameIndex === "number")
WebInspector.extensionServer.notifyViewHidden(this._id);
},
_onLoad: function()
{
this._frameIndex = Array.prototype.indexOf.call(window.frames, this._iframe.contentWindow);
if (this.isShowing())
WebInspector.extensionServer.notifyViewShown(this._id, this._frameIndex);
}
}
WebInspector.ExtensionView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ExtensionNotifierView = function(id)
{
WebInspector.View.call(this);
this._id = id;
}
WebInspector.ExtensionNotifierView.prototype = {
wasShown: function()
{
WebInspector.extensionServer.notifyViewShown(this._id);
},
willHide: function()
{
WebInspector.extensionServer.notifyViewHidden(this._id);
}
}
WebInspector.ExtensionNotifierView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.ExtensionPanel = function(id, pageURL)
{
WebInspector.Panel.call(this, id);
this.setHideOnDetach();
this._statusBarItems = [];
var extensionView = new WebInspector.ExtensionView(id, pageURL, "extension panel");
extensionView.show(this.element);
this.setDefaultFocusedElement(extensionView.defaultFocusedElement());
}
WebInspector.ExtensionPanel.prototype = {
defaultFocusedElement: function()
{
return WebInspector.View.prototype.defaultFocusedElement.call(this);
},
get statusBarItems()
{
return this._statusBarItems;
},
addStatusBarItem: function(element)
{
this._statusBarItems.push(element);
},
searchCanceled: function(startingNewSearch)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.CancelSearch);
WebInspector.Panel.prototype.searchCanceled.apply(this, arguments);
},
performSearch: function(query)
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PerformSearch, query);
WebInspector.Panel.prototype.performSearch.apply(this, arguments);
},
jumpToNextSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.NextSearchResult);
WebInspector.Panel.prototype.jumpToNextSearchResult.call(this);
},
jumpToPreviousSearchResult: function()
{
WebInspector.extensionServer.notifySearchAction(this.name, WebInspector.extensionAPI.panels.SearchAction.PreviousSearchResult);
WebInspector.Panel.prototype.jumpToPreviousSearchResult.call(this);
}
}
WebInspector.ExtensionPanel.prototype.__proto__ = WebInspector.Panel.prototype;
WebInspector.ExtensionButton = function(id, iconURL, tooltip, disabled)
{
this._id = id;
this.element = document.createElement("button");
this.element.className = "status-bar-item extension";
this.element.addEventListener("click", this._onClicked.bind(this), false);
this.update(iconURL, tooltip, disabled);
}
WebInspector.ExtensionButton.prototype = {
update: function(iconURL, tooltip, disabled)
{
if (typeof iconURL === "string")
this.element.style.backgroundImage = "url(" + iconURL + ")";
if (typeof tooltip === "string")
this.element.title = tooltip;
if (typeof disabled === "boolean")
this.element.disabled = disabled;
},
_onClicked: function()
{
WebInspector.extensionServer.notifyButtonClicked(this._id);
}
}
WebInspector.ExtensionSidebarPane = function(title, id)
{
WebInspector.SidebarPane.call(this, title);
this._id = id;
}
WebInspector.ExtensionSidebarPane.prototype = {
setObject: function(object, title, callback)
{
this._createObjectPropertiesView();
this._setObject(WebInspector.RemoteObject.fromLocalObject(object), title, callback);
},
setExpression: function(expression, title, evaluateOptions, securityOrigin, callback)
{
this._createObjectPropertiesView();
return WebInspector.extensionServer.evaluate(expression, true, false, evaluateOptions, securityOrigin, this._onEvaluate.bind(this, title, callback));
},
setPage: function(url)
{
if (this._objectPropertiesView) {
this._objectPropertiesView.detach();
delete this._objectPropertiesView;
}
if (this._extensionView)
this._extensionView.detach(true);
this._extensionView = new WebInspector.ExtensionView(this._id, url, "extension fill");
this._extensionView.show(this.bodyElement);
if (!this.bodyElement.style.height)
this.setHeight("150px");
},
setHeight: function(height)
{
this.bodyElement.style.height = height;
},
_onEvaluate: function(title, callback, error, result, wasThrown)
{
if (error)
callback(error.toString());
else
this._setObject(WebInspector.RemoteObject.fromPayload(result), title, callback);
},
_createObjectPropertiesView: function()
{
if (this._objectPropertiesView)
return;
if (this._extensionView) {
this._extensionView.detach(true);
delete this._extensionView;
}
this._objectPropertiesView = new WebInspector.ExtensionNotifierView(this._id);
this._objectPropertiesView.show(this.bodyElement);
},
_setObject: function(object, title, callback)
{
if (!this._objectPropertiesView) {
callback("operation cancelled");
return;
}
this._objectPropertiesView.element.removeChildren();
var section = new WebInspector.ObjectPropertiesSection(object, title);
if (!title)
section.headerElement.addStyleClass("hidden");
section.expanded = true;
section.editable = false;
this._objectPropertiesView.element.appendChild(section.element);
callback();
}
}
WebInspector.ExtensionSidebarPane.prototype.__proto__ = WebInspector.SidebarPane.prototype;
WebInspector.EmptyView = function(text)
{
WebInspector.View.call(this);
this._text = text;
}
WebInspector.EmptyView.prototype = {
wasShown: function()
{
this.element.className = "storage-empty-view";
this.element.textContent = this._text;
},
set text(text)
{
this._text = text;
if (this.isShowing())
this.element.textContent = this._text;
},
}
WebInspector.EmptyView.prototype.__proto__ = WebInspector.View.prototype;
WebInspector.Formatter = function()
{
}
WebInspector.Formatter.createFormatter = function(contentType)
{
if (contentType === WebInspector.resourceTypes.Script || contentType === WebInspector.resourceTypes.Document)
return new WebInspector.ScriptFormatter();
return new WebInspector.IdentityFormatter();
}
WebInspector.Formatter.locationToPosition = function(lineEndings, lineNumber, columnNumber)
{
var position = lineNumber ? lineEndings[lineNumber - 1] + 1 : 0;
return position + columnNumber;
}
WebInspector.Formatter.positionToLocation = function(lineEndings, position)
{
var lineNumber = lineEndings.upperBound(position - 1);
if (!lineNumber)
var columnNumber = position;
else
var columnNumber = position - lineEndings[lineNumber - 1] - 1;
return [lineNumber, columnNumber];
}
WebInspector.Formatter.prototype = {
formatContent: function(mimeType, content, callback)
{
}
}
WebInspector.ScriptFormatter = function()
{
this._tasks = [];
}
WebInspector.ScriptFormatter.prototype = {
formatContent: function(mimeType, content, callback)
{
content = content.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '');
const method = "format";
var parameters = { mimeType: mimeType, content: content, indentString: WebInspector.settings.textEditorIndent.get() };
this._tasks.push({ data: parameters, callback: callback });
this._worker.postMessage({ method: method, params: parameters });
},
_didFormatContent: function(event)
{
var task = this._tasks.shift();
var originalContent = task.data.content;
var formattedContent = event.data.content;
var mapping = event.data["mapping"];
var sourceMapping = new WebInspector.FormatterSourceMappingImpl(originalContent.lineEndings(), formattedContent.lineEndings(), mapping);
task.callback(formattedContent, sourceMapping);
},
get _worker()
{
if (!this._cachedWorker) {
this._cachedWorker = new Worker("ScriptFormatterWorker.js");
this._cachedWorker.onmessage = this._didFormatContent.bind(this);
}
return this._cachedWorker;
}
}
WebInspector.IdentityFormatter = function()
{
this._tasks = [];
}
WebInspector.IdentityFormatter.prototype = {
formatContent: function(mimeType, content, callback)
{
callback(content, new WebInspector.IdentityFormatterSourceMapping());
}
}
WebInspector.FormatterMappingPayload = function()
{
this.original = [];
this.formatted = [];
}
WebInspector.FormatterSourceMapping = function()
{
}
WebInspector.FormatterSourceMapping.prototype = {
originalToFormatted: function(lineNumber, columnNumber) { },
formattedToOriginal: function(lineNumber, columnNumber) { }
}
WebInspector.IdentityFormatterSourceMapping = function()
{
}
WebInspector.IdentityFormatterSourceMapping.prototype = {
originalToFormatted: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0];
},
formattedToOriginal: function(lineNumber, columnNumber)
{
return [lineNumber, columnNumber || 0];
}
}
WebInspector.FormatterSourceMappingImpl = function(originalLineEndings, formattedLineEndings, mapping)
{
this._originalLineEndings = originalLineEndings;
this._formattedLineEndings = formattedLineEndings;
this._mapping = mapping;
}
WebInspector.FormatterSourceMappingImpl.prototype = {
originalToFormatted: function(lineNumber, columnNumber)
{
var originalPosition = WebInspector.Formatter.locationToPosition(this._originalLineEndings, lineNumber, columnNumber || 0);
var formattedPosition = this._convertPosition(this._mapping.original, this._mapping.formatted, originalPosition || 0);
return WebInspector.Formatter.positionToLocation(this._formattedLineEndings, formattedPosition);
},
formattedToOriginal: function(lineNumber, columnNumber)
{
var formattedPosition = WebInspector.Formatter.locationToPosition(this._formattedLineEndings, lineNumber, columnNumber || 0);
var originalPosition = this._convertPosition(this._mapping.formatted, this._mapping.original, formattedPosition);
return WebInspector.Formatter.positionToLocation(this._originalLineEndings, originalPosition || 0);
},
_convertPosition: function(positions1, positions2, position)
{
var index = positions1.upperBound(position) - 1;
var convertedPosition = positions2[index] + position - positions1[index];
if (index < positions2.length - 1 && convertedPosition > positions2[index + 1])
convertedPosition = positions2[index + 1];
return convertedPosition;
}
}
WebInspector.DOMSyntaxHighlighter = function(mimeType, stripExtraWhitespace)
{
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
this._stripExtraWhitespace = stripExtraWhitespace;
}
WebInspector.DOMSyntaxHighlighter.prototype = {
createSpan: function(content, className)
{
var span = document.createElement("span");
span.className = "webkit-" + className;
if (this._stripExtraWhitespace)
content = content.replace(/^[\n\r]*/, "").replace(/\s*$/, "");
span.appendChild(document.createTextNode(content));
return span;
},
syntaxHighlightNode: function(node)
{
this._tokenizer.condition = this._tokenizer.createInitialCondition();
var lines = node.textContent.split("\n");
node.removeChildren();
for (var i = lines[0].length ? 0 : 1; i < lines.length; ++i) {
var line = lines[i];
var plainTextStart = 0;
this._tokenizer.line = line;
var column = 0;
do {
var newColumn = this._tokenizer.nextToken(column);
var tokenType = this._tokenizer.tokenType;
if (tokenType) {
if (column > plainTextStart) {
var plainText = line.substring(plainTextStart, column);
node.appendChild(document.createTextNode(plainText));
}
var token = line.substring(column, newColumn);
node.appendChild(this.createSpan(token, tokenType));
plainTextStart = newColumn;
}
column = newColumn;
} while (column < line.length)
if (plainTextStart < line.length) {
var plainText = line.substring(plainTextStart, line.length);
node.appendChild(document.createTextNode(plainText));
}
if (i < lines.length - 1)
node.appendChild(document.createElement("br"));
}
}
}
WebInspector.TextRange = function(startLine, startColumn, endLine, endColumn)
{
this.startLine = startLine;
this.startColumn = startColumn;
this.endLine = endLine;
this.endColumn = endColumn;
}
WebInspector.TextRange.createFromLocation = function(line, column)
{
return new WebInspector.TextRange(line, column, line, column);
}
WebInspector.TextRange.fromObject = function (serializedTextRange)
{
return new WebInspector.TextRange(serializedTextRange.startLine, serializedTextRange.startColumn, serializedTextRange.endLine, serializedTextRange.endColumn);
}
WebInspector.TextRange.prototype = {
isEmpty: function()
{
return this.startLine === this.endLine && this.startColumn === this.endColumn;
},
get linesCount()
{
return this.endLine - this.startLine;
},
collapseToEnd: function()
{
return new WebInspector.TextRange(this.endLine, this.endColumn, this.endLine, this.endColumn);
},
normalize: function()
{
if (this.startLine > this.endLine || (this.startLine === this.endLine && this.startColumn > this.endColumn))
return new WebInspector.TextRange(this.endLine, this.endColumn, this.startLine, this.startColumn);
else
return this;
},
clone: function()
{
return new WebInspector.TextRange(this.startLine, this.startColumn, this.endLine, this.endColumn);
},
serializeToObject: function()
{
var serializedTextRange = {};
serializedTextRange.startLine = this.startLine;
serializedTextRange.startColumn = this.startColumn;
serializedTextRange.endLine = this.endLine;
serializedTextRange.endColumn = this.endColumn;
return serializedTextRange;
},
compareTo: function(other)
{
if (this.startLine > other.startLine)
return 1;
if (this.startLine < other.startLine)
return -1;
if (this.startColumn > other.startColumn)
return 1;
if (this.startColumn < other.startColumn)
return -1;
return 0;
}
}
WebInspector.TextEditorCommand = function(newRange, originalText)
{
this.newRange = newRange;
this.originalText = originalText;
}
WebInspector.TextEditorModel = function()
{
this._lines = [""];
this._attributes = [];
this._undoStack = [];
this._noPunctuationRegex = /[^ !%&()*+,-.:;<=>?\[\]\^{|}~]+/;
this._lineBreak = "\n";
}
WebInspector.TextEditorModel.Indent = {
TwoSpaces: " ",
FourSpaces: " ",
EightSpaces: " ",
TabCharacter: "\t"
}
WebInspector.TextEditorModel.Events = {
TextChanged: "TextChanged"
}
WebInspector.TextEditorModel.endsWithBracketRegex = /[{(\[]\s*$/;
WebInspector.TextEditorModel.prototype = {
get linesCount()
{
return this._lines.length;
},
text: function()
{
return this._lines.join(this._lineBreak);
},
range: function()
{
return new WebInspector.TextRange(0, 0, this._lines.length - 1, this._lines[this._lines.length - 1].length);
},
get lineBreak()
{
return this._lineBreak;
},
line: function(lineNumber)
{
if (lineNumber >= this._lines.length)
throw "Out of bounds:" + lineNumber;
return this._lines[lineNumber];
},
lineLength: function(lineNumber)
{
return this._lines[lineNumber].length;
},
setText: function(text)
{
text = text || "";
var range = this.range();
this._lineBreak = /\r\n/.test(text) ? "\r\n" : "\n";
var newRange = this._innerSetText(range, text);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange});
},
editRange: function(range, text)
{
var originalText = this.copyRange(range);
if (text === originalText)
return range;
var newRange = this._innerSetText(range, text);
this._pushUndoableCommand(newRange, originalText);
this.dispatchEventToListeners(WebInspector.TextEditorModel.Events.TextChanged, { oldRange: range, newRange: newRange });
return newRange;
},
_innerSetText: function(range, text)
{
this._eraseRange(range);
if (text === "")
return new WebInspector.TextRange(range.startLine, range.startColumn, range.startLine, range.startColumn);
var newLines = text.split(/\r?\n/);
var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var suffix = this._lines[range.startLine].substring(range.startColumn);
var postCaret = prefix.length;
if (newLines.length === 1) {
this._setLine(range.startLine, prefix + newLines[0] + suffix);
postCaret += newLines[0].length;
} else {
this._setLine(range.startLine, prefix + newLines[0]);
this._insertLines(range, newLines);
this._setLine(range.startLine + newLines.length - 1, newLines[newLines.length - 1] + suffix);
postCaret = newLines[newLines.length - 1].length;
}
return new WebInspector.TextRange(range.startLine, range.startColumn,
range.startLine + newLines.length - 1, postCaret);
},
_insertLines: function(range, newLines)
{
var lines = new Array(this._lines.length + newLines.length - 1);
for (var i = 0; i <= range.startLine; ++i)
lines[i] = this._lines[i];
for (var i = 1; i < newLines.length; ++i)
lines[range.startLine + i] = newLines[i];
for (var i = range.startLine + newLines.length; i < lines.length; ++i)
lines[i] = this._lines[i - newLines.length + 1];
this._lines = lines;
var attributes = new Array(lines.length);
var insertionIndex = range.startColumn ? range.startLine + 1 : range.startLine;
for (var i = 0; i < insertionIndex; ++i)
attributes[i] = this._attributes[i];
for (var i = insertionIndex + newLines.length - 1; i < attributes.length; ++i)
attributes[i] = this._attributes[i - newLines.length + 1];
this._attributes = attributes;
},
_eraseRange: function(range)
{
if (range.isEmpty())
return;
var prefix = this._lines[range.startLine].substring(0, range.startColumn);
var suffix = this._lines[range.endLine].substring(range.endColumn);
if (range.endLine > range.startLine) {
this._lines.splice(range.startLine + 1, range.endLine - range.startLine);
this._attributes.splice(range.startColumn ? range.startLine + 1 : range.startLine, range.endLine - range.startLine);
}
this._setLine(range.startLine, prefix + suffix);
},
_setLine: function(lineNumber, text)
{
this._lines[lineNumber] = text;
},
wordRange: function(lineNumber, column)
{
return new WebInspector.TextRange(lineNumber, this.wordStart(lineNumber, column, true), lineNumber, this.wordEnd(lineNumber, column, true));
},
wordStart: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var prefix = line.substring(0, column).split("").reverse().join("");
var prefixMatch = this._noPunctuationRegex.exec(prefix);
return prefixMatch && (!gapless || prefixMatch.index === 0) ? column - prefixMatch.index - prefixMatch[0].length : column;
},
wordEnd: function(lineNumber, column, gapless)
{
var line = this._lines[lineNumber];
var suffix = line.substring(column);
var suffixMatch = this._noPunctuationRegex.exec(suffix);
return suffixMatch && (!gapless || suffixMatch.index === 0) ? column + suffixMatch.index + suffixMatch[0].length : column;
},
copyRange: function(range)
{
if (!range)
range = this.range();
var clip = [];
if (range.startLine === range.endLine) {
clip.push(this._lines[range.startLine].substring(range.startColumn, range.endColumn));
return clip.join(this._lineBreak);
}
clip.push(this._lines[range.startLine].substring(range.startColumn));
for (var i = range.startLine + 1; i < range.endLine; ++i)
clip.push(this._lines[i]);
clip.push(this._lines[range.endLine].substring(0, range.endColumn));
return clip.join(this._lineBreak);
},
setAttribute: function(line, name, value)
{
var attrs = this._attributes[line];
if (!attrs) {
attrs = {};
this._attributes[line] = attrs;
}
attrs[name] = value;
},
getAttribute: function(line, name)
{
var attrs = this._attributes[line];
return attrs ? attrs[name] : null;
},
removeAttribute: function(line, name)
{
var attrs = this._attributes[line];
if (attrs)
delete attrs[name];
},
_pushUndoableCommand: function(newRange, originalText)
{
var command = new WebInspector.TextEditorCommand(newRange.clone(), originalText);
if (this._inUndo)
this._redoStack.push(command);
else {
if (!this._inRedo)
this._redoStack = [];
this._undoStack.push(command);
}
return command;
},
undo: function(beforeCallback, afterCallback)
{
if (!this._undoStack.length)
return null;
this._markRedoableState();
this._inUndo = true;
var range = this._doUndo(this._undoStack, beforeCallback, afterCallback);
delete this._inUndo;
return range;
},
redo: function(beforeCallback, afterCallback)
{
if (!this._redoStack || !this._redoStack.length)
return null;
this.markUndoableState();
this._inRedo = true;
var range = this._doUndo(this._redoStack, beforeCallback, afterCallback);
delete this._inRedo;
return range;
},
_doUndo: function(stack, beforeCallback, afterCallback)
{
var range = null;
for (var i = stack.length - 1; i >= 0; --i) {
var command = stack[i];
stack.length = i;
if (beforeCallback)
beforeCallback();
range = this.editRange(command.newRange, command.originalText);
if (afterCallback)
afterCallback(command.newRange, range);
if (i > 0 && stack[i - 1].explicit)
return range;
}
return range;
},
markUndoableState: function()
{
if (this._undoStack.length)
this._undoStack[this._undoStack.length - 1].explicit = true;
},
_markRedoableState: function()
{
if (this._redoStack.length)
this._redoStack[this._redoStack.length - 1].explicit = true;
},
resetUndoStack: function()
{
this._undoStack = [];
}
}
WebInspector.TextEditorModel.prototype.__proto__ = WebInspector.Object.prototype;
WebInspector.TextEditorHighlighter = function(textModel, damageCallback)
{
this._textModel = textModel;
this._tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/html");
this._damageCallback = damageCallback;
this._highlightChunkLimit = 1000;
}
WebInspector.TextEditorHighlighter._MaxLineCount = 10000;
WebInspector.TextEditorHighlighter.prototype = {
set mimeType(mimeType)
{
var tokenizer = WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer(mimeType);
if (tokenizer)
this._tokenizer = tokenizer;
},
set highlightChunkLimit(highlightChunkLimit)
{
this._highlightChunkLimit = highlightChunkLimit;
},
highlight: function(endLine, forceRun)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;
var state = this._textModel.getAttribute(endLine - 1, "highlight");
if (state && state.postConditionStringified) {
return;
}
this._requestedEndLine = endLine;
if (this._highlightTimer && !forceRun) {
return;
}
var startLine = endLine;
while (startLine > 0) {
state = this._textModel.getAttribute(startLine - 1, "highlight");
if (state && state.postConditionStringified)
break;
startLine--;
}
this._highlightInChunks(startLine, endLine);
},
updateHighlight: function(startLine, endLine)
{
if (this._textModel.linesCount > WebInspector.TextEditorHighlighter._MaxLineCount)
return;
this._clearHighlightState(startLine);
if (startLine) {
var state = this._textModel.getAttribute(startLine - 1, "highlight");
if (!state || !state.postConditionStringified) {
return false;
}
}
var restored = this._highlightLines(startLine, endLine);
if (!restored) {
for (var i = this._lastHighlightedLine; i < this._textModel.linesCount; ++i) {
var state = this._textModel.getAttribute(i, "highlight");
if (!state && i > endLine)
break;
this._textModel.setAttribute(i, "highlight-outdated", state);
this._textModel.removeAttribute(i, "highlight");
}
if (this._highlightTimer) {
clearTimeout(this._highlightTimer);
this._requestedEndLine = endLine;
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
}
}
return restored;
},
_highlightInChunks: function(startLine, endLine)
{
delete this._highlightTimer;
var state = this._textModel.getAttribute(this._requestedEndLine - 1, "highlight");
if (state && state.postConditionStringified)
return;
if (this._requestedEndLine !== endLine) {
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, startLine, this._requestedEndLine), 100);
return;
}
if (this._requestedEndLine > this._textModel.linesCount)
this._requestedEndLine = this._textModel.linesCount;
this._highlightLines(startLine, this._requestedEndLine);
if (this._lastHighlightedLine < this._requestedEndLine)
this._highlightTimer = setTimeout(this._highlightInChunks.bind(this, this._lastHighlightedLine, this._requestedEndLine), 10);
},
_highlightLines: function(startLine, endLine)
{
var state = this._textModel.getAttribute(startLine - 1, "highlight");
var postConditionStringified = state ? state.postConditionStringified : JSON.stringify(this._tokenizer.createInitialCondition());
var tokensCount = 0;
for (var lineNumber = startLine; lineNumber < endLine; ++lineNumber) {
state = this._selectHighlightState(lineNumber, postConditionStringified);
if (state.postConditionStringified) {
postConditionStringified = state.postConditionStringified;
} else {
var lastHighlightedColumn = 0;
if (state.midConditionStringified) {
lastHighlightedColumn = state.lastHighlightedColumn;
postConditionStringified = state.midConditionStringified;
}
var line = this._textModel.line(lineNumber);
this._tokenizer.line = line;
this._tokenizer.condition = JSON.parse(postConditionStringified);
do {
var newColumn = this._tokenizer.nextToken(lastHighlightedColumn);
var tokenType = this._tokenizer.tokenType;
if (tokenType)
state[lastHighlightedColumn] = { length: newColumn - lastHighlightedColumn, tokenType: tokenType };
lastHighlightedColumn = newColumn;
if (++tokensCount > this._highlightChunkLimit)
break;
} while (lastHighlightedColumn < line.length);
postConditionStringified = JSON.stringify(this._tokenizer.condition);
if (lastHighlightedColumn < line.length) {
state.lastHighlightedColumn = lastHighlightedColumn;
state.midConditionStringified = postConditionStringified;
break;
} else {
delete state.lastHighlightedColumn;
delete state.midConditionStringified;
state.postConditionStringified = postConditionStringified;
}
}
var nextLineState = this._textModel.getAttribute(lineNumber + 1, "highlight");
if (nextLineState && nextLineState.preConditionStringified === state.postConditionStringified) {
++lineNumber;
this._damageCallback(startLine, lineNumber);
for (; lineNumber < endLine; ++lineNumber) {
state = this._textModel.getAttribute(lineNumber, "highlight");
if (!state || !state.postConditionStringified)
break;
}
this._lastHighlightedLine = lineNumber;
return true;
}
}
this._damageCallback(startLine, lineNumber);
this._lastHighlightedLine = lineNumber;
return false;
},
_selectHighlightState: function(lineNumber, preConditionStringified)
{
var state = this._textModel.getAttribute(lineNumber, "highlight");
if (state && state.preConditionStringified === preConditionStringified)
return state;
var outdatedState = this._textModel.getAttribute(lineNumber, "highlight-outdated");
if (outdatedState && outdatedState.preConditionStringified === preConditionStringified) {
this._textModel.setAttribute(lineNumber, "highlight", outdatedState);
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
return outdatedState;
}
if (state)
this._textModel.setAttribute(lineNumber, "highlight-outdated", state);
state = {};
state.preConditionStringified = preConditionStringified;
this._textModel.setAttribute(lineNumber, "highlight", state);
return state;
},
_clearHighlightState: function(lineNumber)
{
this._textModel.removeAttribute(lineNumber, "highlight");
this._textModel.removeAttribute(lineNumber, "highlight-outdated");
}
}
WebInspector.SourceTokenizer = function()
{
}
WebInspector.SourceTokenizer.prototype = {
set line(line) {
this._line = line;
},
set condition(condition)
{
this._condition = condition;
},
get condition()
{
return this._condition;
},
getLexCondition: function()
{
return this.condition.lexCondition;
},
setLexCondition: function(lexCondition)
{
this.condition.lexCondition = lexCondition;
},
_charAt: function(cursor)
{
return cursor < this._line.length ? this._line.charAt(cursor) : "\n";
},
createInitialCondition: function()
{
},
nextToken: function(cursor)
{
}
}
WebInspector.SourceTokenizer.Registry = function() {
this._tokenizers = {};
this._tokenizerConstructors = {
"text/css": "SourceCSSTokenizer",
"text/html": "SourceHTMLTokenizer",
"text/javascript": "SourceJavaScriptTokenizer",
"text/x-scss": "SourceCSSTokenizer"
};
}
WebInspector.SourceTokenizer.Registry.getInstance = function()
{
if (!WebInspector.SourceTokenizer.Registry._instance)
WebInspector.SourceTokenizer.Registry._instance = new WebInspector.SourceTokenizer.Registry();
return WebInspector.SourceTokenizer.Registry._instance;
}
WebInspector.SourceTokenizer.Registry.prototype = {
getTokenizer: function(mimeType)
{
if (!this._tokenizerConstructors[mimeType])
return null;
var tokenizerClass = this._tokenizerConstructors[mimeType];
var tokenizer = this._tokenizers[tokenizerClass];
if (!tokenizer) {
tokenizer = new WebInspector[tokenizerClass]();
this._tokenizers[tokenizerClass] = tokenizer;
}
return tokenizer;
}
}
WebInspector.SourceCSSTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);
this._propertyKeywords = WebInspector.CSSCompletions.cssPropertiesMetainfoKeySet();
this._colorKeywords = WebInspector.CSSKeywordCompletions.colors();
this._valueKeywords = [
"above", "absolute", "activeborder", "activecaption", "afar", "after-white-space", "ahead", "alias", "all", "all-scroll",
"alternate", "always", "amharic", "amharic-abegede", "antialiased", "appworkspace", "arabic-indic", "armenian", "asterisks",
"auto", "avoid", "background", "backwards", "baseline", "below", "bidi-override", "binary", "bengali", "blink",
"block", "block-axis", "bold", "bolder", "border", "border-box", "both", "bottom", "break-all", "break-word", "button",
"button-bevel", "buttonface", "buttonhighlight", "buttonshadow", "buttontext", "cambodian", "capitalize", "caps-lock-indicator",
"caption", "captiontext", "caret", "cell", "center", "checkbox", "circle", "cjk-earthly-branch", "cjk-heavenly-stem", "cjk-ideographic",
"clear", "clip", "close-quote", "col-resize", "collapse", "compact", "condensed", "contain", "content", "content-box", "context-menu",
"continuous", "copy", "cover", "crop", "cross", "crosshair", "currentcolor", "cursive", "dashed", "decimal", "decimal-leading-zero", "default",
"default-button", "destination-atop", "destination-in", "destination-out", "destination-over", "devanagari", "disc", "discard", "document",
"dot-dash", "dot-dot-dash", "dotted", "double", "down", "e-resize", "ease", "ease-in", "ease-in-out", "ease-out", "element",
"ellipsis", "embed", "end", "ethiopic", "ethiopic-abegede", "ethiopic-abegede-am-et", "ethiopic-abegede-gez",
"ethiopic-abegede-ti-er", "ethiopic-abegede-ti-et", "ethiopic-halehame-aa-er", "ethiopic-halehame-aa-et",
"ethiopic-halehame-am-et", "ethiopic-halehame-gez", "ethiopic-halehame-om-et", "ethiopic-halehame-sid-et",
"ethiopic-halehame-so-et", "ethiopic-halehame-ti-er", "ethiopic-halehame-ti-et", "ethiopic-halehame-tig", "ew-resize", "expanded",
"extra-condensed", "extra-expanded", "fantasy", "fast", "fill", "fixed", "flat", "footnotes", "forwards", "from", "geometricPrecision",
"georgian", "graytext", "groove", "gujarati", "gurmukhi", "hand", "hangul", "hangul-consonant", "hebrew", "help",
"hidden", "hide", "higher", "highlight", "highlighttext", "hiragana", "hiragana-iroha", "horizontal", "hsl", "hsla", "icon", "ignore",
"inactiveborder", "inactivecaption", "inactivecaptiontext", "infinite", "infobackground", "infotext", "inherit", "initial", "inline",
"inline-axis", "inline-block", "inline-table", "inset", "inside", "intrinsic", "invert", "italic", "justify", "kannada", "katakana",
"katakana-iroha", "khmer", "landscape", "lao", "large", "larger", "left", "level", "lighter", "line-through", "linear", "lines",
"list-item", "listbox", "listitem", "local", "logical", "loud", "lower", "lower-alpha", "lower-armenian", "lower-greek",
"lower-hexadecimal", "lower-latin", "lower-norwegian", "lower-roman", "lowercase", "ltr", "malayalam", "match", "media-controls-background",
"media-current-time-display", "media-fullscreen-button", "media-mute-button", "media-play-button", "media-return-to-realtime-button",
"media-rewind-button", "media-seek-back-button", "media-seek-forward-button", "media-slider", "media-sliderthumb", "media-time-remaining-display",
"media-volume-slider", "media-volume-slider-container", "media-volume-sliderthumb", "medium", "menu", "menulist", "menulist-button",
"menulist-text", "menulist-textfield", "menutext", "message-box", "middle", "min-intrinsic", "mix", "mongolian", "monospace", "move", "multiple",
"myanmar", "n-resize", "narrower", "navy", "ne-resize", "nesw-resize", "no-close-quote", "no-drop", "no-open-quote", "no-repeat", "none",
"normal", "not-allowed", "nowrap", "ns-resize", "nw-resize", "nwse-resize", "oblique", "octal", "open-quote", "optimizeLegibility",
"optimizeSpeed", "oriya", "oromo", "outset", "outside", "overlay", "overline", "padding", "padding-box", "painted", "paused",
"persian", "plus-darker", "plus-lighter", "pointer", "portrait", "pre", "pre-line", "pre-wrap", "preserve-3d", "progress",
"push-button", "radio", "read-only", "read-write", "read-write-plaintext-only", "relative", "repeat", "repeat-x",
"repeat-y", "reset", "reverse", "rgb", "rgba", "ridge", "right", "round", "row-resize", "rtl", "run-in", "running", "s-resize", "sans-serif",
"scroll", "scrollbar", "se-resize", "searchfield", "searchfield-cancel-button", "searchfield-decoration", "searchfield-results-button",
"searchfield-results-decoration", "semi-condensed", "semi-expanded", "separate", "serif", "show", "sidama", "single",
"skip-white-space", "slide", "slider-horizontal", "slider-vertical", "sliderthumb-horizontal", "sliderthumb-vertical", "slow",
"small", "small-caps", "small-caption", "smaller", "solid", "somali", "source-atop", "source-in", "source-out", "source-over",
"space", "square", "square-button", "start", "static", "status-bar", "stretch", "stroke", "sub", "subpixel-antialiased", "super",
"sw-resize", "table", "table-caption", "table-cell", "table-column", "table-column-group", "table-footer-group", "table-header-group",
"table-row", "table-row-group", "telugu", "text", "text-bottom", "text-top", "textarea", "textfield", "thai", "thick", "thin",
"threeddarkshadow", "threedface", "threedhighlight", "threedlightshadow", "threedshadow", "tibetan", "tigre", "tigrinya-er", "tigrinya-er-abegede",
"tigrinya-et", "tigrinya-et-abegede", "to", "top", "transparent", "ultra-condensed", "ultra-expanded", "underline", "up", "upper-alpha", "upper-armenian",
"upper-greek", "upper-hexadecimal", "upper-latin", "upper-norwegian", "upper-roman", "uppercase", "urdu", "url", "vertical", "vertical-text", "visible",
"visibleFill", "visiblePainted", "visibleStroke", "visual", "w-resize", "wait", "wave", "white", "wider", "window", "windowframe", "windowtext",
"x-large", "x-small", "xor", "xx-large", "xx-small", "yellow", "-wap-marquee", "-webkit-activelink", "-webkit-auto", "-webkit-baseline-middle",
"-webkit-body", "-webkit-box", "-webkit-center", "-webkit-control", "-webkit-focus-ring-color", "-webkit-grab", "-webkit-grabbing",
"-webkit-gradient", "-webkit-inline-box", "-webkit-left", "-webkit-link", "-webkit-marquee", "-webkit-mini-control", "-webkit-nowrap", "-webkit-pictograph",
"-webkit-right", "-webkit-small-control", "-webkit-text", "-webkit-xxx-large", "-webkit-zoom-in", "-webkit-zoom-out",
].keySet();
this._scssValueKeywords = [
"abs", "adjust-color", "adjust-hue", "alpha", "append", "ceil", "change-color", "comparable", "complement", "darken", "desaturate",
"fade-in", "fade-out", "floor", "grayscale", "hue", "ie-hex-str", "invert", "join", "length", "lighten",
"lightness", "max", "min", "mix", "nth", "opacify", "opacity", "percentage", "quote", "round", "saturate",
"saturation", "scale-color", "transparentize", "type-of", "unit", "unitless", "unquote", "zip"
].keySet();
this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DSTRING: 2,
SSTRING: 3
};
this._parseConditions = {
INITIAL: 0,
PROPERTY: 1,
PROPERTY_VALUE: 2,
AT_RULE: 3,
AT_MEDIA_RULE: 4
};
this.case_INITIAL = 1000;
this.case_COMMENT = 1002;
this.case_DSTRING = 1003;
this.case_SSTRING = 1004;
this.condition = this.createInitialCondition();
}
WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords = ["from", "if", "in", "through"].keySet();
WebInspector.SourceCSSTokenizer.MediaTypes = ["all", "aural", "braille", "embossed", "handheld", "import", "print", "projection", "screen", "tty", "tv"].keySet();
WebInspector.SourceCSSTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
_stringToken: function(cursor, stringEnds)
{
if (this._isPropertyValue())
this.tokenType = "css-string";
else
this.tokenType = null;
return cursor;
},
_isPropertyValue: function()
{
return this._condition.parseCondition === this._parseConditions.PROPERTY_VALUE || this._condition.parseCondition === this._parseConditions.AT_RULE;
},
_setParseCondition: function(condition)
{
this._condition.parseCondition = condition;
},
nextToken: function(cursor)
{
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
while (1) {
switch (gotoCase)
{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 2) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
{ gotoCase = this.case_COMMENT; continue; };
}
} else {
if (this.getLexCondition() < 3) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}
case this.case_COMMENT:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '*') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "css-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 12; continue; };
case 4:
++cursor;
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych != '/') { gotoCase = 11; continue; };
case 7:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "css-comment"; return cursor; }
case 9:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 9; continue; };
if (yych == '/') { gotoCase = 7; continue; };
case 11:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 12:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 11; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '*') { gotoCase = 9; continue; };
{ gotoCase = 11; continue; };
}
case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 17; continue; };
if (yych <= '\f') { gotoCase = 16; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 16; continue; };
{ gotoCase = 19; continue; };
} else {
if (yych == '\\') { gotoCase = 21; continue; };
{ gotoCase = 16; continue; };
}
}
case 15:
{ return this._stringToken(cursor); }
case 16:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 23; continue; };
case 17:
++cursor;
case 18:
{ this.tokenType = null; return cursor; }
case 19:
++cursor;
case 20:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 21:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych <= '&') { gotoCase = 18; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 18; continue; };
} else {
if (yych != 'b') { gotoCase = 18; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 18; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych <= 'q') { gotoCase = 18; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 18; continue; };
} else {
if (yych != 'v') { gotoCase = 18; continue; };
}
}
}
case 22:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 15; continue; };
if (yych <= '\f') { gotoCase = 22; continue; };
{ gotoCase = 15; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 22; continue; };
{ gotoCase = 26; continue; };
} else {
if (yych != '\\') { gotoCase = 22; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 22; continue; };
if (yych >= '\'') { gotoCase = 22; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 22; continue; };
} else {
if (yych == 'b') { gotoCase = 22; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 22; continue; };
} else {
if (yych <= 'n') { gotoCase = 22; continue; };
if (yych >= 'r') { gotoCase = 22; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 22; continue; };
} else {
if (yych == 'v') { gotoCase = 22; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 15; continue; };
case 26:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 20; continue; };
case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych <= ':') {
if (yych <= '&') {
if (yych <= '"') {
if (yych <= ' ') { gotoCase = 29; continue; };
if (yych <= '!') { gotoCase = 31; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '#') { gotoCase = 34; continue; };
if (yych <= '$') { gotoCase = 35; continue; };
if (yych >= '&') { gotoCase = 31; continue; };
}
} else {
if (yych <= '-') {
if (yych <= '\'') { gotoCase = 36; continue; };
if (yych >= '-') { gotoCase = 37; continue; };
} else {
if (yych <= '.') { gotoCase = 38; continue; };
if (yych <= '/') { gotoCase = 39; continue; };
if (yych <= '9') { gotoCase = 40; continue; };
{ gotoCase = 42; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '=') {
if (yych <= ';') { gotoCase = 44; continue; };
if (yych >= '=') { gotoCase = 31; continue; };
} else {
if (yych <= '?') { gotoCase = 29; continue; };
if (yych != '\\') { gotoCase = 31; continue; };
}
} else {
if (yych <= 'z') {
if (yych == '_') { gotoCase = 31; continue; };
if (yych >= 'a') { gotoCase = 31; continue; };
} else {
if (yych <= '{') { gotoCase = 46; continue; };
if (yych == '}') { gotoCase = 48; continue; };
}
}
}
case 29:
++cursor;
case 30:
{ this.tokenType = null; return cursor; }
case 31:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 51; continue; };
case 32:
{
var token = this._line.substring(cursorOnEnter, cursor);
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.INITIAL || this._condition.parseCondition === this._parseConditions.PROPERTY) {
if (token.charAt(0) === "@") {
this.tokenType = "css-at-rule";
this._setParseCondition(token === "@media" ? this._parseConditions.AT_MEDIA_RULE : this._parseConditions.AT_RULE);
this._condition.atKeyword = token;
} else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else if (this._propertyKeywords.hasOwnProperty(token))
this.tokenType = "css-property";
} else if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE || this._condition.parseCondition === this._parseConditions.AT_RULE) {
if (WebInspector.SourceCSSTokenizer.SCSSAtRelatedKeywords.hasOwnProperty(token))
this.tokenType = "css-at-rule";
else if (WebInspector.SourceCSSTokenizer.MediaTypes.hasOwnProperty(token))
this.tokenType = "css-keyword";
}
if (this.tokenType)
return cursor;
if (this._isPropertyValue()) {
var firstChar = token.charAt(0);
if (firstChar === "$")
this.tokenType = "scss-variable";
else if (firstChar === "!")
this.tokenType = "css-bang-keyword";
else if (this._condition.atKeyword === "@extend")
this.tokenType = "css-selector";
else if (this._valueKeywords.hasOwnProperty(token) || this._scssValueKeywords.hasOwnProperty(token))
this.tokenType = "css-keyword";
else if (this._colorKeywords.hasOwnProperty(token)) {
this.tokenType = "css-color";
}
} else if (this._condition.parseCondition !== this._parseConditions.PROPERTY_VALUE)
this.tokenType = "css-selector";
return cursor;
}
case 33:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych <= '%') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych <= '<') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 132; continue; };
{ gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
{ gotoCase = 132; continue; };
}
}
}
case 34:
yych = this._charAt(++cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
{ gotoCase = 30; continue; };
}
case 35:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 30; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych <= '%') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
} else {
if (yych == '\\') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 30; continue; };
{ gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 30; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
{ gotoCase = 30; continue; };
}
}
}
case 36:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
{ gotoCase = 116; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 37:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '.') { gotoCase = 67; continue; };
if (yych <= '/') { gotoCase = 51; continue; };
if (yych <= '9') { gotoCase = 52; continue; };
{ gotoCase = 51; continue; };
case 38:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 30; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
{ gotoCase = 30; continue; };
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych == '*') { gotoCase = 106; continue; };
{ gotoCase = 51; continue; };
case 40:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
switch (yych) {
case '!':
case '"':
case '&':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z': { gotoCase = 50; continue; };
case '%': { gotoCase = 69; continue; };
case '.': { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': { gotoCase = 52; continue; };
case 'H': { gotoCase = 54; continue; };
case '_': { gotoCase = 55; continue; };
case 'c': { gotoCase = 56; continue; };
case 'd': { gotoCase = 57; continue; };
case 'e': { gotoCase = 58; continue; };
case 'g': { gotoCase = 59; continue; };
case 'i': { gotoCase = 60; continue; };
case 'k': { gotoCase = 61; continue; };
case 'm': { gotoCase = 62; continue; };
case 'p': { gotoCase = 63; continue; };
case 'r': { gotoCase = 64; continue; };
case 's': { gotoCase = 65; continue; };
case 't': { gotoCase = 66; continue; };
default: { gotoCase = 41; continue; };
}
case 41:
{
if (this._isPropertyValue())
this.tokenType = "css-number";
else
this.tokenType = null;
return cursor;
}
case 42:
++cursor;
{
this.tokenType = null;
if (this._condition.parseCondition === this._parseConditions.PROPERTY || this._condition.parseCondition === this._parseConditions.INITIAL)
this._setParseCondition(this._parseConditions.PROPERTY_VALUE);
return cursor;
}
case 44:
++cursor;
{
this.tokenType = null;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 46:
++cursor;
{
this.tokenType = "block-start";
this._condition.openBraces = (this._condition.openBraces || 0) + 1;
if (this._condition.parseCondition === this._parseConditions.AT_MEDIA_RULE)
this._setParseCondition(this._parseConditions.INITIAL);
else
this._setParseCondition(this._parseConditions.PROPERTY);
return cursor;
}
case 48:
++cursor;
{
this.tokenType = "block-end";
if (this._condition.openBraces > 0)
--this._condition.openBraces;
this._setParseCondition(this._condition.openBraces ? this._parseConditions.PROPERTY : this._parseConditions.INITIAL);
delete this._condition.atKeyword;
return cursor;
}
case 50:
++cursor;
yych = this._charAt(cursor);
case 51:
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 32; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 32; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
} else {
if (yych == '\\') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 32; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 32; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 32; continue; };
}
}
}
case 52:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
switch (yych) {
case '!':
case '"':
case '&':
case '\'':
case '-':
case '/':
case '=':
case '@':
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
case 'G':
case 'I':
case 'J':
case 'K':
case 'L':
case 'M':
case 'N':
case 'O':
case 'P':
case 'Q':
case 'R':
case 'S':
case 'T':
case 'U':
case 'V':
case 'W':
case 'X':
case 'Y':
case 'Z':
case '[':
case ']':
case 'a':
case 'b':
case 'f':
case 'h':
case 'j':
case 'l':
case 'n':
case 'o':
case 'q':
case 'u':
case 'v':
case 'w':
case 'x':
case 'y':
case 'z': { gotoCase = 50; continue; };
case '%': { gotoCase = 69; continue; };
case '.': { gotoCase = 67; continue; };
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9': { gotoCase = 52; continue; };
case 'H': { gotoCase = 54; continue; };
case '_': { gotoCase = 55; continue; };
case 'c': { gotoCase = 56; continue; };
case 'd': { gotoCase = 57; continue; };
case 'e': { gotoCase = 58; continue; };
case 'g': { gotoCase = 59; continue; };
case 'i': { gotoCase = 60; continue; };
case 'k': { gotoCase = 61; continue; };
case 'm': { gotoCase = 62; continue; };
case 'p': { gotoCase = 63; continue; };
case 'r': { gotoCase = 64; continue; };
case 's': { gotoCase = 65; continue; };
case 't': { gotoCase = 66; continue; };
default: { gotoCase = 41; continue; };
}
case 54:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 55:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 103; continue; };
{ gotoCase = 51; continue; };
case 56:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 57:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 102; continue; };
{ gotoCase = 51; continue; };
case 58:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 59:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 100; continue; };
{ gotoCase = 51; continue; };
case 60:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 61:
yych = this._charAt(++cursor);
if (yych == 'H') { gotoCase = 99; continue; };
{ gotoCase = 51; continue; };
case 62:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
if (yych == 's') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 63:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
} else {
if (yych <= 't') { gotoCase = 65; continue; };
if (yych == 'x') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
}
case 64:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 97; continue; };
if (yych == 'e') { gotoCase = 98; continue; };
{ gotoCase = 51; continue; };
case 65:
yych = this._charAt(++cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 41; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych <= '%') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych <= ',') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 41; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych == '\\') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych <= '^') { gotoCase = 41; continue; };
{ gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 41; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
{ gotoCase = 41; continue; };
}
}
}
case 66:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 95; continue; };
{ gotoCase = 51; continue; };
case 67:
yych = this._charAt(++cursor);
if (yych <= '/') { gotoCase = 68; continue; };
if (yych <= '9') { gotoCase = 70; continue; };
case 68:
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 32; continue; };
} else {
{ gotoCase = 41; continue; };
}
case 69:
yych = this._charAt(++cursor);
{ gotoCase = 41; continue; };
case 70:
yyaccept = 1;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= 'f') {
if (yych <= 'H') {
if (yych <= '/') {
if (yych == '%') { gotoCase = 69; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= '9') { gotoCase = 70; continue; };
if (yych <= 'G') { gotoCase = 41; continue; };
{ gotoCase = 82; continue; };
}
} else {
if (yych <= 'b') {
if (yych == '_') { gotoCase = 74; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'c') { gotoCase = 76; continue; };
if (yych <= 'd') { gotoCase = 79; continue; };
if (yych >= 'f') { gotoCase = 41; continue; };
}
}
} else {
if (yych <= 'm') {
if (yych <= 'i') {
if (yych <= 'g') { gotoCase = 80; continue; };
if (yych <= 'h') { gotoCase = 41; continue; };
{ gotoCase = 78; continue; };
} else {
if (yych == 'k') { gotoCase = 83; continue; };
if (yych <= 'l') { gotoCase = 41; continue; };
{ gotoCase = 77; continue; };
}
} else {
if (yych <= 'q') {
if (yych == 'p') { gotoCase = 75; continue; };
{ gotoCase = 41; continue; };
} else {
if (yych <= 'r') { gotoCase = 73; continue; };
if (yych <= 's') { gotoCase = 69; continue; };
if (yych <= 't') { gotoCase = 81; continue; };
{ gotoCase = 41; continue; };
}
}
}
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 73:
yych = this._charAt(++cursor);
if (yych == 'a') { gotoCase = 93; continue; };
if (yych == 'e') { gotoCase = 94; continue; };
{ gotoCase = 68; continue; };
case 74:
yych = this._charAt(++cursor);
if (yych == '_') { gotoCase = 90; continue; };
{ gotoCase = 68; continue; };
case 75:
yych = this._charAt(++cursor);
if (yych <= 's') {
if (yych == 'c') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= 't') { gotoCase = 69; continue; };
if (yych == 'x') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
}
case 76:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 77:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
if (yych == 's') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 78:
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 79:
yych = this._charAt(++cursor);
if (yych == 'e') { gotoCase = 89; continue; };
{ gotoCase = 68; continue; };
case 80:
yych = this._charAt(++cursor);
if (yych == 'r') { gotoCase = 87; continue; };
{ gotoCase = 68; continue; };
case 81:
yych = this._charAt(++cursor);
if (yych == 'u') { gotoCase = 85; continue; };
{ gotoCase = 68; continue; };
case 82:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 83:
yych = this._charAt(++cursor);
if (yych != 'H') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 85:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 87:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 89:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 90:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 68; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 93:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 94:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 69; continue; };
{ gotoCase = 68; continue; };
case 95:
yych = this._charAt(++cursor);
if (yych != 'r') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'n') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 97:
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 98:
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 99:
yych = this._charAt(++cursor);
if (yych == 'z') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 100:
yych = this._charAt(++cursor);
if (yych != 'a') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'd') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 102:
yych = this._charAt(++cursor);
if (yych == 'g') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 103:
yych = this._charAt(++cursor);
if (yych != 'q') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych != 'e') { gotoCase = 51; continue; };
yych = this._charAt(++cursor);
if (yych == 'm') { gotoCase = 65; continue; };
{ gotoCase = 51; continue; };
case 106:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 110; continue; };
{ gotoCase = 106; continue; };
} else {
if (yych <= '\r') { gotoCase = 110; continue; };
if (yych != '*') { gotoCase = 106; continue; };
}
case 108:
++cursor;
yych = this._charAt(cursor);
if (yych == '*') { gotoCase = 108; continue; };
if (yych == '/') { gotoCase = 112; continue; };
{ gotoCase = 106; continue; };
case 110:
++cursor;
this.setLexCondition(this._lexConditions.COMMENT);
{ this.tokenType = "css-comment"; return cursor; }
case 112:
++cursor;
{ this.tokenType = "css-comment"; return cursor; }
case 114:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '"') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych <= ' ') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '%') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 114; continue; };
} else {
if (yych == '-') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 114; continue; };
if (yych <= '<') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '?') { gotoCase = 118; continue; };
if (yych <= '[') { gotoCase = 114; continue; };
{ gotoCase = 120; continue; };
}
} else {
if (yych <= '_') {
if (yych == '^') { gotoCase = 118; continue; };
{ gotoCase = 114; continue; };
} else {
if (yych <= '`') { gotoCase = 118; continue; };
if (yych <= 'z') { gotoCase = 114; continue; };
{ gotoCase = 118; continue; };
}
}
}
case 116:
++cursor;
if ((yych = this._charAt(cursor)) <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 117; continue; };
if (yych <= '"') { gotoCase = 50; continue; };
if (yych >= '&') { gotoCase = 50; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 50; continue; };
} else {
if (yych <= '.') { gotoCase = 117; continue; };
if (yych <= '9') { gotoCase = 50; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 50; continue; };
} else {
if (yych != '\\') { gotoCase = 50; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 50; continue; };
} else {
if (yych <= '`') { gotoCase = 117; continue; };
if (yych <= 'z') { gotoCase = 50; continue; };
}
}
}
case 117:
{ return this._stringToken(cursor, true); }
case 118:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 118; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 118; continue; };
}
}
case 120:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 118; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == '\\') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 118; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'n') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 118; continue; };
} else {
if (yych == 'v') { gotoCase = 118; continue; };
{ gotoCase = 68; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.SSTRING);
{ return this._stringToken(cursor); }
case 123:
yych = this._charAt(++cursor);
{ gotoCase = 117; continue; };
case 124:
++cursor;
yych = this._charAt(cursor);
if (yych <= '<') {
if (yych <= '\'') {
if (yych <= ' ') { gotoCase = 126; continue; };
if (yych <= '"') { gotoCase = 124; continue; };
if (yych >= '&') { gotoCase = 124; continue; };
} else {
if (yych <= '-') {
if (yych >= '-') { gotoCase = 124; continue; };
} else {
if (yych <= '.') { gotoCase = 126; continue; };
if (yych <= '9') { gotoCase = 124; continue; };
}
}
} else {
if (yych <= ']') {
if (yych <= '?') {
if (yych <= '=') { gotoCase = 124; continue; };
} else {
if (yych != '\\') { gotoCase = 124; continue; };
}
} else {
if (yych <= '_') {
if (yych >= '_') { gotoCase = 124; continue; };
} else {
if (yych <= '`') { gotoCase = 126; continue; };
if (yych <= 'z') { gotoCase = 124; continue; };
}
}
}
case 126:
{
if (this._condition.parseCondition === this._condition.parseCondition.INITIAL || this._condition.parseCondition === this._condition.parseCondition.AT_RULE)
this._setParseCondition(this._parseConditions.PROPERTY);
this.tokenType = "scss-variable";
return cursor;
}
case 127:
++cursor;
yych = this._charAt(cursor);
if (yych <= '@') {
if (yych <= '/') { gotoCase = 129; continue; };
if (yych <= '9') { gotoCase = 127; continue; };
} else {
if (yych <= 'Z') { gotoCase = 127; continue; };
if (yych <= '`') { gotoCase = 129; continue; };
if (yych <= 'z') { gotoCase = 127; continue; };
}
case 129:
{
if (this._isPropertyValue())
this.tokenType = "css-color";
else if (this._condition.parseCondition === this._parseConditions.INITIAL)
this.tokenType = "css-selector";
else
this.tokenType = null;
return cursor;
}
case 130:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
if (yych <= '.') {
if (yych <= '!') {
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 32; continue; };
} else {
if (yych <= '\r') { gotoCase = 32; continue; };
if (yych >= '!') { gotoCase = 130; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 116; continue; };
if (yych >= '&') { gotoCase = 130; continue; };
} else {
if (yych == '-') { gotoCase = 130; continue; };
}
}
} else {
if (yych <= '\\') {
if (yych <= '=') {
if (yych <= '9') { gotoCase = 130; continue; };
if (yych >= '=') { gotoCase = 130; continue; };
} else {
if (yych <= '?') { gotoCase = 132; continue; };
if (yych <= '[') { gotoCase = 130; continue; };
{ gotoCase = 134; continue; };
}
} else {
if (yych <= '_') {
if (yych != '^') { gotoCase = 130; continue; };
} else {
if (yych <= '`') { gotoCase = 132; continue; };
if (yych <= 'z') { gotoCase = 130; continue; };
}
}
}
case 132:
++cursor;
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 68; continue; };
if (yych <= '\f') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
} else {
if (yych <= '"') {
if (yych <= '!') { gotoCase = 132; continue; };
{ gotoCase = 123; continue; };
} else {
if (yych != '\\') { gotoCase = 132; continue; };
}
}
case 134:
++cursor;
yych = this._charAt(cursor);
if (yych <= 'a') {
if (yych <= '!') {
if (yych <= '\n') {
if (yych <= '\t') { gotoCase = 68; continue; };
} else {
if (yych != '\r') { gotoCase = 68; continue; };
}
} else {
if (yych <= '\'') {
if (yych <= '"') { gotoCase = 132; continue; };
if (yych <= '&') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == '\\') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
}
} else {
if (yych <= 'q') {
if (yych <= 'f') {
if (yych <= 'b') { gotoCase = 132; continue; };
if (yych <= 'e') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'n') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
} else {
if (yych <= 't') {
if (yych == 's') { gotoCase = 68; continue; };
{ gotoCase = 132; continue; };
} else {
if (yych == 'v') { gotoCase = 132; continue; };
{ gotoCase = 68; continue; };
}
}
}
++cursor;
this.setLexCondition(this._lexConditions.DSTRING);
{ return this._stringToken(cursor); }
case this.case_SSTRING:
yych = this._charAt(cursor);
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 141; continue; };
if (yych <= '\f') { gotoCase = 140; continue; };
{ gotoCase = 141; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 140; continue; };
{ gotoCase = 143; continue; };
} else {
if (yych == '\\') { gotoCase = 145; continue; };
{ gotoCase = 140; continue; };
}
}
case 139:
{ return this._stringToken(cursor); }
case 140:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 147; continue; };
case 141:
++cursor;
case 142:
{ this.tokenType = null; return cursor; }
case 143:
++cursor;
case 144:
this.setLexCondition(this._lexConditions.INITIAL);
{ return this._stringToken(cursor, true); }
case 145:
yych = this._charAt(++cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych <= '&') { gotoCase = 142; continue; };
} else {
if (yych <= '\\') {
if (yych <= '[') { gotoCase = 142; continue; };
} else {
if (yych != 'b') { gotoCase = 142; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych >= 'g') { gotoCase = 142; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych <= 'q') { gotoCase = 142; continue; };
}
} else {
if (yych <= 't') {
if (yych <= 's') { gotoCase = 142; continue; };
} else {
if (yych != 'v') { gotoCase = 142; continue; };
}
}
}
case 146:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 147:
if (yych <= '\r') {
if (yych == '\n') { gotoCase = 139; continue; };
if (yych <= '\f') { gotoCase = 146; continue; };
{ gotoCase = 139; continue; };
} else {
if (yych <= '\'') {
if (yych <= '&') { gotoCase = 146; continue; };
{ gotoCase = 150; continue; };
} else {
if (yych != '\\') { gotoCase = 146; continue; };
}
}
++cursor;
yych = this._charAt(cursor);
if (yych <= 'e') {
if (yych <= '\'') {
if (yych == '"') { gotoCase = 146; continue; };
if (yych >= '\'') { gotoCase = 146; continue; };
} else {
if (yych <= '\\') {
if (yych >= '\\') { gotoCase = 146; continue; };
} else {
if (yych == 'b') { gotoCase = 146; continue; };
}
}
} else {
if (yych <= 'r') {
if (yych <= 'm') {
if (yych <= 'f') { gotoCase = 146; continue; };
} else {
if (yych <= 'n') { gotoCase = 146; continue; };
if (yych >= 'r') { gotoCase = 146; continue; };
}
} else {
if (yych <= 't') {
if (yych >= 't') { gotoCase = 146; continue; };
} else {
if (yych == 'v') { gotoCase = 146; continue; };
}
}
}
cursor = YYMARKER;
{ gotoCase = 139; continue; };
case 150:
++cursor;
yych = this._charAt(cursor);
{ gotoCase = 144; continue; };
}
}
}
}
WebInspector.SourceCSSTokenizer.prototype.__proto__ = WebInspector.SourceTokenizer.prototype;
WebInspector.SourceHTMLTokenizer = function()
{
WebInspector.SourceTokenizer.call(this);
this._lexConditions = {
INITIAL: 0,
COMMENT: 1,
DOCTYPE: 2,
TAG: 3,
DSTRING: 4,
SSTRING: 5
};
this.case_INITIAL = 1000;
this.case_COMMENT = 1001;
this.case_DOCTYPE = 1002;
this.case_TAG = 1003;
this.case_DSTRING = 1004;
this.case_SSTRING = 1005;
this._parseConditions = {
INITIAL: 0,
ATTRIBUTE: 1,
ATTRIBUTE_VALUE: 2,
LINKIFY: 4,
A_NODE: 8,
SCRIPT: 16,
STYLE: 32
};
this.condition = this.createInitialCondition();
}
WebInspector.SourceHTMLTokenizer.prototype = {
createInitialCondition: function()
{
return { lexCondition: this._lexConditions.INITIAL, parseCondition: this._parseConditions.INITIAL };
},
set line(line) {
if (this._condition.internalJavaScriptTokenizerCondition) {
var match = /<\/script/i.exec(line);
if (match) {
this._internalJavaScriptTokenizer.line = line.substring(0, match.index);
} else
this._internalJavaScriptTokenizer.line = line;
} else if (this._condition.internalCSSTokenizerCondition) {
var match = /<\/style/i.exec(line);
if (match) {
this._internalCSSTokenizer.line = line.substring(0, match.index);
} else
this._internalCSSTokenizer.line = line;
}
this._line = line;
},
_isExpectingAttribute: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE;
},
_isExpectingAttributeValue: function()
{
return this._condition.parseCondition & this._parseConditions.ATTRIBUTE_VALUE;
},
_setExpectingAttribute: function()
{
if (this._isExpectingAttributeValue())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE_VALUE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE;
},
_setExpectingAttributeValue: function()
{
if (this._isExpectingAttribute())
this._condition.parseCondition ^= this._parseConditions.ATTRIBUTE;
this._condition.parseCondition |= this._parseConditions.ATTRIBUTE_VALUE;
},
_stringToken: function(cursor, stringEnds)
{
if (!this._isExpectingAttributeValue()) {
this.tokenType = null;
return cursor;
}
this.tokenType = this._attrValueTokenType();
if (stringEnds)
this._setExpectingAttribute();
return cursor;
},
_attrValueTokenType: function()
{
if (this._condition.parseCondition & this._parseConditions.LINKIFY) {
if (this._condition.parseCondition & this._parseConditions.A_NODE)
return "html-external-link";
return "html-resource-link";
}
return "html-attribute-value";
},
get _internalJavaScriptTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/javascript");
},
get _internalCSSTokenizer()
{
return WebInspector.SourceTokenizer.Registry.getInstance().getTokenizer("text/css");
},
scriptStarted: function(cursor)
{
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.createInitialCondition();
},
scriptEnded: function(cursor)
{
},
styleSheetStarted: function(cursor)
{
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.createInitialCondition();
},
styleSheetEnded: function(cursor)
{
},
nextToken: function(cursor)
{
if (this._condition.internalJavaScriptTokenizerCondition) {
this.line = this._line;
if (cursor !== this._internalJavaScriptTokenizer._line.length) {
this._internalJavaScriptTokenizer.condition = this._condition.internalJavaScriptTokenizerCondition;
var result = this._internalJavaScriptTokenizer.nextToken(cursor);
this.tokenType = this._internalJavaScriptTokenizer.tokenType;
this._condition.internalJavaScriptTokenizerCondition = this._internalJavaScriptTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._condition.internalJavaScriptTokenizerCondition;
} else if (this._condition.internalCSSTokenizerCondition) {
this.line = this._line;
if (cursor !== this._internalCSSTokenizer._line.length) {
this._internalCSSTokenizer.condition = this._condition.internalCSSTokenizerCondition;
var result = this._internalCSSTokenizer.nextToken(cursor);
this.tokenType = this._internalCSSTokenizer.tokenType;
this._condition.internalCSSTokenizerCondition = this._internalCSSTokenizer.condition;
return result;
} else if (cursor !== this._line.length)
delete this._condition.internalCSSTokenizerCondition;
}
var cursorOnEnter = cursor;
var gotoCase = 1;
var YYMARKER;
while (1) {
switch (gotoCase)
{
case 1: var yych;
var yyaccept = 0;
if (this.getLexCondition() < 3) {
if (this.getLexCondition() < 1) {
{ gotoCase = this.case_INITIAL; continue; };
} else {
if (this.getLexCondition() < 2) {
{ gotoCase = this.case_COMMENT; continue; };
} else {
{ gotoCase = this.case_DOCTYPE; continue; };
}
}
} else {
if (this.getLexCondition() < 4) {
{ gotoCase = this.case_TAG; continue; };
} else {
if (this.getLexCondition() < 5) {
{ gotoCase = this.case_DSTRING; continue; };
} else {
{ gotoCase = this.case_SSTRING; continue; };
}
}
}
case this.case_COMMENT:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 4; continue; };
{ gotoCase = 3; continue; };
} else {
if (yych <= '\r') { gotoCase = 4; continue; };
if (yych == '-') { gotoCase = 6; continue; };
{ gotoCase = 3; continue; };
}
case 2:
{ this.tokenType = "html-comment"; return cursor; }
case 3:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
{ gotoCase = 9; continue; };
case 4:
++cursor;
case 5:
{ this.tokenType = null; return cursor; }
case 6:
yyaccept = 1;
yych = this._charAt(YYMARKER = ++cursor);
if (yych != '-') { gotoCase = 5; continue; };
case 7:
++cursor;
yych = this._charAt(cursor);
if (yych == '>') { gotoCase = 10; continue; };
case 8:
yyaccept = 0;
YYMARKER = ++cursor;
yych = this._charAt(cursor);
case 9:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 2; continue; };
{ gotoCase = 8; continue; };
} else {
if (yych <= '\r') { gotoCase = 2; continue; };
if (yych == '-') { gotoCase = 12; continue; };
{ gotoCase = 8; continue; };
}
case 10:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-comment"; return cursor; }
case 12:
++cursor;
yych = this._charAt(cursor);
if (yych == '-') { gotoCase = 7; continue; };
cursor = YYMARKER;
if (yyaccept <= 0) {
{ gotoCase = 2; continue; };
} else {
{ gotoCase = 5; continue; };
}
case this.case_DOCTYPE:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 18; continue; };
{ gotoCase = 17; continue; };
} else {
if (yych <= '\r') { gotoCase = 18; continue; };
if (yych == '>') { gotoCase = 20; continue; };
{ gotoCase = 17; continue; };
}
case 16:
{ this.tokenType = "html-doctype"; return cursor; }
case 17:
yych = this._charAt(++cursor);
{ gotoCase = 23; continue; };
case 18:
++cursor;
{ this.tokenType = null; return cursor; }
case 20:
++cursor;
this.setLexCondition(this._lexConditions.INITIAL);
{ this.tokenType = "html-doctype"; return cursor; }
case 22:
++cursor;
yych = this._charAt(cursor);
case 23:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
} else {
if (yych <= '\r') { gotoCase = 16; continue; };
if (yych == '>') { gotoCase = 16; continue; };
{ gotoCase = 22; continue; };
}
case this.case_DSTRING:
yych = this._charAt(cursor);
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 28; continue; };
{ gotoCase = 27; continue; };
} else {
if (yych <= '\r') { gotoCase = 28; continue; };
if (yych == '"') { gotoCase = 30; continue; };
{ gotoCase = 27; continue; };
}
case 26:
{ return this._stringToken(cursor); }
case 27:
yych = this._charAt(++cursor);
{ gotoCase = 34; continue; };
case 28:
++cursor;
{ this.tokenType = null; return cursor; }
case 30:
++cursor;
case 31:
this.setLexCondition(this._lexConditions.TAG);
{ return this._stringToken(cursor, true); }
case 32:
yych = this._charAt(++cursor);
{ gotoCase = 31; continue; };
case 33:
++cursor;
yych = this._charAt(cursor);
case 34:
if (yych <= '\f') {
if (yych == '\n') { gotoCase = 26; continue; };
{ gotoCase = 33; continue; };
} else {
if (yych <= '\r') { gotoCase = 26; continue; };
if (yych == '"') { gotoCase = 32; continue; };
{ gotoCase = 33; continue; };
}
case this.case_INITIAL:
yych = this._charAt(cursor);
if (yych == '<') { gotoCase = 39; continue; };
++cursor;
{ this.tokenType = null; return cursor; }
case 39:
yyaccept = 0;
yych = this._charAt(YYMARKER = ++cursor);
if (yych <= '/') {
if (yych == '!') { gotoCase = 44; continue; };
if (yych >= '/') { gotoCase = 41; continue; };
} else {
if (yych <= 'S') {
if (yych >= 'S') { gotoCase = 42; continue; };
} else {
if (yych == 's') { gotoCase = 42;
View raw

(Sorry about that, but we can’t show files that are this big right now.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment