| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 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 /** | 4 /** |
| 5 * @unrestricted | 5 * @unrestricted |
| 6 */ | 6 */ |
| 7 Emulation.DeviceModeView = class extends UI.VBox { | 7 Emulation.DeviceModeView = class extends UI.VBox { |
| 8 constructor() { | 8 constructor() { |
| 9 super(true); | 9 super(true); |
| 10 this.setMinimumSize(150, 150); | 10 this.setMinimumSize(150, 150); |
| (...skipping 341 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 352 this._toolbar.restore(); | 352 this._toolbar.restore(); |
| 353 } | 353 } |
| 354 | 354 |
| 355 /** | 355 /** |
| 356 * @override | 356 * @override |
| 357 */ | 357 */ |
| 358 willHide() { | 358 willHide() { |
| 359 this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null); | 359 this._model.emulate(Emulation.DeviceModeModel.Type.None, null, null); |
| 360 } | 360 } |
| 361 | 361 |
| 362 captureScreenshot() { | 362 /** |
| 363 var target = this._model.target(); | 363 * @return {!Promise} |
| 364 if (!target) | 364 */ |
| 365 async captureScreenshot() { |
| 366 SDK.DOMModel.muteHighlight(); |
| 367 var screenshot = await this._model.captureScreenshot(false); |
| 368 SDK.DOMModel.unmuteHighlight(); |
| 369 if (screenshot === null) |
| 365 return; | 370 return; |
| 366 var screenCaptureModel = target.model(SDK.ScreenCaptureModel); | |
| 367 if (!screenCaptureModel) | |
| 368 return; | |
| 369 SDK.DOMModel.muteHighlight(); | |
| 370 | 371 |
| 371 var zoomFactor = UI.zoomManager.zoomFactor(); | 372 var pageImage = new Image(); |
| 372 var rect = this._contentArea.getBoundingClientRect(); | 373 pageImage.src = 'data:image/png;base64,' + screenshot; |
| 373 var availableSize = new UI.Size(Math.max(rect.width * zoomFactor, 1), Math.m
ax(rect.height * zoomFactor, 1)); | 374 pageImage.onload = async () => { |
| 374 var outlineVisible = this._model.deviceOutlineSetting().get(); | 375 var scale = 1 / this._model.scale(); |
| 376 var outlineRect = this._model.outlineRect().scale(scale); |
| 377 var screenRect = this._model.screenRect().scale(scale); |
| 378 var visiblePageRect = this._model.visiblePageRect().scale(scale); |
| 379 var contentLeft = screenRect.left + visiblePageRect.left - outlineRect.lef
t; |
| 380 var contentTop = screenRect.top + visiblePageRect.top - outlineRect.top; |
| 375 | 381 |
| 376 if (availableSize.width < this._model.screenRect().width || | |
| 377 availableSize.height < this._model.screenRect().height) { | |
| 378 UI.inspectorView.minimize(); | |
| 379 this._model.deviceOutlineSetting().set(false); | |
| 380 } | |
| 381 | |
| 382 screenCaptureModel.captureScreenshot('png', 100).then(screenshotCaptured.bin
d(this)); | |
| 383 | |
| 384 /** | |
| 385 * @param {?string} content | |
| 386 * @this {Emulation.DeviceModeView} | |
| 387 */ | |
| 388 function screenshotCaptured(content) { | |
| 389 this._model.deviceOutlineSetting().set(outlineVisible); | |
| 390 var dpr = window.devicePixelRatio; | |
| 391 var outlineRect = this._model.outlineRect().scale(dpr); | |
| 392 var screenRect = this._model.screenRect().scale(dpr); | |
| 393 screenRect.left -= outlineRect.left; | |
| 394 screenRect.top -= outlineRect.top; | |
| 395 var visiblePageRect = this._model.visiblePageRect().scale(dpr); | |
| 396 visiblePageRect.left += screenRect.left; | |
| 397 visiblePageRect.top += screenRect.top; | |
| 398 outlineRect.left = 0; | |
| 399 outlineRect.top = 0; | |
| 400 | |
| 401 SDK.DOMModel.unmuteHighlight(); | |
| 402 UI.inspectorView.restore(); | |
| 403 | |
| 404 if (content === null) | |
| 405 return; | |
| 406 | |
| 407 // Create a canvas to splice the images together. | |
| 408 var canvas = createElement('canvas'); | 382 var canvas = createElement('canvas'); |
| 383 canvas.width = Math.floor(outlineRect.width); |
| 384 canvas.height = Math.floor(outlineRect.height); |
| 409 var ctx = canvas.getContext('2d'); | 385 var ctx = canvas.getContext('2d'); |
| 410 canvas.width = outlineRect.width; | |
| 411 canvas.height = outlineRect.height; | |
| 412 ctx.imageSmoothingEnabled = false; | 386 ctx.imageSmoothingEnabled = false; |
| 413 | 387 |
| 414 var promise = Promise.resolve(); | |
| 415 if (this._model.outlineImage()) | 388 if (this._model.outlineImage()) |
| 416 promise = promise.then(paintImage.bind(null, this._model.outlineImage(),
outlineRect)); | 389 await this._paintImage(ctx, this._model.outlineImage(), outlineRect.rela
tiveTo(outlineRect)); |
| 417 promise = promise.then(drawBorder); | |
| 418 if (this._model.screenImage()) | 390 if (this._model.screenImage()) |
| 419 promise = promise.then(paintImage.bind(null, this._model.screenImage(),
screenRect)); | 391 await this._paintImage(ctx, this._model.screenImage(), screenRect.relati
veTo(outlineRect)); |
| 420 promise.then(paintScreenshot.bind(this)); | 392 ctx.drawImage(pageImage, Math.floor(contentLeft), Math.floor(contentTop)); |
| 421 | 393 this._saveScreenshot(canvas); |
| 422 /** | 394 }; |
| 423 * @param {string} src | |
| 424 * @param {!UI.Rect} rect | |
| 425 * @return {!Promise<undefined>} | |
| 426 */ | |
| 427 function paintImage(src, rect) { | |
| 428 var callback; | |
| 429 var promise = new Promise(fulfill => callback = fulfill); | |
| 430 var image = new Image(); | |
| 431 image.crossOrigin = 'Anonymous'; | |
| 432 image.srcset = src; | |
| 433 image.onload = onImageLoad; | |
| 434 image.onerror = callback; | |
| 435 return promise; | |
| 436 | |
| 437 function onImageLoad() { | |
| 438 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height); | |
| 439 callback(); | |
| 440 } | |
| 441 } | |
| 442 | |
| 443 function drawBorder() { | |
| 444 ctx.strokeStyle = 'hsla(0, 0%, 98%, 0.5)'; | |
| 445 ctx.lineWidth = 1; | |
| 446 ctx.setLineDash([10, 10]); | |
| 447 ctx.strokeRect(screenRect.left + 1, screenRect.top + 1, screenRect.width
- 2, screenRect.height - 2); | |
| 448 } | |
| 449 | |
| 450 /** | |
| 451 * @this {Emulation.DeviceModeView} | |
| 452 */ | |
| 453 function paintScreenshot() { | |
| 454 var pageImage = new Image(); | |
| 455 pageImage.src = 'data:image/png;base64,' + content; | |
| 456 pageImage.onload = () => { | |
| 457 ctx.drawImage( | |
| 458 pageImage, visiblePageRect.left, visiblePageRect.top, Math.min(pag
eImage.naturalWidth, screenRect.width), | |
| 459 Math.min(pageImage.naturalHeight, screenRect.height)); | |
| 460 var url = target.inspectedURL(); | |
| 461 var fileName = url ? url.trimURL().removeURLFragment() : ''; | |
| 462 if (this._model.type() === Emulation.DeviceModeModel.Type.Device) | |
| 463 fileName += Common.UIString('(%s)', this._model.device().title); | |
| 464 // Trigger download. | |
| 465 var link = createElement('a'); | |
| 466 link.download = fileName + '.png'; | |
| 467 link.href = canvas.toDataURL('image/png'); | |
| 468 link.click(); | |
| 469 }; | |
| 470 } | |
| 471 } | |
| 472 } | 395 } |
| 473 | 396 |
| 474 captureFullSizeScreenshot() { | 397 /** |
| 398 * @return {!Promise} |
| 399 */ |
| 400 async captureFullSizeScreenshot() { |
| 475 SDK.DOMModel.muteHighlight(); | 401 SDK.DOMModel.muteHighlight(); |
| 476 this._model.captureFullSizeScreenshot(content => { | 402 var screenshot = await this._model.captureScreenshot(true); |
| 477 SDK.DOMModel.unmuteHighlight(); | 403 SDK.DOMModel.unmuteHighlight(); |
| 478 if (content === null) | 404 if (screenshot === null) |
| 479 return; | 405 return; |
| 406 |
| 407 var pageImage = new Image(); |
| 408 pageImage.src = 'data:image/png;base64,' + screenshot; |
| 409 pageImage.onload = () => { |
| 480 var canvas = createElement('canvas'); | 410 var canvas = createElement('canvas'); |
| 481 var pageImage = new Image(); | 411 canvas.width = pageImage.width; |
| 482 pageImage.src = 'data:image/png;base64,' + content; | 412 canvas.height = pageImage.height; |
| 483 pageImage.onload = () => { | 413 var ctx = canvas.getContext('2d'); |
| 484 var ctx = canvas.getContext('2d'); | 414 ctx.imageSmoothingEnabled = false; |
| 485 ctx.imageSmoothingEnabled = false; | 415 ctx.drawImage(pageImage, 0, 0); |
| 486 canvas.width = pageImage.width; | 416 this._saveScreenshot(canvas); |
| 487 canvas.height = pageImage.height; | 417 }; |
| 488 ctx.drawImage(pageImage, 0, 0); | 418 } |
| 489 var url = this._model.target() && this._model.target().inspectedURL(); | 419 |
| 490 var fileName = url ? url.trimURL().removeURLFragment() : ''; | 420 /** |
| 491 if (this._model.type() === Emulation.DeviceModeModel.Type.Device) | 421 * @param {!CanvasRenderingContext2D} ctx |
| 492 fileName += Common.UIString('(%s)', this._model.device().title); | 422 * @param {string} src |
| 493 var link = createElement('a'); | 423 * @param {!UI.Rect} rect |
| 494 link.download = fileName + '.png'; | 424 * @return {!Promise} |
| 495 canvas.toBlob(function(blob) { | 425 */ |
| 496 link.href = URL.createObjectURL(blob); | 426 _paintImage(ctx, src, rect) { |
| 497 link.click(); | 427 return new Promise(fulfill => { |
| 498 }); | 428 var image = new Image(); |
| 429 image.crossOrigin = 'Anonymous'; |
| 430 image.srcset = src; |
| 431 image.onerror = fulfill; |
| 432 image.onload = () => { |
| 433 ctx.drawImage(image, rect.left, rect.top, rect.width, rect.height); |
| 434 fulfill(); |
| 499 }; | 435 }; |
| 500 }); | 436 }); |
| 501 } | 437 } |
| 438 |
| 439 /** |
| 440 * @param {!Element} canvas |
| 441 */ |
| 442 _saveScreenshot(canvas) { |
| 443 var url = this._model.target() && this._model.target().inspectedURL(); |
| 444 var fileName = url ? url.trimURL().removeURLFragment() : ''; |
| 445 if (this._model.type() === Emulation.DeviceModeModel.Type.Device) |
| 446 fileName += Common.UIString('(%s)', this._model.device().title); |
| 447 var link = createElement('a'); |
| 448 link.download = fileName + '.png'; |
| 449 canvas.toBlob(blob => { |
| 450 link.href = URL.createObjectURL(blob); |
| 451 link.click(); |
| 452 }); |
| 453 } |
| 502 }; | 454 }; |
| 503 | 455 |
| 504 /** | 456 /** |
| 505 * @unrestricted | 457 * @unrestricted |
| 506 */ | 458 */ |
| 507 Emulation.DeviceModeView.Ruler = class extends UI.VBox { | 459 Emulation.DeviceModeView.Ruler = class extends UI.VBox { |
| 508 /** | 460 /** |
| 509 * @param {boolean} horizontal | 461 * @param {boolean} horizontal |
| 510 * @param {function(number)} applyCallback | 462 * @param {function(number)} applyCallback |
| 511 */ | 463 */ |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 return Promise.resolve(); | 546 return Promise.resolve(); |
| 595 } | 547 } |
| 596 | 548 |
| 597 /** | 549 /** |
| 598 * @param {number} size | 550 * @param {number} size |
| 599 */ | 551 */ |
| 600 _onMarkerClick(size) { | 552 _onMarkerClick(size) { |
| 601 this._applyCallback.call(null, size); | 553 this._applyCallback.call(null, size); |
| 602 } | 554 } |
| 603 }; | 555 }; |
| OLD | NEW |