123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- // Copyright 2013 the V8 project authors. 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.
- // This is a copy from blink dev tools, see:
- // http://src.chromium.org/viewvc/blink/trunk/Source/devtools/front_end/SourceMap.js
- // revision: 153407
- // Added to make the file work without dev tools
- export const WebInspector = {};
- WebInspector.ParsedURL = {};
- WebInspector.ParsedURL.completeURL = function(){};
- // start of original file content
- /*
- * 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.
- */
- /**
- * Implements Source Map V3 model. See http://code.google.com/p/closure-compiler/wiki/SourceMaps
- * for format description.
- * @constructor
- * @param {string} sourceMappingURL
- * @param {SourceMapV3} payload
- */
- WebInspector.SourceMap = function(sourceMappingURL, payload)
- {
- if (!WebInspector.SourceMap.prototype._base64Map) {
- const base64Digits = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- WebInspector.SourceMap.prototype._base64Map = {};
- for (let i = 0; i < base64Digits.length; ++i)
- WebInspector.SourceMap.prototype._base64Map[base64Digits.charAt(i)] = i;
- }
- this._sourceMappingURL = sourceMappingURL;
- this._reverseMappingsBySourceURL = {};
- this._mappings = [];
- this._sources = {};
- this._sourceContentByURL = {};
- this._parseMappingPayload(payload);
- }
- /**
- * @param {string} sourceMapURL
- * @param {string} compiledURL
- * @param {function(WebInspector.SourceMap)} callback
- */
- WebInspector.SourceMap.load = function(sourceMapURL, compiledURL, callback)
- {
- NetworkAgent.loadResourceForFrontend(WebInspector.resourceTreeModel.mainFrame.id, sourceMapURL, undefined, contentLoaded.bind(this));
- /**
- * @param {?Protocol.Error} error
- * @param {number} statusCode
- * @param {NetworkAgent.Headers} headers
- * @param {string} content
- */
- function contentLoaded(error, statusCode, headers, content)
- {
- if (error || !content || statusCode >= 400) {
- console.error(`Could not load content for ${sourceMapURL} : ${error || (`HTTP status code: ${statusCode}`)}`);
- callback(null);
- return;
- }
- if (content.slice(0, 3) === ")]}")
- content = content.substring(content.indexOf('\n'));
- try {
- const payload = /** @type {SourceMapV3} */ (JSON.parse(content));
- const baseURL = sourceMapURL.startsWith("data:") ? compiledURL : sourceMapURL;
- callback(new WebInspector.SourceMap(baseURL, payload));
- } catch(e) {
- console.error(e.message);
- callback(null);
- }
- }
- }
- WebInspector.SourceMap.prototype = {
- /**
- * @return {Array.<string>}
- */
- sources()
- {
- return Object.keys(this._sources);
- },
- /**
- * @param {string} sourceURL
- * @return {string|undefined}
- */
- sourceContent(sourceURL)
- {
- return this._sourceContentByURL[sourceURL];
- },
- /**
- * @param {string} sourceURL
- * @param {WebInspector.ResourceType} contentType
- * @return {WebInspector.ContentProvider}
- */
- sourceContentProvider(sourceURL, contentType)
- {
- const lastIndexOfDot = sourceURL.lastIndexOf(".");
- const extension = lastIndexOfDot !== -1 ? sourceURL.substr(lastIndexOfDot + 1) : "";
- const mimeType = WebInspector.ResourceType.mimeTypesForExtensions[extension.toLowerCase()];
- const sourceContent = this.sourceContent(sourceURL);
- if (sourceContent)
- return new WebInspector.StaticContentProvider(contentType, sourceContent, mimeType);
- return new WebInspector.CompilerSourceMappingContentProvider(sourceURL, contentType, mimeType);
- },
- /**
- * @param {SourceMapV3} mappingPayload
- */
- _parseMappingPayload(mappingPayload)
- {
- if (mappingPayload.sections)
- this._parseSections(mappingPayload.sections);
- else
- this._parseMap(mappingPayload, 0, 0);
- },
- /**
- * @param {Array.<SourceMapV3.Section>} sections
- */
- _parseSections(sections)
- {
- for (let i = 0; i < sections.length; ++i) {
- const section = sections[i];
- this._parseMap(section.map, section.offset.line, section.offset.column);
- }
- },
- /**
- * @param {number} lineNumber in compiled resource
- * @param {number} columnNumber in compiled resource
- * @return {?Array}
- */
- findEntry(lineNumber, columnNumber)
- {
- let first = 0;
- let count = this._mappings.length;
- while (count > 1) {
- const step = count >> 1;
- const middle = first + step;
- const mapping = this._mappings[middle];
- if (lineNumber < mapping[0] || (lineNumber === mapping[0] && columnNumber < mapping[1]))
- count = step;
- else {
- first = middle;
- count -= step;
- }
- }
- const entry = this._mappings[first];
- if (!first && entry && (lineNumber < entry[0] || (lineNumber === entry[0] && columnNumber < entry[1])))
- return null;
- return entry;
- },
- /**
- * @param {string} sourceURL of the originating resource
- * @param {number} lineNumber in the originating resource
- * @return {Array}
- */
- findEntryReversed(sourceURL, lineNumber)
- {
- const mappings = this._reverseMappingsBySourceURL[sourceURL];
- for ( ; lineNumber < mappings.length; ++lineNumber) {
- const mapping = mappings[lineNumber];
- if (mapping)
- return mapping;
- }
- return this._mappings[0];
- },
- /**
- * @override
- */
- _parseMap(map, lineNumber, columnNumber)
- {
- let sourceIndex = 0;
- let sourceLineNumber = 0;
- let sourceColumnNumber = 0;
- let nameIndex = 0;
- const sources = [];
- const originalToCanonicalURLMap = {};
- for (let i = 0; i < map.sources.length; ++i) {
- const originalSourceURL = map.sources[i];
- let sourceRoot = map.sourceRoot || "";
- if (sourceRoot && !sourceRoot.endsWith("/")) sourceRoot += "/";
- const href = sourceRoot + originalSourceURL;
- const url = WebInspector.ParsedURL.completeURL(this._sourceMappingURL, href) || href;
- originalToCanonicalURLMap[originalSourceURL] = url;
- sources.push(url);
- this._sources[url] = true;
- if (map.sourcesContent && map.sourcesContent[i]) {
- this._sourceContentByURL[url] = map.sourcesContent[i];
- }
- }
- const stringCharIterator = new WebInspector.SourceMap.StringCharIterator(map.mappings);
- let sourceURL = sources[sourceIndex];
- while (true) {
- if (stringCharIterator.peek() === ",")
- stringCharIterator.next();
- else {
- while (stringCharIterator.peek() === ";") {
- lineNumber += 1;
- columnNumber = 0;
- stringCharIterator.next();
- }
- if (!stringCharIterator.hasNext())
- break;
- }
- columnNumber += this._decodeVLQ(stringCharIterator);
- if (this._isSeparator(stringCharIterator.peek())) {
- this._mappings.push([lineNumber, columnNumber]);
- continue;
- }
- const sourceIndexDelta = this._decodeVLQ(stringCharIterator);
- if (sourceIndexDelta) {
- sourceIndex += sourceIndexDelta;
- sourceURL = sources[sourceIndex];
- }
- sourceLineNumber += this._decodeVLQ(stringCharIterator);
- sourceColumnNumber += this._decodeVLQ(stringCharIterator);
- if (!this._isSeparator(stringCharIterator.peek()))
- nameIndex += this._decodeVLQ(stringCharIterator);
- this._mappings.push([lineNumber, columnNumber, sourceURL, sourceLineNumber, sourceColumnNumber]);
- }
- for (let i = 0; i < this._mappings.length; ++i) {
- const mapping = this._mappings[i];
- const url = mapping[2];
- if (!url) continue;
- if (!this._reverseMappingsBySourceURL[url]) {
- this._reverseMappingsBySourceURL[url] = [];
- }
- const reverseMappings = this._reverseMappingsBySourceURL[url];
- const sourceLine = mapping[3];
- if (!reverseMappings[sourceLine]) {
- reverseMappings[sourceLine] = [mapping[0], mapping[1]];
- }
- }
- },
- /**
- * @param {string} char
- * @return {boolean}
- */
- _isSeparator(char)
- {
- return char === "," || char === ";";
- },
- /**
- * @param {WebInspector.SourceMap.StringCharIterator} stringCharIterator
- * @return {number}
- */
- _decodeVLQ(stringCharIterator)
- {
- // Read unsigned value.
- let result = 0;
- let shift = 0;
- let digit;
- do {
- digit = this._base64Map[stringCharIterator.next()];
- result += (digit & this._VLQ_BASE_MASK) << shift;
- shift += this._VLQ_BASE_SHIFT;
- } while (digit & this._VLQ_CONTINUATION_MASK);
- // Fix the sign.
- const negate = result & 1;
- // Use unsigned right shift, so that the 32nd bit is properly shifted
- // to the 31st, and the 32nd becomes unset.
- result >>>= 1;
- if (negate) {
- // We need to OR 0x80000000 here to ensure the 32nd bit (the sign bit
- // in a 32bit int) is always set for negative numbers. If `result`
- // were 1, (meaning `negate` is true and all other bits were zeros),
- // `result` would now be 0. But -0 doesn't flip the 32nd bit as
- // intended. All other numbers will successfully set the 32nd bit
- // without issue, so doing this is a noop for them.
- return -result | 0x80000000;
- }
- return result;
- },
- _VLQ_BASE_SHIFT: 5,
- _VLQ_BASE_MASK: (1 << 5) - 1,
- _VLQ_CONTINUATION_MASK: 1 << 5
- }
- /**
- * @constructor
- * @param {string} string
- */
- WebInspector.SourceMap.StringCharIterator = function(string)
- {
- this._string = string;
- this._position = 0;
- }
- WebInspector.SourceMap.StringCharIterator.prototype = {
- /**
- * @return {string}
- */
- next()
- {
- return this._string.charAt(this._position++);
- },
- /**
- * @return {string}
- */
- peek()
- {
- return this._string.charAt(this._position);
- },
- /**
- * @return {boolean}
- */
- hasNext()
- {
- return this._position < this._string.length;
- }
- }
|