2 * Copyright (C) 2011 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 WebInspector
.Formatter = function()
39 * @param {!WebInspector.ResourceType} contentType
40 * @param {string} mimeType
41 * @param {string} content
42 * @param {function(string, !WebInspector.FormatterSourceMapping)} callback
44 WebInspector
.Formatter
.format = function(contentType
, mimeType
, content
, callback
)
46 if (contentType
=== WebInspector
.resourceTypes
.Script
|| contentType
=== WebInspector
.resourceTypes
.Document
|| contentType
=== WebInspector
.resourceTypes
.Stylesheet
)
47 new WebInspector
.ScriptFormatter(mimeType
, content
, callback
);
49 new WebInspector
.IdentityFormatter(mimeType
, content
, callback
);
53 * @param {!Array.<number>} lineEndings
54 * @param {number} lineNumber
55 * @param {number} columnNumber
58 WebInspector
.Formatter
.locationToPosition = function(lineEndings
, lineNumber
, columnNumber
)
60 var position
= lineNumber
? lineEndings
[lineNumber
- 1] + 1 : 0;
61 return position
+ columnNumber
;
65 * @param {!Array.<number>} lineEndings
66 * @param {number} position
67 * @return {!Array.<number>}
69 WebInspector
.Formatter
.positionToLocation = function(lineEndings
, position
)
71 var lineNumber
= lineEndings
.upperBound(position
- 1);
73 var columnNumber
= position
;
75 var columnNumber
= position
- lineEndings
[lineNumber
- 1] - 1;
76 return [lineNumber
, columnNumber
];
81 * @implements {WebInspector.Formatter}
82 * @param {string} mimeType
83 * @param {string} content
84 * @param {function(string, !WebInspector.FormatterSourceMapping)} callback
86 WebInspector
.ScriptFormatter = function(mimeType
, content
, callback
)
88 content
= content
.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, '');
89 this._callback
= callback
;
90 this._originalContent
= content
;
92 this._worker
= new WorkerRuntime
.Worker("script_formatter_worker");
93 this._worker
.onmessage
= this._didFormatContent
.bind(this);
98 indentString
: WebInspector
.moduleSetting("textEditorIndent").get()
100 this._worker
.postMessage({ method
: "format", params
: parameters
});
103 WebInspector
.ScriptFormatter
.prototype = {
105 * @param {!MessageEvent} event
107 _didFormatContent: function(event
)
109 this._worker
.terminate();
110 var originalContent
= this._originalContent
;
111 var formattedContent
= event
.data
.content
;
112 var mapping
= event
.data
["mapping"];
113 var sourceMapping
= new WebInspector
.FormatterSourceMappingImpl(originalContent
.lineEndings(), formattedContent
.lineEndings(), mapping
);
114 this._callback(formattedContent
, sourceMapping
);
120 * @implements {WebInspector.Formatter}
121 * @param {string} mimeType
122 * @param {string} content
123 * @param {function(string, !WebInspector.FormatterSourceMapping)} callback
125 WebInspector
.IdentityFormatter = function(mimeType
, content
, callback
)
127 callback(content
, new WebInspector
.IdentityFormatterSourceMapping());
131 * @typedef {{original: !Array.<number>, formatted: !Array.<number>}}
133 WebInspector
.FormatterMappingPayload
;
138 WebInspector
.FormatterSourceMapping = function()
142 WebInspector
.FormatterSourceMapping
.prototype = {
144 * @param {number} lineNumber
145 * @param {number=} columnNumber
146 * @return {!Array.<number>}
148 originalToFormatted: function(lineNumber
, columnNumber
) { },
151 * @param {number} lineNumber
152 * @param {number=} columnNumber
153 * @return {!Array.<number>}
155 formattedToOriginal: function(lineNumber
, columnNumber
) { }
160 * @implements {WebInspector.FormatterSourceMapping}
162 WebInspector
.IdentityFormatterSourceMapping = function()
166 WebInspector
.IdentityFormatterSourceMapping
.prototype = {
169 * @param {number} lineNumber
170 * @param {number=} columnNumber
171 * @return {!Array.<number>}
173 originalToFormatted: function(lineNumber
, columnNumber
)
175 return [lineNumber
, columnNumber
|| 0];
180 * @param {number} lineNumber
181 * @param {number=} columnNumber
182 * @return {!Array.<number>}
184 formattedToOriginal: function(lineNumber
, columnNumber
)
186 return [lineNumber
, columnNumber
|| 0];
192 * @implements {WebInspector.FormatterSourceMapping}
193 * @param {!Array.<number>} originalLineEndings
194 * @param {!Array.<number>} formattedLineEndings
195 * @param {!WebInspector.FormatterMappingPayload} mapping
197 WebInspector
.FormatterSourceMappingImpl = function(originalLineEndings
, formattedLineEndings
, mapping
)
199 this._originalLineEndings
= originalLineEndings
;
200 this._formattedLineEndings
= formattedLineEndings
;
201 this._mapping
= mapping
;
204 WebInspector
.FormatterSourceMappingImpl
.prototype = {
207 * @param {number} lineNumber
208 * @param {number=} columnNumber
209 * @return {!Array.<number>}
211 originalToFormatted: function(lineNumber
, columnNumber
)
213 var originalPosition
= WebInspector
.Formatter
.locationToPosition(this._originalLineEndings
, lineNumber
, columnNumber
|| 0);
214 var formattedPosition
= this._convertPosition(this._mapping
.original
, this._mapping
.formatted
, originalPosition
|| 0);
215 return WebInspector
.Formatter
.positionToLocation(this._formattedLineEndings
, formattedPosition
);
220 * @param {number} lineNumber
221 * @param {number=} columnNumber
222 * @return {!Array.<number>}
224 formattedToOriginal: function(lineNumber
, columnNumber
)
226 var formattedPosition
= WebInspector
.Formatter
.locationToPosition(this._formattedLineEndings
, lineNumber
, columnNumber
|| 0);
227 var originalPosition
= this._convertPosition(this._mapping
.formatted
, this._mapping
.original
, formattedPosition
);
228 return WebInspector
.Formatter
.positionToLocation(this._originalLineEndings
, originalPosition
|| 0);
232 * @param {!Array.<number>} positions1
233 * @param {!Array.<number>} positions2
234 * @param {number} position
237 _convertPosition: function(positions1
, positions2
, position
)
239 var index
= positions1
.upperBound(position
) - 1;
240 var convertedPosition
= positions2
[index
] + position
- positions1
[index
];
241 if (index
< positions2
.length
- 1 && convertedPosition
> positions2
[index
+ 1])
242 convertedPosition
= positions2
[index
+ 1];
243 return convertedPosition
;