[フレーム]

Class: Opal::SourceMap::File

Inherits:
Object
  • Object
  • Opal::SourceMap::File
show all
Includes:
Map
Defined in:
opal/lib/opal/source_map/file.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Map

#as_json , #cache , #marshal_dump , #marshal_load , #to_data_uri_comment , #to_h , #to_json , #to_s

Constructor Details

#initialize(fragments, file, source, generated_code = nil) ⇒ File

Returns a new instance of File.

10
11
12
13
14
15
16
17
# File 'opal/lib/opal/source_map/file.rb', line 10
def initialize(fragments, file, source, generated_code = nil)
 @fragments = fragments
 @file = file
 @source = source
 @names_map = Hash.new { |hash, name| hash[name] = hash.size }
 @generated_code = generated_code
 @absolute_mappings = nil
end

Instance Attribute Details

#fileObject (readonly)

Returns the value of attribute file.

7
8
9
# File 'opal/lib/opal/source_map/file.rb', line 7
def file
 @file
end

#fragmentsObject (readonly)

Returns the value of attribute fragments.

6
7
8
# File 'opal/lib/opal/source_map/file.rb', line 6
def fragments
 @fragments
end

#sourceObject (readonly)

Returns the value of attribute source.

8
9
10
# File 'opal/lib/opal/source_map/file.rb', line 8
def source
 @source
end

Instance Method Details

#absolute_mappingsObject

The "mappings" data is broken down as follows:

each group representing a line in the generated file is separated by a ";" each segment is separated by a "," each segment is made up of 1,4 or 5 variable length fields.

160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
# File 'opal/lib/opal/source_map/file.rb', line 160
def absolute_mappings
 @absolute_mappings ||= begin
 mappings = []
 fragments_by_line.each do |raw_segments|
 generated_column = 0
 segments = []
 raw_segments.each do |(generated_code, fragment)|
 unless fragment.is_a?(Opal ::Fragment ) && fragment.skip_source_map?
 segments << segment_from_fragment(fragment, generated_column)
 end
 generated_column += generated_code.size
 end
 mappings << segments
 end
 mappings
 end
end

#generated_codeObject

19
20
21
# File 'opal/lib/opal/source_map/file.rb', line 19
def generated_code
 @generated_code ||= @fragments.map(&:code).join
end

#map(source_root: '') ⇒ Object

Proposed Format 1: { 2: "version" : 3, 3: "file": "out.js", 4: "sourceRoot": "", 5: "sources": ["foo.js", "bar.js"], 6: "sourcesContent": [null, null], 7: "names": ["src", "maps", "are", "fun"], 8: "mappings": "A,AAAB;;ABCDE;" 9: }

Line 1: The entire file is a single JSON object Line 2: File version (always the first entry in the object) and must be a positive integer. Line 3: An optional name of the generated code that this source map is associated with. Line 4: An optional source root, useful for relocating source files on a server or removing repeated values in the "sources" entry. This value is prepended to the individual entries in the "source" field. Line 5: A list of original sources used by the "mappings" entry. Line 6: An optional list of source content, useful when the "source" can’t be hosted. The contents are listed in the same order as the sources in line 5. "null" may be used if some original sources should be retrieved by name. Line 7: A list of symbol names used by the "mappings" entry. Line 8: A string with the encoded mapping data.

48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'opal/lib/opal/source_map/file.rb', line 48
def map(source_root: '')
 {
 version: 3,
 # file: "out.js", # This is optional
 sourceRoot: source_root,
 sources: [file],
 sourcesContent: [source.encoding == Encoding::UTF_8 ? source : source.encode('UTF-8', undef: :replace)],
 names: names,
 mappings: Opal ::SourceMap ::VLQ .encode_mappings (relative_mappings),
 # x_com_opalrb_original_lines: source.count("\n"),
 # x_com_opalrb_generated_lines: generated_code.count("\n"),
 }
end

#namesObject

62
63
64
65
66
67
# File 'opal/lib/opal/source_map/file.rb', line 62
def names
 @names ||= begin
 absolute_mappings # let the processing happen
 @names_map.to_a.sort_by { |_, index| index }.map { |name, _| name }
 end
end

#relative_mappingsObject

126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'opal/lib/opal/source_map/file.rb', line 126
def relative_mappings
 @relative_mappings ||= begin
 reference_segment = [0, 0, 0, 0, 0]
 reference_name_index = 0
 absolute_mappings.map do |absolute_mapping|
 # [generated_column, source_index, original_line, original_column, map_name_index]
 reference_segment[0] = 0 # reset the generated_column at each new line

 absolute_mapping.map do |absolute_segment|
 segment = []
 segment[0] = absolute_segment[0] - reference_segment[0]
 segment[1] = absolute_segment[1] - (reference_segment[1] || 0)
 segment[2] = absolute_segment[2] - (reference_segment[2] || 0)
 segment[3] = absolute_segment[3] - (reference_segment[3] || 0)
 # Since [4] can be nil we need to keep track of it in the reference_segment even if it's nil in absolute_segment
 if absolute_segment[4]
 segment[4] = absolute_segment[4].to_int - (reference_segment[4] || reference_name_index).to_int
 reference_name_index = absolute_segment[4]
 end
 reference_segment = absolute_segment
 segment
 end
 end
 end
end

#segment_from_fragment(fragment, generated_column) ⇒ Object

The fields in each segment are:

  1. The zero-based starting column of the line in the generated code that the segment represents. If this is the first field of the first segment, or the first segment following a new generated line (";"), then this field holds the whole base 64 VLQ. Otherwise, this field contains a base 64 VLQ that is relative to the previous occurrence of this field. Note that this is different than the fields below because the previous value is reset after every generated line.

  2. If present, an zero-based index into the "sources" list. This field is a base 64 VLQ relative to the previous occurrence of this field, unless this is the first occurrence of this field, in which case the whole value is represented.

  3. If present, the zero-based starting line in the original source represented. This field is a base 64 VLQ relative to the previous occurrence of this field, unless this is the first occurrence of this field, in which case the whole value is represented. Always present if there is a source field.

  4. If present, the zero-based starting column of the line in the source represented. This field is a base 64 VLQ relative to the previous occurrence of this field, unless this is the first occurrence of this field, in which case the whole value is represented. Always present if there is a source field.

  5. If present, the zero-based index into the "names" list associated with this segment. This field is a base 64 VLQ relative to the previous occurrence of this field, unless this is the first occurrence of this field, in which case the whole value is represented.

100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'opal/lib/opal/source_map/file.rb', line 100
def segment_from_fragment(fragment, generated_column)
 source_index = 0 # always 0, we're dealing with a single file
 original_line = (fragment.line || 0) - 1 # fragments have 1-based lines
 original_line = 0 if original_line < 0 # line 0 (-1) for fragments in source maps will crash
 # browsers devtools and the webpack build process
 original_column = fragment.column || 0 # fragments have 0-based columns

 if fragment.source_map_name
 map_name_index = (@names_map[fragment.source_map_name.to_s] ||= @names_map.size)
 [
 generated_column,
 source_index,
 original_line,
 original_column,
 map_name_index,
 ]
 else
 [
 generated_column,
 source_index,
 original_line,
 original_column,
 ]
 end
end

AltStyle によって変換されたページ (->オリジナル) /