| 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 |