Best JavaScript code snippet using playwright-internal
DimensionsInput.test.js
Source:DimensionsInput.test.js
1/*2 * Copyright (C) 2019 - present Instructure, Inc.3 *4 * This file is part of Canvas.5 *6 * Canvas is free software: you can redistribute it and/or modify it under7 * the terms of the GNU Affero General Public License as published by the Free8 * Software Foundation, version 3 of the License.9 *10 * Canvas is distributed in the hope that it will be useful, but WITHOUT ANY11 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR12 * A PARTICULAR PURPOSE. See the GNU Affero General Public License for more13 * details.14 *15 * You should have received a copy of the GNU Affero General Public License along16 * with this program. If not, see <http://www.gnu.org/licenses/>.17 */18import React from 'react'19import {render} from '@testing-library/react'20import DimensionsInput, {useDimensionsState} from '..'21import DimensionsInputDriver from './DimensionsInputDriver'22const NAN_ERROR = 'Width and height must be numbers'23const ASPECT_MESSAGE = 'Aspect ratio will be preserved'24describe('RCE > Plugins > Shared > DimensionsInput', () => {25 let $container26 let component27 let dimensions28 let dimensionsState29 let initialState30 let props31 beforeEach(() => {32 $container = document.body.appendChild(document.createElement('div'))33 dimensionsState = null34 initialState = {35 appliedHeight: 300,36 appliedWidth: 150,37 naturalHeight: 200,38 naturalWidth: 10039 }40 props = {41 minWidth: 30,42 minHeight: 6043 }44 })45 afterEach(() => {46 component.unmount()47 $container.remove()48 })49 function SpecComponent() {50 const {minHeight, minWidth} = props51 dimensionsState = useDimensionsState(initialState, {minHeight, minWidth})52 return <DimensionsInput dimensionsState={dimensionsState} {...props} />53 }54 function renderComponent() {55 component = render(<SpecComponent />, {container: $container})56 dimensions = new DimensionsInputDriver($container.firstChild)57 }58 function buildMinDimensionsError() {59 return `Must be at least ${props.minWidth} x ${props.minHeight}px`60 }61 describe('"Width" field', () => {62 it('is present', () => {63 renderComponent()64 expect(dimensions.width).not.toBeNull()65 })66 describe('when a width has been applied to the element', () => {67 it('uses the applied width as the field value', () => {68 renderComponent()69 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth}`)70 })71 it('uses the applied width for the dimensions state width', () => {72 renderComponent()73 expect(dimensionsState.width).toEqual(initialState.appliedWidth)74 })75 describe('when the applied width is less than the minimum width', () => {76 beforeEach(() => {77 initialState.appliedWidth = props.minWidth - 178 renderComponent()79 })80 it('displays a validation error with the field', () => {81 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])82 })83 it('sets the dimensions state as invalid', () => {84 expect(dimensionsState.isValid).toEqual(false)85 })86 })87 })88 describe('when no width has been applied to the element', () => {89 beforeEach(() => {90 initialState.appliedWidth = null91 renderComponent()92 })93 it('uses the natural width as the field value', () => {94 expect(dimensions.width.value).toEqual(`${initialState.naturalWidth}`)95 })96 it('uses the applied width for the dimensions state width', () => {97 expect(dimensionsState.width).toEqual(initialState.naturalWidth)98 })99 })100 describe('when the value changes', () => {101 beforeEach(renderComponent)102 it('updates the value in the field', () => {103 dimensions.width.setValue('120')104 expect(dimensions.width.value).toEqual('120')105 })106 it('updates dimensions state width with the parsed number', () => {107 dimensions.width.setValue('120')108 expect(dimensionsState.width).toEqual(120)109 })110 it('proportionally scales the height in the dimensions state', () => {111 dimensions.width.setValue('120')112 expect(dimensionsState.height).toEqual(240)113 })114 it('updates the height field with the scaled height', () => {115 dimensions.width.setValue('120')116 expect(dimensions.height.value).toEqual('240')117 })118 describe('when the value includes whitespace', () => {119 it('preserves the whitespace in the field', () => {120 dimensions.width.setValue(' 120 ')121 expect(dimensions.width.value).toEqual(' 120 ')122 })123 it('ignores whitespace in the dimensions state width', () => {124 dimensions.width.setValue(' 120 ')125 expect(dimensionsState.width).toEqual(120)126 })127 })128 describe('when the value is a decimal number', () => {129 it('preserves the decimal value in the field', () => {130 dimensions.width.setValue('119.51')131 expect(dimensions.width.value).toEqual('119.51')132 })133 it('sets the dimensions state width with the rounded integer', () => {134 dimensions.width.setValue('119.51')135 expect(dimensionsState.width).toEqual(120)136 })137 })138 describe('when the value is cleared', () => {139 beforeEach(() => {140 dimensions.width.setValue('')141 })142 it('sets the dimensions state width to null', () => {143 expect(dimensionsState.width).toBeNull()144 })145 it('clears the height field', () => {146 expect(dimensions.height.value).toEqual('')147 })148 it('sets the dimensions state height to null', () => {149 expect(dimensionsState.height).toBeNull()150 })151 it('sets the dimensions state as invalid', () => {152 expect(dimensionsState.isValid).toEqual(false)153 })154 })155 describe('when the value is not a number', () => {156 it('preserves the invalid value in the field', () => {157 dimensions.width.setValue('twelve')158 expect(dimensions.width.value).toEqual('twelve')159 })160 it('sets the dimensions state width to NaN', () => {161 dimensions.width.setValue('twelve')162 expect(dimensionsState.width).toBeNaN()163 })164 it('clears the height field', () => {165 dimensions.width.setValue('twelve')166 expect(dimensions.height.value).toEqual('')167 })168 it('sets the dimensions state height to NaN', () => {169 dimensions.width.setValue('twelve')170 expect(dimensionsState.height).toBeNaN()171 })172 })173 describe('when the value is not a finite number', () => {174 beforeEach(() => {175 dimensions.width.setValue('Infinity')176 })177 it('preserves the value in the field', () => {178 expect(dimensions.width.value).toEqual('Infinity')179 })180 it('sets the dimensions state width to NaN', () => {181 expect(dimensionsState.width).toBeNaN()182 })183 it('sets the dimensions state as invalid', () => {184 expect(dimensionsState.isValid).toEqual(false)185 })186 it('displays a validation error with the field', () => {187 expect(dimensions.messageTexts).toEqual([NAN_ERROR])188 })189 })190 describe('when the value is less than the minimum', () => {191 it('displays a validation error with the field', () => {192 dimensions.width.setValue(props.minWidth - 1)193 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])194 })195 it('sets the dimensions state as invalid', () => {196 dimensions.width.setValue(props.minWidth - 1)197 expect(dimensionsState.isValid).toEqual(false)198 })199 })200 describe('when the value becomes valid', () => {201 beforeEach(() => {202 dimensions.width.setValue(props.minWidth - 1)203 dimensions.width.setValue(props.minWidth)204 })205 it('removes the validation error from the field', () => {206 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])207 })208 it('sets the dimensions state as valid', () => {209 expect(dimensionsState.isValid).toEqual(true)210 })211 })212 describe('when the value remains invalid', () => {213 beforeEach(() => {214 dimensions.width.setValue('')215 dimensions.width.setValue(1)216 })217 it('displays a validation error with the field', () => {218 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])219 })220 it('sets the dimensions state as invalid', () => {221 expect(dimensionsState.isValid).toEqual(false)222 })223 })224 })225 describe('when decremented', () => {226 describe('when a width has been applied to the element', () => {227 beforeEach(() => {228 renderComponent()229 dimensions.width.decrement()230 })231 it('decrements the applied width for the field value', () => {232 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth - 1}`)233 })234 it('decrements the applied width for the dimensions state width', () => {235 expect(dimensionsState.width).toEqual(initialState.appliedWidth - 1)236 })237 })238 describe('when no width has been applied to the element', () => {239 beforeEach(() => {240 initialState.appliedWidth = null241 renderComponent()242 dimensions.width.decrement()243 })244 it('decrements the natural width for the field value', () => {245 expect(dimensions.width.value).toEqual(`${initialState.naturalWidth - 1}`)246 })247 it('decrements the natural width for the dimensions state width', () => {248 expect(dimensionsState.width).toEqual(initialState.naturalWidth - 1)249 })250 })251 describe('when the applied width is less than the minimum width', () => {252 beforeEach(() => {253 initialState.appliedWidth = props.minWidth - 1254 renderComponent()255 dimensions.width.decrement()256 })257 it('uses the minimum width for the field value', () => {258 expect(dimensions.width.value).toEqual(`${props.minWidth}`)259 })260 it('uses the minimum width for the dimensions state width', () => {261 expect(dimensionsState.width).toEqual(props.minWidth)262 })263 it('removes the validation error from the field', () => {264 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])265 })266 it('sets the dimensions state as valid', () => {267 expect(dimensionsState.isValid).toEqual(true)268 })269 })270 it('proportionally scales the height in the dimensions state', () => {271 renderComponent()272 dimensions.width.decrement()273 expect(dimensionsState.height).toEqual(initialState.appliedHeight - 2)274 })275 it('updates the height field with the scaled height', () => {276 renderComponent()277 dimensions.width.decrement()278 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight - 2}`)279 })280 describe('when the value had been cleared', () => {281 beforeEach(() => {282 renderComponent()283 dimensions.width.setValue('')284 dimensions.width.decrement()285 })286 it('decrements the initial width for the field value', () => {287 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth - 1}`)288 })289 it('decrements the initial width for the dimensions state width', () => {290 expect(dimensionsState.width).toEqual(initialState.appliedWidth - 1)291 })292 it('removes the validation error from the field', () => {293 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])294 })295 it('sets the dimensions state as valid', () => {296 expect(dimensionsState.isValid).toEqual(true)297 })298 })299 describe('when the value is the minimum width', () => {300 beforeEach(() => {301 renderComponent()302 dimensions.width.setValue(props.minWidth)303 dimensions.width.decrement()304 })305 it('preserves the value in the field', () => {306 expect(dimensions.width.value).toEqual(`${props.minWidth}`)307 })308 it('sets the dimensions state width to the minimum width', () => {309 expect(dimensionsState.width).toEqual(props.minWidth)310 })311 })312 describe('when the height is the minimum height', () => {313 beforeEach(() => {314 props.minHeight = 120315 props.minWidth = 10316 renderComponent()317 dimensions.height.setValue(props.minHeight)318 dimensions.width.decrement()319 })320 it('preserves the value in the height field', () => {321 expect(dimensions.height.value).toEqual(`${props.minHeight}`)322 })323 it('preserves the aspect ratio for the width field', () => {324 expect(dimensions.width.value).toEqual(`${props.minHeight / 2}`)325 })326 it('sets the dimensions state height to the minimum height', () => {327 expect(dimensionsState.height).toEqual(props.minHeight)328 })329 it('preserves the aspect ratio for the dimensions state width', () => {330 expect(dimensionsState.width).toEqual(props.minHeight / 2)331 })332 })333 describe('when the value is not a number', () => {334 beforeEach(() => {335 renderComponent()336 dimensions.height.setValue('twelve')337 dimensions.height.decrement()338 })339 it('preserves the invalid value in the field', () => {340 expect(dimensions.height.value).toEqual('twelve')341 })342 it('sets the dimensions state height to NaN', () => {343 expect(dimensionsState.height).toBeNaN()344 })345 })346 })347 describe('when incremented', () => {348 describe('when a width has been applied to the element', () => {349 beforeEach(() => {350 renderComponent()351 dimensions.width.increment()352 })353 it('increments the applied width for the field value', () => {354 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth + 1}`)355 })356 it('increments the applied width for the dimensions state width', () => {357 expect(dimensionsState.width).toEqual(initialState.appliedWidth + 1)358 })359 })360 describe('when no width has been applied to the element', () => {361 beforeEach(() => {362 initialState.appliedWidth = null363 renderComponent()364 dimensions.width.increment()365 })366 it('increments the natural width for the field value', () => {367 expect(dimensions.width.value).toEqual(`${initialState.naturalWidth + 1}`)368 })369 it('increments the natural width for the dimensions state width', () => {370 expect(dimensionsState.width).toEqual(initialState.naturalWidth + 1)371 })372 })373 describe('when the applied width is less than the minimum width', () => {374 beforeEach(() => {375 initialState.appliedWidth = props.minWidth - 2376 renderComponent()377 dimensions.width.increment()378 })379 it('uses the minimum width for the field value', () => {380 expect(dimensions.width.value).toEqual(`${props.minWidth}`)381 })382 it('uses the minimum width for the dimensions state width', () => {383 expect(dimensionsState.width).toEqual(props.minWidth)384 })385 it('removes the validation error from the field', () => {386 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])387 })388 it('sets the dimensions state as valid', () => {389 expect(dimensionsState.isValid).toEqual(true)390 })391 })392 it('proportionally scales the height in the dimensions state', () => {393 renderComponent()394 dimensions.width.increment()395 // height is twice the width and scales at twice the rate396 expect(dimensionsState.height).toEqual(initialState.appliedHeight + 2)397 })398 it('updates the height field with the scaled height', () => {399 renderComponent()400 dimensions.width.increment()401 // height is twice the width and scales at twice the rate402 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight + 2}`)403 })404 describe('when the value had been cleared', () => {405 beforeEach(() => {406 renderComponent()407 dimensions.width.setValue('')408 dimensions.width.increment()409 })410 it('increments the initial width for the field value', () => {411 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth + 1}`)412 })413 it('increments the initial width for the dimensions state width', () => {414 expect(dimensionsState.width).toEqual(initialState.appliedWidth + 1)415 })416 it('removes the validation error from the field', () => {417 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])418 })419 it('sets the dimensions state as valid', () => {420 expect(dimensionsState.isValid).toEqual(true)421 })422 })423 describe('when the value is not a number', () => {424 beforeEach(() => {425 renderComponent()426 dimensions.width.setValue('twelve')427 dimensions.width.increment()428 })429 it('preserves the invalid value in the field', () => {430 expect(dimensions.width.value).toEqual('twelve')431 })432 it('sets the dimensions state width to NaN', () => {433 expect(dimensionsState.width).toBeNaN()434 })435 })436 })437 })438 describe('"Height" field', () => {439 it('is present', () => {440 renderComponent()441 expect(dimensions.height).not.toBeNull()442 })443 describe('when a height has been applied to the element', () => {444 it('uses the applied height as the field value', () => {445 renderComponent()446 expect(dimensions.height.value).toEqual('300')447 })448 it('uses the applied height for the dimensions state height', () => {449 renderComponent()450 expect(dimensionsState.height).toEqual(300)451 })452 describe('when the applied height is less than the minimum height', () => {453 beforeEach(() => {454 initialState.appliedHeight = props.minHeight - 1455 renderComponent()456 })457 it('displays a validation error with the field', () => {458 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])459 })460 it('sets the dimensions state as invalid', () => {461 expect(dimensionsState.isValid).toEqual(false)462 })463 })464 })465 describe('when no height has been applied to the element', () => {466 beforeEach(() => {467 initialState.appliedHeight = null468 renderComponent()469 })470 it('uses the natural height as the field value', () => {471 expect(dimensions.height.value).toEqual('200')472 })473 it('uses the applied height for the dimensions state height', () => {474 expect(dimensionsState.height).toEqual(200)475 })476 })477 describe('when the value changes', () => {478 beforeEach(renderComponent)479 it('updates the value in the field', () => {480 dimensions.height.setValue('120')481 expect(dimensions.height.value).toEqual('120')482 })483 it('updates dimensions state height with the parsed number', () => {484 dimensions.height.setValue('120')485 expect(dimensionsState.height).toEqual(120)486 })487 it('proportionally scales the width in the dimensions state', () => {488 dimensions.height.setValue('120')489 expect(dimensionsState.width).toEqual(60)490 })491 it('updates the width field with the scaled width', () => {492 dimensions.height.setValue('120')493 expect(dimensions.width.value).toEqual('60')494 })495 describe('when the value includes whitespace', () => {496 it('preserves the whitespace in the field', () => {497 dimensions.height.setValue(' 120 ')498 expect(dimensions.height.value).toEqual(' 120 ')499 })500 it('ignores whitespace in the dimensions state height', () => {501 dimensions.height.setValue(' 120 ')502 expect(dimensionsState.height).toEqual(120)503 })504 })505 describe('when the value is a decimal number', () => {506 it('preserves the decimal value in the field', () => {507 dimensions.height.setValue('119.51')508 expect(dimensions.height.value).toEqual('119.51')509 })510 it('sets the dimensions state height with the rounded integer', () => {511 dimensions.height.setValue('119.51')512 expect(dimensionsState.height).toEqual(120)513 })514 })515 describe('when the value is cleared', () => {516 beforeEach(() => {517 dimensions.height.setValue('')518 })519 it('sets the dimensions state height to null', () => {520 expect(dimensionsState.height).toBeNull()521 })522 it('clears the width field', () => {523 expect(dimensions.width.value).toEqual('')524 })525 it('sets the dimensions state width to null', () => {526 expect(dimensionsState.width).toBeNull()527 })528 it('sets the dimensions state as invalid', () => {529 expect(dimensionsState.isValid).toEqual(false)530 })531 })532 describe('when the value is not a number', () => {533 beforeEach(() => {534 dimensions.height.setValue('twelve')535 })536 it('preserves the invalid value in the field', () => {537 expect(dimensions.height.value).toEqual('twelve')538 })539 it('sets the dimensions state height to NaN', () => {540 expect(dimensionsState.height).toBeNaN()541 })542 it('clears the width field', () => {543 expect(dimensions.width.value).toEqual('')544 })545 it('sets the dimensions state width to NaN', () => {546 expect(dimensionsState.width).toBeNaN()547 })548 })549 describe('when the value is not a finite number', () => {550 beforeEach(() => {551 dimensions.height.setValue('Infinity')552 })553 it('preserves the value in the field', () => {554 expect(dimensions.height.value).toEqual('Infinity')555 })556 it('sets the dimensions state height to NaN', () => {557 expect(dimensionsState.height).toBeNaN()558 })559 it('sets the dimensions state as invalid', () => {560 expect(dimensionsState.isValid).toEqual(false)561 })562 it('displays a validation error with the field', () => {563 expect(dimensions.messageTexts).toEqual([NAN_ERROR])564 })565 })566 describe('when the value is less than the minimum', () => {567 beforeEach(() => {568 dimensions.height.setValue(props.minHeight)569 dimensions.height.setValue(props.minHeight - 1)570 })571 it('displays a validation error with the field', () => {572 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])573 })574 it('sets the dimensions state as invalid', () => {575 expect(dimensionsState.isValid).toEqual(false)576 })577 })578 describe('when the value becomes valid', () => {579 beforeEach(() => {580 dimensions.height.setValue(props.minHeight - 1)581 dimensions.height.setValue(props.minHeight)582 })583 it('removes the validation error from the field', () => {584 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])585 })586 it('sets the dimensions state as valid', () => {587 expect(dimensionsState.isValid).toEqual(true)588 })589 })590 describe('when the value remains invalid', () => {591 beforeEach(() => {592 dimensions.height.setValue('')593 dimensions.height.setValue(1)594 })595 it('displays a validation error with the field', () => {596 expect(dimensions.messageTexts).toEqual([buildMinDimensionsError()])597 })598 it('sets the dimensions state as invalid', () => {599 expect(dimensionsState.isValid).toEqual(false)600 })601 })602 })603 describe('when decremented', () => {604 describe('when a height has been applied to the element', () => {605 beforeEach(() => {606 renderComponent()607 dimensions.height.decrement()608 })609 it('decrements the applied height for the field value', () => {610 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight - 1}`)611 })612 it('decrements the applied height for the dimensions state height', () => {613 expect(dimensionsState.height).toEqual(initialState.appliedHeight - 1)614 })615 })616 describe('when no height has been applied to the element', () => {617 beforeEach(() => {618 initialState.appliedHeight = null619 renderComponent()620 dimensions.height.decrement()621 })622 it('decrements the natural height for the field value', () => {623 expect(dimensions.height.value).toEqual(`${initialState.naturalHeight - 1}`)624 })625 it('decrements the natural height for the dimensions state height', () => {626 expect(dimensionsState.height).toEqual(initialState.naturalHeight - 1)627 })628 })629 describe('when the applied height is less than the minimum height', () => {630 beforeEach(() => {631 initialState.appliedHeight = props.minHeight - 1632 renderComponent()633 dimensions.height.decrement()634 })635 it('uses the minimum height for the field value', () => {636 expect(dimensions.height.value).toEqual(`${props.minHeight}`)637 })638 it('uses the minimum height for the dimensions state height', () => {639 expect(dimensionsState.height).toEqual(props.minHeight)640 })641 it('removes the validation error from the field', () => {642 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])643 })644 it('sets the dimensions state as valid', () => {645 expect(dimensionsState.isValid).toEqual(true)646 })647 })648 it('proportionally scales the width in the dimensions state', () => {649 renderComponent()650 dimensions.height.decrement()651 dimensions.height.decrement() // decrement twice to ensure a round number decrement of width652 expect(dimensionsState.width).toEqual(initialState.appliedWidth - 1)653 })654 it('updates the width field with the scaled width', () => {655 renderComponent()656 dimensions.height.decrement()657 dimensions.height.decrement() // decrement twice to ensure a round number decrement of width658 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth - 1}`)659 })660 describe('when the value had been cleared', () => {661 beforeEach(() => {662 renderComponent()663 dimensions.height.setValue('')664 dimensions.height.decrement()665 })666 it('decrements the initial height for the field value', () => {667 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight - 1}`)668 })669 it('decrements the initial height for the dimensions state height', () => {670 expect(dimensionsState.height).toEqual(initialState.appliedHeight - 1)671 })672 it('removes the validation error from the field', () => {673 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])674 })675 it('sets the dimensions state as valid', () => {676 expect(dimensionsState.isValid).toEqual(true)677 })678 })679 describe('when the value is the minimum height', () => {680 beforeEach(() => {681 renderComponent()682 dimensions.height.setValue(props.minHeight)683 dimensions.height.decrement()684 })685 it('preserves the value in the field', () => {686 expect(dimensions.height.value).toEqual(`${props.minHeight}`)687 })688 it('sets the dimensions state height to the minimum height', () => {689 expect(dimensionsState.height).toEqual(props.minHeight)690 })691 })692 describe('when the width is the minimum width', () => {693 beforeEach(() => {694 props.minHeight = 10695 props.minWidth = 60696 renderComponent()697 dimensions.width.setValue(props.minWidth)698 dimensions.height.decrement()699 })700 it('preserves the value in the width field', () => {701 expect(dimensions.width.value).toEqual(`${props.minWidth}`)702 })703 it('preserves the aspect ratio for the height field', () => {704 expect(dimensions.height.value).toEqual('120')705 })706 it('sets the dimensions state width to the minimum width', () => {707 expect(dimensionsState.width).toEqual(props.minWidth)708 })709 it('preserves the aspect ratio for the dimensions state height', () => {710 expect(dimensionsState.height).toEqual(120)711 })712 })713 describe('when the value is not a number', () => {714 beforeEach(() => {715 renderComponent()716 dimensions.height.setValue('twelve')717 dimensions.height.decrement()718 })719 it('preserves the invalid value in the field', () => {720 expect(dimensions.height.value).toEqual('twelve')721 })722 it('sets the dimensions state height to NaN', () => {723 expect(dimensionsState.height).toBeNaN()724 })725 })726 })727 describe('when incremented', () => {728 describe('when a height has been applied to the element', () => {729 beforeEach(() => {730 renderComponent()731 dimensions.height.increment()732 })733 it('increments the applied height for the field value', () => {734 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight + 1}`)735 })736 it('increments the applied height for the dimensions state height', () => {737 expect(dimensionsState.height).toEqual(initialState.appliedHeight + 1)738 })739 })740 describe('when no height has been applied to the element', () => {741 beforeEach(() => {742 initialState.appliedHeight = null743 renderComponent()744 dimensions.height.increment()745 })746 it('increments the natural height for the field value', () => {747 expect(dimensions.height.value).toEqual(`${initialState.naturalHeight + 1}`)748 })749 it('increments the natural height for the dimensions state height', () => {750 expect(dimensionsState.height).toEqual(initialState.naturalHeight + 1)751 })752 })753 describe('when the applied height is less than the minimum height', () => {754 beforeEach(() => {755 initialState.appliedHeight = props.minHeight - 2756 renderComponent()757 dimensions.height.increment()758 })759 it('uses the minimum height for the field value', () => {760 expect(dimensions.height.value).toEqual(`${props.minHeight}`)761 })762 it('uses the minimum height for the dimensions state height', () => {763 expect(dimensionsState.height).toEqual(props.minHeight)764 })765 it('removes the validation error from the field', () => {766 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])767 })768 it('sets the dimensions state as valid', () => {769 expect(dimensionsState.isValid).toEqual(true)770 })771 })772 it('proportionally scales the width in the dimensions state', () => {773 renderComponent()774 dimensions.height.increment()775 dimensions.height.increment() // increment twice to ensure a round number increment of width776 expect(dimensionsState.width).toEqual(initialState.appliedWidth + 1)777 })778 it('updates the width field with the scaled width', () => {779 renderComponent()780 dimensions.height.increment()781 dimensions.height.increment() // increment twice to ensure a round number increment of width782 expect(dimensions.width.value).toEqual(`${initialState.appliedWidth + 1}`)783 })784 describe('when the value had been cleared', () => {785 beforeEach(() => {786 renderComponent()787 dimensions.height.setValue('')788 dimensions.height.increment()789 })790 it('increments the initial height for the field value', () => {791 expect(dimensions.height.value).toEqual(`${initialState.appliedHeight + 1}`)792 })793 it('increments the initial height for the dimensions state height', () => {794 expect(dimensionsState.height).toEqual(initialState.appliedHeight + 1)795 })796 it('removes the validation error from the field', () => {797 expect(dimensions.messageTexts).toEqual([ASPECT_MESSAGE])798 })799 it('sets the dimensions state as valid', () => {800 expect(dimensionsState.isValid).toEqual(true)801 })802 })803 describe('when the value is not a number', () => {804 beforeEach(() => {805 renderComponent()806 dimensions.height.setValue('twelve')807 dimensions.height.increment()808 })809 it('preserves the invalid value in the field', () => {810 expect(dimensions.height.value).toEqual('twelve')811 })812 it('sets the dimensions state height to NaN', () => {813 expect(dimensionsState.height).toBeNaN()814 })815 })816 })817 })...
ve.dm.Scalable.js
Source:ve.dm.Scalable.js
1/*!2 * VisualEditor DataModel Scalable class.3 *4 * @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org5 */6/**7 * Scalable object.8 *9 * @class10 * @mixins OO.EventEmitter11 *12 * @constructor13 * @param {Object} [config] Configuration options14 * @cfg {boolean} [fixedRatio=true] Object has a fixed aspect ratio15 * @cfg {Object} [currentDimensions] Current dimensions, width & height16 * @cfg {Object} [originalDimensions] Original dimensions, width & height17 * @cfg {Object} [defaultDimensions] Default dimensions, width & height18 * @cfg {boolean} [isDefault] Object is using its default dimensions19 * @cfg {Object} [minDimensions] Minimum dimensions, width & height20 * @cfg {Object} [maxDimensions] Maximum dimensions, width & height21 * @cfg {boolean} [enforceMin=true] Enforce the minimum dimensions22 * @cfg {boolean} [enforceMax=true] Enforce the maximum dimensions23 */24ve.dm.Scalable = function VeDmScalable( config ) {25 config = ve.extendObject( {26 fixedRatio: true,27 enforceMin: true,28 enforceMax: true29 }, config );30 // Mixin constructors31 OO.EventEmitter.call( this );32 // Computed properties33 this.ratio = null;34 this.valid = null;35 this.defaultSize = false;36 // Initialize37 this.currentDimensions = null;38 this.defaultDimensions = null;39 this.originalDimensions = null;40 this.minDimensions = null;41 this.maxDimensions = null;42 // Properties43 this.fixedRatio = config.fixedRatio;44 if ( config.currentDimensions ) {45 this.setCurrentDimensions( config.currentDimensions );46 }47 if ( config.originalDimensions ) {48 this.setOriginalDimensions( config.originalDimensions );49 }50 if ( config.defaultDimensions ) {51 this.setDefaultDimensions( config.defaultDimensions );52 }53 if ( config.isDefault ) {54 this.toggleDefault( !!config.isDefault );55 }56 if ( config.minDimensions ) {57 this.setMinDimensions( config.minDimensions );58 }59 if ( config.maxDimensions ) {60 this.setMaxDimensions( config.maxDimensions );61 }62 this.setEnforcedMin( config.enforceMin );63 this.setEnforcedMax( config.enforceMax );64};65/* Inheritance */66OO.mixinClass( ve.dm.Scalable, OO.EventEmitter );67/* Events */68/**69 * Current changed70 *71 * @event currentSizeChange72 * @param {Object} currentDimensions Current dimensions width and height73 */74/**75 * Default size or state changed76 *77 * @event defaultSizeChange78 * @param {boolean} isDefault The size is default79 */80/**81 * Original size changed82 *83 * @event originalSizeChange84 * @param {Object} originalDimensions Original dimensions width and height85 */86/**87 * Min size changed88 *89 * @event minSizeChange90 * @param {Object} minDimensions Min dimensions width and height91 */92/**93 * Max size changed94 *95 * @event maxSizeChange96 * @param {Object} maxDimensions Max dimensions width and height97 */98/**99 * Calculate the dimensions from a given value of either width or height.100 * This method doesn't take into account any restrictions of minimum or maximum,101 * it simply calculates the new dimensions according to the aspect ratio in case102 * it exists.103 *104 * If aspect ratio does not exist, or if the original object is empty, or if the105 * original object is fully specified, the object is returned as-is without106 * calculations.107 *108 * @param {Object} dimensions Dimensions object with either width or height109 * if both are given, the object will be returned as-is.110 * @param {number} [dimensions.width] The width of the image111 * @param {number} [dimensions.height] The height of the image112 * @param {number} [ratio] The image width/height ratio, if it exists113 * @return {Object} Dimensions object with width and height114 */115ve.dm.Scalable.static.getDimensionsFromValue = function ( dimensions, ratio ) {116 dimensions = ve.copy( dimensions );117 // Normalize for 'empty' values that are specifically given118 // so if '' is explicitly given, it should be translated to 0119 if ( dimensions.width === '' ) {120 dimensions.width = 0;121 }122 if ( dimensions.height === '' ) {123 dimensions.height = 0;124 }125 // Calculate the opposite size if needed126 if ( !dimensions.height && ratio !== null && +dimensions.width ) {127 dimensions.height = Math.round( dimensions.width / ratio );128 }129 if ( !dimensions.width && ratio !== null && +dimensions.height ) {130 dimensions.width = Math.round( dimensions.height * ratio );131 }132 return dimensions;133};134/**135 * Check if an object is a dimensions object.136 * Make sure that if width or height are set, they are not 'undefined'.137 *138 * @param {Object} dimensions A dimensions object to test139 * @return {boolean} Valid or invalid dimensions object140 */141ve.dm.Scalable.static.isDimensionsObjectValid = function ( dimensions ) {142 if (143 dimensions &&144 !ve.isEmptyObject( dimensions ) &&145 (146 dimensions.width !== undefined ||147 dimensions.height !== undefined148 )149 ) {150 return true;151 }152 return false;153};154/* Methods */155/**156 * Clone the current scalable object157 *158 * @return {ve.dm.Scalable} Cloned scalable object159 */160ve.dm.Scalable.prototype.clone = function () {161 var currentDimensions = this.getCurrentDimensions(),162 originalDimensions = this.getOriginalDimensions(),163 defaultDimensions = this.getDefaultDimensions(),164 minDimensions = this.getMinDimensions(),165 maxDimensions = this.getMaxDimensions(),166 config = {167 isDefault: !!this.isDefault(),168 enforceMin: !!this.isEnforcedMin(),169 enforceMax: !!this.isEnforcedMax()170 };171 if ( currentDimensions ) {172 config.currentDimensions = ve.copy( currentDimensions );173 }174 if ( originalDimensions ) {175 config.originalDimensions = ve.copy( originalDimensions );176 }177 if ( defaultDimensions ) {178 config.defaultDimensions = ve.copy( defaultDimensions );179 }180 if ( minDimensions ) {181 config.minDimensions = ve.copy( minDimensions );182 }183 if ( maxDimensions ) {184 config.maxDimensions = ve.copy( maxDimensions );185 }186 return new this.constructor( config );187};188/**189 * Set the fixed aspect ratio from specified dimensions.190 *191 * @param {Object} dimensions Dimensions object with width & height192 */193ve.dm.Scalable.prototype.setRatioFromDimensions = function ( dimensions ) {194 if ( dimensions && dimensions.width && dimensions.height ) {195 this.ratio = dimensions.width / dimensions.height;196 }197 this.valid = null;198};199/**200 * Set the current dimensions201 *202 * Also sets the aspect ratio if not set and in fixed ratio mode.203 *204 * @param {Object} dimensions Dimensions object with width & height205 * @fires currentSizeChange206 */207ve.dm.Scalable.prototype.setCurrentDimensions = function ( dimensions ) {208 if (209 this.constructor.static.isDimensionsObjectValid( dimensions ) &&210 !ve.compare( dimensions, this.getCurrentDimensions() )211 ) {212 this.currentDimensions = ve.copy( dimensions );213 // Only use current dimensions for ratio if it isn't set214 if ( this.fixedRatio && !this.ratio ) {215 this.setRatioFromDimensions( this.getCurrentDimensions() );216 }217 this.valid = null;218 this.emit( 'currentSizeChange', this.getCurrentDimensions() );219 }220};221/**222 * Set the original dimensions223 *224 * Also resets the aspect ratio if in fixed ratio mode.225 *226 * @param {Object} dimensions Dimensions object with width & height227 * @fires originalSizeChange228 */229ve.dm.Scalable.prototype.setOriginalDimensions = function ( dimensions ) {230 if (231 this.constructor.static.isDimensionsObjectValid( dimensions ) &&232 !ve.compare( dimensions, this.getOriginalDimensions() )233 ) {234 this.originalDimensions = ve.copy( dimensions );235 // Always overwrite ratio236 if ( this.fixedRatio ) {237 this.setRatioFromDimensions( this.getOriginalDimensions() );238 }239 this.valid = null;240 this.emit( 'originalSizeChange', this.getOriginalDimensions() );241 }242};243/**244 * Set the default dimensions245 *246 * @param {Object} dimensions Dimensions object with width & height247 * @fires defaultSizeChange248 */249ve.dm.Scalable.prototype.setDefaultDimensions = function ( dimensions ) {250 if (251 this.constructor.static.isDimensionsObjectValid( dimensions ) &&252 !ve.compare( dimensions, this.getDefaultDimensions() )253 ) {254 this.defaultDimensions = ve.copy( dimensions );255 this.valid = null;256 this.emit( 'defaultSizeChange', this.isDefault() );257 }258};259/**260 * Reset and remove the default dimensions261 *262 * @fires defaultSizeChange263 */264ve.dm.Scalable.prototype.clearDefaultDimensions = function () {265 if ( this.defaultDimensions !== null ) {266 this.defaultDimensions = null;267 this.valid = null;268 this.emit( 'defaultSizeChange', this.isDefault() );269 }270};271/**272 * Reset and remove the default dimensions273 *274 * @fires originalSizeChange275 */276ve.dm.Scalable.prototype.clearOriginalDimensions = function () {277 if ( this.originalDimensions !== null ) {278 this.originalDimensions = null;279 this.valid = null;280 this.emit( 'originalSizeChange', this.isDefault() );281 }282};283/**284 * Toggle the default size setting, or set it to particular value285 *286 * @param {boolean} [isDefault] Default or not, toggles if unset287 * @fires defaultSizeChange288 */289ve.dm.Scalable.prototype.toggleDefault = function ( isDefault ) {290 if ( isDefault === undefined ) {291 isDefault = !this.isDefault();292 }293 if ( this.isDefault() !== isDefault ) {294 this.defaultSize = isDefault;295 if ( isDefault ) {296 this.setCurrentDimensions(297 this.getDefaultDimensions()298 );299 }300 this.emit( 'defaultSizeChange', this.isDefault() );301 }302};303/**304 * Set the minimum dimensions305 *306 * @param {Object} dimensions Dimensions object with width & height307 * @fires minSizeChange308 */309ve.dm.Scalable.prototype.setMinDimensions = function ( dimensions ) {310 if (311 this.constructor.static.isDimensionsObjectValid( dimensions ) &&312 !ve.compare( dimensions, this.getMinDimensions() )313 ) {314 this.minDimensions = ve.copy( dimensions );315 this.valid = null;316 this.emit( 'minSizeChange', dimensions );317 }318};319/**320 * Set the maximum dimensions321 *322 * @param {Object} dimensions Dimensions object with width & height323 * @fires maxSizeChange324 */325ve.dm.Scalable.prototype.setMaxDimensions = function ( dimensions ) {326 if (327 this.constructor.static.isDimensionsObjectValid( dimensions ) &&328 !ve.compare( dimensions, this.getMaxDimensions() )329 ) {330 this.maxDimensions = ve.copy( dimensions );331 this.emit( 'maxSizeChange', dimensions );332 this.valid = null;333 }334};335/**336 * Clear the minimum dimensions337 *338 * @fires minSizeChange339 */340ve.dm.Scalable.prototype.clearMinDimensions = function () {341 if ( this.minDimensions !== null ) {342 this.minDimensions = null;343 this.valid = null;344 this.emit( 'minSizeChange', this.minDimensions );345 }346};347/**348 * Clear the maximum dimensions349 *350 * @fires maxSizeChange351 */352ve.dm.Scalable.prototype.clearMaxDimensions = function () {353 if ( this.maxDimensions !== null ) {354 this.maxDimensions = null;355 this.valid = null;356 this.emit( 'maxSizeChange', this.maxDimensions );357 }358};359/**360 * Get the original dimensions361 *362 * @return {Object} Dimensions object with width & height363 */364ve.dm.Scalable.prototype.getCurrentDimensions = function () {365 return this.currentDimensions;366};367/**368 * Get the original dimensions369 *370 * @return {Object} Dimensions object with width & height371 */372ve.dm.Scalable.prototype.getOriginalDimensions = function () {373 return this.originalDimensions;374};375/**376 * Get the default dimensions377 *378 * @return {Object} Dimensions object with width & height379 */380ve.dm.Scalable.prototype.getDefaultDimensions = function () {381 return this.defaultDimensions;382};383/**384 * Get the default state of the scalable object385 *386 * @return {boolean} Default size or custom387 */388ve.dm.Scalable.prototype.isDefault = function () {389 return this.defaultSize;390};391/**392 * Get the minimum dimensions393 *394 * @return {Object} Dimensions object with width & height395 */396ve.dm.Scalable.prototype.getMinDimensions = function () {397 return this.minDimensions;398};399/**400 * Get the maximum dimensions401 *402 * @return {Object} Dimensions object with width & height403 */404ve.dm.Scalable.prototype.getMaxDimensions = function () {405 return this.maxDimensions;406};407/**408 * The object enforces the minimum dimensions when scaling409 *410 * @return {boolean} Enforces the minimum dimensions411 */412ve.dm.Scalable.prototype.isEnforcedMin = function () {413 return this.enforceMin;414};415/**416 * The object enforces the maximum dimensions when scaling417 *418 * @return {boolean} Enforces the maximum dimensions419 */420ve.dm.Scalable.prototype.isEnforcedMax = function () {421 return this.enforceMax;422};423/**424 * Set enforcement of minimum dimensions425 *426 * @param {boolean} enforceMin Enforces the minimum dimensions427 */428ve.dm.Scalable.prototype.setEnforcedMin = function ( enforceMin ) {429 this.valid = null;430 this.enforceMin = !!enforceMin;431};432/**433 * Set enforcement of maximum dimensions434 *435 * @param {boolean} enforceMax Enforces the maximum dimensions436 */437ve.dm.Scalable.prototype.setEnforcedMax = function ( enforceMax ) {438 this.valid = null;439 this.enforceMax = !!enforceMax;440};441/**442 * Get the fixed aspect ratio (width/height)443 *444 * @return {number} Aspect ratio445 */446ve.dm.Scalable.prototype.getRatio = function () {447 return this.ratio;448};449/**450 * Check if the object has a fixed ratio451 *452 * @return {boolean} The object has a fixed ratio453 */454ve.dm.Scalable.prototype.isFixedRatio = function () {455 return this.fixedRatio;456};457/**458 * Get the current scale of the object459 *460 * @return {number|null} A scale (1=100%), or null if not applicable461 */462ve.dm.Scalable.prototype.getCurrentScale = function () {463 if ( !this.isFixedRatio() || !this.getCurrentDimensions() || !this.getOriginalDimensions() ) {464 return null;465 }466 return this.getCurrentDimensions().width / this.getOriginalDimensions().width;467};468/**469 * Check if current dimensions are smaller than minimum dimensions in either direction470 *471 * Only possible if enforceMin is false.472 *473 * @return {boolean} Current dimensions are greater than maximum dimensions474 */475ve.dm.Scalable.prototype.isTooSmall = function () {476 return !!( this.getCurrentDimensions() && this.getMinDimensions() &&477 (478 this.getCurrentDimensions().width < this.getMinDimensions().width ||479 this.getCurrentDimensions().height < this.getMinDimensions().height480 )481 );482};483/**484 * Check if current dimensions are greater than maximum dimensions in either direction485 *486 * Only possible if enforceMax is false.487 *488 * @return {boolean} Current dimensions are greater than maximum dimensions489 */490ve.dm.Scalable.prototype.isTooLarge = function () {491 return !!( this.getCurrentDimensions() && this.getMaxDimensions() &&492 (493 this.getCurrentDimensions().width > this.getMaxDimensions().width ||494 this.getCurrentDimensions().height > this.getMaxDimensions().height495 )496 );497};498/**499 * Get a set of dimensions bounded by current restrictions, from specified dimensions500 *501 * @param {Object} dimensions Dimensions object with width & height502 * @param {number} [grid] Optional grid size to snap to503 * @return {Object} Dimensions object with width & height504 */505ve.dm.Scalable.prototype.getBoundedDimensions = function ( dimensions, grid ) {506 var ratio, snap, snapMin, snapMax,507 minDimensions = this.isEnforcedMin() && this.getMinDimensions(),508 maxDimensions = this.isEnforcedMax() && this.getMaxDimensions();509 dimensions = ve.copy( dimensions );510 // Bound to min/max511 if ( minDimensions ) {512 dimensions.width = Math.max( dimensions.width, this.minDimensions.width );513 dimensions.height = Math.max( dimensions.height, this.minDimensions.height );514 }515 if ( maxDimensions ) {516 dimensions.width = Math.min( dimensions.width, this.maxDimensions.width );517 dimensions.height = Math.min( dimensions.height, this.maxDimensions.height );518 }519 // Bound to ratio520 if ( this.isFixedRatio() ) {521 ratio = dimensions.width / dimensions.height;522 if ( ratio < this.getRatio() ) {523 dimensions.height = Math.round( dimensions.width / this.getRatio() );524 } else {525 dimensions.width = Math.round( dimensions.height * this.getRatio() );526 }527 }528 // Snap to grid529 if ( grid ) {530 snapMin = minDimensions ? Math.ceil( minDimensions.width / grid ) : -Infinity;531 snapMax = maxDimensions ? Math.floor( maxDimensions.width / grid ) : Infinity;532 snap = Math.round( dimensions.width / grid );533 dimensions.width = Math.max( Math.min( snap, snapMax ), snapMin ) * grid;534 if ( this.isFixedRatio() ) {535 // If the ratio is fixed we can't snap both to the grid, so just snap the width536 dimensions.height = Math.round( dimensions.width / this.getRatio() );537 } else {538 snapMin = minDimensions ? Math.ceil( minDimensions.height / grid ) : -Infinity;539 snapMax = maxDimensions ? Math.floor( maxDimensions.height / grid ) : Infinity;540 snap = Math.round( dimensions.height / grid );541 dimensions.height = Math.max( Math.min( snap, snapMax ), snapMin ) * grid;542 }543 }544 return dimensions;545};546/**547 * Checks whether the current dimensions are numeric and within range548 *549 * @return {boolean} Current dimensions are valid550 */551ve.dm.Scalable.prototype.isCurrentDimensionsValid = function () {552 var dimensions = this.getCurrentDimensions(),553 minDimensions = this.isEnforcedMin() && !ve.isEmptyObject( this.getMinDimensions() ) && this.getMinDimensions(),554 maxDimensions = this.isEnforcedMax() && !ve.isEmptyObject( this.getMaxDimensions() ) && this.getMaxDimensions();555 this.valid = (556 !!dimensions &&557 // Dimensions must be non-zero558 +dimensions.width &&559 +dimensions.height &&560 (561 !minDimensions || (562 dimensions.width >= minDimensions.width &&563 dimensions.height >= minDimensions.height564 )565 ) &&566 (567 !maxDimensions || (568 dimensions.width <= maxDimensions.width &&569 dimensions.height <= maxDimensions.height570 )571 )572 );573 return this.valid;...
draw.js
Source:draw.js
1/**2 * draw.js : Not optimally desgiend, but to assist in learning, a wrapper 3 * of the CreateJS Graphic API to reduce boiler-plate and that also supports4 * calculation of width and height properties on shapes.5 * 6 * For CreateJS Graphic API not wrapped by this version, use the Graphic API directly.7 * See: http://www.createjs.com/Docs/EaselJS/classes/Graphics.html8 *9 */10(function (window) {11 const TYPE_RECTANGULAR = 'retangular';12 const TYPE_CIRCULAR = 'circular';13 const TYPE_TRIANGULAR = 'triangular';14 const TYPE_IRREGULAR = 'irregular';15 const TYPE_LINEAR = 'linear';16 17 window.opspark = window.opspark || {};18 19 function sortNumbersAscending(a, b) { return a - b; }20 function sortNumbersDescending(a, b) { return b - a; }21 22 function randomIntBetween(min, max) { 23 return Math.floor(Math.random() * (max - min + 1) + min);24 }25 26 function blurFilterOn(displayObject, blurX, blurY, quality) {27 blurX = (blurX) ? blurX : 5;28 blurY = (blurY) ? blurY : 5;29 quality = (quality) ? quality : 1;30 31 var blurFilter = new createjs.BlurFilter(blurX, blurY, quality);32 displayObject.filters = (displayObject.filters) ? displayObject.filters.concat(blurFilter) : [blurFilter];33 displayObject.cache(-displayObject.radius, -displayObject.radius, displayObject.width, displayObject.height);34 return displayObject;35 }36 37 function randomColor(r, g, b, a) {38 if (a) { return 'rgba(' + randomRGBRange(r) + ',' + randomRGBRange(g) + ',' + randomRGBRange(b) + ',' + a + ')'; }39 return '#' + randomRGBRange(r) + randomRGBRange(g) + randomRGBRange(b);40 }41 function randomRGBRange(maxRange) {42 return Math.floor(Math.random() * (maxRange + 1)).toString(16); 43 }44 45 function getStartPointX(object) {46 switch (object.type) {47 case TYPE_CIRCULAR:48 return -(object.radius) + object.xOffset;49 default:50 return object.xOffset;51 }52 }53 54 function getStartPointY(object) {55 switch (object.type) {56 case TYPE_CIRCULAR:57 return -(object.radius) + object.yOffset;58 default:59 return object.yOffset;60 }61 }62 63 function getEndPointX(object) {64 switch (object.type) {65 case TYPE_CIRCULAR:66 return object.radius + object.xOffset;67 default:68 return object.xOffset + object.width;69 }70 }71 72 function getEndPointY(object) {73 switch (object.type) {74 case TYPE_CIRCULAR:75 return object.radius + object.yOffset;76 default:77 return object.yOffset + object.height;78 }79 }80 81 function buildDimensions(type, width, height, xOffset, yOffset, radius) {82 var dimensions = {83 type: type,84 width: width,85 height: height,86 xOffset: (xOffset) ? xOffset : 0,87 yOffset: (yOffset) ? yOffset : 088 };89 if (radius) { dimensions.radius = radius; }90 return dimensions;91 }92 93 var draw = {94 setDimensionsOn: function (shape, dimensions) {95 /*96 * If the shape already has dimensions, it means we're adding graphics to it, making it composite.97 */98 if (shape.dimensions) {99 // first figure out the points of extremity //100 var xStartPoint = [getStartPointX(shape), getStartPointX(dimensions)].sort(sortNumbersAscending)[0];101 var xEndPoint = [getEndPointX(shape), getEndPointX(dimensions)].sort(sortNumbersAscending)[1];102 103 var yStartPoint = [getStartPointY(shape), getStartPointY(dimensions)].sort(sortNumbersAscending)[0];104 var yEndPoint = [getEndPointY(shape), getEndPointY(dimensions)].sort(sortNumbersAscending)[1];105 106 var xs = 0;107 var ys = 0;108 109 /*110 * for the width calculation, we don't care about the y value 111 * of the points of comparison, and vice versa for height.112 */113 xs = xEndPoint - xStartPoint;114 xs = xs * xs;115 dimensions.width = Math.sqrt(xs + ys);116 117 xs = 0;118 ys = yEndPoint - yStartPoint;119 ys = ys * ys;120 dimensions.height = Math.sqrt(xs + ys);121 122 dimensions.xOffset = xStartPoint;123 dimensions.yOffset = yStartPoint;124 125 /*126 * If we're compounding graphics, the shape is now irregular.127 */128 dimensions.type = TYPE_IRREGULAR;129 130 /*131 * We don't need to track radius on irregular objects.132 */133 if (shape.radius) { delete shape.radius; }134 }135 136 shape.setBounds(dimensions.xOffset, dimensions.yOffset, dimensions.width, dimensions.height);137 shape.dimensions = dimensions;138 shape.width = dimensions.width;139 shape.height = dimensions.height;140 shape.xOffset = dimensions.xOffset;141 shape.yOffset = dimensions.yOffset;142 shape.type = dimensions.type;143 // debug //144 // console.log(shape.width);145 // console.log(shape.height);146 147 return shape;148 },149 150 line: function (fromX, fromY, toX, toY, strokeColor, strokeStyle, onShape) {151 var dimensions = buildDimensions(TYPE_LINEAR, toX, toY, fromX, fromY);152 153 var shape = (onShape) ? onShape : new createjs.Shape();154 shape.graphics155 .setStrokeStyle(strokeStyle)156 .beginStroke(strokeColor)157 .moveTo(dimensions.xOffset, dimensions.yOffset)158 .lineTo(toX, toY);159 160 return draw.setDimensionsOn(shape, dimensions);161 },162 163 rect: function (width, height, color, strokeColor, strokeStyle, xOffset, yOffset, onShape) { 164 var dimensions = buildDimensions(TYPE_RECTANGULAR, width, height, xOffset, yOffset);165 166 var shape = (onShape) ? onShape : new createjs.Shape();167 shape.graphics168 .setStrokeStyle(strokeStyle)169 .beginStroke(strokeColor)170 .beginFill(color)171 .drawRect(dimensions.xOffset, dimensions.yOffset, width, height);172 173 return draw.setDimensionsOn(shape, dimensions, onShape);174 },175 176 roundRect: function (width, height, radius, color, strokeColor, strokeStyle, xOffset, yOffset, onShape) {177 var dimensions = buildDimensions(TYPE_RECTANGULAR, width, height, xOffset, yOffset);178 179 var shape = (onShape) ? onShape : new createjs.Shape();180 shape.graphics181 .setStrokeStyle(strokeStyle)182 .beginStroke(strokeColor)183 .beginFill(color)184 .drawRoundRect(dimensions.xOffset, dimensions.yOffset, width, height, radius);185 draw.setDimensionsOn(shape, dimensions);186 shape.dimensions.cornerRadius = radius;187 return shape;188 },189 190 roundRectComplex: function (width, 191 height, 192 radiusTopLeft, 193 radiusTopRight, 194 radiusBottomRight, 195 radiusBottomLeft, 196 color, 197 strokeColor, 198 strokeStyle, 199 xOffset, 200 yOffset, 201 onShape) {202 var dimensions = buildDimensions(TYPE_RECTANGULAR, width, height, xOffset, yOffset);203 204 var shape = (onShape) ? onShape : new createjs.Shape();205 shape.graphics206 .setStrokeStyle(strokeStyle)207 .beginStroke(strokeColor)208 .beginFill(color)209 .drawRoundRectComplex(dimensions.xOffset, 210 dimensions.yOffset, 211 width, 212 height, 213 radiusTopLeft, 214 radiusTopRight, 215 radiusBottomRight, 216 radiusBottomLeft);217 218 draw.setDimensionsOn(shape, dimensions);219 shape.dimensions.radiusTopLeft = radiusTopLeft;220 shape.dimensions.radiusTopRight = radiusTopRight;221 shape.dimensions.radiusBottomRight = radiusBottomRight;222 shape.dimensions.radiusBottomLeft = radiusBottomLeft;223 return shape;224 },225 circle: function (radius, color, strokeColor, strokeStyle, xOffset, yOffset, onShape) { 226 var dimensions = buildDimensions(TYPE_CIRCULAR, radius * 2, radius * 2, xOffset, yOffset, radius);227 228 var shape = (onShape) ? onShape : new createjs.Shape();229 shape.graphics230 .setStrokeStyle(strokeStyle)231 .beginStroke(strokeColor)232 .beginFill(color)233 .drawCircle(dimensions.xOffset, dimensions.yOffset, radius);234 235 draw.setDimensionsOn(shape, dimensions);236 shape.radius = radius;237 return shape;238 },239 drawEllipse: function (width, height, color, strokeColor, strokeStyle, xOffset, yOffset, onShape) {240 var dimensions = buildDimensions(TYPE_RECTANGULAR, width, height, xOffset, yOffset);241 242 var shape = (onShape) ? onShape : new createjs.Shape();243 shape.graphics244 .setStrokeStyle(strokeStyle)245 .beginStroke(strokeColor)246 .beginFill(color)247 .drawEllipse(dimensions.xOffset, dimensions.yOffset, width, height);248 249 return draw.setDimensionsOn(shape, dimensions);250 },251 polyStar: function (radius, sides, pointSize, angle, color, strokeColor, strokeStyle, xOffset, yOffset, onShape) {252 var dimensions = buildDimensions(TYPE_CIRCULAR, radius * 2, radius * 2, xOffset, yOffset, radius);253 254 var shape = (onShape) ? onShape : new createjs.Shape();255 shape.graphics256 .setStrokeStyle(strokeStyle)257 .beginStroke(strokeColor)258 .beginFill(color)259 .drawPolyStar(dimensions.xOffset, dimensions.yOffset, radius, sides, pointSize || 0, angle);260 261 draw.setDimensionsOn(shape, dimensions);262 shape.radius = radius;263 return shape;264 },265 266 267 randomCircleInArea: function (area, randomizeAlpha, addCross, borderColor, borderThickness, randomRadialProps) {268 var props, circle;269 270 props = (randomRadialProps) ? randomRadialProps : draw.randomRadialProps(area);271 272 if (addCross) {273 // always make sure the cross is visible - it won't be if randomizeAlpha is false //274 randomizeAlpha = true;275 circle = draw.line(-(props.radius), 0, props.radius, 0, borderColor || '#000', 2);276 draw.line(0, -(props.radius), 0, props.radius, borderColor || '#000', 2, circle);277 }278 279 if (borderColor && !borderThickness) { borderThickness = 1; }280 281 // first draw the circle's border - don't use stroke //282 circle = draw.circle(props.radius+borderThickness, borderColor, null, null, null, null, circle);283 draw.circle(props.radius, props.color, null, null, null, null, circle);284 circle.x = props.x;285 circle.y = props.y;286 287 288 289 if (randomizeAlpha) {circle.alpha = Math.random(); }290 291 return circle;292 },293 294 randomRadialProps: function (area, radiusMin, radiusMax, redMax, greenMax, blueMax) {295 return {296 radius: randomIntBetween(radiusMin || 5, radiusMax || 20),297 color: randomColor(redMax || 255, greenMax || 255, blueMax || 255),298 x: randomIntBetween(0, area.width),299 y: randomIntBetween(0, area.height)300 };301 },302 303 randomColor: randomColor,304 randomRGBRange: randomRGBRange,305 306 getStartPointX: getStartPointX,307 getStartPointY: getStartPointY,308 getEndPointX: getEndPointX,309 getEndPointY: getEndPointY,310 311 blurFilterOn: blurFilterOn,312 313 fps: function (color) {314 color = (color) ? color : '#FFF';315 var _textfield = new createjs.Text("-- fps", "bold 15px Arial", color);316 var _fps = new createjs.Container();317 _fps.textfield = _textfield;318 _fps.addChild(_textfield);319 _fps.update = function (parent) {320 _textfield.text = Math.round(createjs.Ticker.getMeasuredFPS()) + " fps";321 };322 return _fps;323 }324 };325 326 window.opspark.draw = draw;...
ve.dm.Scalable.test.js
Source:ve.dm.Scalable.test.js
1/*!2 * VisualEditor DataModel Scalable tests.3 *4 * @copyright 2011-2020 VisualEditor Team and others; see http://ve.mit-license.org5 */6QUnit.module( 've.dm.Scalable' );7QUnit.test( 'construction/clone/getters/setters/toggleDefault/clearers', function ( assert ) {8 var eventEmitted = false,9 currentDimensions = {10 width: 300,11 height: 20012 },13 originalDimensions = {14 width: 600,15 height: 40016 },17 defaultDimensions = {18 width: 150,19 height: 5020 },21 minDimensions = {22 width: 1,23 height: 124 },25 maxDimensions = {26 width: 1200,27 height: 80028 },29 scalable = new ve.dm.Scalable( {30 currentDimensions: currentDimensions,31 originalDimensions: originalDimensions,32 defaultDimensions: defaultDimensions,33 minDimensions: minDimensions,34 maxDimensions: maxDimensions35 } ),36 clone = scalable.clone();37 assert.deepEqual( scalable, clone, 'Clone is deepEqual' );38 assert.notStrictEqual( scalable, clone, 'Clone is not reference equal' );39 assert.deepEqual( scalable.getCurrentDimensions(), currentDimensions, 'getCurrentDimensions' );40 assert.deepEqual( scalable.getOriginalDimensions(), originalDimensions, 'getOriginalDimensions' );41 assert.deepEqual( scalable.getDefaultDimensions(), defaultDimensions, 'getDefaultDimensions' );42 assert.deepEqual( scalable.getMinDimensions(), minDimensions, 'getMinDimensions' );43 assert.deepEqual( scalable.getMaxDimensions(), maxDimensions, 'getMaxDimensions' );44 assert.strictEqual( scalable.getRatio(), 1.5, 'getRatio' );45 scalable.toggleDefault();46 assert.deepEqual( scalable.getCurrentDimensions(), scalable.getDefaultDimensions(), 'toggleDefault makes an image use default dimensions' );47 scalable.toggleDefault();48 assert.deepEqual( scalable.getCurrentDimensions(), scalable.getDefaultDimensions(), 'toggleDefault on an already-default image has no effect' );49 scalable.toggleDefault( false );50 assert.deepEqual( scalable.getCurrentDimensions(), scalable.getDefaultDimensions(), 'toggleDefault( false ) on an already-default image has no effect' );51 scalable.clearDefaultDimensions();52 assert.strictEqual( scalable.getDefaultDimensions(), null, 'clearDefaultDimensions' );53 scalable.on( 'defaultSizeChange', function () {54 eventEmitted = true;55 } );56 eventEmitted = false;57 scalable.clearDefaultDimensions();58 scalable.off( 'defaultSizeChange' );59 assert.strictEqual( eventEmitted, false, 'clearDefaultDimensions doesn\'t re-run' );60 scalable.clearOriginalDimensions();61 assert.strictEqual( scalable.getOriginalDimensions(), null, 'clearOriginalDimensions' );62 scalable.on( 'originalSizeChange', function () {63 eventEmitted = true;64 } );65 eventEmitted = false;66 scalable.clearOriginalDimensions();67 scalable.off( 'originalSizeChange' );68 assert.strictEqual( eventEmitted, false, 'clearOriginalDimensions doesn\'t re-run' );69 scalable.clearMinDimensions();70 assert.strictEqual( scalable.getMinDimensions(), null, 'clearMinDimensions' );71 scalable.on( 'minSizeChange', function () {72 eventEmitted = true;73 } );74 eventEmitted = false;75 scalable.clearMinDimensions();76 scalable.off( 'minSizeChange' );77 assert.strictEqual( eventEmitted, false, 'clearMinDimensions doesn\'t re-run' );78 scalable.clearMaxDimensions();79 assert.strictEqual( scalable.getMaxDimensions(), null, 'clearMaxDimensions' );80 scalable.on( 'maxSizeChange', function () {81 eventEmitted = true;82 } );83 eventEmitted = false;84 scalable.clearMaxDimensions();85 scalable.off( 'maxSizeChange' );86 assert.strictEqual( eventEmitted, false, 'clearMaxDimensions doesn\'t re-run' );87 assert.deepEqual( scalable.getBoundedDimensions( { width: 448, height: 317 }, 10 ), { width: 450, height: 300 }, 'getBoundedDimensions without bounds snapped to 10px grid' );88 scalable.fixedRatio = false;89 assert.deepEqual( scalable.getBoundedDimensions( { width: 448, height: 317 }, 10 ), { width: 450, height: 320 }, 'getBoundedDimensions without bounds or fixed ratio snapped to 10px grid' );90 scalable.fixedRatio = true;91 scalable.setRatioFromDimensions( scalable.getCurrentDimensions() );92 clone = scalable.clone();93 clone.setOriginalDimensions();94 clone.setDefaultDimensions();95 clone.setMinDimensions();96 clone.setMaxDimensions();97 assert.strictEqual( clone.getOriginalDimensions(), scalable.getOriginalDimensions(), 'setOriginalDimensions without values is a no-op' );98 assert.strictEqual( clone.getDefaultDimensions(), scalable.getDefaultDimensions(), 'setDefaultDimensions without values is a no-op' );99 assert.strictEqual( clone.getMinDimensions(), scalable.getMinDimensions(), 'setMinDimensions without values is a no-op' );100 assert.strictEqual( clone.getMaxDimensions(), scalable.getMaxDimensions(), 'setMaxDimensions without values is a no-op' );101 clone = scalable.clone();102 clone.setRatioFromDimensions();103 assert.strictEqual( clone.getRatio(), scalable.getRatio(), 'setRatioFromDimensions without values is a no-op' );104 scalable.setOriginalDimensions( { width: 300, height: 100 } );105 assert.strictEqual( scalable.getRatio(), 3, 'setOriginalDimensions overwrites the ratio if set' );106 scalable.fixedRatio = false;107 scalable.setOriginalDimensions( { width: 300, height: 200 } );108 assert.strictEqual( scalable.getRatio(), 3, 'setOriginalDimensions doesn\'t overwrite the ratio if not set' );109 scalable.fixedRatio = true;110 scalable.setOriginalDimensions( { width: 1, height: 1 } );111 assert.strictEqual( scalable.getRatio(), 1, 'setOriginalDimensions overwrites the ratio if set again' );112} );113QUnit.test( 'getBoundedDimensions/getCurrentScale/isCurrentDimensionsValid/isTooSmall/isTooLarge', function ( assert ) {114 var currentDimensions = {115 width: 300,116 height: 200117 },118 originalDimensions = {119 width: 600,120 height: 400121 },122 minDimensions = {123 width: 150,124 height: 100125 },126 maxDimensions = {127 width: 1200,128 height: 800129 },130 scalable = new ve.dm.Scalable( {131 currentDimensions: currentDimensions,132 originalDimensions: originalDimensions,133 minDimensions: minDimensions,134 maxDimensions: maxDimensions135 } );136 assert.deepEqual( scalable.getBoundedDimensions( { width: 600, height: 600 } ), { width: 600, height: 400 }, 'getBoundedDimensions' );137 assert.deepEqual( scalable.getBoundedDimensions( { width: 2000, height: 2000 } ), { width: 1200, height: 800 }, 'getBoundedDimensions beyond maxDimensions' );138 assert.deepEqual( scalable.getBoundedDimensions( { width: 30, height: 30 } ), { width: 150, height: 100 }, 'getBoundedDimensions beyond minDimensions' );139 assert.deepEqual( scalable.getBoundedDimensions( { width: 448, height: 317 }, 10 ), { width: 450, height: 300 }, 'getBoundedDimensions snapped to 10px grid' );140 scalable.fixedRatio = false;141 assert.strictEqual( scalable.getCurrentScale(), null, 'Scale is null when not fixed ratio' );142 assert.deepEqual( scalable.getBoundedDimensions( { width: 600, height: 600 } ), { width: 600, height: 600 }, 'getBoundedDimensions, no fixed ratio' );143 assert.deepEqual( scalable.getBoundedDimensions( { width: 448, height: 317 }, 10 ), { width: 450, height: 320 }, 'getBoundedDimensions snapped to 10px grid, no fixed ratio' );144 scalable.fixedRatio = true;145 assert.strictEqual( scalable.isCurrentDimensionsValid(), true, '300x200 are valid dimensions' );146 assert.strictEqual( scalable.getCurrentScale(), 0.5, '300x200 is scale of 0.5' );147 scalable.setCurrentDimensions( { width: 1200, height: 800 } );148 assert.strictEqual( scalable.getCurrentScale(), 2, '1200x800 is scale of 2' );149 scalable.setCurrentDimensions( { width: 1300, height: 810 } );150 assert.strictEqual( scalable.isCurrentDimensionsValid(), false, 'Too large dimensions are not valid' );151 assert.strictEqual( scalable.isTooSmall(), false, 'Too large dimensions are not too small' );152 assert.strictEqual( scalable.isTooLarge(), true, 'Too large dimensions are too large' );153 scalable.setCurrentDimensions( { width: 30, height: 20 } );154 assert.strictEqual( scalable.isCurrentDimensionsValid(), false, 'Too small dimensions are not valid' );155 assert.strictEqual( scalable.isTooSmall(), true, 'Too large dimensions are too small' );156 assert.strictEqual( scalable.isTooLarge(), false, 'Too large dimensions are not too large' );157} );158QUnit.test( 'isDefault/toggleDefault', function ( assert ) {159 var scalable = new ve.dm.Scalable( {160 isDefault: true161 } ),162 clone = scalable.clone();163 assert.deepEqual( scalable, clone, 'Clone is deepEqual even when config is sparse' );164 assert.strictEqual( scalable.isDefault(), true, 'isDefault' );165 scalable.toggleDefault();166 assert.strictEqual( scalable.isDefault(), false, 'toggleDefault changes true to false' );167 scalable.toggleDefault();168 assert.strictEqual( scalable.isDefault(), true, 'toggleDefault changes false to true' );169} );170QUnit.test( 'isDimensionsObjectValid', function ( assert ) {171 var i,172 cases = [173 { dimensions: null, expected: false, msg: 'Null' },174 { dimensions: { width: 200 }, expected: true, msg: 'Only width' },175 { dimensions: { height: 200 }, expected: true, msg: 'Only height' },176 { dimensions: {}, expected: false, msg: 'Empty object' },177 { dimensions: { width: undefined, height: undefined }, expected: false, msg: 'Explicity undefined' }178 ];179 for ( i = 0; i < cases.length; i++ ) {180 assert.strictEqual( ve.dm.Scalable.static.isDimensionsObjectValid( cases[ i ].dimensions ), cases[ i ].expected, cases[ i ].msg );181 }182} );183QUnit.test( 'getDimensionsFromValue', function ( assert ) {184 var i,185 cases = [186 { dimensions: { width: 200 }, ratio: 1, expected: { width: 200, height: 200 }, msg: 'Only width' },187 { dimensions: { height: 200 }, ratio: 2, expected: { width: 400, height: 200 }, msg: 'Only height' },188 { dimensions: { width: '', height: 400 }, ratio: 0.5, expected: { width: 200, height: 400 }, msg: 'Empty width' },189 { dimensions: { width: 200, height: '' }, ratio: 0.5, expected: { width: 200, height: 400 }, msg: 'Empty height' }190 ];191 for ( i = 0; i < cases.length; i++ ) {192 assert.deepEqual( ve.dm.Scalable.static.getDimensionsFromValue( cases[ i ].dimensions, cases[ i ].ratio ), cases[ i ].expected, cases[ i ].msg );193 }...
hlsl.getdimensions.dx10.frag
Source:hlsl.getdimensions.dx10.frag
1SamplerState g_sSamp : register(s0);2uniform Texture1D <float4> g_tTex1df4 : register(t0);3Texture1D <int4> g_tTex1di4;4Texture1D <uint4> g_tTex1du4;5Texture2D <float4> g_tTex2df4;6Texture2D <int4> g_tTex2di4;7Texture2D <uint4> g_tTex2du4;8Texture3D <float4> g_tTex3df4;9Texture3D <int4> g_tTex3di4;10Texture3D <uint4> g_tTex3du4;11TextureCube <float4> g_tTexcdf4;12TextureCube <int4> g_tTexcdi4;13TextureCube <uint4> g_tTexcdu4;14Texture1DArray <float4> g_tTex1df4a;15Texture1DArray <int4> g_tTex1di4a;16Texture1DArray <uint4> g_tTex1du4a;17Texture2DArray <float4> g_tTex2df4a;18Texture2DArray <int4> g_tTex2di4a;19Texture2DArray <uint4> g_tTex2du4a;20TextureCubeArray <float4> g_tTexcdf4a;21TextureCubeArray <int4> g_tTexcdi4a;22TextureCubeArray <uint4> g_tTexcdu4a;23Texture2DMS <float4> g_tTex2dmsf4;24Texture2DMS <int4> g_tTex2dmsi4;25Texture2DMS <uint4> g_tTex2dmsu4;26Texture2DMSArray <float4> g_tTex2dmsf4a;27Texture2DMSArray <int4> g_tTex2dmsi4a;28Texture2DMSArray <uint4> g_tTex2dmsu4a;29struct PS_OUTPUT30{31 float4 Color : SV_Target0;32 float Depth : SV_Depth;33};34PS_OUTPUT main()35{36 PS_OUTPUT psout;37 uint MipLevel;38 uint WidthU;39 uint HeightU;40 uint ElementsU;41 uint DepthU;42 uint NumberOfLevelsU;43 uint NumberOfSamplesU;44 float WidthF;45 float HeightF;46 float ElementsF;47 float DepthF;48 float NumberOfLevelsF;49 float NumberOfSamplesF;50 // 1D, float tx, uint params51 g_tTex1df4 . GetDimensions(WidthU);52 g_tTex1df4 . GetDimensions(6, WidthU, NumberOfLevelsU);53 // 1D, int, uint params54 g_tTex1di4 . GetDimensions(WidthU);55 g_tTex1di4 . GetDimensions(6, WidthU, NumberOfLevelsU);56 // 1D, uint, uint params57 g_tTex1du4 . GetDimensions(WidthU);58 g_tTex1du4 . GetDimensions(6, WidthU, NumberOfLevelsU);59 // 1DArray, float tx, uint params60 g_tTex1df4a . GetDimensions(WidthU, ElementsU);61 g_tTex1df4a . GetDimensions(6, WidthU, ElementsU, NumberOfLevelsU);62 // 1DArray, int, uint params63 g_tTex1di4a . GetDimensions(WidthU, ElementsU);64 g_tTex1di4a . GetDimensions(6, WidthU, ElementsU, NumberOfLevelsU);65 // 1DArray, uint, uint params66 g_tTex1du4a . GetDimensions(WidthU, ElementsU);67 g_tTex1du4a . GetDimensions(6, WidthU, ElementsU, NumberOfLevelsU);68 // 2D, float tx, uint params69 g_tTex2df4 . GetDimensions(WidthU, HeightU);70 g_tTex2df4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);71 // 2D, int, uint params72 g_tTex2di4 . GetDimensions(WidthU, HeightU);73 g_tTex2di4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);74 // 2D, uint, uint params75 g_tTex2du4 . GetDimensions(WidthU, HeightU);76 g_tTex2du4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);77 // 2Darray, float tx, uint params78 g_tTex2df4a . GetDimensions(WidthU, HeightU, ElementsU);79 g_tTex2df4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);80 // 2Darray, int, uint params81 g_tTex2di4a . GetDimensions(WidthU, HeightU, ElementsU);82 g_tTex2di4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);83 // 2Darray, uint, uint params84 g_tTex2du4a . GetDimensions(WidthU, HeightU, ElementsU);85 g_tTex2du4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);86 // 3D, float tx, uint params87 g_tTex3df4 . GetDimensions(WidthU, HeightU, DepthU);88 g_tTex3df4 . GetDimensions(6, WidthU, HeightU, DepthU, NumberOfLevelsU);89 // 3D, int, uint params90 g_tTex3di4 . GetDimensions(WidthU, HeightU, DepthU);91 g_tTex3di4 . GetDimensions(6, WidthU, HeightU, DepthU, NumberOfLevelsU);92 // 3D, uint, uint params93 g_tTex3du4 . GetDimensions(WidthU, HeightU, DepthU);94 g_tTex3du4 . GetDimensions(6, WidthU, HeightU, DepthU, NumberOfLevelsU);95 // Cube, float tx, uint params96 g_tTexcdf4 . GetDimensions(WidthU, HeightU);97 g_tTexcdf4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);98 // Cube, int, uint params99 g_tTexcdi4 . GetDimensions(WidthU, HeightU);100 g_tTexcdi4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);101 // Cube, uint, uint params102 g_tTexcdu4 . GetDimensions(WidthU, HeightU);103 g_tTexcdu4 . GetDimensions(6, WidthU, HeightU, NumberOfLevelsU);104 // Cubearray, float tx, uint params105 g_tTexcdf4a . GetDimensions(WidthU, HeightU, ElementsU);106 g_tTexcdf4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);107 // Cubearray, int, uint params108 g_tTexcdi4a . GetDimensions(WidthU, HeightU, ElementsU);109 g_tTexcdi4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);110 // Cubearray, uint, uint params111 g_tTexcdu4a . GetDimensions(WidthU, HeightU, ElementsU);112 g_tTexcdu4a . GetDimensions(6, WidthU, HeightU, ElementsU, NumberOfLevelsU);113 // 2DMS, float tx, uint params114 g_tTex2dmsf4 . GetDimensions(WidthU, HeightU, NumberOfSamplesU);115 // 2DMS, int tx, uint params116 g_tTex2dmsi4 . GetDimensions(WidthU, HeightU, NumberOfSamplesU);117 // 2DMS, uint tx, uint params118 g_tTex2dmsu4 . GetDimensions(WidthU, HeightU, NumberOfSamplesU);119 // 2DMSArray, float tx, uint params120 g_tTex2dmsf4a . GetDimensions(WidthU, HeightU, ElementsU, NumberOfSamplesU);121 // 2DMSArray, int tx, uint params122 g_tTex2dmsi4a . GetDimensions(WidthU, HeightU, ElementsU, NumberOfSamplesU);123 // 2DMSArray, uint tx, uint params124 g_tTex2dmsu4a . GetDimensions(WidthU, HeightU, ElementsU, NumberOfSamplesU);125 // TODO: ***************************************************126 // Change this to 1 to enable float overloads when the HLSL127 // function overload resolution is fixed.128#define OVERLOAD_FIX 0129 // TODO: enable when function overload resolution rules are fixed130#if OVERLOAD_FIX131 // 1D, float tx, float params132 g_tTex1df4 . GetDimensions(WidthF);133 g_tTex1df4 . GetDimensions(6, WidthF, NumberOfLevelsF);134 // 1D, int, float params135 g_tTex1di4 . GetDimensions(WidthF);136 g_tTex1di4 . GetDimensions(6, WidthF, NumberOfLevelsF);137 // 1D, uint, float params138 g_tTex1du4 . GetDimensions(WidthF);139 g_tTex1du4 . GetDimensions(6, WidthF, NumberOfLevelsF);140 // 1DArray, float tx, float params141 g_tTex1df4a . GetDimensions(WidthF, ElementsF);142 g_tTex1df4a . GetDimensions(6, WidthF, ElementsF, NumberOfLevelsF);143 // 1DArray, int, float params144 g_tTex1di4a . GetDimensions(WidthF, ElementsF);145 g_tTex1di4a . GetDimensions(6, WidthF, ElementsF, NumberOfLevelsF);146 // 1DArray, uint, float params147 g_tTex1du4a . GetDimensions(WidthF, ElementsF);148 g_tTex1du4a . GetDimensions(6, WidthF, ElementsF, NumberOfLevelsF);149 // 2D, float tx, float params150 g_tTex2df4 . GetDimensions(WidthF, HeightF);151 g_tTex2df4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);152 // 2D, int, float params153 g_tTex2di4 . GetDimensions(WidthF, HeightF);154 g_tTex2di4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);155 // 2D, uint, float params156 g_tTex2du4 . GetDimensions(WidthF, HeightF);157 g_tTex2du4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);158 // 2Darray, float tx, float params159 g_tTex2df4a . GetDimensions(WidthF, HeightF, ElementsF);160 g_tTex2df4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);161 // 2Darray, int, float params162 g_tTex2di4a . GetDimensions(WidthF, HeightF, ElementsF);163 g_tTex2di4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);164 // 2Darray, uint, float params165 g_tTex2du4a . GetDimensions(WidthF, HeightF, ElementsF);166 g_tTex2du4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);167 // 3D, float tx, float params168 g_tTex3df4 . GetDimensions(WidthF, HeightF, DepthF);169 g_tTex3df4 . GetDimensions(6, WidthF, HeightF, DepthF, NumberOfLevelsF);170 // 3D, int, float params171 g_tTex3di4 . GetDimensions(WidthF, HeightF, DepthF);172 g_tTex3di4 . GetDimensions(6, WidthF, HeightF, DepthF, NumberOfLevelsF);173 // 3D, uint, float params174 g_tTex3du4 . GetDimensions(WidthF, HeightF, DepthF);175 g_tTex3du4 . GetDimensions(6, WidthF, HeightF, DepthF, NumberOfLevelsF);176 // Cube, float tx, float params177 g_tTexcdf4 . GetDimensions(WidthF, HeightF);178 g_tTexcdf4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);179 // Cube, int, float params180 g_tTexcdi4 . GetDimensions(WidthF, HeightF);181 g_tTexcdi4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);182 // Cube, uint, float params183 g_tTexcdu4 . GetDimensions(WidthF, HeightF);184 g_tTexcdu4 . GetDimensions(6, WidthF, HeightF, NumberOfLevelsF);185 // Cubearray, float tx, float params186 g_tTexcdf4a . GetDimensions(WidthF, HeightF, ElementsF);187 g_tTexcdf4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);188 // Cubearray, int, float params189 g_tTexcdi4a . GetDimensions(WidthF, HeightF, ElementsF);190 g_tTexcdi4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);191 // Cubearray, uint, float params192 g_tTexcdu4a . GetDimensions(WidthF, HeightF, ElementsF);193 g_tTexcdu4a . GetDimensions(6, WidthF, HeightF, ElementsF, NumberOfLevelsF);194 // 2DMS, float tx, uint params195 g_tTex2dmsf4 . GetDimensions(WidthF, HeightF, NumberOfSamplesF);196 // 2DMS, int tx, uint params197 g_tTex2dmsi4 . GetDimensions(WidthF, HeightF, NumberOfSamplesF);198 // 2DMS, uint tx, uint params199 g_tTex2dmsu4 . GetDimensions(WidthF, HeightF, NumberOfSamplesF);200 // 2DMSArray, float tx, uint params201 g_tTex2dmsf4a . GetDimensions(WidthF, HeightF, ElementsF, NumberOfSamplesF);202 // 2DMSArray, int tx, uint params203 g_tTex2dmsi4a . GetDimensions(WidthF, HeightF, ElementsF, NumberOfSamplesF);204 // 2DMSArray, uint tx, uint params205 g_tTex2dmsu4a . GetDimensions(WidthF, HeightF, ElementsF, NumberOfSamplesF);206#endif // OVERLOAD_FIX207 psout.Color = 1.0;208 psout.Depth = 1.0;209 return psout;...
animation-presets.js
Source:animation-presets.js
1/**2 * Copyright 2017 The AMP HTML Authors. All Rights Reserved.3 *4 * Licensed under the Apache License, Version 2.0 (the "License");5 * you may not use this file except in compliance with the License.6 * You may obtain a copy of the License at7 *8 * http://www.apache.org/licenses/LICENSE-2.09 *10 * Unless required by applicable law or agreed to in writing, software11 * distributed under the License is distributed on an "AS-IS" BASIS,12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.13 * See the License for the specific language governing permissions and14 * limitations under the License.15 */16import {GRID_LAYER_TEMPLATE_CLASS_NAMES} from './amp-story-grid-layer';17import {StoryAnimationPresetDef} from './animation-types';18import {19 calculateTargetScalingFactor,20 rotateAndTranslate,21 scaleAndTranslate,22 translate2d,23 whooshIn,24} from './animation-presets-utils';25import {px} from '../../../src/style';26const FULL_BLEED_CATEGORY = 'full-bleed';27const FILL_TEMPLATE_LAYOUT = 'fill';28/**29 * A list of animations that are full bleed.30 * @private @const {!Array<string>}31 */32const FULL_BLEED_ANIMATION_NAMES = [33 'pan-up',34 'pan-down',35 'pan-right',36 'pan-left',37 'zoom-in',38 'zoom-out',39];40/**41 * A mapping of animation categories to corresponding CSS class names.42 * @private @const {!Object<string, string>}43 */44const ANIMATION_CSS_CLASS_NAMES = {45 [FULL_BLEED_CATEGORY]:46 'i-amphtml-story-grid-template-with-full-bleed-animation',47};48/**49 * Perform style-specific operations for presets.50 * @param {!Element} el51 * @param {string} presetName52 */53export function setStyleForPreset(el, presetName) {54 // For full bleed animations.55 if (FULL_BLEED_ANIMATION_NAMES.indexOf(presetName) >= 0) {56 const parent = el.parentElement;57 if (parent.classList.contains(58 GRID_LAYER_TEMPLATE_CLASS_NAMES[FILL_TEMPLATE_LAYOUT])) {59 parent.classList60 .remove(GRID_LAYER_TEMPLATE_CLASS_NAMES[FILL_TEMPLATE_LAYOUT]);61 }62 parent.classList.add(ANIMATION_CSS_CLASS_NAMES[FULL_BLEED_CATEGORY]);63 }64}65/** @const {!Object<string, !StoryAnimationPresetDef>} */66// First keyframe will always be considered offset: 0 and will be applied to the67// element as the first frame before animation starts.68export const PRESETS = {69 'pulse': {70 duration: 500,71 easing: 'linear',72 keyframes: [73 {74 offset: 0,75 transform: 'scale(1)',76 },77 {78 offset: 0.25,79 transform: 'scale(0.95)',80 },81 {82 offset: 0.75,83 transform: 'scale(1.05)',84 },85 {86 offset: 1,87 transform: 'scale(1)',88 },89 ],90 },91 'fly-in-left': {92 duration: 500,93 easing: 'ease-out',94 keyframes(dimensions) {95 const offsetX = -(dimensions.targetX + dimensions.targetWidth);96 return translate2d(offsetX, 0, 0, 0);97 },98 },99 'fly-in-right': {100 duration: 500,101 easing: 'ease-out',102 keyframes(dimensions) {103 const offsetX = dimensions.pageWidth - dimensions.targetX;104 return translate2d(offsetX, 0, 0, 0);105 },106 },107 'fly-in-top': {108 duration: 500,109 easing: 'ease-out',110 keyframes(dimensions) {111 const offsetY = -(dimensions.targetY + dimensions.targetHeight);112 return translate2d(0, offsetY, 0, 0);113 },114 },115 'fly-in-bottom': {116 duration: 500,117 easing: 'ease-out',118 keyframes(dimensions) {119 const offsetY = dimensions.pageHeight - dimensions.targetY;120 return translate2d(0, offsetY, 0, 0);121 },122 },123 'rotate-in-left': {124 duration: 700,125 easing: 'ease-out',126 keyframes(dimensions) {127 const offsetX = -(dimensions.targetX + dimensions.targetWidth);128 return rotateAndTranslate(offsetX, 0, 0, 0, -1);129 },130 },131 'rotate-in-right': {132 duration: 700,133 easing: 'ease-out',134 keyframes(dimensions) {135 const offsetX = dimensions.pageWidth - dimensions.targetX;136 return rotateAndTranslate(offsetX, 0, 0, 0, 1);137 },138 },139 'fade-in': {140 duration: 500,141 easing: 'ease-out',142 keyframes: [143 {144 opacity: 0,145 },146 {147 opacity: 1,148 },149 ],150 },151 'drop': {152 duration: 1600,153 keyframes(dimensions) {154 const maxBounceHeight =155 Math.max(160, dimensions.targetY + dimensions.targetHeight);156 return [157 {158 offset: 0,159 transform: `translateY(${px(-maxBounceHeight)})`,160 easing: 'cubic-bezier(.75,.05,.86,.08)',161 },162 {163 offset: 0.3,164 transform: 'translateY(0)',165 easing: 'cubic-bezier(.22,.61,.35,1)',166 },167 {168 offset: 0.52,169 transform: `translateY(${px(-0.6 * maxBounceHeight)})`,170 easing: 'cubic-bezier(.75,.05,.86,.08)',171 },172 {173 offset: 0.74,174 transform: 'translateY(0)',175 easing: 'cubic-bezier(.22,.61,.35,1)',176 },177 {178 offset: 0.83,179 transform: `translateY(${px(-0.3 * maxBounceHeight)})`,180 easing: 'cubic-bezier(.75,.05,.86,.08)',181 },182 {183 offset: 1,184 transform: 'translateY(0)',185 easing: 'cubic-bezier(.22,.61,.35,1)',186 },187 ];188 },189 },190 'twirl-in': {191 duration: 1000,192 easing: 'cubic-bezier(.2,.75,.4,1)',193 keyframes: [194 {195 transform: 'rotate(-540deg) scale(0.1)',196 opacity: 0,197 },198 {199 transform: 'none',200 opacity: 1,201 },202 ],203 },204 'whoosh-in-left': {205 duration: 500,206 easing: 'ease-out',207 keyframes(dimensions) {208 const offsetX = -(dimensions.targetX + dimensions.targetWidth);209 return whooshIn(offsetX, 0, 0, 0);210 },211 },212 'whoosh-in-right': {213 duration: 500,214 easing: 'ease-out',215 keyframes(dimensions) {216 const offsetX = dimensions.pageWidth - dimensions.targetX;217 return whooshIn(offsetX, 0, 0, 0);218 },219 },220 'pan-left': {221 duration: 1000,222 easing: 'linear',223 keyframes(dimensions) {224 const scalingFactor = calculateTargetScalingFactor(dimensions);225 dimensions.targetWidth *= scalingFactor;226 dimensions.targetHeight *= scalingFactor;227 const offsetX = dimensions.pageWidth - dimensions.targetWidth;228 const offsetY = (dimensions.pageHeight - dimensions.targetHeight) / 2;229 return scaleAndTranslate(offsetX, offsetY, 0, offsetY, scalingFactor);230 },231 },232 'pan-right': {233 duration: 1000,234 easing: 'linear',235 keyframes(dimensions) {236 const scalingFactor = calculateTargetScalingFactor(dimensions);237 dimensions.targetWidth *= scalingFactor;238 dimensions.targetHeight *= scalingFactor;239 const offsetX = dimensions.pageWidth - dimensions.targetWidth;240 const offsetY = (dimensions.pageHeight - dimensions.targetHeight) / 2;241 return scaleAndTranslate(0, offsetY, offsetX, offsetY, scalingFactor);242 },243 },244 'pan-down': {245 duration: 1000,246 easing: 'linear',247 keyframes(dimensions) {248 const scalingFactor = calculateTargetScalingFactor(dimensions);249 dimensions.targetWidth *= scalingFactor;250 dimensions.targetHeight *= scalingFactor;251 const offsetX = -dimensions.targetWidth / 2;252 const offsetY = dimensions.pageHeight - dimensions.targetHeight;253 return scaleAndTranslate(offsetX, 0, offsetX, offsetY, scalingFactor);254 },255 },256 'pan-up': {257 duration: 1000,258 easing: 'linear',259 keyframes(dimensions) {260 const scalingFactor = calculateTargetScalingFactor(dimensions);261 dimensions.targetWidth *= scalingFactor;262 dimensions.targetHeight *= scalingFactor;263 const offsetX = -dimensions.targetWidth / 2;264 const offsetY = dimensions.pageHeight - dimensions.targetHeight;265 return scaleAndTranslate(offsetX, offsetY, offsetX, 0, scalingFactor);266 },267 },268 'zoom-in': {269 duration: 1000,270 easing: 'linear',271 keyframes: [272 {transform: 'scale(1,1)'},273 {transform: 'scale(3,3)'},274 ],275 },276 'zoom-out': {277 duration: 1000,278 easing: 'linear',279 keyframes: [280 {transform: 'scale(3,3)'},281 {transform: 'scale(1,1)'},282 ],283 },...
model.js
Source:model.js
1/*!2 * Piwik - free/libre analytics platform3 *4 * @link http://piwik.org5 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later6 */7(function () {8 angular.module('piwikApp').factory('customDimensionsModel', customDimensionsModel);9 customDimensionsModel.$inject = ['piwikApi', '$q'];10 function customDimensionsModel(piwikApi, $q) {11 var fetchAllPromise;12 var model = {13 customDimensions : [],14 availableScopes: [],15 extractionDimensions: [],16 isLoading: false,17 isUpdating: false,18 fetchCustomDimensionsConfiguration: fetchCustomDimensionsConfiguration,19 findCustomDimension: findCustomDimension,20 createOrUpdateDimension: createOrUpdateDimension,21 reload: reload22 };23 return model;24 function reload()25 {26 model.customDimensions = [];27 model.availableScopes = [];28 model.extractionDimensions = [];29 fetchAllPromise = null;30 fetchCustomDimensionsConfiguration();31 }32 function fetchCustomDimensionsConfiguration() {33 if (fetchAllPromise) {34 return fetchAllPromise;35 }36 model.isLoading = true;37 var deferred = $q.defer();38 // .fetch does not return a proper promise39 piwikApi.fetch({method: 'CustomDimensions.getConfiguredCustomDimensions'}).then(function (customDimensions) {40 model.customDimensions = customDimensions;41 deferred.resolve(customDimensions);42 });43 fetchAllPromise = $q.all([deferred.promise, fetchAvailableScopes(), fetchAvailableExtractionDimensions()]).then(function () {44 model.isLoading = false;45 return model.customDimensions;46 });47 return fetchAllPromise;48 }49 function fetchAvailableExtractionDimensions() {50 var deferred = $q.defer();51 // .fetch does not return a proper promise52 piwikApi.fetch({method: 'CustomDimensions.getAvailableExtractionDimensions'}).then(function (availableExtractionDimensions) {53 model.extractionDimensions = availableExtractionDimensions;54 deferred.resolve(availableExtractionDimensions);55 });56 return deferred.promise;57 }58 function fetchAvailableScopes() {59 var deferred = $q.defer();60 // .fetch does not return a proper promise61 piwikApi.fetch({method: 'CustomDimensions.getAvailableScopes'}).then(function (availableScopes) {62 model.availableScopes = availableScopes;63 deferred.resolve(availableScopes);64 });65 return deferred.promise;66 }67 function findCustomDimension(customDimensionId) {68 return fetchCustomDimensionsConfiguration().then(function (customDimensions) {69 var found;70 angular.forEach(customDimensions, function (dimension) {71 if (parseInt(dimension.idcustomdimension, 10) === customDimensionId) {72 found = dimension;73 }74 });75 return found;76 });77 }78 function createOrUpdateDimension(dimension, method) {79 dimension = angular.copy(dimension);80 dimension.active = dimension.active ? '1' : '0';81 dimension.method = method;82 var extractions = dimension.extractions;83 delete dimension.extractions;84 dimension.caseSensitive = dimension.case_sensitive ? '1' : '0';85 delete dimension.case_sensitive;86 model.isUpdating = true;87 return piwikApi.post(dimension, {extractions: extractions}).then(function (response) {88 model.isUpdating = false;89 return {type: 'success'};90 }, function (error) {91 model.isUpdating = false;92 return {type: 'error', message: error};93 });94 }95 }...
index.js
Source:index.js
1const getAudioDimensions = require('./audio');2const getImageDimensions = require('./image');3const getVideoDimensions = require('./video');4const functions = {5 audio: getAudioDimensions,6 image: getImageDimensions,7 video: getVideoDimensions8};9/**10 * Get the dimensional info for a given filename and file type.11 *12 * @example <caption>Get video dimensions.</caption>13 * ```js14 * const getMediaDimensions = require('get-media-dimensions');15 *16 * // get video dimensions = { width, height, duration }17 * const dimensions = await getMediaDimensions('./video.mp4');18 * const dimensions = await getMediaDimensions('https://somewhere.com/video.mp4');19 * ```20 *21 * @example <caption>Get image dimensions.</caption>22 * ```js23 * // get image dimensions = { width, height }24 * const dimensions = await getMediaDimensions('./image.jpg', 'image');25 * const dimensions = await getMediaDimensions('https://somewhere.com/image.jpg', 'image');26 * ```27 *28 * @example <caption>Get audio dimensions.</caption>29 * ```js30 * // get audio dimensions = { duration }31 * const dimensions = await getMediaDimensions('./audio.mp3', 'audio');32 * const dimensions = await getMediaDimensions('https://somewhere.com/audio.mp3', 'audio');33 * ```34 *35 * @kind function36 * @name getMediaDimensions37 * @param {string} urlOrFilename either a remote url or a local filename.38 * @param {string} type the type of media (`audio`, `image`, or `video`).39 * @return {object}40 */41async function getMediaDimensions (urlOrFilename, type) {42 if (!functions[type]) throw new Error(`unknown type ${type}`);43 return functions[type](urlOrFilename);44}...
Using AI Code Generation
1const { webkit } = require('playwright');2(async () => {3 const browser = await webkit.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 await page.screenshot({ path: 'example.png' });7 const dimensions = await page.evaluate(() => {8 return {9 }10 });11 console.log('Dimensions:', dimensions);12 await browser.close();13})();
Using AI Code Generation
1const {chromium, devices} = require('playwright');2(async () => {3 const browser = await chromium.launch();4 const context = await browser.newContext();5 const page = await context.newPage();6 const dimensions = await page._client.send('Emulation.getDeviceMetricsOverride');7 console.log(dimensions);8 await browser.close();9})();10const {chromium, devices} = require('playwright');11(async () => {12 const browser = await chromium.launch();13 const context = await browser.newContext();14 const page = await context.newPage();15 const dimensions = await page._client.send('Emulation.getDeviceMetricsOverride');16 console.log(dimensions);17 await browser.close();18})();19const {chromium, devices} = require('playwright');20(async () => {21 const browser = await chromium.launch();22 const context = await browser.newContext();23 const page = await context.newPage();24 const dimensions = await page._client.send('Emulation.getDeviceMetricsOverride');25 console.log(dimensions);26 await browser.close();27})();28const {chromium, devices} = require('playwright');29(async () => {30 const browser = await chromium.launch();31 const context = await browser.newContext();32 const page = await context.newPage();33 const dimensions = await page._client.send('Emulation.getDeviceMetricsOverride');34 console.log(dimensions);35 await browser.close();36})();37const {chromium, devices} = require('playwright');38(async () => {39 const browser = await chromium.launch();40 const context = await browser.newContext();41 const page = await context.newPage();42 const dimensions = await page._client.send('Emulation.getDeviceMetricsOverride');43 console.log(dimensions);44 await browser.close();45})();
LambdaTest’s Playwright tutorial will give you a broader idea about the Playwright automation framework, its unique features, and use cases with examples to exceed your understanding of Playwright testing. This tutorial will give A to Z guidance, from installing the Playwright framework to some best practices and advanced concepts.
Get 100 minutes of automation test minutes FREE!!