OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | |
5 /** | 4 /** |
6 * @constructor | 5 * @unrestricted |
7 */ | 6 */ |
8 WebInspector.EmulatedDevice = function() | 7 WebInspector.EmulatedDevice = class { |
9 { | 8 constructor() { |
10 /** @type {string} */ | 9 /** @type {string} */ |
11 this.title = ""; | 10 this.title = ''; |
12 /** @type {string} */ | 11 /** @type {string} */ |
13 this.type = WebInspector.EmulatedDevice.Type.Unknown; | 12 this.type = WebInspector.EmulatedDevice.Type.Unknown; |
14 /** @type {!WebInspector.EmulatedDevice.Orientation} */ | 13 /** @type {!WebInspector.EmulatedDevice.Orientation} */ |
15 this.vertical = {width: 0, height: 0, outlineInsets: null, outlineImage: nul
l}; | 14 this.vertical = {width: 0, height: 0, outlineInsets: null, outlineImage: nul
l}; |
16 /** @type {!WebInspector.EmulatedDevice.Orientation} */ | 15 /** @type {!WebInspector.EmulatedDevice.Orientation} */ |
17 this.horizontal = {width: 0, height: 0, outlineInsets: null, outlineImage: n
ull}; | 16 this.horizontal = {width: 0, height: 0, outlineInsets: null, outlineImage: n
ull}; |
18 /** @type {number} */ | 17 /** @type {number} */ |
19 this.deviceScaleFactor = 1; | 18 this.deviceScaleFactor = 1; |
20 /** @type {!Array.<string>} */ | 19 /** @type {!Array.<string>} */ |
21 this.capabilities = [WebInspector.EmulatedDevice.Capability.Touch, WebInspec
tor.EmulatedDevice.Capability.Mobile]; | 20 this.capabilities = [WebInspector.EmulatedDevice.Capability.Touch, WebInspec
tor.EmulatedDevice.Capability.Mobile]; |
22 /** @type {string} */ | 21 /** @type {string} */ |
23 this.userAgent = ""; | 22 this.userAgent = ''; |
24 /** @type {!Array.<!WebInspector.EmulatedDevice.Mode>} */ | 23 /** @type {!Array.<!WebInspector.EmulatedDevice.Mode>} */ |
25 this.modes = []; | 24 this.modes = []; |
26 | 25 |
27 /** @type {string} */ | 26 /** @type {string} */ |
28 this._show = WebInspector.EmulatedDevice._Show.Default; | 27 this._show = WebInspector.EmulatedDevice._Show.Default; |
29 /** @type {boolean} */ | 28 /** @type {boolean} */ |
30 this._showByDefault = true; | 29 this._showByDefault = true; |
31 | 30 |
32 /** @type {?Runtime.Extension} */ | 31 /** @type {?Runtime.Extension} */ |
33 this._extension = null; | 32 this._extension = null; |
| 33 } |
| 34 |
| 35 /** |
| 36 * @param {*} json |
| 37 * @return {?WebInspector.EmulatedDevice} |
| 38 */ |
| 39 static fromJSONV1(json) { |
| 40 try { |
| 41 /** |
| 42 * @param {*} object |
| 43 * @param {string} key |
| 44 * @param {string} type |
| 45 * @param {*=} defaultValue |
| 46 * @return {*} |
| 47 */ |
| 48 function parseValue(object, key, type, defaultValue) { |
| 49 if (typeof object !== 'object' || object === null || !object.hasOwnPrope
rty(key)) { |
| 50 if (typeof defaultValue !== 'undefined') |
| 51 return defaultValue; |
| 52 throw new Error('Emulated device is missing required property \'' + ke
y + '\''); |
| 53 } |
| 54 var value = object[key]; |
| 55 if (typeof value !== type || value === null) |
| 56 throw new Error('Emulated device property \'' + key + '\' has wrong ty
pe \'' + typeof value + '\''); |
| 57 return value; |
| 58 } |
| 59 |
| 60 /** |
| 61 * @param {*} object |
| 62 * @param {string} key |
| 63 * @return {number} |
| 64 */ |
| 65 function parseIntValue(object, key) { |
| 66 var value = /** @type {number} */ (parseValue(object, key, 'number')); |
| 67 if (value !== Math.abs(value)) |
| 68 throw new Error('Emulated device value \'' + key + '\' must be integer
'); |
| 69 return value; |
| 70 } |
| 71 |
| 72 /** |
| 73 * @param {*} json |
| 74 * @return {!Insets} |
| 75 */ |
| 76 function parseInsets(json) { |
| 77 return new Insets( |
| 78 parseIntValue(json, 'left'), parseIntValue(json, 'top'), parseIntVal
ue(json, 'right'), |
| 79 parseIntValue(json, 'bottom')); |
| 80 } |
| 81 |
| 82 /** |
| 83 * @param {*} json |
| 84 * @return {!WebInspector.EmulatedDevice.Orientation} |
| 85 */ |
| 86 function parseOrientation(json) { |
| 87 var result = {}; |
| 88 |
| 89 result.width = parseIntValue(json, 'width'); |
| 90 if (result.width < 0 || result.width > WebInspector.DeviceModeModel.MaxD
eviceSize || |
| 91 result.width < WebInspector.DeviceModeModel.MinDeviceSize) |
| 92 throw new Error('Emulated device has wrong width: ' + result.width); |
| 93 |
| 94 result.height = parseIntValue(json, 'height'); |
| 95 if (result.height < 0 || result.height > WebInspector.DeviceModeModel.Ma
xDeviceSize || |
| 96 result.height < WebInspector.DeviceModeModel.MinDeviceSize) |
| 97 throw new Error('Emulated device has wrong height: ' + result.height); |
| 98 |
| 99 var outlineInsets = parseValue(json['outline'], 'insets', 'object', null
); |
| 100 if (outlineInsets) { |
| 101 result.outlineInsets = parseInsets(outlineInsets); |
| 102 if (result.outlineInsets.left < 0 || result.outlineInsets.top < 0) |
| 103 throw new Error('Emulated device has wrong outline insets'); |
| 104 result.outlineImage = /** @type {string} */ (parseValue(json['outline'
], 'image', 'string')); |
| 105 } |
| 106 return /** @type {!WebInspector.EmulatedDevice.Orientation} */ (result); |
| 107 } |
| 108 |
| 109 var result = new WebInspector.EmulatedDevice(); |
| 110 result.title = /** @type {string} */ (parseValue(json, 'title', 'string'))
; |
| 111 result.type = /** @type {string} */ (parseValue(json, 'type', 'string')); |
| 112 var rawUserAgent = /** @type {string} */ (parseValue(json, 'user-agent', '
string')); |
| 113 result.userAgent = WebInspector.MultitargetNetworkManager.patchUserAgentWi
thChromeVersion(rawUserAgent); |
| 114 |
| 115 var capabilities = parseValue(json, 'capabilities', 'object', []); |
| 116 if (!Array.isArray(capabilities)) |
| 117 throw new Error('Emulated device capabilities must be an array'); |
| 118 result.capabilities = []; |
| 119 for (var i = 0; i < capabilities.length; ++i) { |
| 120 if (typeof capabilities[i] !== 'string') |
| 121 throw new Error('Emulated device capability must be a string'); |
| 122 result.capabilities.push(capabilities[i]); |
| 123 } |
| 124 |
| 125 result.deviceScaleFactor = /** @type {number} */ (parseValue(json['screen'
], 'device-pixel-ratio', 'number')); |
| 126 if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100) |
| 127 throw new Error('Emulated device has wrong deviceScaleFactor: ' + result
.deviceScaleFactor); |
| 128 |
| 129 result.vertical = parseOrientation(parseValue(json['screen'], 'vertical',
'object')); |
| 130 result.horizontal = parseOrientation(parseValue(json['screen'], 'horizonta
l', 'object')); |
| 131 |
| 132 var modes = parseValue(json, 'modes', 'object', []); |
| 133 if (!Array.isArray(modes)) |
| 134 throw new Error('Emulated device modes must be an array'); |
| 135 result.modes = []; |
| 136 for (var i = 0; i < modes.length; ++i) { |
| 137 var mode = {}; |
| 138 mode.title = /** @type {string} */ (parseValue(modes[i], 'title', 'strin
g')); |
| 139 mode.orientation = /** @type {string} */ (parseValue(modes[i], 'orientat
ion', 'string')); |
| 140 if (mode.orientation !== WebInspector.EmulatedDevice.Vertical && |
| 141 mode.orientation !== WebInspector.EmulatedDevice.Horizontal) |
| 142 throw new Error('Emulated device mode has wrong orientation \'' + mode
.orientation + '\''); |
| 143 var orientation = result.orientationByName(mode.orientation); |
| 144 mode.insets = parseInsets(parseValue(modes[i], 'insets', 'object')); |
| 145 if (mode.insets.top < 0 || mode.insets.left < 0 || mode.insets.right < 0
|| mode.insets.bottom < 0 || |
| 146 mode.insets.top + mode.insets.bottom > orientation.height || |
| 147 mode.insets.left + mode.insets.right > orientation.width) { |
| 148 throw new Error('Emulated device mode \'' + mode.title + '\'has wrong
mode insets'); |
| 149 } |
| 150 mode.image = /** @type {string} */ (parseValue(modes[i], 'image', 'strin
g', null)); |
| 151 result.modes.push(mode); |
| 152 } |
| 153 |
| 154 result._showByDefault = /** @type {boolean} */ (parseValue(json, 'show-by-
default', 'boolean', undefined)); |
| 155 result._show = |
| 156 /** @type {string} */ (parseValue(json, 'show', 'string', WebInspector
.EmulatedDevice._Show.Default)); |
| 157 |
| 158 return result; |
| 159 } catch (e) { |
| 160 return null; |
| 161 } |
| 162 } |
| 163 |
| 164 /** |
| 165 * @param {!WebInspector.EmulatedDevice} device1 |
| 166 * @param {!WebInspector.EmulatedDevice} device2 |
| 167 * @return {number} |
| 168 */ |
| 169 static deviceComparator(device1, device2) { |
| 170 var order1 = (device1._extension && device1._extension.descriptor()['order']
) || -1; |
| 171 var order2 = (device2._extension && device2._extension.descriptor()['order']
) || -1; |
| 172 if (order1 > order2) |
| 173 return 1; |
| 174 if (order2 > order1) |
| 175 return -1; |
| 176 return device1.title < device2.title ? -1 : (device1.title > device2.title ?
1 : 0); |
| 177 } |
| 178 |
| 179 /** |
| 180 * @return {?Runtime.Extension} |
| 181 */ |
| 182 extension() { |
| 183 return this._extension; |
| 184 } |
| 185 |
| 186 /** |
| 187 * @param {?Runtime.Extension} extension |
| 188 */ |
| 189 setExtension(extension) { |
| 190 this._extension = extension; |
| 191 } |
| 192 |
| 193 /** |
| 194 * @param {string} orientation |
| 195 * @return {!Array.<!WebInspector.EmulatedDevice.Mode>} |
| 196 */ |
| 197 modesForOrientation(orientation) { |
| 198 var result = []; |
| 199 for (var index = 0; index < this.modes.length; index++) { |
| 200 if (this.modes[index].orientation === orientation) |
| 201 result.push(this.modes[index]); |
| 202 } |
| 203 return result; |
| 204 } |
| 205 |
| 206 /** |
| 207 * @return {*} |
| 208 */ |
| 209 _toJSON() { |
| 210 var json = {}; |
| 211 json['title'] = this.title; |
| 212 json['type'] = this.type; |
| 213 json['user-agent'] = this.userAgent; |
| 214 json['capabilities'] = this.capabilities; |
| 215 |
| 216 json['screen'] = {}; |
| 217 json['screen']['device-pixel-ratio'] = this.deviceScaleFactor; |
| 218 json['screen']['vertical'] = this._orientationToJSON(this.vertical); |
| 219 json['screen']['horizontal'] = this._orientationToJSON(this.horizontal); |
| 220 |
| 221 json['modes'] = []; |
| 222 for (var i = 0; i < this.modes.length; ++i) { |
| 223 var mode = {}; |
| 224 mode['title'] = this.modes[i].title; |
| 225 mode['orientation'] = this.modes[i].orientation; |
| 226 mode['insets'] = {}; |
| 227 mode['insets']['left'] = this.modes[i].insets.left; |
| 228 mode['insets']['top'] = this.modes[i].insets.top; |
| 229 mode['insets']['right'] = this.modes[i].insets.right; |
| 230 mode['insets']['bottom'] = this.modes[i].insets.bottom; |
| 231 if (this.modes[i].image) |
| 232 mode['image'] = this.modes[i].image; |
| 233 json['modes'].push(mode); |
| 234 } |
| 235 |
| 236 json['show-by-default'] = this._showByDefault; |
| 237 json['show'] = this._show; |
| 238 |
| 239 return json; |
| 240 } |
| 241 |
| 242 /** |
| 243 * @param {!WebInspector.EmulatedDevice.Orientation} orientation |
| 244 * @return {*} |
| 245 */ |
| 246 _orientationToJSON(orientation) { |
| 247 var json = {}; |
| 248 json['width'] = orientation.width; |
| 249 json['height'] = orientation.height; |
| 250 if (orientation.outlineInsets) { |
| 251 json['outline'] = {}; |
| 252 json['outline']['insets'] = {}; |
| 253 json['outline']['insets']['left'] = orientation.outlineInsets.left; |
| 254 json['outline']['insets']['top'] = orientation.outlineInsets.top; |
| 255 json['outline']['insets']['right'] = orientation.outlineInsets.right; |
| 256 json['outline']['insets']['bottom'] = orientation.outlineInsets.bottom; |
| 257 json['outline']['image'] = orientation.outlineImage; |
| 258 } |
| 259 return json; |
| 260 } |
| 261 |
| 262 /** |
| 263 * @param {!WebInspector.EmulatedDevice.Mode} mode |
| 264 * @return {string} |
| 265 */ |
| 266 modeImage(mode) { |
| 267 if (!mode.image) |
| 268 return ''; |
| 269 if (!this._extension) |
| 270 return mode.image; |
| 271 return this._extension.module().substituteURL(mode.image); |
| 272 } |
| 273 |
| 274 /** |
| 275 * @param {!WebInspector.EmulatedDevice.Mode} mode |
| 276 * @return {string} |
| 277 */ |
| 278 outlineImage(mode) { |
| 279 var orientation = this.orientationByName(mode.orientation); |
| 280 if (!orientation.outlineImage) |
| 281 return ''; |
| 282 if (!this._extension) |
| 283 return orientation.outlineImage; |
| 284 return this._extension.module().substituteURL(orientation.outlineImage); |
| 285 } |
| 286 |
| 287 /** |
| 288 * @param {string} name |
| 289 * @return {!WebInspector.EmulatedDevice.Orientation} |
| 290 */ |
| 291 orientationByName(name) { |
| 292 return name === WebInspector.EmulatedDevice.Vertical ? this.vertical : this.
horizontal; |
| 293 } |
| 294 |
| 295 /** |
| 296 * @return {boolean} |
| 297 */ |
| 298 show() { |
| 299 if (this._show === WebInspector.EmulatedDevice._Show.Default) |
| 300 return this._showByDefault; |
| 301 return this._show === WebInspector.EmulatedDevice._Show.Always; |
| 302 } |
| 303 |
| 304 /** |
| 305 * @param {boolean} show |
| 306 */ |
| 307 setShow(show) { |
| 308 this._show = show ? WebInspector.EmulatedDevice._Show.Always : WebInspector.
EmulatedDevice._Show.Never; |
| 309 } |
| 310 |
| 311 /** |
| 312 * @param {!WebInspector.EmulatedDevice} other |
| 313 */ |
| 314 copyShowFrom(other) { |
| 315 this._show = other._show; |
| 316 } |
| 317 |
| 318 /** |
| 319 * @return {boolean} |
| 320 */ |
| 321 touch() { |
| 322 return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Touc
h) !== -1; |
| 323 } |
| 324 |
| 325 /** |
| 326 * @return {boolean} |
| 327 */ |
| 328 mobile() { |
| 329 return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.Mobi
le) !== -1; |
| 330 } |
34 }; | 331 }; |
35 | 332 |
36 /** @typedef {!{title: string, orientation: string, insets: !Insets, image: ?str
ing}} */ | 333 /** @typedef {!{title: string, orientation: string, insets: !Insets, image: ?str
ing}} */ |
37 WebInspector.EmulatedDevice.Mode; | 334 WebInspector.EmulatedDevice.Mode; |
38 | 335 |
39 /** @typedef {!{width: number, height: number, outlineInsets: ?Insets, outlineIm
age: ?string}} */ | 336 /** @typedef {!{width: number, height: number, outlineInsets: ?Insets, outlineIm
age: ?string}} */ |
40 WebInspector.EmulatedDevice.Orientation; | 337 WebInspector.EmulatedDevice.Orientation; |
41 | 338 |
42 WebInspector.EmulatedDevice.Horizontal = "horizontal"; | 339 WebInspector.EmulatedDevice.Horizontal = 'horizontal'; |
43 WebInspector.EmulatedDevice.Vertical = "vertical"; | 340 WebInspector.EmulatedDevice.Vertical = 'vertical'; |
44 | 341 |
45 WebInspector.EmulatedDevice.Type = { | 342 WebInspector.EmulatedDevice.Type = { |
46 Phone: "phone", | 343 Phone: 'phone', |
47 Tablet: "tablet", | 344 Tablet: 'tablet', |
48 Notebook: "notebook", | 345 Notebook: 'notebook', |
49 Desktop: "desktop", | 346 Desktop: 'desktop', |
50 Unknown: "unknown" | 347 Unknown: 'unknown' |
51 }; | 348 }; |
52 | 349 |
53 WebInspector.EmulatedDevice.Capability = { | 350 WebInspector.EmulatedDevice.Capability = { |
54 Touch: "touch", | 351 Touch: 'touch', |
55 Mobile: "mobile" | 352 Mobile: 'mobile' |
56 }; | 353 }; |
57 | 354 |
58 WebInspector.EmulatedDevice._Show = { | 355 WebInspector.EmulatedDevice._Show = { |
59 Always: "Always", | 356 Always: 'Always', |
60 Default: "Default", | 357 Default: 'Default', |
61 Never: "Never" | 358 Never: 'Never' |
62 }; | |
63 | |
64 /** | |
65 * @param {*} json | |
66 * @return {?WebInspector.EmulatedDevice} | |
67 */ | |
68 WebInspector.EmulatedDevice.fromJSONV1 = function(json) | |
69 { | |
70 try { | |
71 /** | |
72 * @param {*} object | |
73 * @param {string} key | |
74 * @param {string} type | |
75 * @param {*=} defaultValue | |
76 * @return {*} | |
77 */ | |
78 function parseValue(object, key, type, defaultValue) | |
79 { | |
80 if (typeof object !== "object" || object === null || !object.hasOwnP
roperty(key)) { | |
81 if (typeof defaultValue !== "undefined") | |
82 return defaultValue; | |
83 throw new Error("Emulated device is missing required property '"
+ key + "'"); | |
84 } | |
85 var value = object[key]; | |
86 if (typeof value !== type || value === null) | |
87 throw new Error("Emulated device property '" + key + "' has wron
g type '" + typeof value + "'"); | |
88 return value; | |
89 } | |
90 | |
91 /** | |
92 * @param {*} object | |
93 * @param {string} key | |
94 * @return {number} | |
95 */ | |
96 function parseIntValue(object, key) | |
97 { | |
98 var value = /** @type {number} */ (parseValue(object, key, "number")
); | |
99 if (value !== Math.abs(value)) | |
100 throw new Error("Emulated device value '" + key + "' must be int
eger"); | |
101 return value; | |
102 } | |
103 | |
104 /** | |
105 * @param {*} json | |
106 * @return {!Insets} | |
107 */ | |
108 function parseInsets(json) | |
109 { | |
110 return new Insets(parseIntValue(json, "left"), parseIntValue(json, "
top"), parseIntValue(json, "right"), parseIntValue(json, "bottom")); | |
111 } | |
112 | |
113 /** | |
114 * @param {*} json | |
115 * @return {!WebInspector.EmulatedDevice.Orientation} | |
116 */ | |
117 function parseOrientation(json) | |
118 { | |
119 var result = {}; | |
120 | |
121 result.width = parseIntValue(json, "width"); | |
122 if (result.width < 0 || result.width > WebInspector.DeviceModeModel.
MaxDeviceSize || result.width < WebInspector.DeviceModeModel.MinDeviceSize) | |
123 throw new Error("Emulated device has wrong width: " + result.wid
th); | |
124 | |
125 result.height = parseIntValue(json, "height"); | |
126 if (result.height < 0 || result.height > WebInspector.DeviceModeMode
l.MaxDeviceSize || result.height < WebInspector.DeviceModeModel.MinDeviceSize) | |
127 throw new Error("Emulated device has wrong height: " + result.he
ight); | |
128 | |
129 var outlineInsets = parseValue(json["outline"], "insets", "object",
null); | |
130 if (outlineInsets) { | |
131 result.outlineInsets = parseInsets(outlineInsets); | |
132 if (result.outlineInsets.left < 0 || result.outlineInsets.top <
0) | |
133 throw new Error("Emulated device has wrong outline insets"); | |
134 result.outlineImage = /** @type {string} */ (parseValue(json["ou
tline"], "image", "string")); | |
135 } | |
136 return /** @type {!WebInspector.EmulatedDevice.Orientation} */ (resu
lt); | |
137 } | |
138 | |
139 var result = new WebInspector.EmulatedDevice(); | |
140 result.title = /** @type {string} */ (parseValue(json, "title", "string"
)); | |
141 result.type = /** @type {string} */ (parseValue(json, "type", "string"))
; | |
142 var rawUserAgent = /** @type {string} */ (parseValue(json, "user-agent",
"string")); | |
143 result.userAgent = WebInspector.MultitargetNetworkManager.patchUserAgent
WithChromeVersion(rawUserAgent); | |
144 | |
145 var capabilities = parseValue(json, "capabilities", "object", []); | |
146 if (!Array.isArray(capabilities)) | |
147 throw new Error("Emulated device capabilities must be an array"); | |
148 result.capabilities = []; | |
149 for (var i = 0; i < capabilities.length; ++i) { | |
150 if (typeof capabilities[i] !== "string") | |
151 throw new Error("Emulated device capability must be a string"); | |
152 result.capabilities.push(capabilities[i]); | |
153 } | |
154 | |
155 result.deviceScaleFactor = /** @type {number} */ (parseValue(json["scree
n"], "device-pixel-ratio", "number")); | |
156 if (result.deviceScaleFactor < 0 || result.deviceScaleFactor > 100) | |
157 throw new Error("Emulated device has wrong deviceScaleFactor: " + re
sult.deviceScaleFactor); | |
158 | |
159 result.vertical = parseOrientation(parseValue(json["screen"], "vertical"
, "object")); | |
160 result.horizontal = parseOrientation(parseValue(json["screen"], "horizon
tal", "object")); | |
161 | |
162 var modes = parseValue(json, "modes", "object", []); | |
163 if (!Array.isArray(modes)) | |
164 throw new Error("Emulated device modes must be an array"); | |
165 result.modes = []; | |
166 for (var i = 0; i < modes.length; ++i) { | |
167 var mode = {}; | |
168 mode.title = /** @type {string} */ (parseValue(modes[i], "title", "s
tring")); | |
169 mode.orientation = /** @type {string} */ (parseValue(modes[i], "orie
ntation", "string")); | |
170 if (mode.orientation !== WebInspector.EmulatedDevice.Vertical && mod
e.orientation !== WebInspector.EmulatedDevice.Horizontal) | |
171 throw new Error("Emulated device mode has wrong orientation '" +
mode.orientation + "'"); | |
172 var orientation = result.orientationByName(mode.orientation); | |
173 mode.insets = parseInsets(parseValue(modes[i], "insets", "object")); | |
174 if (mode.insets.top < 0 || mode.insets.left < 0 || mode.insets.right
< 0 || mode.insets.bottom < 0 || | |
175 mode.insets.top + mode.insets.bottom > orientation.height || mod
e.insets.left + mode.insets.right > orientation.width) { | |
176 throw new Error("Emulated device mode '" + mode.title + "'has wr
ong mode insets"); | |
177 } | |
178 mode.image = /** @type {string} */ (parseValue(modes[i], "image", "s
tring", null)); | |
179 result.modes.push(mode); | |
180 } | |
181 | |
182 result._showByDefault = /** @type {boolean} */ (parseValue(json, "show-b
y-default", "boolean", undefined)); | |
183 result._show = /** @type {string} */ (parseValue(json, "show", "string",
WebInspector.EmulatedDevice._Show.Default)); | |
184 | |
185 return result; | |
186 } catch (e) { | |
187 return null; | |
188 } | |
189 }; | |
190 | |
191 /** | |
192 * @param {!WebInspector.EmulatedDevice} device1 | |
193 * @param {!WebInspector.EmulatedDevice} device2 | |
194 * @return {number} | |
195 */ | |
196 WebInspector.EmulatedDevice.deviceComparator = function(device1, device2) | |
197 { | |
198 var order1 = (device1._extension && device1._extension.descriptor()["order"]
) || -1; | |
199 var order2 = (device2._extension && device2._extension.descriptor()["order"]
) || -1; | |
200 if (order1 > order2) | |
201 return 1; | |
202 if (order2 > order1) | |
203 return -1; | |
204 return device1.title < device2.title ? -1 : (device1.title > device2.title ?
1 : 0); | |
205 }; | |
206 | |
207 WebInspector.EmulatedDevice.prototype = { | |
208 /** | |
209 * @return {?Runtime.Extension} | |
210 */ | |
211 extension: function() | |
212 { | |
213 return this._extension; | |
214 }, | |
215 | |
216 /** | |
217 * @param {?Runtime.Extension} extension | |
218 */ | |
219 setExtension: function(extension) | |
220 { | |
221 this._extension = extension; | |
222 }, | |
223 | |
224 /** | |
225 * @param {string} orientation | |
226 * @return {!Array.<!WebInspector.EmulatedDevice.Mode>} | |
227 */ | |
228 modesForOrientation: function(orientation) | |
229 { | |
230 var result = []; | |
231 for (var index = 0; index < this.modes.length; index++) { | |
232 if (this.modes[index].orientation === orientation) | |
233 result.push(this.modes[index]); | |
234 } | |
235 return result; | |
236 }, | |
237 | |
238 /** | |
239 * @return {*} | |
240 */ | |
241 _toJSON: function() | |
242 { | |
243 var json = {}; | |
244 json["title"] = this.title; | |
245 json["type"] = this.type; | |
246 json["user-agent"] = this.userAgent; | |
247 json["capabilities"] = this.capabilities; | |
248 | |
249 json["screen"] = {}; | |
250 json["screen"]["device-pixel-ratio"] = this.deviceScaleFactor; | |
251 json["screen"]["vertical"] = this._orientationToJSON(this.vertical); | |
252 json["screen"]["horizontal"] = this._orientationToJSON(this.horizontal); | |
253 | |
254 json["modes"] = []; | |
255 for (var i = 0; i < this.modes.length; ++i) { | |
256 var mode = {}; | |
257 mode["title"] = this.modes[i].title; | |
258 mode["orientation"] = this.modes[i].orientation; | |
259 mode["insets"] = {}; | |
260 mode["insets"]["left"] = this.modes[i].insets.left; | |
261 mode["insets"]["top"] = this.modes[i].insets.top; | |
262 mode["insets"]["right"] = this.modes[i].insets.right; | |
263 mode["insets"]["bottom"] = this.modes[i].insets.bottom; | |
264 if (this.modes[i].image) | |
265 mode["image"] = this.modes[i].image; | |
266 json["modes"].push(mode); | |
267 } | |
268 | |
269 json["show-by-default"] = this._showByDefault; | |
270 json["show"] = this._show; | |
271 | |
272 return json; | |
273 }, | |
274 | |
275 /** | |
276 * @param {!WebInspector.EmulatedDevice.Orientation} orientation | |
277 * @return {*} | |
278 */ | |
279 _orientationToJSON: function(orientation) | |
280 { | |
281 var json = {}; | |
282 json["width"] = orientation.width; | |
283 json["height"] = orientation.height; | |
284 if (orientation.outlineInsets) { | |
285 json["outline"] = {}; | |
286 json["outline"]["insets"] = {}; | |
287 json["outline"]["insets"]["left"] = orientation.outlineInsets.left; | |
288 json["outline"]["insets"]["top"] = orientation.outlineInsets.top; | |
289 json["outline"]["insets"]["right"] = orientation.outlineInsets.right
; | |
290 json["outline"]["insets"]["bottom"] = orientation.outlineInsets.bott
om; | |
291 json["outline"]["image"] = orientation.outlineImage; | |
292 } | |
293 return json; | |
294 }, | |
295 | |
296 /** | |
297 * @param {!WebInspector.EmulatedDevice.Mode} mode | |
298 * @return {string} | |
299 */ | |
300 modeImage: function(mode) | |
301 { | |
302 if (!mode.image) | |
303 return ""; | |
304 if (!this._extension) | |
305 return mode.image; | |
306 return this._extension.module().substituteURL(mode.image); | |
307 }, | |
308 | |
309 /** | |
310 * @param {!WebInspector.EmulatedDevice.Mode} mode | |
311 * @return {string} | |
312 */ | |
313 outlineImage: function(mode) | |
314 { | |
315 var orientation = this.orientationByName(mode.orientation); | |
316 if (!orientation.outlineImage) | |
317 return ""; | |
318 if (!this._extension) | |
319 return orientation.outlineImage; | |
320 return this._extension.module().substituteURL(orientation.outlineImage); | |
321 }, | |
322 | |
323 /** | |
324 * @param {string} name | |
325 * @return {!WebInspector.EmulatedDevice.Orientation} | |
326 */ | |
327 orientationByName: function(name) | |
328 { | |
329 return name === WebInspector.EmulatedDevice.Vertical ? this.vertical : t
his.horizontal; | |
330 }, | |
331 | |
332 /** | |
333 * @return {boolean} | |
334 */ | |
335 show: function() | |
336 { | |
337 if (this._show === WebInspector.EmulatedDevice._Show.Default) | |
338 return this._showByDefault; | |
339 return this._show === WebInspector.EmulatedDevice._Show.Always; | |
340 }, | |
341 | |
342 /** | |
343 * @param {boolean} show | |
344 */ | |
345 setShow: function(show) | |
346 { | |
347 this._show = show ? WebInspector.EmulatedDevice._Show.Always : WebInspec
tor.EmulatedDevice._Show.Never; | |
348 }, | |
349 | |
350 /** | |
351 * @param {!WebInspector.EmulatedDevice} other | |
352 */ | |
353 copyShowFrom: function(other) | |
354 { | |
355 this._show = other._show; | |
356 }, | |
357 | |
358 /** | |
359 * @return {boolean} | |
360 */ | |
361 touch: function() | |
362 { | |
363 return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.
Touch) !== -1; | |
364 }, | |
365 | |
366 /** | |
367 * @return {boolean} | |
368 */ | |
369 mobile: function() | |
370 { | |
371 return this.capabilities.indexOf(WebInspector.EmulatedDevice.Capability.
Mobile) !== -1; | |
372 } | |
373 }; | 359 }; |
374 | 360 |
375 | 361 |
376 /** | 362 /** |
377 * @constructor | 363 * @unrestricted |
378 * @extends {WebInspector.Object} | |
379 */ | 364 */ |
380 WebInspector.EmulatedDevicesList = function() | 365 WebInspector.EmulatedDevicesList = class extends WebInspector.Object { |
381 { | 366 constructor() { |
382 WebInspector.Object.call(this); | 367 super(); |
383 | 368 |
384 /** @type {!WebInspector.Setting} */ | 369 /** @type {!WebInspector.Setting} */ |
385 this._standardSetting = WebInspector.settings.createSetting("standardEmulate
dDeviceList", []); | 370 this._standardSetting = WebInspector.settings.createSetting('standardEmulate
dDeviceList', []); |
386 /** @type {!Array.<!WebInspector.EmulatedDevice>} */ | 371 /** @type {!Array.<!WebInspector.EmulatedDevice>} */ |
387 this._standard = []; | 372 this._standard = []; |
388 this._listFromJSONV1(this._standardSetting.get(), this._standard); | 373 this._listFromJSONV1(this._standardSetting.get(), this._standard); |
389 this._updateStandardDevices(); | 374 this._updateStandardDevices(); |
390 | 375 |
391 /** @type {!WebInspector.Setting} */ | 376 /** @type {!WebInspector.Setting} */ |
392 this._customSetting = WebInspector.settings.createSetting("customEmulatedDev
iceList", []); | 377 this._customSetting = WebInspector.settings.createSetting('customEmulatedDev
iceList', []); |
393 /** @type {!Array.<!WebInspector.EmulatedDevice>} */ | 378 /** @type {!Array.<!WebInspector.EmulatedDevice>} */ |
394 this._custom = []; | 379 this._custom = []; |
395 if (!this._listFromJSONV1(this._customSetting.get(), this._custom)) | 380 if (!this._listFromJSONV1(this._customSetting.get(), this._custom)) |
396 this.saveCustomDevices(); | 381 this.saveCustomDevices(); |
| 382 } |
| 383 |
| 384 /** |
| 385 * @return {!WebInspector.EmulatedDevicesList} |
| 386 */ |
| 387 static instance() { |
| 388 if (!WebInspector.EmulatedDevicesList._instance) |
| 389 WebInspector.EmulatedDevicesList._instance = new WebInspector.EmulatedDevi
cesList(); |
| 390 return /** @type {!WebInspector.EmulatedDevicesList} */ (WebInspector.Emulat
edDevicesList._instance); |
| 391 } |
| 392 |
| 393 _updateStandardDevices() { |
| 394 var devices = []; |
| 395 var extensions = self.runtime.extensions('emulated-device'); |
| 396 for (var i = 0; i < extensions.length; ++i) { |
| 397 var device = WebInspector.EmulatedDevice.fromJSONV1(extensions[i].descript
or()['device']); |
| 398 device.setExtension(extensions[i]); |
| 399 devices.push(device); |
| 400 } |
| 401 this._copyShowValues(this._standard, devices); |
| 402 this._standard = devices; |
| 403 this.saveStandardDevices(); |
| 404 } |
| 405 |
| 406 /** |
| 407 * @param {!Array.<*>} jsonArray |
| 408 * @param {!Array.<!WebInspector.EmulatedDevice>} result |
| 409 * @return {boolean} |
| 410 */ |
| 411 _listFromJSONV1(jsonArray, result) { |
| 412 if (!Array.isArray(jsonArray)) |
| 413 return false; |
| 414 var success = true; |
| 415 for (var i = 0; i < jsonArray.length; ++i) { |
| 416 var device = WebInspector.EmulatedDevice.fromJSONV1(jsonArray[i]); |
| 417 if (device) { |
| 418 result.push(device); |
| 419 if (!device.modes.length) { |
| 420 device.modes.push({ |
| 421 title: '', |
| 422 orientation: WebInspector.EmulatedDevice.Horizontal, |
| 423 insets: new Insets(0, 0, 0, 0), |
| 424 image: null |
| 425 }); |
| 426 device.modes.push({ |
| 427 title: '', |
| 428 orientation: WebInspector.EmulatedDevice.Vertical, |
| 429 insets: new Insets(0, 0, 0, 0), |
| 430 image: null |
| 431 }); |
| 432 } |
| 433 } else { |
| 434 success = false; |
| 435 } |
| 436 } |
| 437 return success; |
| 438 } |
| 439 |
| 440 /** |
| 441 * @return {!Array.<!WebInspector.EmulatedDevice>} |
| 442 */ |
| 443 standard() { |
| 444 return this._standard; |
| 445 } |
| 446 |
| 447 /** |
| 448 * @return {!Array.<!WebInspector.EmulatedDevice>} |
| 449 */ |
| 450 custom() { |
| 451 return this._custom; |
| 452 } |
| 453 |
| 454 revealCustomSetting() { |
| 455 WebInspector.Revealer.reveal(this._customSetting); |
| 456 } |
| 457 |
| 458 /** |
| 459 * @param {!WebInspector.EmulatedDevice} device |
| 460 */ |
| 461 addCustomDevice(device) { |
| 462 this._custom.push(device); |
| 463 this.saveCustomDevices(); |
| 464 } |
| 465 |
| 466 /** |
| 467 * @param {!WebInspector.EmulatedDevice} device |
| 468 */ |
| 469 removeCustomDevice(device) { |
| 470 this._custom.remove(device); |
| 471 this.saveCustomDevices(); |
| 472 } |
| 473 |
| 474 saveCustomDevices() { |
| 475 var json = this._custom.map(/** @param {!WebInspector.EmulatedDevice} device
*/ function(device) { |
| 476 return device._toJSON(); |
| 477 }); |
| 478 this._customSetting.set(json); |
| 479 this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.Custom
DevicesUpdated); |
| 480 } |
| 481 |
| 482 saveStandardDevices() { |
| 483 var json = this._standard.map(/** @param {!WebInspector.EmulatedDevice} devi
ce */ function(device) { |
| 484 return device._toJSON(); |
| 485 }); |
| 486 this._standardSetting.set(json); |
| 487 this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.Standa
rdDevicesUpdated); |
| 488 } |
| 489 |
| 490 /** |
| 491 * @param {!Array.<!WebInspector.EmulatedDevice>} from |
| 492 * @param {!Array.<!WebInspector.EmulatedDevice>} to |
| 493 */ |
| 494 _copyShowValues(from, to) { |
| 495 var deviceById = new Map(); |
| 496 for (var i = 0; i < from.length; ++i) |
| 497 deviceById.set(from[i].title, from[i]); |
| 498 |
| 499 for (var i = 0; i < to.length; ++i) { |
| 500 var title = to[i].title; |
| 501 if (deviceById.has(title)) |
| 502 to[i].copyShowFrom(/** @type {!WebInspector.EmulatedDevice} */ (deviceBy
Id.get(title))); |
| 503 } |
| 504 } |
397 }; | 505 }; |
398 | 506 |
399 /** @enum {symbol} */ | 507 /** @enum {symbol} */ |
400 WebInspector.EmulatedDevicesList.Events = { | 508 WebInspector.EmulatedDevicesList.Events = { |
401 CustomDevicesUpdated: Symbol("CustomDevicesUpdated"), | 509 CustomDevicesUpdated: Symbol('CustomDevicesUpdated'), |
402 StandardDevicesUpdated: Symbol("StandardDevicesUpdated") | 510 StandardDevicesUpdated: Symbol('StandardDevicesUpdated') |
403 }; | |
404 | |
405 WebInspector.EmulatedDevicesList.prototype = { | |
406 _updateStandardDevices: function() | |
407 { | |
408 var devices = []; | |
409 var extensions = self.runtime.extensions("emulated-device"); | |
410 for (var i = 0; i < extensions.length; ++i) { | |
411 var device = WebInspector.EmulatedDevice.fromJSONV1(extensions[i].de
scriptor()["device"]); | |
412 device.setExtension(extensions[i]); | |
413 devices.push(device); | |
414 } | |
415 this._copyShowValues(this._standard, devices); | |
416 this._standard = devices; | |
417 this.saveStandardDevices(); | |
418 }, | |
419 | |
420 /** | |
421 * @param {!Array.<*>} jsonArray | |
422 * @param {!Array.<!WebInspector.EmulatedDevice>} result | |
423 * @return {boolean} | |
424 */ | |
425 _listFromJSONV1: function(jsonArray, result) | |
426 { | |
427 if (!Array.isArray(jsonArray)) | |
428 return false; | |
429 var success = true; | |
430 for (var i = 0; i < jsonArray.length; ++i) { | |
431 var device = WebInspector.EmulatedDevice.fromJSONV1(jsonArray[i]); | |
432 if (device) { | |
433 result.push(device); | |
434 if (!device.modes.length) { | |
435 device.modes.push({title: "", orientation: WebInspector.Emul
atedDevice.Horizontal, insets: new Insets(0, 0, 0, 0), image: null}); | |
436 device.modes.push({title: "", orientation: WebInspector.Emul
atedDevice.Vertical, insets: new Insets(0, 0, 0, 0), image: null}); | |
437 } | |
438 } else { | |
439 success = false; | |
440 } | |
441 } | |
442 return success; | |
443 }, | |
444 | |
445 /** | |
446 * @return {!Array.<!WebInspector.EmulatedDevice>} | |
447 */ | |
448 standard: function() | |
449 { | |
450 return this._standard; | |
451 }, | |
452 | |
453 /** | |
454 * @return {!Array.<!WebInspector.EmulatedDevice>} | |
455 */ | |
456 custom: function() | |
457 { | |
458 return this._custom; | |
459 }, | |
460 | |
461 revealCustomSetting: function() | |
462 { | |
463 WebInspector.Revealer.reveal(this._customSetting); | |
464 }, | |
465 | |
466 /** | |
467 * @param {!WebInspector.EmulatedDevice} device | |
468 */ | |
469 addCustomDevice: function(device) | |
470 { | |
471 this._custom.push(device); | |
472 this.saveCustomDevices(); | |
473 }, | |
474 | |
475 /** | |
476 * @param {!WebInspector.EmulatedDevice} device | |
477 */ | |
478 removeCustomDevice: function(device) | |
479 { | |
480 this._custom.remove(device); | |
481 this.saveCustomDevices(); | |
482 }, | |
483 | |
484 saveCustomDevices: function() | |
485 { | |
486 var json = this._custom.map(/** @param {!WebInspector.EmulatedDevice} de
vice */ function(device) { return device._toJSON(); }); | |
487 this._customSetting.set(json); | |
488 this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.Cu
stomDevicesUpdated); | |
489 }, | |
490 | |
491 saveStandardDevices: function() | |
492 { | |
493 var json = this._standard.map(/** @param {!WebInspector.EmulatedDevice}
device */ function(device) { return device._toJSON(); }); | |
494 this._standardSetting.set(json); | |
495 this.dispatchEventToListeners(WebInspector.EmulatedDevicesList.Events.St
andardDevicesUpdated); | |
496 }, | |
497 | |
498 /** | |
499 * @param {!Array.<!WebInspector.EmulatedDevice>} from | |
500 * @param {!Array.<!WebInspector.EmulatedDevice>} to | |
501 */ | |
502 _copyShowValues: function(from, to) | |
503 { | |
504 var deviceById = new Map(); | |
505 for (var i = 0; i < from.length; ++i) | |
506 deviceById.set(from[i].title, from[i]); | |
507 | |
508 for (var i = 0; i < to.length; ++i) { | |
509 var title = to[i].title; | |
510 if (deviceById.has(title)) | |
511 to[i].copyShowFrom(/** @type {!WebInspector.EmulatedDevice} */ (
deviceById.get(title))); | |
512 } | |
513 }, | |
514 | |
515 __proto__: WebInspector.Object.prototype | |
516 }; | 511 }; |
517 | 512 |
518 /** @type {?WebInspector.EmulatedDevicesList} */ | 513 /** @type {?WebInspector.EmulatedDevicesList} */ |
519 WebInspector.EmulatedDevicesList._instance; | 514 WebInspector.EmulatedDevicesList._instance; |
520 | 515 |
521 /** | 516 |
522 * @return {!WebInspector.EmulatedDevicesList} | |
523 */ | |
524 WebInspector.EmulatedDevicesList.instance = function() | |
525 { | |
526 if (!WebInspector.EmulatedDevicesList._instance) | |
527 WebInspector.EmulatedDevicesList._instance = new WebInspector.EmulatedDe
vicesList(); | |
528 return /** @type {!WebInspector.EmulatedDevicesList} */ (WebInspector.Emulat
edDevicesList._instance); | |
529 }; | |
OLD | NEW |