devtools_app.js 191 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454
  1. Root.allDescriptors.push(...[{"dependencies":["ui","host"],"extensions":[{"title":"What's New","id":"release-note","className":"Help.ReleaseNoteView","location":"drawer-view","type":"view","order":1,"persistence":"closeable"},{"category":"Appearance","title":"Show What's New after each update","defaultValue":true,"settingName":"help.show-release-note","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show What's New after each update"},{"value":false,"title":"Do not show What's New after each update"}]},{"category":"Help","className":"Help.ReleaseNotesActionDelegate","type":"action","actionId":"help.release-notes","title":"Release notes"},{"order":10,"type":"context-menu-item","location":"mainMenuHelp/default","actionId":"help.release-notes"},{"category":"Help","tags":"bug","title":"Report a DevTools issue","className":"Help.ReportIssueActionDelegate","actionId":"help.report-issue","type":"action"},{"order":11,"type":"context-menu-item","location":"mainMenuHelp/default","actionId":"help.report-issue"},{"className":"Help.HelpLateInitialization","type":"late-initialization"}],"name":"help","scripts":["help_module.js"],"modules":["help.js","HelpImpl.js","ReleaseNoteView.js","ReleaseNoteText.js"]},{"dependencies":["elements"],"extensions":[{"title":"Accessibility","id":"accessibility.view","className":"Accessibility.AccessibilitySidebarView","location":"elements-sidebar","type":"view","order":10,"persistence":"permanent"}],"name":"accessibility","scripts":["accessibility_module.js"],"skip_compilation":["ARIAProperties.js"],"modules":["accessibility.js","AccessibilityModel.js","AccessibilitySidebarView.js","AccessibilityNodeView.js","AccessibilityStrings.js","ARIAAttributesView.js","ARIAMetadata.js","AXBreadcrumbsPane.js"]},{"dependencies":["components","sdk","timeline_model","ui","perf_ui"],"modules":["LayerDetailsView.js","LayerTreeOutline.js","LayerViewHost.js","Layers3DView.js","PaintProfilerView.js","TransformController.js"],"name":"layer_viewer","scripts":["layer_viewer_module.js"]},{"dependencies":["ui","sdk","data_grid"],"modules":["cookie_table.js","CookiesTable.js"],"name":"cookie_table","scripts":[]},{"dependencies":["emulation"],"extensions":[{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 4","screen":{"horizontal":{"width":480,"height":320},"device-pixel-ratio":2,"vertical":{"width":320,"height":480}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 7_1_2 like Mac OS X) AppleWebKit/537.51.2 (KHTML, like Gecko) Version/7.0 Mobile/11D257 Safari/9537.53","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 5/SE","screen":{"horizontal":{"width":568,"outline":{"insets":{"top":25,"right":115,"bottom":28,"left":115},"image":"@url(iPhone5-landscape.svg)"},"height":320},"device-pixel-ratio":2,"vertical":{"width":320,"outline":{"insets":{"top":105,"right":25,"bottom":111,"left":29},"image":"@url(iPhone5-portrait.svg)"},"height":568}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 10_3_1 like Mac OS X) AppleWebKit/603.1.30 (KHTML, like Gecko) Version/10.0 Mobile/14E304 Safari/602.1","type":"phone"},"type":"emulated-device","order":30},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 6/7/8","screen":{"horizontal":{"width":667,"outline":{"insets":{"top":28,"right":106,"bottom":28,"left":106},"image":"@url(iPhone6-landscape.svg)"},"height":375},"device-pixel-ratio":2,"vertical":{"width":375,"outline":{"insets":{"top":105,"right":28,"bottom":105,"left":28},"image":"@url(iPhone6-portrait.svg)"},"height":667}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1","type":"phone"},"type":"emulated-device","order":31},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone 6/7/8 Plus","screen":{"horizontal":{"width":736,"outline":{"insets":{"top":29,"right":109,"bottom":27,"left":109},"image":"@url(iPhone6Plus-landscape.svg)"},"height":414},"device-pixel-ratio":3,"vertical":{"width":414,"outline":{"insets":{"top":107,"right":30,"bottom":111,"left":26},"image":"@url(iPhone6Plus-portrait.svg)"},"height":736}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1","type":"phone"},"type":"emulated-device","order":32},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPhone X","screen":{"horizontal":{"width":812,"height":375},"device-pixel-ratio":3,"vertical":{"width":375,"height":812}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPhone; CPU iPhone OS 13_2_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.0.3 Mobile/15E148 Safari/604.1","type":"phone"},"type":"emulated-device","order":33},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"BlackBerry Z30","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (BB10; Touch) AppleWebKit/537.10+ (KHTML, like Gecko) Version/10.0.9.2372 Mobile Safari/537.10+","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 4","screen":{"horizontal":{"width":640,"height":384},"device-pixel-ratio":2,"vertical":{"width":384,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 4.4.2; Nexus 4 Build/KOT49H) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":25,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5-vertical-default-1x.png) 1x, @url(google-nexus-5-vertical-default-2x.png) 2x","orientation":"vertical","title":"default"},{"insets":{"top":80,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5-vertical-navigation-1x.png) 1x, @url(google-nexus-5-vertical-navigation-2x.png) 2x","orientation":"vertical","title":"navigation bar"},{"insets":{"top":80,"right":0,"bottom":312,"left":0},"image":"@url(google-nexus-5-vertical-keyboard-1x.png) 1x, @url(google-nexus-5-vertical-keyboard-2x.png) 2x","orientation":"vertical","title":"keyboard"},{"insets":{"top":25,"right":42,"bottom":0,"left":0},"image":"@url(google-nexus-5-horizontal-default-1x.png) 1x, @url(google-nexus-5-horizontal-default-2x.png) 2x","orientation":"horizontal","title":"default"},{"insets":{"top":80,"right":42,"bottom":0,"left":0},"image":"@url(google-nexus-5-horizontal-navigation-1x.png) 1x, @url(google-nexus-5-horizontal-navigation-2x.png) 2x","orientation":"horizontal","title":"navigation bar"},{"insets":{"top":80,"right":42,"bottom":202,"left":0},"image":"@url(google-nexus-5-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5-horizontal-keyboard-2x.png) 2x","orientation":"horizontal","title":"keyboard"}],"title":"Nexus 5","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":24,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5x-vertical-default-1x.png) 1x, @url(google-nexus-5x-vertical-default-2x.png) 2x","orientation":"vertical","title":"default"},{"insets":{"top":80,"right":0,"bottom":48,"left":0},"image":"@url(google-nexus-5x-vertical-navigation-1x.png) 1x, @url(google-nexus-5x-vertical-navigation-2x.png) 2x","orientation":"vertical","title":"navigation bar"},{"insets":{"top":80,"right":0,"bottom":342,"left":0},"image":"@url(google-nexus-5x-vertical-keyboard-1x.png) 1x, @url(google-nexus-5x-vertical-keyboard-2x.png) 2x","orientation":"vertical","title":"keyboard"},{"insets":{"top":24,"right":48,"bottom":0,"left":0},"image":"@url(google-nexus-5x-horizontal-default-1x.png) 1x, @url(google-nexus-5x-horizontal-default-2x.png) 2x","orientation":"horizontal","title":"default"},{"insets":{"top":80,"right":48,"bottom":0,"left":0},"image":"@url(google-nexus-5x-horizontal-navigation-1x.png) 1x, @url(google-nexus-5x-horizontal-navigation-2x.png) 2x","orientation":"horizontal","title":"navigation bar"},{"insets":{"top":80,"right":48,"bottom":222,"left":0},"image":"@url(google-nexus-5x-horizontal-keyboard-1x.png) 1x, @url(google-nexus-5x-horizontal-keyboard-2x.png) 2x","orientation":"horizontal","title":"keyboard"}],"title":"Nexus 5X","screen":{"horizontal":{"width":732,"outline":{"insets":{"top":21,"right":98,"bottom":19,"left":88},"image":"@url(Nexus5X-landscape.svg)"},"height":412},"device-pixel-ratio":2.625,"vertical":{"width":412,"outline":{"insets":{"top":88,"right":22,"bottom":98,"left":18},"image":"@url(Nexus5X-portrait.svg)"},"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 8.0.0; Nexus 5X Build/OPR4.170623.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 6","screen":{"horizontal":{"width":732,"height":412},"device-pixel-ratio":3.5,"vertical":{"width":412,"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 7.1.1; Nexus 6 Build/N6F26U) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 6P","screen":{"horizontal":{"width":732,"outline":{"insets":{"top":17,"right":88,"bottom":17,"left":94},"image":"@url(Nexus6P-landscape.svg)"},"height":412},"device-pixel-ratio":3.5,"vertical":{"width":412,"outline":{"insets":{"top":94,"right":16,"bottom":88,"left":16},"image":"@url(Nexus6P-portrait.svg)"},"height":732}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 8.0.0; Nexus 6P Build/OPP3.170518.006) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Pixel 2","screen":{"horizontal":{"width":731,"height":411},"device-pixel-ratio":2.625,"vertical":{"width":411,"height":731}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 8.0; Pixel 2 Build/OPD3.170816.012) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":20},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Pixel 2 XL","screen":{"horizontal":{"width":823,"height":411},"device-pixel-ratio":3.5,"vertical":{"width":411,"height":823}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 8.0.0; Pixel 2 XL Build/OPD1.170816.004) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":21},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"LG Optimus L70","screen":{"horizontal":{"width":640,"height":384},"device-pixel-ratio":1.25,"vertical":{"width":384,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.4.2; en-us; LGMS323 Build/KOT49I.MS32310c) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nokia N9","screen":{"horizontal":{"width":854,"height":480},"device-pixel-ratio":1,"vertical":{"width":480,"height":854}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (MeeGo; NokiaN9) AppleWebKit/534.13 (KHTML, like Gecko) NokiaBrowser/8.5.0 Mobile Safari/534.13","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nokia Lumia 520","screen":{"horizontal":{"width":533,"height":320},"device-pixel-ratio":1.5,"vertical":{"width":320,"height":533}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (compatible; MSIE 10.0; Windows Phone 8.0; Trident/6.0; IEMobile/10.0; ARM; Touch; NOKIA; Lumia 520)","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Microsoft Lumia 550","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":640,"height":360}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 550) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Microsoft Lumia 950","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":4,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Windows Phone 10.0; Android 4.2.1; Microsoft; Lumia 950) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2486.0 Mobile Safari/537.36 Edge/14.14263","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy S III","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.0; en-us; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy S5","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36","type":"phone"},"type":"emulated-device","order":10},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"JioPhone 2","screen":{"horizontal":{"width":320,"height":240},"device-pixel-ratio":1,"vertical":{"width":240,"height":320}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Mobile; LYF/F300B/LYF-F300B-001-01-15-130718-i;Android; rv:48.0) Gecko/48.0 Firefox/48.0 KAIOS/2.5","type":"phone"},"type":"emulated-device","order":1},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Kindle Fire HDX","screen":{"horizontal":{"width":1280,"height":800},"device-pixel-ratio":2,"vertical":{"width":800,"height":1280}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; en-us; KFAPWI Build/JDQ39) AppleWebKit/535.19 (KHTML, like Gecko) Silk/3.13 Safari/535.19 Silk-Accelerated=true","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPad Mini","screen":{"horizontal":{"width":1024,"height":768},"device-pixel-ratio":2,"vertical":{"width":768,"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPad","screen":{"horizontal":{"width":1024,"outline":{"insets":{"top":56,"right":116,"bottom":52,"left":112},"image":"@url(iPad-landscape.svg)"},"height":768},"device-pixel-ratio":2,"vertical":{"width":768,"outline":{"insets":{"top":114,"right":55,"bottom":114,"left":52},"image":"@url(iPad-portrait.svg)"},"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1","type":"tablet"},"type":"emulated-device","order":40},{"device":{"show-by-default":true,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"iPad Pro","screen":{"horizontal":{"width":1366,"height":1024},"device-pixel-ratio":2,"vertical":{"width":1024,"height":1366}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (iPad; CPU OS 11_0 like Mac OS X) AppleWebKit/604.1.34 (KHTML, like Gecko) Version/11.0 Mobile/15A5341f Safari/604.1","type":"tablet"},"type":"emulated-device","order":41},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Blackberry PlayBook","screen":{"horizontal":{"width":1024,"height":600},"device-pixel-ratio":1,"vertical":{"width":600,"height":1024}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (PlayBook; U; RIM Tablet OS 2.1.0; en-US) AppleWebKit/536.2+ (KHTML like Gecko) Version/7.2.1.0 Safari/536.2+","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 10","screen":{"horizontal":{"width":1280,"height":800},"device-pixel-ratio":2,"vertical":{"width":800,"height":1280}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 10 Build/MOB31T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Nexus 7","screen":{"horizontal":{"width":960,"height":600},"device-pixel-ratio":2,"vertical":{"width":600,"height":960}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; Android 6.0.1; Nexus 7 Build/MOB30X) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Safari/537.36","type":"tablet"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy Note 3","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":3,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.3; en-us; SM-N900T Build/JSS15J) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"vertical","title":"default"},{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Galaxy Note II","screen":{"horizontal":{"width":640,"height":360},"device-pixel-ratio":2,"vertical":{"width":360,"height":640}},"capabilities":["touch","mobile"],"user-agent":"Mozilla/5.0 (Linux; U; Android 4.1; en-us; GT-N7100 Build/JRO03C) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30","type":"phone"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with touch","screen":{"horizontal":{"width":1280,"height":950},"device-pixel-ratio":1,"vertical":{"width":950,"height":1280}},"capabilities":["touch"],"user-agent":"","type":"notebook"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with HiDPI screen","screen":{"horizontal":{"width":1440,"height":900},"device-pixel-ratio":2,"vertical":{"width":900,"height":1440}},"capabilities":[],"user-agent":"","type":"notebook"},"type":"emulated-device"},{"device":{"show-by-default":false,"modes":[{"insets":{"top":0,"right":0,"bottom":0,"left":0},"orientation":"horizontal","title":"default"}],"title":"Laptop with MDPI screen","screen":{"horizontal":{"width":1280,"height":800},"device-pixel-ratio":1,"vertical":{"width":800,"height":1280}},"capabilities":[],"user-agent":"","type":"notebook"},"type":"emulated-device"}],"name":"emulated_devices","scripts":[]},{"dependencies":["components","emulation","timeline","inspector_main","sdk","services","ui"],"extensions":[{"title":"Audits","tags":"lighthouse, pwa","id":"audits","className":"Audits.AuditsPanel","location":"panel","type":"view","order":90}],"name":"audits","scripts":["audits_module.js"],"skip_compilation":["lighthouse/report.js","lighthouse/report-generator.js"],"modules":["audits.js","lighthouse/report.js","lighthouse/report-generator.js","RadioSetting.js","AuditsPanel.js","AuditsController.js","AuditsReportSelector.js","AuditsReportRenderer.js","AuditsStartView.js","AuditsStatusView.js","AuditsProtocolService.js"]},{"extensions":[{"title":"Layers","id":"layers","className":"Layers.LayersPanel","location":"panel","type":"view","order":100,"persistence":"closeable"}],"dependencies":["layer_viewer"],"modules":["LayerPaintProfilerView.js","LayerTreeModel.js","LayersPanel.js"],"name":"layers","scripts":[]},{"dependencies":["common","browser_sdk"],"modules":["har_importer.js","HARFormat.js","HARImporter.js"],"name":"har_importer"},{"name":"network","modules":[],"dependencies":["search","source_frame","components","perf_ui","cookie_table","data_grid","browser_sdk","mobile_throttling","har_importer","persistence"],"extensions":[{"title":"Network","id":"network","className":"Network.NetworkPanel","location":"panel","type":"view","order":40},{"className":"Network.NetworkPanel.ContextMenuProvider","contextTypes":["SDK.NetworkRequest","SDK.Resource","Workspace.UISourceCode"],"type":"@UI.ContextMenu.Provider"},{"className":"Network.NetworkPanel.RequestRevealer","contextTypes":["SDK.NetworkRequest"],"destination":"Network panel","type":"@Common.Revealer"},{"className":"Network.NetworkPanel.RequestLocationRevealer","contextTypes":["Network.UIRequestLocation"],"type":"@Common.Revealer"},{"category":"Network","title":"Color-code resource types","defaultValue":false,"tags":"color code, resource type","settingName":"networkColorCodeResourceTypes","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Color code by resource type"},{"value":false,"title":"Use default colors"}]},{"category":"Network","title":"Group network log by frame","defaultValue":false,"tags":"network, frame, group","settingName":"network.group-by-frame","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Group network log items by frame"},{"value":false,"title":"Don't group network log items by frame"}]},{"iconClass":"largeicon-start-recording","toggledIconClass":"largeicon-stop-recording","className":"Network.NetworkPanel.ActionDelegate","toggleWithRedColor":true,"actionId":"network.toggle-recording","toggleable":true,"contextTypes":["Network.NetworkPanel"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"type":"action","options":[{"value":true,"title":"Record network log"},{"value":false,"title":"Stop recording network log"}]},{"className":"Network.NetworkPanel.ActionDelegate","contextTypes":["Network.NetworkPanel"],"bindings":[{"shortcut":"Esc"}],"type":"action","actionId":"network.hide-request-details"},{"title":"Request blocking","id":"network.blocked-urls","className":"Network.BlockedURLsPane","location":"drawer-view","type":"view","order":60,"persistence":"closeable"},{"title":"Network conditions","tags":"disk cache, network throttling, useragent, user agent, user-agent","id":"network.config","className":"Network.NetworkConfigView","location":"drawer-view","type":"view","order":40,"persistence":"closeable"},{"category":"Network","className":"Network.NetworkPanel","type":"@UI.ViewLocationResolver","name":"network-sidebar"},{"title":"Search","className":"Network.SearchNetworkView","location":"network-sidebar","type":"view","id":"network.search-network-tab","persistence":"permanent"},{"category":"DevTools","title":"Search","className":"Network.NetworkPanel.ActionDelegate","contextTypes":["Network.NetworkPanel"],"actionId":"network.search","bindings":[{"platform":"mac","shortcut":"Meta+F"},{"platform":"windows,linux","shortcut":"Ctrl+F"}],"type":"action"}],"scripts":["network_module.js"]},{"skip_compilation":["dagre.js"],"modules":[],"name":"dagre_layout","scripts":["dagre_layout_module.js"]},{"name":"media","modules":[],"dependencies":["components","sdk","ui","data_grid"],"extensions":[{"title":"Media","tags":"media, video","id":"media","className":"Media.MainView","experiment":"mediaInspector","location":"panel","type":"view","order":100,"persistence":"closeable"}],"scripts":["media_module.js"]},{"dependencies":["elements"],"extensions":[{"title":"Animations","id":"animations","className":"Animation.AnimationTimeline","location":"drawer-view","type":"view","order":0,"persistence":"closeable"}],"name":"animation","scripts":["animation_module.js"],"modules":["animation.js","AnimationModel.js","AnimationGroupPreviewUI.js","AnimationScreenshotPopover.js","AnimationTimeline.js","AnimationUI.js"]},{"name":"resources","modules":[],"dependencies":["source_frame","cookie_table","inline_editor","data_grid","components","object_ui","perf_ui","mobile_throttling","network","sources"],"extensions":[{"title":"Application","tags":"pwa","id":"resources","className":"Resources.ResourcesPanel","location":"panel","type":"view","order":70},{"className":"Resources.ResourcesPanel.ResourceRevealer","contextTypes":["SDK.Resource"],"destination":"Application panel","type":"@Common.Revealer"},{"category":"Resources","className":"Resources.ClearStorageView.ActionDelegate","type":"action","actionId":"resources.clear","title":"Clear site data"},{"iconClass":"largeicon-start-recording","toggledIconClass":"largeicon-stop-recording","className":"Resources.BackgroundServiceView.ActionDelegate","toggleWithRedColor":true,"actionId":"background-service.toggle-recording","toggleable":true,"contextTypes":["Resources.BackgroundServiceView"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"category":"Background Services","type":"action","options":[{"value":true,"title":"Start recording events"},{"value":false,"title":"Stop recording events"}]}],"scripts":["resources_module.js"]},{"dependencies":["components","extensions","inline_editor","color_picker","event_listeners"],"extensions":[{"title":"Elements","id":"elements","className":"Elements.ElementsPanel","location":"panel","type":"view","order":10},{"className":"Elements.ElementsPanel.ContextMenuProvider","contextTypes":["SDK.RemoteObject","SDK.DOMNode","SDK.DeferredDOMNode"],"type":"@UI.ContextMenu.Provider"},{"className":"Elements.ElementsTreeOutline.Renderer","contextTypes":["SDK.DOMNode","SDK.DeferredDOMNode"],"type":"@UI.Renderer"},{"className":"Elements.ElementsPanel.DOMNodeRevealer","contextTypes":["SDK.DOMNode","SDK.DeferredDOMNode","SDK.RemoteObject"],"destination":"Elements panel","type":"@Common.Revealer"},{"className":"Elements.DOMLinkifier.Linkifier","contextTypes":["SDK.DOMNode","SDK.DeferredDOMNode"],"type":"@Common.Linkifier"},{"className":"Elements.ElementsPanel.CSSPropertyRevealer","contextTypes":["SDK.CSSProperty"],"destination":"styles sidebar","type":"@Common.Revealer"},{"category":"Elements","title":"Show user agent shadow DOM","defaultValue":false,"settingName":"showUAShadowDOM","settingType":"boolean","type":"setting","order":1},{"category":"Elements","title":"Word wrap","defaultValue":true,"options":[{"value":true,"title":"Enable DOM word wrap"},{"value":false,"title":"Disable DOM word wrap"}],"settingName":"domWordWrap","settingType":"boolean","type":"setting","order":2},{"category":"Elements","title":"Show HTML comments","defaultValue":true,"options":[{"value":true,"title":"Show HTML comments"},{"value":false,"title":"Hide HTML comments"}],"settingName":"showHTMLComments","settingType":"boolean","type":"setting","order":3},{"category":"Elements","title":"Reveal DOM node on hover","defaultValue":true,"settingName":"highlightNodeOnHoverInOverlay","settingType":"boolean","type":"setting","order":4},{"category":"Elements","title":"Show detailed inspect tooltip","defaultValue":true,"settingName":"showDetailedInspectTooltip","settingType":"boolean","type":"setting","order":5},{"defaultValue":true,"type":"setting","settingName":"showEventListenersForAncestors","settingType":"boolean"},{"className":"Elements.ElementStatePaneWidget.ButtonProvider","type":"@UI.ToolbarItem.Provider","order":1,"location":"styles-sidebarpane-toolbar"},{"className":"Elements.ClassesPaneWidget.ButtonProvider","type":"@UI.ToolbarItem.Provider","order":2,"location":"styles-sidebarpane-toolbar"},{"className":"Elements.StylesSidebarPane.ButtonProvider","type":"@UI.ToolbarItem.Provider","order":100,"location":"styles-sidebarpane-toolbar"},{"className":"Elements.ElementsActionDelegate","contextTypes":["Elements.ElementsPanel"],"bindings":[{"shortcut":"H"}],"type":"action","actionId":"elements.hide-element"},{"className":"Elements.ElementsActionDelegate","contextTypes":["Elements.ElementsPanel"],"bindings":[{"shortcut":"F2"}],"type":"action","actionId":"elements.edit-as-html"},{"className":"Elements.ElementsActionDelegate","contextTypes":["Elements.ElementsPanel"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Z"},{"platform":"mac","shortcut":"Meta+Z"}],"type":"action","actionId":"elements.undo"},{"className":"Elements.ElementsActionDelegate","contextTypes":["Elements.ElementsPanel"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Y"},{"platform":"mac","shortcut":"Meta+Shift+Z"}],"type":"action","actionId":"elements.redo"},{"className":"Elements.ElementsPanel.PseudoStateMarkerDecorator","marker":"pseudo-state-marker","type":"@Elements.MarkerDecorator"},{"marker":"hidden-marker","factoryName":"Elements.GenericDecorator","type":"@Elements.MarkerDecorator","color":"#555","title":"Element is hidden"},{"iconClass":"largeicon-node-search","title":"Select an element in the page to inspect it","className":"Elements.InspectElementModeController.ToggleSearchActionDelegate","actionId":"elements.toggle-element-search","toggleable":true,"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Shift+C"},{"platform":"mac","shortcut":"Meta+Shift+C"}],"type":"action"},{"className":"Elements.InspectElementModeController.ToggleSearchActionDelegate","category":"Screenshot","type":"action","actionId":"elements.capture-area-screenshot","title":"Capture area screenshot"},{"order":0,"type":"@UI.ToolbarItem.Provider","actionId":"elements.toggle-element-search","location":"main-toolbar-left"},{"category":"Elements","className":"Elements.ElementsPanel","type":"@UI.ViewLocationResolver","name":"elements-sidebar"},{"title":"Event Listeners","id":"elements.eventListeners","className":"Elements.EventListenersWidget","location":"elements-sidebar","hasToolbar":true,"type":"view","order":5,"persistence":"permanent"},{"title":"Properties","id":"elements.domProperties","className":"Elements.PropertiesWidget","location":"elements-sidebar","type":"view","order":7,"persistence":"permanent"},{"title":"Stack Trace","id":"elements.domCreation","className":"Elements.NodeStackTraceWidget","experiment":"captureNodeCreationStacks","location":"elements-sidebar","type":"view","order":10,"persistence":"permanent"}],"name":"elements","scripts":["elements_module.js"],"modules":["elements.js","InspectElementModeController.js","ColorSwatchPopoverIcon.js","ComputedStyleModel.js","DOMLinkifier.js","DOMPath.js","ElementsBreadcrumbs.js","ElementsSidebarPane.js","ElementsTreeElement.js","ElementsTreeOutline.js","EventListenersWidget.js","MarkerDecorator.js","MetricsSidebarPane.js","PlatformFontsWidget.js","PropertiesWidget.js","NodeStackTraceWidget.js","StylePropertyHighlighter.js","StylesSidebarPane.js","StylePropertyTreeElement.js","ComputedStyleWidget.js","ElementsPanel.js","ClassesPaneWidget.js","ElementStatePaneWidget.js","ElementsTreeElementHighlighter.js"]},{"dependencies":["elements","ui","sdk","data_grid","extensions"],"extensions":[{"title":"CSS Overview","id":"cssoverview","className":"CssOverview.CSSOverviewPanel","experiment":"cssOverview","location":"panel","type":"view","order":95}],"name":"css_overview","scripts":["css_overview_module.js"],"modules":["CSSOverviewController.js","CSSOverviewUnusedDeclarations.js","CSSOverviewModel.js","CSSOverviewStartView.js","CSSOverviewProcessingView.js","CSSOverviewCompletedView.js","CSSOverviewSidebarPanel.js","CSSOverviewPanel.js"]},{"name":"timeline","modules":[],"dependencies":["components","coverage","layer_viewer","timeline_model","perf_ui","extensions","data_grid","profiler","mobile_throttling"],"extensions":[{"title":"Performance","id":"timeline","className":"Timeline.TimelinePanel","location":"panel","type":"view","order":50},{"category":"Performance","title":"Hide chrome frame in Layers view","defaultValue":false,"settingName":"frameViewerHideChromeWindow","settingType":"boolean","type":"setting"},{"className":"Timeline.LoadTimelineHandler","type":"@Common.QueryParamHandler","name":"loadTimelineFromURL"},{"order":10,"type":"context-menu-item","location":"timelineMenu/open","actionId":"timeline.load-from-file"},{"order":15,"type":"context-menu-item","location":"timelineMenu/open","actionId":"timeline.save-to-file"},{"iconClass":"largeicon-start-recording","toggledIconClass":"largeicon-stop-recording","className":"Timeline.TimelinePanel.ActionDelegate","toggleWithRedColor":true,"actionId":"timeline.toggle-recording","toggleable":true,"contextTypes":["Timeline.TimelinePanel"],"bindings":[{"platform":"windows,linux","shortcut":"Ctrl+E"},{"platform":"mac","shortcut":"Meta+E"}],"type":"action","options":[{"value":true,"title":"Record"},{"value":false,"title":"Stop"}]},{"iconClass":"largeicon-refresh","category":"Performance","title":"Start profiling and reload page","className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"actionId":"timeline.record-reload","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+Shift+E"},{"platform":"mac","shortcut":"Meta+Shift+E"}],"type":"action"},{"category":"Timeline","title":"Save profile\u2026","className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"actionId":"timeline.save-to-file","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+S"},{"platform":"mac","shortcut":"Meta+S"}],"type":"action"},{"category":"Timeline","title":"Load profile\u2026","className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"actionId":"timeline.load-from-file","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+O"},{"platform":"mac","shortcut":"Meta+O"}],"type":"action"},{"className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"bindings":[{"shortcut":"["}],"type":"action","actionId":"timeline.jump-to-previous-frame"},{"className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"bindings":[{"shortcut":"]"}],"type":"action","actionId":"timeline.jump-to-next-frame"},{"category":"Performance","title":"Show recent timeline sessions","className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"actionId":"timeline.show-history","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+H"},{"platform":"mac","shortcut":"Meta+Y"}],"type":"action"},{"title":"JavaScript Profiler","id":"js_profiler","className":"Profiler.JSProfilerPanel","location":"panel","type":"view","order":65,"persistence":"closeable"},{"className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"bindings":[{"platform":"windows,linux","shortcut":"Alt+Left"},{"platform":"mac","shortcut":"Meta+Left"}],"type":"action","actionId":"timeline.previous-recording"},{"className":"Timeline.TimelinePanel.ActionDelegate","contextTypes":["Timeline.TimelinePanel"],"bindings":[{"platform":"windows,linux","shortcut":"Alt+Right"},{"platform":"mac","shortcut":"Meta+Right"}],"type":"action","actionId":"timeline.next-recording"}],"scripts":["timeline_module.js"]},{"name":"browser_debugger","modules":["browser_debugger.js","DOMBreakpointsSidebarPane.js","EventListenerBreakpointsSidebarPane.js","ObjectEventListenersSidebarPane.js","XHRBreakpointsSidebarPane.js"],"dependencies":["elements","sources","console"],"extensions":[{"title":"Event Listener Breakpoints","id":"sources.eventListenerBreakpoints","className":"BrowserDebugger.EventListenerBreakpointsSidebarPane","location":"sources.sidebar-bottom","type":"view","order":9,"persistence":"permanent"},{"className":"BrowserDebugger.XHRBreakpointsSidebarPane","contextTypes":["SDK.DebuggerPausedDetails"],"type":"@UI.ContextFlavorListener"},{"title":"XHR/fetch Breakpoints","id":"sources.xhrBreakpoints","className":"BrowserDebugger.XHRBreakpointsSidebarPane","location":"sources.sidebar-bottom","hasToolbar":true,"type":"view","order":5,"persistence":"permanent"},{"title":"DOM Breakpoints","id":"sources.domBreakpoints","factoryName":"BrowserDebugger.DOMBreakpointsSidebarPane","location":"sources.sidebar-bottom","type":"view","order":7,"persistence":"permanent"},{"title":"DOM Breakpoints","id":"elements.domBreakpoints","factoryName":"BrowserDebugger.DOMBreakpointsSidebarPane","location":"elements-sidebar","type":"view","order":6,"persistence":"permanent"},{"marker":"breakpoint-marker","factoryName":"Elements.GenericDecorator","type":"@Elements.MarkerDecorator","color":"rgb(105, 140, 254)","title":"DOM Breakpoint"},{"className":"BrowserDebugger.DOMBreakpointsSidebarPane.ContextMenuProvider","contextTypes":["SDK.DOMNode"],"type":"@UI.ContextMenu.Provider"},{"className":"BrowserDebugger.DOMBreakpointsSidebarPane","contextTypes":["SDK.DebuggerPausedDetails"],"type":"@UI.ContextFlavorListener"},{"title":"Global Listeners","id":"sources.globalListeners","className":"BrowserDebugger.ObjectEventListenersSidebarPane","location":"sources.sidebar-bottom","hasToolbar":true,"type":"view","order":8,"persistence":"permanent"},{"title":"Page","id":"navigator-network","className":"Sources.NetworkNavigatorView","location":"navigator-view","type":"view","order":2,"persistence":"permanent"},{"title":"Overrides","id":"navigator-overrides","className":"Sources.OverridesNavigatorView","location":"navigator-view","type":"view","order":4,"persistence":"permanent"},{"title":"Content scripts","id":"navigator-contentScripts","className":"Sources.ContentScriptsNavigatorView","location":"navigator-view","type":"view","order":5,"persistence":"permanent"},{"className":"Sources.OverridesNavigatorView","viewId":"navigator-overrides","type":"@Sources.NavigatorView"},{"className":"Sources.ContentScriptsNavigatorView","viewId":"navigator-contentScripts","type":"@Sources.NavigatorView"}],"scripts":["browser_debugger_module.js"]},{"dependencies":["bindings","components","platform","ui","mobile_throttling"],"extensions":[{"className":"Emulation.AdvancedAppProvider","type":"@Common.AppProvider","order":0,"condition":"can_dock"},{"category":"Mobile","iconClass":"largeicon-phone","title":"Toggle device toolbar","className":"Emulation.DeviceModeWrapper.ActionDelegate","actionId":"emulation.toggle-device-mode","toggleable":true,"bindings":[{"platform":"windows,linux","shortcut":"Shift+Ctrl+M"},{"platform":"mac","shortcut":"Shift+Meta+M"}],"type":"action","condition":"can_dock"},{"category":"Screenshot","className":"Emulation.DeviceModeWrapper.ActionDelegate","type":"action","actionId":"emulation.capture-screenshot","title":"Capture screenshot"},{"actionId":"emulation.capture-screenshot","type":"context-menu-item","location":"deviceModeMenu/save","order":12},{"order":1,"type":"@UI.ToolbarItem.Provider","actionId":"emulation.toggle-device-mode","condition":"can_dock","location":"main-toolbar-left"},{"category":"Screenshot","className":"Emulation.DeviceModeWrapper.ActionDelegate","type":"action","actionId":"emulation.capture-full-height-screenshot","title":"Capture full size screenshot"},{"category":"Screenshot","className":"Emulation.DeviceModeWrapper.ActionDelegate","type":"action","actionId":"emulation.capture-node-screenshot","title":"Capture node screenshot"},{"actionId":"emulation.capture-full-height-screenshot","type":"context-menu-item","location":"deviceModeMenu/save","order":13},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"showMediaQueryInspector","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show media queries"},{"value":false,"title":"Hide media queries"}]},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"emulation.showRulers","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show rulers"},{"value":false,"title":"Hide rulers"}]},{"category":"Mobile","tags":"device","defaultValue":false,"settingName":"emulation.showDeviceOutline","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Show device frame"},{"value":false,"title":"Hide device frame"}]},{"title":"Devices","settings":["standardEmulatedDeviceList","customEmulatedDeviceList"],"id":"devices","className":"Emulation.DevicesSettingsTab","location":"settings-view","type":"view","order":30},{"className":"Emulation.SensorsView.ShowActionDelegate","type":"action","actionId":"emulation.show-sensors","title":"Sensors"},{"title":"Sensors","tags":"geolocation, timezones, accelerometer, device orientation","id":"sensors","className":"Emulation.SensorsView","location":"drawer-view","type":"view","order":100,"persistence":"closeable"},{"defaultValue":[{"lat":52.520007,"timezoneId":"Europe/Berlin","long":13.404954,"title":"Berlin"},{"lat":51.507351,"timezoneId":"Europe/London","long":-0.127758,"title":"London"},{"lat":55.755826,"timezoneId":"Europe/Moscow","long":37.6173,"title":"Moscow"},{"lat":37.386052,"timezoneId":"US/Pacific","long":-122.083851,"title":"Mountain View"},{"lat":19.075984,"timezoneId":"Asia/Kolkata","long":72.877656,"title":"Mumbai"},{"lat":37.774929,"timezoneId":"US/Pacific","long":-122.419416,"title":"San Francisco"},{"lat":31.230416,"timezoneId":"Asia/Shanghai","long":121.473701,"title":"Shanghai"},{"lat":-23.55052,"timezoneId":"America/Sao_Paulo","long":-46.633309,"title":"S\u00e3o Paulo"},{"lat":35.689487,"timezoneId":"Asia/Tokyo","long":139.691706,"title":"Tokyo"}],"type":"setting","settingName":"emulation.geolocations","settingType":"array"},{"title":"Geolocations","settings":["emulation.geolocations"],"id":"emulation-geolocations","className":"Emulation.GeolocationsSettingsTab","location":"settings-view","type":"view","order":40}],"name":"emulation"},{"dependencies":["network","platform","ui","sdk"],"extensions":[{"title":"Security","id":"security","className":"Security.SecurityPanel","location":"panel","type":"view","order":80}],"name":"security","scripts":["security_module.js"],"modules":["security.js","SecurityModel.js","SecurityPanel.js"]},{"dependencies":["common","sdk","ui","protocol"],"extensions":[{"defaultValue":[],"type":"setting","settingName":"customNetworkConditions","settingType":"array"},{"category":"Network","tags":"device, throttling","title":"Go offline","className":"MobileThrottling.ThrottlingManager.ActionDelegate","actionId":"network-conditions.network-offline","type":"action"},{"category":"Network","tags":"device, throttling","title":"Enable slow 3G throttling","className":"MobileThrottling.ThrottlingManager.ActionDelegate","actionId":"network-conditions.network-low-end-mobile","type":"action"},{"category":"Network","tags":"device, throttling","title":"Enable fast 3G throttling","className":"MobileThrottling.ThrottlingManager.ActionDelegate","actionId":"network-conditions.network-mid-tier-mobile","type":"action"},{"category":"Network","tags":"device, throttling","title":"Go online","className":"MobileThrottling.ThrottlingManager.ActionDelegate","actionId":"network-conditions.network-online","type":"action"},{"title":"Throttling","settings":["customNetworkConditions"],"id":"throttling-conditions","className":"MobileThrottling.ThrottlingSettingsTab","location":"settings-view","type":"view","order":35}],"name":"mobile_throttling","modules":["mobile_throttling.js","ThrottlingPresets.js","MobileThrottlingSelector.js","NetworkPanelIndicator.js","NetworkThrottlingSelector.js","ThrottlingSettingsTab.js","ThrottlingManager.js"]},{"modules":[],"dependencies":["platform","ui","host","components"],"extensions":[{"title":"Remote devices","tags":"usb, android, mobile","id":"remote-devices","className":"Devices.DevicesView","location":"drawer-view","type":"view","order":50,"persistence":"closeable"}],"name":"devices","scripts":["devices_module.js"]},{"dependencies":["components","sdk","ui"],"extensions":[{"title":"WebAudio","tags":"audio","id":"web-audio","className":"WebAudio.WebAudioView","location":"drawer-view","type":"view","order":100,"persistence":"closeable"}],"name":"web_audio","scripts":["web_audio_module.js"],"modules":["web_audio.js","graph_visualizer/Types.js","graph_visualizer/GraphStyle.js","graph_visualizer/GraphManager.js","graph_visualizer/NodeRendererUtility.js","graph_visualizer/NodeView.js","graph_visualizer/EdgeView.js","graph_visualizer/GraphView.js","WebAudioModel.js","AudioContextSelector.js","AudioContextContentBuilder.js","WebAudioView.js"]},{"dependencies":["sdk"],"modules":["timeline_model.js","TimelineModelFilter.js","TracingLayerTree.js","TimelineModel.js","TimelineIRModel.js","TimelineJSProfile.js","TimelineFrameModel.js","TimelineProfileTree.js"],"name":"timeline_model","scripts":[]},{"dependencies":["components","mobile_throttling"],"extensions":[{"className":"InspectorMain.InspectorMain","type":"early-initialization"},{"category":"Navigation","iconClass":"largeicon-refresh","title":"Reload page","className":"InspectorMain.ReloadActionDelegate","actionId":"inspector_main.reload","bindings":[{"platform":"windows,linux","shortcut":"Ctrl+R F5"},{"platform":"mac","shortcut":"Meta+R"}],"type":"action"},{"category":"Navigation","title":"Hard reload page","className":"InspectorMain.ReloadActionDelegate","actionId":"inspector_main.hard-reload","bindings":[{"platform":"windows,linux","shortcut":"Shift+Ctrl+R Shift+F5 Ctrl+F5 Ctrl+Shift+F5"},{"platform":"mac","shortcut":"Shift+Meta+R"}],"type":"action"},{"className":"InspectorMain.NodeIndicator","type":"@UI.ToolbarItem.Provider","order":2,"location":"main-toolbar-left"},{"category":"Network","title":"Force ad blocking on this site","storageType":"session","defaultValue":false,"settingName":"network.adBlockingEnabled","settingType":"boolean","type":"setting","options":[{"value":true,"title":"Block ads on this site"},{"value":false,"title":"Show ads on this site, if allowed"}]},{"category":"DevTools","title":"Auto-open DevTools for popups","defaultValue":false,"options":[{"value":true,"title":"Auto-open DevTools for popups"},{"value":false,"title":"Do not auto-open DevTools for popups"}],"settingName":"autoAttachToCreatedPages","settingType":"boolean","type":"setting","order":2},{"category":"DevTools","title":"Emulate a focused page","storageType":"session","defaultValue":false,"options":[{"value":true,"title":"Emulate a focused page"},{"value":false,"title":"Do not emulate a focused page"}],"settingName":"emulatePageFocus","settingType":"boolean","type":"setting","order":2},{"category":"Appearance","title":"Don't show Chrome Data Saver warning","defaultValue":false,"settingName":"disableDataSaverInfobar","settingType":"boolean","type":"setting"},{"category":"Appearance","title":"Disable paused state overlay","defaultValue":false,"settingName":"disablePausedStateOverlay","settingType":"boolean","type":"setting"},{"title":"Rendering","id":"rendering","className":"InspectorMain.RenderingOptionsView","location":"drawer-view","type":"view","order":50,"persistence":"closeable"}],"name":"inspector_main","modules":["inspector_main.js","RenderingOptions.js","InspectorMain.js"]},{"dependencies":["sdk","ui"],"extensions":[{"title":"Performance monitor","tags":"performance, system monitor, monitor, activity, metrics","id":"performance.monitor","className":"PerformanceMonitor.PerformanceMonitor","location":"drawer-view","type":"view","order":100,"persistence":"closeable"}],"name":"performance_monitor","scripts":["performance_monitor_module.js"],"modules":["performance_monitor.js","PerformanceMonitor.js"]}]);Root.applicationDescriptor.modules.push(...[{"name":"help"},{"type":"remote","name":"accessibility"},{"name":"layer_viewer"},{"name":"cookie_table"},{"type":"remote","name":"emulated_devices"},{"name":"audits"},{"name":"layers"},{"name":"har_importer"},{"name":"network"},{"type":"remote","name":"dagre_layout"},{"name":"media"},{"name":"animation"},{"name":"resources"},{"name":"elements"},{"name":"css_overview"},{"name":"timeline"},{"name":"browser_debugger"},{"type":"autostart","name":"emulation"},{"name":"performance_monitor"},{"type":"autostart","name":"mobile_throttling"},{"name":"devices"},{"name":"web_audio"},{"name":"timeline_model"},{"type":"autostart","name":"inspector_main"},{"name":"security"}]);self['MobileThrottling']=self['MobileThrottling']||{};self['Emulation']=self['Emulation']||{};Emulation.AdvancedApp=class{constructor(){Components.dockController.addEventListener(Components.DockController.Events.BeforeDockSideChanged,this._openToolboxWindow,this);}
  2. static _instance(){if(!Emulation.AdvancedApp._appInstance){Emulation.AdvancedApp._appInstance=new Emulation.AdvancedApp();}
  3. return Emulation.AdvancedApp._appInstance;}
  4. presentUI(document){const rootView=new UI.RootView();this._rootSplitWidget=new UI.SplitWidget(false,true,'InspectorView.splitViewState',555,300,true);this._rootSplitWidget.show(rootView.element);this._rootSplitWidget.setSidebarWidget(UI.inspectorView);this._rootSplitWidget.setDefaultFocusedChild(UI.inspectorView);UI.inspectorView.setOwnerSplit(this._rootSplitWidget);this._inspectedPagePlaceholder=Emulation.InspectedPagePlaceholder.instance();this._inspectedPagePlaceholder.addEventListener(Emulation.InspectedPagePlaceholder.Events.Update,this._onSetInspectedPageBounds.bind(this),this);this._deviceModeView=new Emulation.DeviceModeWrapper(this._inspectedPagePlaceholder);Components.dockController.addEventListener(Components.DockController.Events.BeforeDockSideChanged,this._onBeforeDockSideChange,this);Components.dockController.addEventListener(Components.DockController.Events.DockSideChanged,this._onDockSideChange,this);Components.dockController.addEventListener(Components.DockController.Events.AfterDockSideChanged,this._onAfterDockSideChange,this);this._onDockSideChange();console.timeStamp('AdvancedApp.attachToBody');rootView.attachToDocument(document);rootView.focus();this._inspectedPagePlaceholder.update();}
  5. _openToolboxWindow(event){if((event.data.to)!==Components.DockController.State.Undocked){return;}
  6. if(this._toolboxWindow){return;}
  7. const url=window.location.href.replace('devtools_app.html','toolbox.html');this._toolboxWindow=window.open(url,undefined);}
  8. toolboxLoaded(toolboxDocument){UI.initializeUIUtils(toolboxDocument,Common.settings.createSetting('uiTheme','default'));UI.installComponentRootStyles((toolboxDocument.body));UI.ContextMenu.installHandler(toolboxDocument);UI.Tooltip.installHandler(toolboxDocument);this._toolboxRootView=new UI.RootView();this._toolboxRootView.attachToDocument(toolboxDocument);this._updateDeviceModeView();}
  9. _updateDeviceModeView(){if(this._isDocked()){this._rootSplitWidget.setMainWidget(this._deviceModeView);}else if(this._toolboxRootView){this._deviceModeView.show(this._toolboxRootView.element);}}
  10. _onBeforeDockSideChange(event){if((event.data.to)===Components.DockController.State.Undocked&&this._toolboxRootView){this._rootSplitWidget.hideSidebar();this._inspectedPagePlaceholder.update();}
  11. this._changingDockSide=true;}
  12. _onDockSideChange(event){this._updateDeviceModeView();const toDockSide=event?(event.data.to):Components.dockController.dockSide();if(toDockSide===Components.DockController.State.Undocked){this._updateForUndocked();}else if(this._toolboxRootView&&event&&(event.data.from)===Components.DockController.State.Undocked){this._rootSplitWidget.hideSidebar();}else{this._updateForDocked(toDockSide);}}
  13. _onAfterDockSideChange(event){if(!this._changingDockSide){return;}
  14. if((event.data.from)===Components.DockController.State.Undocked){this._updateForDocked((event.data.to));}
  15. this._changingDockSide=false;this._inspectedPagePlaceholder.update();}
  16. _updateForDocked(dockSide){this._rootSplitWidget.resizerElement().style.transform=dockSide===Components.DockController.State.DockedToRight?'translateX(2px)':dockSide===Components.DockController.State.DockedToLeft?'translateX(-2px)':'';this._rootSplitWidget.setVertical(dockSide===Components.DockController.State.DockedToRight||dockSide===Components.DockController.State.DockedToLeft);this._rootSplitWidget.setSecondIsSidebar(dockSide===Components.DockController.State.DockedToRight||dockSide===Components.DockController.State.DockedToBottom);this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(),true);this._rootSplitWidget.toggleResizer(UI.inspectorView.topResizerElement(),dockSide===Components.DockController.State.DockedToBottom);this._rootSplitWidget.showBoth();}
  17. _updateForUndocked(){this._rootSplitWidget.toggleResizer(this._rootSplitWidget.resizerElement(),false);this._rootSplitWidget.toggleResizer(UI.inspectorView.topResizerElement(),false);this._rootSplitWidget.hideMain();}
  18. _isDocked(){return Components.dockController.dockSide()!==Components.DockController.State.Undocked;}
  19. _onSetInspectedPageBounds(event){if(this._changingDockSide){return;}
  20. const window=this._inspectedPagePlaceholder.element.window();if(!window.innerWidth||!window.innerHeight){return;}
  21. if(!this._inspectedPagePlaceholder.isShowing()){return;}
  22. const bounds=(event.data);console.timeStamp('AdvancedApp.setInspectedPageBounds');Host.InspectorFrontendHost.setInspectedPageBounds(bounds);}};Emulation.AdvancedApp._appInstance;Emulation.AdvancedAppProvider=class{createApp(){return Emulation.AdvancedApp._instance();}};;Emulation.EmulatedDevice=class{constructor(){this.title='';this.type=Emulation.EmulatedDevice.Type.Unknown;this.vertical={width:0,height:0,outlineInsets:null,outlineImage:null};this.horizontal={width:0,height:0,outlineInsets:null,outlineImage:null};this.deviceScaleFactor=1;this.capabilities=[Emulation.EmulatedDevice.Capability.Touch,Emulation.EmulatedDevice.Capability.Mobile];this.userAgent='';this.modes=[];this._show=Emulation.EmulatedDevice._Show.Default;this._showByDefault=true;this._extension=null;}
  23. static fromJSONV1(json){try{function parseValue(object,key,type,defaultValue){if(typeof object!=='object'||object===null||!object.hasOwnProperty(key)){if(typeof defaultValue!=='undefined'){return defaultValue;}
  24. throw new Error('Emulated device is missing required property \''+key+'\'');}
  25. const value=object[key];if(typeof value!==type||value===null){throw new Error('Emulated device property \''+key+'\' has wrong type \''+typeof value+'\'');}
  26. return value;}
  27. function parseIntValue(object,key){const value=(parseValue(object,key,'number'));if(value!==Math.abs(value)){throw new Error('Emulated device value \''+key+'\' must be integer');}
  28. return value;}
  29. function parseInsets(json){return new UI.Insets(parseIntValue(json,'left'),parseIntValue(json,'top'),parseIntValue(json,'right'),parseIntValue(json,'bottom'));}
  30. function parseOrientation(json){const result={};result.width=parseIntValue(json,'width');if(result.width<0||result.width>Emulation.DeviceModeModel.MaxDeviceSize||result.width<Emulation.DeviceModeModel.MinDeviceSize){throw new Error('Emulated device has wrong width: '+result.width);}
  31. result.height=parseIntValue(json,'height');if(result.height<0||result.height>Emulation.DeviceModeModel.MaxDeviceSize||result.height<Emulation.DeviceModeModel.MinDeviceSize){throw new Error('Emulated device has wrong height: '+result.height);}
  32. const outlineInsets=parseValue(json['outline'],'insets','object',null);if(outlineInsets){result.outlineInsets=parseInsets(outlineInsets);if(result.outlineInsets.left<0||result.outlineInsets.top<0){throw new Error('Emulated device has wrong outline insets');}
  33. result.outlineImage=(parseValue(json['outline'],'image','string'));}
  34. return(result);}
  35. const result=new Emulation.EmulatedDevice();result.title=(parseValue(json,'title','string'));result.type=(parseValue(json,'type','string'));const rawUserAgent=(parseValue(json,'user-agent','string'));result.userAgent=SDK.MultitargetNetworkManager.patchUserAgentWithChromeVersion(rawUserAgent);const capabilities=parseValue(json,'capabilities','object',[]);if(!Array.isArray(capabilities)){throw new Error('Emulated device capabilities must be an array');}
  36. result.capabilities=[];for(let i=0;i<capabilities.length;++i){if(typeof capabilities[i]!=='string'){throw new Error('Emulated device capability must be a string');}
  37. result.capabilities.push(capabilities[i]);}
  38. result.deviceScaleFactor=(parseValue(json['screen'],'device-pixel-ratio','number'));if(result.deviceScaleFactor<0||result.deviceScaleFactor>100){throw new Error('Emulated device has wrong deviceScaleFactor: '+result.deviceScaleFactor);}
  39. result.vertical=parseOrientation(parseValue(json['screen'],'vertical','object'));result.horizontal=parseOrientation(parseValue(json['screen'],'horizontal','object'));const modes=parseValue(json,'modes','object',[]);if(!Array.isArray(modes)){throw new Error('Emulated device modes must be an array');}
  40. result.modes=[];for(let i=0;i<modes.length;++i){const mode={};mode.title=(parseValue(modes[i],'title','string'));mode.orientation=(parseValue(modes[i],'orientation','string'));if(mode.orientation!==Emulation.EmulatedDevice.Vertical&&mode.orientation!==Emulation.EmulatedDevice.Horizontal){throw new Error('Emulated device mode has wrong orientation \''+mode.orientation+'\'');}
  41. const orientation=result.orientationByName(mode.orientation);mode.insets=parseInsets(parseValue(modes[i],'insets','object'));if(mode.insets.top<0||mode.insets.left<0||mode.insets.right<0||mode.insets.bottom<0||mode.insets.top+mode.insets.bottom>orientation.height||mode.insets.left+mode.insets.right>orientation.width){throw new Error('Emulated device mode \''+mode.title+'\'has wrong mode insets');}
  42. mode.image=(parseValue(modes[i],'image','string',null));result.modes.push(mode);}
  43. result._showByDefault=(parseValue(json,'show-by-default','boolean',undefined));result._show=(parseValue(json,'show','string',Emulation.EmulatedDevice._Show.Default));return result;}catch(e){return null;}}
  44. static deviceComparator(device1,device2){const order1=(device1._extension&&device1._extension.descriptor()['order'])||-1;const order2=(device2._extension&&device2._extension.descriptor()['order'])||-1;if(order1>order2){return 1;}
  45. if(order2>order1){return-1;}
  46. return device1.title<device2.title?-1:(device1.title>device2.title?1:0);}
  47. extension(){return this._extension;}
  48. setExtension(extension){this._extension=extension;}
  49. modesForOrientation(orientation){const result=[];for(let index=0;index<this.modes.length;index++){if(this.modes[index].orientation===orientation){result.push(this.modes[index]);}}
  50. return result;}
  51. _toJSON(){const json={};json['title']=this.title;json['type']=this.type;json['user-agent']=this.userAgent;json['capabilities']=this.capabilities;json['screen']={};json['screen']['device-pixel-ratio']=this.deviceScaleFactor;json['screen']['vertical']=this._orientationToJSON(this.vertical);json['screen']['horizontal']=this._orientationToJSON(this.horizontal);json['modes']=[];for(let i=0;i<this.modes.length;++i){const mode={};mode['title']=this.modes[i].title;mode['orientation']=this.modes[i].orientation;mode['insets']={};mode['insets']['left']=this.modes[i].insets.left;mode['insets']['top']=this.modes[i].insets.top;mode['insets']['right']=this.modes[i].insets.right;mode['insets']['bottom']=this.modes[i].insets.bottom;if(this.modes[i].image){mode['image']=this.modes[i].image;}
  52. json['modes'].push(mode);}
  53. json['show-by-default']=this._showByDefault;json['show']=this._show;return json;}
  54. _orientationToJSON(orientation){const json={};json['width']=orientation.width;json['height']=orientation.height;if(orientation.outlineInsets){json['outline']={};json['outline']['insets']={};json['outline']['insets']['left']=orientation.outlineInsets.left;json['outline']['insets']['top']=orientation.outlineInsets.top;json['outline']['insets']['right']=orientation.outlineInsets.right;json['outline']['insets']['bottom']=orientation.outlineInsets.bottom;json['outline']['image']=orientation.outlineImage;}
  55. return json;}
  56. modeImage(mode){if(!mode.image){return'';}
  57. if(!this._extension){return mode.image;}
  58. return this._extension.module().substituteURL(mode.image);}
  59. outlineImage(mode){const orientation=this.orientationByName(mode.orientation);if(!orientation.outlineImage){return'';}
  60. if(!this._extension){return orientation.outlineImage;}
  61. return this._extension.module().substituteURL(orientation.outlineImage);}
  62. orientationByName(name){return name===Emulation.EmulatedDevice.Vertical?this.vertical:this.horizontal;}
  63. show(){if(this._show===Emulation.EmulatedDevice._Show.Default){return this._showByDefault;}
  64. return this._show===Emulation.EmulatedDevice._Show.Always;}
  65. setShow(show){this._show=show?Emulation.EmulatedDevice._Show.Always:Emulation.EmulatedDevice._Show.Never;}
  66. copyShowFrom(other){this._show=other._show;}
  67. touch(){return this.capabilities.indexOf(Emulation.EmulatedDevice.Capability.Touch)!==-1;}
  68. mobile(){return this.capabilities.indexOf(Emulation.EmulatedDevice.Capability.Mobile)!==-1;}};Emulation.EmulatedDevice.Mode;Emulation.EmulatedDevice.Orientation;Emulation.EmulatedDevice.Horizontal='horizontal';Emulation.EmulatedDevice.Vertical='vertical';Emulation.EmulatedDevice.Type={Phone:'phone',Tablet:'tablet',Notebook:'notebook',Desktop:'desktop',Unknown:'unknown'};Emulation.EmulatedDevice.Capability={Touch:'touch',Mobile:'mobile'};Emulation.EmulatedDevice._Show={Always:'Always',Default:'Default',Never:'Never'};Emulation.EmulatedDevicesList=class extends Common.Object{constructor(){super();this._standardSetting=Common.settings.createSetting('standardEmulatedDeviceList',[]);this._standard=[];this._listFromJSONV1(this._standardSetting.get(),this._standard);this._updateStandardDevices();this._customSetting=Common.settings.createSetting('customEmulatedDeviceList',[]);this._custom=[];if(!this._listFromJSONV1(this._customSetting.get(),this._custom)){this.saveCustomDevices();}}
  69. static instance(){if(!Emulation.EmulatedDevicesList._instance){Emulation.EmulatedDevicesList._instance=new Emulation.EmulatedDevicesList();}
  70. return(Emulation.EmulatedDevicesList._instance);}
  71. _updateStandardDevices(){const devices=[];const extensions=self.runtime.extensions('emulated-device');for(let i=0;i<extensions.length;++i){const device=Emulation.EmulatedDevice.fromJSONV1(extensions[i].descriptor()['device']);device.setExtension(extensions[i]);devices.push(device);}
  72. this._copyShowValues(this._standard,devices);this._standard=devices;this.saveStandardDevices();}
  73. _listFromJSONV1(jsonArray,result){if(!Array.isArray(jsonArray)){return false;}
  74. let success=true;for(let i=0;i<jsonArray.length;++i){const device=Emulation.EmulatedDevice.fromJSONV1(jsonArray[i]);if(device){result.push(device);if(!device.modes.length){device.modes.push({title:'',orientation:Emulation.EmulatedDevice.Horizontal,insets:new UI.Insets(0,0,0,0),image:null});device.modes.push({title:'',orientation:Emulation.EmulatedDevice.Vertical,insets:new UI.Insets(0,0,0,0),image:null});}}else{success=false;}}
  75. return success;}
  76. standard(){return this._standard;}
  77. custom(){return this._custom;}
  78. revealCustomSetting(){Common.Revealer.reveal(this._customSetting);}
  79. addCustomDevice(device){this._custom.push(device);this.saveCustomDevices();}
  80. removeCustomDevice(device){this._custom.remove(device);this.saveCustomDevices();}
  81. saveCustomDevices(){const json=this._custom.map(function(device){return device._toJSON();});this._customSetting.set(json);this.dispatchEventToListeners(Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated);}
  82. saveStandardDevices(){const json=this._standard.map(function(device){return device._toJSON();});this._standardSetting.set(json);this.dispatchEventToListeners(Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated);}
  83. _copyShowValues(from,to){const deviceById=new Map();for(let i=0;i<from.length;++i){deviceById.set(from[i].title,from[i]);}
  84. for(let i=0;i<to.length;++i){const title=to[i].title;if(deviceById.has(title)){to[i].copyShowFrom((deviceById.get(title)));}}}};Emulation.EmulatedDevicesList.Events={CustomDevicesUpdated:Symbol('CustomDevicesUpdated'),StandardDevicesUpdated:Symbol('StandardDevicesUpdated')};Emulation.EmulatedDevicesList._instance;;Emulation.DevicesSettingsTab=class extends UI.VBox{constructor(){super();this.element.classList.add('settings-tab-container');this.element.classList.add('devices-settings-tab');this.registerRequiredCSS('emulation/devicesSettingsTab.css');const header=this.element.createChild('header');header.createChild('h1').createTextChild(ls`Emulated Devices`);this.containerElement=this.element.createChild('div','settings-container-wrapper').createChild('div','settings-tab settings-content settings-container');const buttonsRow=this.containerElement.createChild('div','devices-button-row');this._addCustomButton=UI.createTextButton(Common.UIString('Add custom device...'),this._addCustomDevice.bind(this));buttonsRow.appendChild(this._addCustomButton);this._list=new UI.ListWidget(this);this._list.registerRequiredCSS('emulation/devicesSettingsTab.css');this._list.element.classList.add('devices-list');this._list.show(this.containerElement);this._muteUpdate=false;this._emulatedDevicesList=Emulation.EmulatedDevicesList.instance();this._emulatedDevicesList.addEventListener(Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated,this._devicesUpdated,this);this._emulatedDevicesList.addEventListener(Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated,this._devicesUpdated,this);this.setDefaultFocusedElement(this._addCustomButton);}
  85. wasShown(){super.wasShown();this._devicesUpdated();}
  86. _devicesUpdated(){if(this._muteUpdate){return;}
  87. this._list.clear();let devices=this._emulatedDevicesList.custom().slice();for(let i=0;i<devices.length;++i){this._list.appendItem(devices[i],true);}
  88. this._list.appendSeparator();devices=this._emulatedDevicesList.standard().slice();devices.sort(Emulation.EmulatedDevice.deviceComparator);for(let i=0;i<devices.length;++i){this._list.appendItem(devices[i],false);}}
  89. _muteAndSaveDeviceList(custom){this._muteUpdate=true;if(custom){this._emulatedDevicesList.saveCustomDevices();}else{this._emulatedDevicesList.saveStandardDevices();}
  90. this._muteUpdate=false;}
  91. _addCustomDevice(){const device=new Emulation.EmulatedDevice();device.deviceScaleFactor=0;device.horizontal.width=700;device.horizontal.height=400;device.vertical.width=400;device.vertical.height=700;this._list.addNewItem(this._emulatedDevicesList.custom().length,device);}
  92. _toNumericInputValue(value){return value?String(value):'';}
  93. renderItem(item,editable){const device=(item);const element=createElementWithClass('div','devices-list-item');const checkbox=element.createChild('input','devices-list-checkbox');checkbox.type='checkbox';checkbox.checked=device.show();checkbox.addEventListener('click',event=>event.consume(),false);element.createChild('div','devices-list-title').textContent=device.title;element.addEventListener('click',onItemClicked.bind(this),false);return element;function onItemClicked(event){const show=!checkbox.checked;device.setShow(show);this._muteAndSaveDeviceList(editable);checkbox.checked=show;event.consume();}}
  94. removeItemRequested(item,index){this._emulatedDevicesList.removeCustomDevice((item));}
  95. commitEdit(item,editor,isNew){const device=(item);device.title=editor.control('title').value.trim();device.vertical.width=editor.control('width').value?parseInt(editor.control('width').value,10):0;device.vertical.height=editor.control('height').value?parseInt(editor.control('height').value,10):0;device.horizontal.width=device.vertical.height;device.horizontal.height=device.vertical.width;device.deviceScaleFactor=editor.control('scale').value?parseFloat(editor.control('scale').value):0;device.userAgent=editor.control('user-agent').value;device.modes=[];device.modes.push({title:'',orientation:Emulation.EmulatedDevice.Vertical,insets:new UI.Insets(0,0,0,0),image:null});device.modes.push({title:'',orientation:Emulation.EmulatedDevice.Horizontal,insets:new UI.Insets(0,0,0,0),image:null});device.capabilities=[];const uaType=editor.control('ua-type').value;if(uaType===Emulation.DeviceModeModel.UA.Mobile||uaType===Emulation.DeviceModeModel.UA.MobileNoTouch){device.capabilities.push(Emulation.EmulatedDevice.Capability.Mobile);}
  96. if(uaType===Emulation.DeviceModeModel.UA.Mobile||uaType===Emulation.DeviceModeModel.UA.DesktopTouch){device.capabilities.push(Emulation.EmulatedDevice.Capability.Touch);}
  97. if(isNew){this._emulatedDevicesList.addCustomDevice(device);}else{this._emulatedDevicesList.saveCustomDevices();}
  98. this._addCustomButton.scrollIntoViewIfNeeded();this._addCustomButton.focus();}
  99. beginEdit(item){const device=(item);const editor=this._createEditor();editor.control('title').value=device.title;editor.control('width').value=this._toNumericInputValue(device.vertical.width);editor.control('height').value=this._toNumericInputValue(device.vertical.height);editor.control('scale').value=this._toNumericInputValue(device.deviceScaleFactor);editor.control('user-agent').value=device.userAgent;let uaType;if(device.mobile()){uaType=device.touch()?Emulation.DeviceModeModel.UA.Mobile:Emulation.DeviceModeModel.UA.MobileNoTouch;}else{uaType=device.touch()?Emulation.DeviceModeModel.UA.DesktopTouch:Emulation.DeviceModeModel.UA.Desktop;}
  100. editor.control('ua-type').value=uaType;return editor;}
  101. _createEditor(){if(this._editor){return this._editor;}
  102. const editor=new UI.ListWidget.Editor();this._editor=editor;const content=editor.contentElement();const fields=content.createChild('div','devices-edit-fields');fields.createChild('div','hbox').appendChild(editor.createInput('title','text',ls`Device Name`,titleValidator));const screen=fields.createChild('div','hbox');screen.appendChild(editor.createInput('width','text',ls`Width`,widthValidator));screen.appendChild(editor.createInput('height','text',ls`Height`,heightValidator));const dpr=editor.createInput('scale','text',ls`Device pixel ratio`,scaleValidator);dpr.classList.add('device-edit-fixed');screen.appendChild(dpr);const ua=fields.createChild('div','hbox');ua.appendChild(editor.createInput('user-agent','text',ls`User agent string`,()=>{return{valid:true};}));const uaTypeOptions=[Emulation.DeviceModeModel.UA.Mobile,Emulation.DeviceModeModel.UA.MobileNoTouch,Emulation.DeviceModeModel.UA.Desktop,Emulation.DeviceModeModel.UA.DesktopTouch];const uaType=editor.createSelect('ua-type',uaTypeOptions,()=>{return{valid:true};},ls`User agent type`);uaType.classList.add('device-edit-fixed');ua.appendChild(uaType);return editor;function titleValidator(item,index,input){let valid=false;let errorMessage;const value=input.value.trim();if(value.length>=Emulation.DeviceModeModel.MaxDeviceNameLength){errorMessage=ls`Device name must be less than ${Emulation.DeviceModeModel.MaxDeviceNameLength} characters.`;}else if(value.length===0){errorMessage=ls`Device name cannot be empty.`;}else{valid=true;}
  103. return{valid,errorMessage};}
  104. function widthValidator(item,index,input){return Emulation.DeviceModeModel.widthValidator(input.value);}
  105. function heightValidator(item,index,input){return Emulation.DeviceModeModel.heightValidator(input.value);}
  106. function scaleValidator(item,index,input){return Emulation.DeviceModeModel.scaleValidator(input.value);}}};;Emulation.InspectedPagePlaceholder=class extends UI.Widget{constructor(){super(true);this.registerRequiredCSS('emulation/inspectedPagePlaceholder.css');UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged,this.onResize,this);this.restoreMinimumSize();}
  107. onResize(){if(this._updateId){this.element.window().cancelAnimationFrame(this._updateId);}
  108. this._updateId=this.element.window().requestAnimationFrame(this.update.bind(this,false));}
  109. restoreMinimumSize(){this.setMinimumSize(150,150);}
  110. clearMinimumSize(){this.setMinimumSize(1,1);}
  111. _dipPageRect(){const zoomFactor=UI.zoomManager.zoomFactor();const rect=this.element.getBoundingClientRect();const bodyRect=this.element.ownerDocument.body.getBoundingClientRect();const left=Math.max(rect.left*zoomFactor,bodyRect.left*zoomFactor);const top=Math.max(rect.top*zoomFactor,bodyRect.top*zoomFactor);const bottom=Math.min(rect.bottom*zoomFactor,bodyRect.bottom*zoomFactor);const right=Math.min(rect.right*zoomFactor,bodyRect.right*zoomFactor);return{x:left,y:top,width:right-left,height:bottom-top};}
  112. update(force){delete this._updateId;const rect=this._dipPageRect();const bounds={x:Math.round(rect.x),y:Math.round(rect.y),height:Math.max(1,Math.round(rect.height)),width:Math.max(1,Math.round(rect.width)),};if(force){--bounds.height;this.dispatchEventToListeners(Emulation.InspectedPagePlaceholder.Events.Update,bounds);++bounds.height;}
  113. this.dispatchEventToListeners(Emulation.InspectedPagePlaceholder.Events.Update,bounds);}};Emulation.InspectedPagePlaceholder.instance=function(){return self.singleton(Emulation.InspectedPagePlaceholder);};Emulation.InspectedPagePlaceholder.Events={Update:Symbol('Update')};;Emulation.MediaQueryInspector=class extends UI.Widget{constructor(getWidthCallback,setWidthCallback){super(true);this.registerRequiredCSS('emulation/mediaQueryInspector.css');this.contentElement.classList.add('media-inspector-view');this.contentElement.addEventListener('click',this._onMediaQueryClicked.bind(this),false);this.contentElement.addEventListener('contextmenu',this._onContextMenu.bind(this),false);this._mediaThrottler=new Common.Throttler(0);this._getWidthCallback=getWidthCallback;this._setWidthCallback=setWidthCallback;this._scale=1;SDK.targetManager.observeModels(SDK.CSSModel,this);UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged,this._renderMediaQueries.bind(this),this);}
  114. modelAdded(cssModel){if(this._cssModel){return;}
  115. this._cssModel=cssModel;this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetAdded,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetRemoved,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(SDK.CSSModel.Events.StyleSheetChanged,this._scheduleMediaQueriesUpdate,this);this._cssModel.addEventListener(SDK.CSSModel.Events.MediaQueryResultChanged,this._scheduleMediaQueriesUpdate,this);}
  116. modelRemoved(cssModel){if(cssModel!==this._cssModel){return;}
  117. this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetAdded,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetRemoved,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(SDK.CSSModel.Events.StyleSheetChanged,this._scheduleMediaQueriesUpdate,this);this._cssModel.removeEventListener(SDK.CSSModel.Events.MediaQueryResultChanged,this._scheduleMediaQueriesUpdate,this);delete this._cssModel;}
  118. setAxisTransform(scale){if(Math.abs(this._scale-scale)<1e-8){return;}
  119. this._scale=scale;this._renderMediaQueries();}
  120. _onMediaQueryClicked(event){const mediaQueryMarker=event.target.enclosingNodeOrSelfWithClass('media-inspector-bar');if(!mediaQueryMarker){return;}
  121. const model=mediaQueryMarker._model;if(model.section()===Emulation.MediaQueryInspector.Section.Max){this._setWidthCallback(model.maxWidthExpression().computedLength());return;}
  122. if(model.section()===Emulation.MediaQueryInspector.Section.Min){this._setWidthCallback(model.minWidthExpression().computedLength());return;}
  123. const currentWidth=this._getWidthCallback();if(currentWidth!==model.minWidthExpression().computedLength()){this._setWidthCallback(model.minWidthExpression().computedLength());}else{this._setWidthCallback(model.maxWidthExpression().computedLength());}}
  124. _onContextMenu(event){if(!this._cssModel||!this._cssModel.isEnabled()){return;}
  125. const mediaQueryMarker=event.target.enclosingNodeOrSelfWithClass('media-inspector-bar');if(!mediaQueryMarker){return;}
  126. const locations=mediaQueryMarker._locations;const uiLocations=new Map();for(let i=0;i<locations.length;++i){const uiLocation=Bindings.cssWorkspaceBinding.rawLocationToUILocation(locations[i]);if(!uiLocation){continue;}
  127. const descriptor=String.sprintf('%s:%d:%d',uiLocation.uiSourceCode.url(),uiLocation.lineNumber+1,uiLocation.columnNumber+1);uiLocations.set(descriptor,uiLocation);}
  128. const contextMenuItems=uiLocations.keysArray().sort();const contextMenu=new UI.ContextMenu(event);const subMenuItem=contextMenu.defaultSection().appendSubMenuItem(Common.UIString('Reveal in source code'));for(let i=0;i<contextMenuItems.length;++i){const title=contextMenuItems[i];subMenuItem.defaultSection().appendItem(title,this._revealSourceLocation.bind(this,(uiLocations.get(title))));}
  129. contextMenu.show();}
  130. _revealSourceLocation(location){Common.Revealer.reveal(location);}
  131. _scheduleMediaQueriesUpdate(){if(!this.isShowing()){return;}
  132. this._mediaThrottler.schedule(this._refetchMediaQueries.bind(this));}
  133. _refetchMediaQueries(){if(!this.isShowing()||!this._cssModel){return Promise.resolve();}
  134. return this._cssModel.mediaQueriesPromise().then(this._rebuildMediaQueries.bind(this));}
  135. _squashAdjacentEqual(models){const filtered=[];for(let i=0;i<models.length;++i){const last=filtered.peekLast();if(!last||!last.equals(models[i])){filtered.push(models[i]);}}
  136. return filtered;}
  137. _rebuildMediaQueries(cssMedias){let queryModels=[];for(let i=0;i<cssMedias.length;++i){const cssMedia=cssMedias[i];if(!cssMedia.mediaList){continue;}
  138. for(let j=0;j<cssMedia.mediaList.length;++j){const mediaQuery=cssMedia.mediaList[j];const queryModel=Emulation.MediaQueryInspector.MediaQueryUIModel.createFromMediaQuery(cssMedia,mediaQuery);if(queryModel&&queryModel.rawLocation()){queryModels.push(queryModel);}}}
  139. queryModels.sort(compareModels);queryModels=this._squashAdjacentEqual(queryModels);let allEqual=this._cachedQueryModels&&this._cachedQueryModels.length===queryModels.length;for(let i=0;allEqual&&i<queryModels.length;++i){allEqual=allEqual&&this._cachedQueryModels[i].equals(queryModels[i]);}
  140. if(allEqual){return;}
  141. this._cachedQueryModels=queryModels;this._renderMediaQueries();function compareModels(model1,model2){return model1.compareTo(model2);}}
  142. _renderMediaQueries(){if(!this._cachedQueryModels||!this.isShowing()){return;}
  143. const markers=[];let lastMarker=null;for(let i=0;i<this._cachedQueryModels.length;++i){const model=this._cachedQueryModels[i];if(lastMarker&&lastMarker.model.dimensionsEqual(model)){lastMarker.locations.push(model.rawLocation());lastMarker.active=lastMarker.active||model.active();}else{lastMarker={active:model.active(),model:model,locations:[model.rawLocation()]};markers.push(lastMarker);}}
  144. this.contentElement.removeChildren();let container=null;for(let i=0;i<markers.length;++i){if(!i||markers[i].model.section()!==markers[i-1].model.section()){container=this.contentElement.createChild('div','media-inspector-marker-container');}
  145. const marker=markers[i];const bar=this._createElementFromMediaQueryModel(marker.model);bar._model=marker.model;bar._locations=marker.locations;bar.classList.toggle('media-inspector-marker-inactive',!marker.active);container.appendChild(bar);}}
  146. _zoomFactor(){return UI.zoomManager.zoomFactor()/this._scale;}
  147. wasShown(){this._scheduleMediaQueriesUpdate();}
  148. _createElementFromMediaQueryModel(model){const zoomFactor=this._zoomFactor();const minWidthValue=model.minWidthExpression()?model.minWidthExpression().computedLength()/zoomFactor:0;const maxWidthValue=model.maxWidthExpression()?model.maxWidthExpression().computedLength()/zoomFactor:0;const result=createElementWithClass('div','media-inspector-bar');if(model.section()===Emulation.MediaQueryInspector.Section.Max){result.createChild('div','media-inspector-marker-spacer');const markerElement=result.createChild('div','media-inspector-marker media-inspector-marker-max-width');markerElement.style.width=maxWidthValue+'px';markerElement.title=model.mediaText();appendLabel(markerElement,model.maxWidthExpression(),false,false);appendLabel(markerElement,model.maxWidthExpression(),true,true);result.createChild('div','media-inspector-marker-spacer');}
  149. if(model.section()===Emulation.MediaQueryInspector.Section.MinMax){result.createChild('div','media-inspector-marker-spacer');const leftElement=result.createChild('div','media-inspector-marker media-inspector-marker-min-max-width');leftElement.style.width=(maxWidthValue-minWidthValue)*0.5+'px';leftElement.title=model.mediaText();appendLabel(leftElement,model.minWidthExpression(),true,false);appendLabel(leftElement,model.maxWidthExpression(),false,true);result.createChild('div','media-inspector-marker-spacer').style.flex='0 0 '+minWidthValue+'px';const rightElement=result.createChild('div','media-inspector-marker media-inspector-marker-min-max-width');rightElement.style.width=(maxWidthValue-minWidthValue)*0.5+'px';rightElement.title=model.mediaText();appendLabel(rightElement,model.minWidthExpression(),true,false);appendLabel(rightElement,model.maxWidthExpression(),false,true);result.createChild('div','media-inspector-marker-spacer');}
  150. if(model.section()===Emulation.MediaQueryInspector.Section.Min){const leftElement=result.createChild('div','media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-left');leftElement.title=model.mediaText();appendLabel(leftElement,model.minWidthExpression(),false,false);result.createChild('div','media-inspector-marker-spacer').style.flex='0 0 '+minWidthValue+'px';const rightElement=result.createChild('div','media-inspector-marker media-inspector-marker-min-width media-inspector-marker-min-width-right');rightElement.title=model.mediaText();appendLabel(rightElement,model.minWidthExpression(),true,true);}
  151. function appendLabel(marker,expression,atLeft,leftAlign){marker.createChild('div','media-inspector-marker-label-container '+(atLeft?'media-inspector-marker-label-container-left':'media-inspector-marker-label-container-right')).createChild('span','media-inspector-marker-label '+
  152. (leftAlign?'media-inspector-label-left':'media-inspector-label-right')).textContent=expression.value()+expression.unit();}
  153. return result;}};Emulation.MediaQueryInspector.Section={Max:0,MinMax:1,Min:2};Emulation.MediaQueryInspector.MediaQueryUIModel=class{constructor(cssMedia,minWidthExpression,maxWidthExpression,active){this._cssMedia=cssMedia;this._minWidthExpression=minWidthExpression;this._maxWidthExpression=maxWidthExpression;this._active=active;if(maxWidthExpression&&!minWidthExpression){this._section=Emulation.MediaQueryInspector.Section.Max;}else if(minWidthExpression&&maxWidthExpression){this._section=Emulation.MediaQueryInspector.Section.MinMax;}else{this._section=Emulation.MediaQueryInspector.Section.Min;}}
  154. static createFromMediaQuery(cssMedia,mediaQuery){let maxWidthExpression=null;let maxWidthPixels=Number.MAX_VALUE;let minWidthExpression=null;let minWidthPixels=Number.MIN_VALUE;const expressions=mediaQuery.expressions();for(let i=0;i<expressions.length;++i){const expression=expressions[i];const feature=expression.feature();if(feature.indexOf('width')===-1){continue;}
  155. const pixels=expression.computedLength();if(feature.startsWith('max-')&&pixels<maxWidthPixels){maxWidthExpression=expression;maxWidthPixels=pixels;}else if(feature.startsWith('min-')&&pixels>minWidthPixels){minWidthExpression=expression;minWidthPixels=pixels;}}
  156. if(minWidthPixels>maxWidthPixels||(!maxWidthExpression&&!minWidthExpression)){return null;}
  157. return new Emulation.MediaQueryInspector.MediaQueryUIModel(cssMedia,minWidthExpression,maxWidthExpression,mediaQuery.active());}
  158. equals(other){return this.compareTo(other)===0;}
  159. dimensionsEqual(other){return this.section()===other.section()&&(!this.minWidthExpression()||(this.minWidthExpression().computedLength()===other.minWidthExpression().computedLength()))&&(!this.maxWidthExpression()||(this.maxWidthExpression().computedLength()===other.maxWidthExpression().computedLength()));}
  160. compareTo(other){if(this.section()!==other.section()){return this.section()-other.section();}
  161. if(this.dimensionsEqual(other)){const myLocation=this.rawLocation();const otherLocation=other.rawLocation();if(!myLocation&&!otherLocation){return this.mediaText().compareTo(other.mediaText());}
  162. if(myLocation&&!otherLocation){return 1;}
  163. if(!myLocation&&otherLocation){return-1;}
  164. if(this.active()!==other.active()){return this.active()?-1:1;}
  165. return myLocation.url.compareTo(otherLocation.url)||myLocation.lineNumber-otherLocation.lineNumber||myLocation.columnNumber-otherLocation.columnNumber;}
  166. if(this.section()===Emulation.MediaQueryInspector.Section.Max){return other.maxWidthExpression().computedLength()-this.maxWidthExpression().computedLength();}
  167. if(this.section()===Emulation.MediaQueryInspector.Section.Min){return this.minWidthExpression().computedLength()-other.minWidthExpression().computedLength();}
  168. return this.minWidthExpression().computedLength()-other.minWidthExpression().computedLength()||other.maxWidthExpression().computedLength()-this.maxWidthExpression().computedLength();}
  169. section(){return this._section;}
  170. mediaText(){return this._cssMedia.text;}
  171. rawLocation(){if(!this._rawLocation){this._rawLocation=this._cssMedia.rawLocation();}
  172. return this._rawLocation;}
  173. minWidthExpression(){return this._minWidthExpression;}
  174. maxWidthExpression(){return this._maxWidthExpression;}
  175. active(){return this._active;}};;Emulation.SensorsView=class extends UI.VBox{constructor(){super(true);this.registerRequiredCSS('emulation/sensors.css');this.contentElement.classList.add('sensors-view');this._geolocationSetting=Common.settings.createSetting('emulation.geolocationOverride','');this._geolocation=SDK.EmulationModel.Geolocation.parseSetting(this._geolocationSetting.get());this._geolocationOverrideEnabled=false;this._createGeolocationSection(this._geolocation);this.contentElement.createChild('div').classList.add('panel-section-separator');this._deviceOrientationSetting=Common.settings.createSetting('emulation.deviceOrientationOverride','');this._deviceOrientation=SDK.EmulationModel.DeviceOrientation.parseSetting(this._deviceOrientationSetting.get());this._deviceOrientationOverrideEnabled=false;this._createDeviceOrientationSection();this.contentElement.createChild('div').classList.add('panel-section-separator');this._appendTouchControl();}
  176. static instance(){if(!Emulation.SensorsView._instanceObject){Emulation.SensorsView._instanceObject=new Emulation.SensorsView();}
  177. return Emulation.SensorsView._instanceObject;}
  178. _createGeolocationSection(geolocation){const geogroup=this.contentElement.createChild('section','sensors-group');const geogroupTitle=UI.createLabel(ls`Geolocation`,'sensors-group-title');geogroup.appendChild(geogroupTitle);const fields=geogroup.createChild('div','geo-fields');const noOverrideOption={title:Common.UIString('No override'),location:Emulation.SensorsView.NonPresetOptions.NoOverride};this._locationSelectElement=fields.createChild('select','chrome-select');UI.ARIAUtils.bindLabelToControl(geogroupTitle,this._locationSelectElement);this._locationSelectElement.appendChild(new Option(noOverrideOption.title,noOverrideOption.location));this._customLocationsGroup=this._locationSelectElement.createChild('optgroup');this._customLocationsGroup.label=ls`Overrides`;const customGeolocations=Common.moduleSetting('emulation.geolocations');const manageButton=UI.createTextButton(ls`Manage`,()=>Common.Revealer.reveal(customGeolocations));UI.ARIAUtils.setAccessibleName(manageButton,ls`Manage the list of geolocations`);fields.appendChild(manageButton);const fillCustomSettings=()=>{this._customLocationsGroup.removeChildren();for(const geolocation of customGeolocations.get()){this._customLocationsGroup.appendChild(new Option(geolocation.title,JSON.stringify(geolocation)));}};customGeolocations.addChangeListener(fillCustomSettings);fillCustomSettings();const customLocationOption={title:Common.UIString('Other\u2026'),location:Emulation.SensorsView.NonPresetOptions.Custom};this._locationSelectElement.appendChild(new Option(customLocationOption.title,customLocationOption.location));const group=this._locationSelectElement.createChild('optgroup');group.label=ls`Error`;group.appendChild(new Option(ls`Location unavailable`,Emulation.SensorsView.NonPresetOptions.Unavailable));this._locationSelectElement.selectedIndex=0;this._locationSelectElement.addEventListener('change',this._geolocationSelectChanged.bind(this));this._fieldsetElement=fields.createChild('fieldset');this._fieldsetElement.disabled=!this._geolocationOverrideEnabled;this._fieldsetElement.id='geolocation-override-section';const latitudeGroup=this._fieldsetElement.createChild('div','latlong-group');const longitudeGroup=this._fieldsetElement.createChild('div','latlong-group');const timezoneGroup=this._fieldsetElement.createChild('div','latlong-group');const cmdOrCtrl=Host.isMac()?'\u2318':'Ctrl';const modifierKeyMessage=ls`Adjust with mousewheel or up/down keys. ${cmdOrCtrl}: ±10, Shift: ±1, Alt: ±0.01`;this._latitudeInput=UI.createInput('','number');latitudeGroup.appendChild(this._latitudeInput);this._latitudeInput.setAttribute('step','any');this._latitudeInput.value=0;this._latitudeSetter=UI.bindInput(this._latitudeInput,this._applyGeolocationUserInput.bind(this),SDK.EmulationModel.Geolocation.latitudeValidator,true,0.1);this._latitudeSetter(String(geolocation.latitude));this._latitudeInput.title=modifierKeyMessage;latitudeGroup.appendChild(UI.createLabel(ls`Latitude`,'latlong-title',this._latitudeInput));this._longitudeInput=UI.createInput('','number');longitudeGroup.appendChild(this._longitudeInput);this._longitudeInput.setAttribute('step','any');this._longitudeInput.value=0;this._longitudeSetter=UI.bindInput(this._longitudeInput,this._applyGeolocationUserInput.bind(this),SDK.EmulationModel.Geolocation.longitudeValidator,true,0.1);this._longitudeSetter(String(geolocation.longitude));this._longitudeInput.title=modifierKeyMessage;longitudeGroup.appendChild(UI.createLabel(ls`Longitude`,'latlong-title',this._longitudeInput));this._timezoneInput=UI.createInput('','text');timezoneGroup.appendChild(this._timezoneInput);this._timezoneInput.value='Europe/Berlin';this._timezoneSetter=UI.bindInput(this._timezoneInput,this._applyGeolocationUserInput.bind(this),SDK.EmulationModel.Geolocation.timezoneIdValidator,false);this._timezoneSetter(String(geolocation.timezoneId));timezoneGroup.appendChild(UI.createLabel(ls`Timezone ID`,'timezone-title',this._timezoneInput));this._timezoneError=timezoneGroup.createChild('div','timezone-error');}
  179. _geolocationSelectChanged(){this._fieldsetElement.disabled=false;this._timezoneError.textContent='';const value=this._locationSelectElement.options[this._locationSelectElement.selectedIndex].value;if(value===Emulation.SensorsView.NonPresetOptions.NoOverride){this._geolocationOverrideEnabled=false;this._fieldsetElement.disabled=true;}else if(value===Emulation.SensorsView.NonPresetOptions.Custom){this._geolocationOverrideEnabled=true;const geolocation=SDK.EmulationModel.Geolocation.parseUserInput(this._latitudeInput.value.trim(),this._longitudeInput.value.trim(),this._timezoneInput.value.trim());if(!geolocation){return;}
  180. this._geolocation=geolocation;}else if(value===Emulation.SensorsView.NonPresetOptions.Unavailable){this._geolocationOverrideEnabled=true;this._geolocation=new SDK.EmulationModel.Geolocation(0,0,'',true);}else{this._geolocationOverrideEnabled=true;const coordinates=JSON.parse(value);this._geolocation=new SDK.EmulationModel.Geolocation(coordinates.lat,coordinates.long,coordinates.timezoneId,false);this._latitudeSetter(coordinates.lat);this._longitudeSetter(coordinates.long);this._timezoneSetter(coordinates.timezoneId);}
  181. this._applyGeolocation();if(value===Emulation.SensorsView.NonPresetOptions.Custom){this._latitudeInput.focus();}}
  182. _applyGeolocationUserInput(){const geolocation=SDK.EmulationModel.Geolocation.parseUserInput(this._latitudeInput.value.trim(),this._longitudeInput.value.trim(),this._timezoneInput.value.trim());if(!geolocation){return;}
  183. this._timezoneError.textContent='';this._setSelectElementLabel(this._locationSelectElement,Emulation.SensorsView.NonPresetOptions.Custom);this._geolocation=geolocation;this._applyGeolocation();}
  184. _applyGeolocation(){if(this._geolocationOverrideEnabled){this._geolocationSetting.set(this._geolocation.toSetting());}
  185. for(const emulationModel of SDK.targetManager.models(SDK.EmulationModel)){emulationModel.emulateGeolocation(this._geolocationOverrideEnabled?this._geolocation:null).catch(err=>{switch(err.type){case'emulation-set-timezone':this._timezoneError.textContent=err.message;break;}});}}
  186. _createDeviceOrientationSection(){const orientationGroup=this.contentElement.createChild('section','sensors-group');const orientationTitle=UI.createLabel(ls`Orientation`,'sensors-group-title');orientationGroup.appendChild(orientationTitle);const orientationContent=orientationGroup.createChild('div','orientation-content');const fields=orientationContent.createChild('div','orientation-fields');const orientationOffOption={title:Common.UIString('Off'),orientation:Emulation.SensorsView.NonPresetOptions.NoOverride};const customOrientationOption={title:Common.UIString('Custom orientation...'),orientation:Emulation.SensorsView.NonPresetOptions.Custom};this._orientationSelectElement=this.contentElement.createChild('select','chrome-select');UI.ARIAUtils.bindLabelToControl(orientationTitle,this._orientationSelectElement);this._orientationSelectElement.appendChild(new Option(orientationOffOption.title,orientationOffOption.orientation));this._orientationSelectElement.appendChild(new Option(customOrientationOption.title,customOrientationOption.orientation));const orientationGroups=Emulation.SensorsView.PresetOrientations;for(let i=0;i<orientationGroups.length;++i){const groupElement=this._orientationSelectElement.createChild('optgroup');groupElement.label=orientationGroups[i].title;const group=orientationGroups[i].value;for(let j=0;j<group.length;++j){groupElement.appendChild(new Option(group[j].title,group[j].orientation));}}
  187. this._orientationSelectElement.selectedIndex=0;fields.appendChild(this._orientationSelectElement);this._orientationSelectElement.addEventListener('change',this._orientationSelectChanged.bind(this));this._deviceOrientationFieldset=this._createDeviceOrientationOverrideElement(this._deviceOrientation);this._stageElement=orientationContent.createChild('div','orientation-stage');this._orientationLayer=this._stageElement.createChild('div','orientation-layer');this._boxElement=this._orientationLayer.createChild('section','orientation-box orientation-element');this._boxElement.createChild('section','orientation-front orientation-element');this._boxElement.createChild('section','orientation-top orientation-element');this._boxElement.createChild('section','orientation-back orientation-element');this._boxElement.createChild('section','orientation-left orientation-element');this._boxElement.createChild('section','orientation-right orientation-element');this._boxElement.createChild('section','orientation-bottom orientation-element');UI.installDragHandle(this._stageElement,this._onBoxDragStart.bind(this),this._onBoxDrag.bind(this),null,'-webkit-grabbing','-webkit-grab');fields.appendChild(this._deviceOrientationFieldset);this._enableOrientationFields(true);this._setBoxOrientation(this._deviceOrientation,false);}
  188. _enableOrientationFields(disable){if(disable){this._deviceOrientationFieldset.disabled=true;this._stageElement.classList.add('disabled');this._stageElement.title=ls`Enable orientation to rotate`;}else{this._deviceOrientationFieldset.disabled=false;this._stageElement.classList.remove('disabled');this._stageElement.title=ls`Shift+drag horizontally to rotate around the y-axis`;}}
  189. _orientationSelectChanged(){const value=this._orientationSelectElement.options[this._orientationSelectElement.selectedIndex].value;this._enableOrientationFields(false);if(value===Emulation.SensorsView.NonPresetOptions.NoOverride){this._deviceOrientationOverrideEnabled=false;this._enableOrientationFields(true);}else if(value===Emulation.SensorsView.NonPresetOptions.Custom){this._deviceOrientationOverrideEnabled=true;this._alphaElement.focus();}else{const parsedValue=JSON.parse(value);this._deviceOrientationOverrideEnabled=true;this._deviceOrientation=new SDK.EmulationModel.DeviceOrientation(parsedValue[0],parsedValue[1],parsedValue[2]);this._setDeviceOrientation(this._deviceOrientation,Emulation.SensorsView.DeviceOrientationModificationSource.SelectPreset);}}
  190. _applyDeviceOrientation(){if(this._deviceOrientationOverrideEnabled){this._deviceOrientationSetting.set(this._deviceOrientation.toSetting());}
  191. for(const emulationModel of SDK.targetManager.models(SDK.EmulationModel)){emulationModel.emulateDeviceOrientation(this._deviceOrientationOverrideEnabled?this._deviceOrientation:null);}}
  192. _setSelectElementLabel(selectElement,labelValue){const optionValues=Array.prototype.map.call(selectElement.options,x=>x.value);selectElement.selectedIndex=optionValues.indexOf(labelValue);}
  193. _applyDeviceOrientationUserInput(){this._setDeviceOrientation(SDK.EmulationModel.DeviceOrientation.parseUserInput(this._alphaElement.value.trim(),this._betaElement.value.trim(),this._gammaElement.value.trim()),Emulation.SensorsView.DeviceOrientationModificationSource.UserInput);this._setSelectElementLabel(this._orientationSelectElement,Emulation.SensorsView.NonPresetOptions.Custom);}
  194. _resetDeviceOrientation(){this._setDeviceOrientation(new SDK.EmulationModel.DeviceOrientation(0,90,0),Emulation.SensorsView.DeviceOrientationModificationSource.ResetButton);this._setSelectElementLabel(this._orientationSelectElement,'[0, 90, 0]');}
  195. _setDeviceOrientation(deviceOrientation,modificationSource){if(!deviceOrientation){return;}
  196. function roundAngle(angle){return Math.round(angle*10000)/10000;}
  197. if(modificationSource!==Emulation.SensorsView.DeviceOrientationModificationSource.UserInput){this._alphaSetter(roundAngle(deviceOrientation.alpha));this._betaSetter(roundAngle(deviceOrientation.beta));this._gammaSetter(roundAngle(deviceOrientation.gamma));}
  198. const animate=modificationSource!==Emulation.SensorsView.DeviceOrientationModificationSource.UserDrag;this._setBoxOrientation(deviceOrientation,animate);this._deviceOrientation=deviceOrientation;this._applyDeviceOrientation();UI.ARIAUtils.alert(ls`Device orientation set to alpha: ${deviceOrientation.alpha}, beta: ${deviceOrientation.beta}, gamma: ${
  199. deviceOrientation.gamma}`,this._orientationSelectElement);}
  200. _createAxisInput(parentElement,input,label){const div=parentElement.createChild('div','orientation-axis-input-container');div.appendChild(input);div.appendChild(UI.createLabel(label,'',input));input.type='number';return UI.bindInput(input,this._applyDeviceOrientationUserInput.bind(this),SDK.EmulationModel.DeviceOrientation.validator,true);}
  201. _createDeviceOrientationOverrideElement(deviceOrientation){const fieldsetElement=createElement('fieldset');fieldsetElement.classList.add('device-orientation-override-section');const cellElement=fieldsetElement.createChild('td','orientation-inputs-cell');this._alphaElement=UI.createInput();this._alphaElement.setAttribute('step','any');this._alphaSetter=this._createAxisInput(cellElement,this._alphaElement,Common.UIString('\u03B1 (alpha)'));this._alphaSetter(String(deviceOrientation.alpha));this._betaElement=UI.createInput();this._betaElement.setAttribute('step','any');this._betaSetter=this._createAxisInput(cellElement,this._betaElement,Common.UIString('\u03B2 (beta)'));this._betaSetter(String(deviceOrientation.beta));this._gammaElement=UI.createInput();this._gammaElement.setAttribute('step','any');this._gammaSetter=this._createAxisInput(cellElement,this._gammaElement,Common.UIString('\u03B3 (gamma)'));this._gammaSetter(String(deviceOrientation.gamma));const resetButton=UI.createTextButton(Common.UIString('Reset'),this._resetDeviceOrientation.bind(this),'orientation-reset-button');UI.ARIAUtils.setAccessibleName(resetButton,ls`Reset device orientation`);resetButton.setAttribute('type','reset');cellElement.appendChild(resetButton);return fieldsetElement;}
  202. _setBoxOrientation(deviceOrientation,animate){if(animate){this._stageElement.classList.add('is-animating');}else{this._stageElement.classList.remove('is-animating');}
  203. const matrix=new WebKitCSSMatrix();this._boxMatrix=matrix.rotate(-deviceOrientation.beta,deviceOrientation.gamma,-deviceOrientation.alpha);const eulerAngles=new UI.Geometry.EulerAngles(deviceOrientation.alpha,deviceOrientation.beta,deviceOrientation.gamma);this._orientationLayer.style.transform=eulerAngles.toRotate3DString();}
  204. _onBoxDrag(event){const mouseMoveVector=this._calculateRadiusVector(event.x,event.y);if(!mouseMoveVector){return true;}
  205. event.consume(true);let axis,angle;if(event.shiftKey){axis=new UI.Geometry.Vector(0,0,-1);angle=(this._mouseDownVector.x-mouseMoveVector.x)*Emulation.SensorsView.ShiftDragOrientationSpeed;}else{axis=UI.Geometry.crossProduct(this._mouseDownVector,mouseMoveVector);angle=UI.Geometry.calculateAngle(this._mouseDownVector,mouseMoveVector);}
  206. let currentMatrix=new WebKitCSSMatrix();currentMatrix=currentMatrix.rotate(-90,0,0).rotateAxisAngle(axis.x,axis.y,axis.z,angle).rotate(90,0,0).multiply(this._originalBoxMatrix);const eulerAngles=UI.Geometry.EulerAngles.fromRotationMatrix(currentMatrix);const newOrientation=new SDK.EmulationModel.DeviceOrientation(-eulerAngles.alpha,-eulerAngles.beta,eulerAngles.gamma);this._setDeviceOrientation(newOrientation,Emulation.SensorsView.DeviceOrientationModificationSource.UserDrag);this._setSelectElementLabel(this._orientationSelectElement,Emulation.SensorsView.NonPresetOptions.Custom);return false;}
  207. _onBoxDragStart(event){if(!this._deviceOrientationOverrideEnabled){return false;}
  208. this._mouseDownVector=this._calculateRadiusVector(event.x,event.y);this._originalBoxMatrix=this._boxMatrix;if(!this._mouseDownVector){return false;}
  209. event.consume(true);return true;}
  210. _calculateRadiusVector(x,y){const rect=this._stageElement.getBoundingClientRect();const radius=Math.max(rect.width,rect.height)/2;const sphereX=(x-rect.left-rect.width/2)/radius;const sphereY=(y-rect.top-rect.height/2)/radius;const sqrSum=sphereX*sphereX+sphereY*sphereY;if(sqrSum>0.5){return new UI.Geometry.Vector(sphereX,sphereY,0.5/Math.sqrt(sqrSum));}
  211. return new UI.Geometry.Vector(sphereX,sphereY,Math.sqrt(1-sqrSum));}
  212. _appendTouchControl(){const groupElement=this.contentElement.createChild('div','sensors-group');const title=UI.createLabel(ls`Touch`,'sensors-group-title');groupElement.appendChild(title);const fieldsElement=groupElement.createChild('div','sensors-group-fields');const select=fieldsElement.createChild('select','chrome-select');UI.ARIAUtils.bindLabelToControl(title,select);select.appendChild(new Option(Common.UIString('Device-based'),'auto'));select.appendChild(new Option(Common.UIString('Force enabled'),'enabled'));select.addEventListener('change',applyTouch,false);const reloadWarning=groupElement.createChild('div','reload-warning hidden');reloadWarning.textContent=Common.UIString('*Requires reload');UI.ARIAUtils.markAsAlert(reloadWarning);function applyTouch(){for(const emulationModel of SDK.targetManager.models(SDK.EmulationModel)){emulationModel.overrideEmulateTouch(select.value==='enabled');}
  213. reloadWarning.classList.remove('hidden');const resourceTreeModel=SDK.targetManager.models(SDK.ResourceTreeModel)[0];if(resourceTreeModel){resourceTreeModel.once(SDK.ResourceTreeModel.Events.MainFrameNavigated).then(()=>reloadWarning.classList.add('hidden'));}}}};Emulation.SensorsView.DeviceOrientationModificationSource={UserInput:'userInput',UserDrag:'userDrag',ResetButton:'resetButton',SelectPreset:'selectPreset'};Emulation.SensorsView.NonPresetOptions={NoOverride:'noOverride',Custom:'custom',Unavailable:'unavailable'};Emulation.SensorsView.PresetOrientations=[{title:ls`Presets`,value:[{title:Common.UIString('Portrait'),orientation:'[0, 90, 0]'},{title:Common.UIString('Portrait upside down'),orientation:'[180, -90, 0]'},{title:Common.UIString('Landscape left'),orientation:'[0, 90, -90]'},{title:Common.UIString('Landscape right'),orientation:'[0, 90, 90]'},{title:Common.UIString('Display up'),orientation:'[0, 0, 0]'},{title:Common.UIString('Display down'),orientation:'[0, 180, 0]'}]}];Emulation.SensorsView.ShowActionDelegate=class{handleAction(context,actionId){UI.viewManager.showView('sensors');return true;}};Emulation.SensorsView.ShiftDragOrientationSpeed=16;;Emulation.DeviceModeModel=class extends Common.Object{constructor(){super();this._screenRect=new UI.Rect(0,0,1,1);this._visiblePageRect=new UI.Rect(0,0,1,1);this._availableSize=new UI.Size(1,1);this._preferredSize=new UI.Size(1,1);this._initialized=false;this._appliedDeviceSize=new UI.Size(1,1);this._appliedDeviceScaleFactor=window.devicePixelRatio;this._appliedUserAgentType=Emulation.DeviceModeModel.UA.Desktop;this._scaleSetting=Common.settings.createSetting('emulation.deviceScale',1);if(!this._scaleSetting.get()){this._scaleSetting.set(1);}
  214. this._scaleSetting.addChangeListener(this._scaleSettingChanged,this);this._widthSetting=Common.settings.createSetting('emulation.deviceWidth',400);if(this._widthSetting.get()<Emulation.DeviceModeModel.MinDeviceSize){this._widthSetting.set(Emulation.DeviceModeModel.MinDeviceSize);}
  215. if(this._widthSetting.get()>Emulation.DeviceModeModel.MaxDeviceSize){this._widthSetting.set(Emulation.DeviceModeModel.MaxDeviceSize);}
  216. this._widthSetting.addChangeListener(this._widthSettingChanged,this);this._heightSetting=Common.settings.createSetting('emulation.deviceHeight',0);if(this._heightSetting.get()&&this._heightSetting.get()<Emulation.DeviceModeModel.MinDeviceSize){this._heightSetting.set(Emulation.DeviceModeModel.MinDeviceSize);}
  217. if(this._heightSetting.get()>Emulation.DeviceModeModel.MaxDeviceSize){this._heightSetting.set(Emulation.DeviceModeModel.MaxDeviceSize);}
  218. this._heightSetting.addChangeListener(this._heightSettingChanged,this);this._uaSetting=Common.settings.createSetting('emulation.deviceUA',Emulation.DeviceModeModel.UA.Mobile);this._uaSetting.addChangeListener(this._uaSettingChanged,this);this._deviceScaleFactorSetting=Common.settings.createSetting('emulation.deviceScaleFactor',0);this._deviceScaleFactorSetting.addChangeListener(this._deviceScaleFactorSettingChanged,this);this._deviceOutlineSetting=Common.settings.moduleSetting('emulation.showDeviceOutline');this._deviceOutlineSetting.addChangeListener(this._deviceOutlineSettingChanged,this);this._toolbarControlsEnabledSetting=Common.settings.createSetting('emulation.toolbarControlsEnabled',true,Common.SettingStorageType.Session);this._type=Emulation.DeviceModeModel.Type.None;this._device=null;this._mode=null;this._fitScale=1;this._touchEnabled=false;this._touchMobile=false;this._emulationModel=null;this._onModelAvailable=null;SDK.targetManager.observeModels(SDK.EmulationModel,this);}
  219. static widthValidator(value){let valid=false;let errorMessage;if(!/^[\d]+$/.test(value)){errorMessage=ls`Width must be a number.`;}else if(value>Emulation.DeviceModeModel.MaxDeviceSize){errorMessage=ls`Width must be less than or equal to ${Emulation.DeviceModeModel.MaxDeviceSize}.`;}else if(value<Emulation.DeviceModeModel.MinDeviceSize){errorMessage=ls`Width must be greater than or equal to ${Emulation.DeviceModeModel.MinDeviceSize}.`;}else{valid=true;}
  220. return{valid,errorMessage};}
  221. static heightValidator(value){let valid=false;let errorMessage;if(!/^[\d]+$/.test(value)){errorMessage=ls`Height must be a number.`;}else if(value>Emulation.DeviceModeModel.MaxDeviceSize){errorMessage=ls`Height must be less than or equal to ${Emulation.DeviceModeModel.MaxDeviceSize}.`;}else if(value<Emulation.DeviceModeModel.MinDeviceSize){errorMessage=ls`Height must be greater than or equal to ${Emulation.DeviceModeModel.MinDeviceSize}.`;}else{valid=true;}
  222. return{valid,errorMessage};}
  223. static scaleValidator(value){let valid=false;let errorMessage;const parsedValue=Number(value.trim());if(!value){valid=true;}else if(Number.isNaN(parsedValue)){errorMessage=ls`Device pixel ratio must be a number or blank.`;}else if(value>Emulation.DeviceModeModel.MaxDeviceScaleFactor){errorMessage=ls`Device pixel ratio must be less than or equal to ${Emulation.DeviceModeModel.MaxDeviceScaleFactor}.`;}else if(value<Emulation.DeviceModeModel.MinDeviceScaleFactor){errorMessage=ls`Device pixel ratio must be greater than or equal to ${Emulation.DeviceModeModel.MinDeviceScaleFactor}.`;}else{valid=true;}
  224. return{valid,errorMessage};}
  225. setAvailableSize(availableSize,preferredSize){this._availableSize=availableSize;this._preferredSize=preferredSize;this._initialized=true;this._calculateAndEmulate(false);}
  226. emulate(type,device,mode,scale){const resetPageScaleFactor=this._type!==type||this._device!==device||this._mode!==mode;this._type=type;if(type===Emulation.DeviceModeModel.Type.Device){console.assert(device&&mode,'Must pass device and mode for device emulation');this._mode=mode;this._device=device;if(this._initialized){const orientation=device.orientationByName(mode.orientation);this._scaleSetting.set(scale||this._calculateFitScale(orientation.width,orientation.height,this._currentOutline(),this._currentInsets()));}}else{this._device=null;this._mode=null;}
  227. if(type!==Emulation.DeviceModeModel.Type.None){Host.userMetrics.actionTaken(Host.UserMetrics.Action.DeviceModeEnabled);}
  228. this._calculateAndEmulate(resetPageScaleFactor);}
  229. setWidth(width){const max=Math.min(Emulation.DeviceModeModel.MaxDeviceSize,this._preferredScaledWidth());width=Math.max(Math.min(width,max),1);this._widthSetting.set(width);}
  230. setWidthAndScaleToFit(width){width=Math.max(Math.min(width,Emulation.DeviceModeModel.MaxDeviceSize),1);this._scaleSetting.set(this._calculateFitScale(width,this._heightSetting.get()));this._widthSetting.set(width);}
  231. setHeight(height){const max=Math.min(Emulation.DeviceModeModel.MaxDeviceSize,this._preferredScaledHeight());height=Math.max(Math.min(height,max),0);if(height===this._preferredScaledHeight()){height=0;}
  232. this._heightSetting.set(height);}
  233. setHeightAndScaleToFit(height){height=Math.max(Math.min(height,Emulation.DeviceModeModel.MaxDeviceSize),0);this._scaleSetting.set(this._calculateFitScale(this._widthSetting.get(),height));this._heightSetting.set(height);}
  234. setScale(scale){this._scaleSetting.set(scale);}
  235. device(){return this._device;}
  236. mode(){return this._mode;}
  237. type(){return this._type;}
  238. screenImage(){return(this._device&&this._mode)?this._device.modeImage(this._mode):'';}
  239. outlineImage(){return(this._device&&this._mode&&this._deviceOutlineSetting.get())?this._device.outlineImage(this._mode):'';}
  240. outlineRect(){return this._outlineRect;}
  241. screenRect(){return this._screenRect;}
  242. visiblePageRect(){return this._visiblePageRect;}
  243. scale(){return this._scale;}
  244. fitScale(){return this._fitScale;}
  245. appliedDeviceSize(){return this._appliedDeviceSize;}
  246. appliedDeviceScaleFactor(){return this._appliedDeviceScaleFactor;}
  247. appliedUserAgentType(){return this._appliedUserAgentType;}
  248. isFullHeight(){return!this._heightSetting.get();}
  249. _isMobile(){switch(this._type){case Emulation.DeviceModeModel.Type.Device:return this._device.mobile();case Emulation.DeviceModeModel.Type.None:return false;case Emulation.DeviceModeModel.Type.Responsive:return this._uaSetting.get()===Emulation.DeviceModeModel.UA.Mobile||this._uaSetting.get()===Emulation.DeviceModeModel.UA.MobileNoTouch;}
  250. return false;}
  251. enabledSetting(){return Common.settings.createSetting('emulation.showDeviceMode',false);}
  252. scaleSetting(){return this._scaleSetting;}
  253. uaSetting(){return this._uaSetting;}
  254. deviceScaleFactorSetting(){return this._deviceScaleFactorSetting;}
  255. deviceOutlineSetting(){return this._deviceOutlineSetting;}
  256. toolbarControlsEnabledSetting(){return this._toolbarControlsEnabledSetting;}
  257. reset(){this._deviceScaleFactorSetting.set(0);this._scaleSetting.set(1);this.setWidth(400);this.setHeight(0);this._uaSetting.set(Emulation.DeviceModeModel.UA.Mobile);}
  258. modelAdded(emulationModel){if(!this._emulationModel&&emulationModel.supportsDeviceEmulation()){this._emulationModel=emulationModel;if(this._onModelAvailable){const callback=this._onModelAvailable;this._onModelAvailable=null;callback();}}else{emulationModel.emulateTouch(this._touchEnabled,this._touchMobile);}}
  259. modelRemoved(emulationModel){if(this._emulationModel===emulationModel){this._emulationModel=null;}}
  260. inspectedURL(){return this._emulationModel?this._emulationModel.target().inspectedURL():null;}
  261. _scaleSettingChanged(){this._calculateAndEmulate(false);}
  262. _widthSettingChanged(){this._calculateAndEmulate(false);}
  263. _heightSettingChanged(){this._calculateAndEmulate(false);}
  264. _uaSettingChanged(){this._calculateAndEmulate(true);}
  265. _deviceScaleFactorSettingChanged(){this._calculateAndEmulate(false);}
  266. _deviceOutlineSettingChanged(){this._calculateAndEmulate(false);}
  267. _preferredScaledWidth(){return Math.floor(this._preferredSize.width/(this._scaleSetting.get()||1));}
  268. _preferredScaledHeight(){return Math.floor(this._preferredSize.height/(this._scaleSetting.get()||1));}
  269. _currentOutline(){let outline=new UI.Insets(0,0,0,0);if(this._type!==Emulation.DeviceModeModel.Type.Device){return outline;}
  270. const orientation=this._device.orientationByName(this._mode.orientation);if(this._deviceOutlineSetting.get()){outline=orientation.outlineInsets||outline;}
  271. return outline;}
  272. _currentInsets(){if(this._type!==Emulation.DeviceModeModel.Type.Device){return new UI.Insets(0,0,0,0);}
  273. return this._mode.insets;}
  274. _calculateAndEmulate(resetPageScaleFactor){if(!this._emulationModel){this._onModelAvailable=this._calculateAndEmulate.bind(this,resetPageScaleFactor);}
  275. const mobile=this._isMobile();if(this._type===Emulation.DeviceModeModel.Type.Device){const orientation=this._device.orientationByName(this._mode.orientation);const outline=this._currentOutline();const insets=this._currentInsets();this._fitScale=this._calculateFitScale(orientation.width,orientation.height,outline,insets);if(mobile){this._appliedUserAgentType=this._device.touch()?Emulation.DeviceModeModel.UA.Mobile:Emulation.DeviceModeModel.UA.MobileNoTouch;}else{this._appliedUserAgentType=this._device.touch()?Emulation.DeviceModeModel.UA.DesktopTouch:Emulation.DeviceModeModel.UA.Desktop;}
  276. this._applyDeviceMetrics(new UI.Size(orientation.width,orientation.height),insets,outline,this._scaleSetting.get(),this._device.deviceScaleFactor,mobile,this._mode.orientation===Emulation.EmulatedDevice.Horizontal?Protocol.Emulation.ScreenOrientationType.LandscapePrimary:Protocol.Emulation.ScreenOrientationType.PortraitPrimary,resetPageScaleFactor);this._applyUserAgent(this._device.userAgent);this._applyTouch(this._device.touch(),mobile);}else if(this._type===Emulation.DeviceModeModel.Type.None){this._fitScale=this._calculateFitScale(this._availableSize.width,this._availableSize.height);this._appliedUserAgentType=Emulation.DeviceModeModel.UA.Desktop;this._applyDeviceMetrics(this._availableSize,new UI.Insets(0,0,0,0),new UI.Insets(0,0,0,0),1,0,mobile,null,resetPageScaleFactor);this._applyUserAgent('');this._applyTouch(false,false);}else if(this._type===Emulation.DeviceModeModel.Type.Responsive){let screenWidth=this._widthSetting.get();if(!screenWidth||screenWidth>this._preferredScaledWidth()){screenWidth=this._preferredScaledWidth();}
  277. let screenHeight=this._heightSetting.get();if(!screenHeight||screenHeight>this._preferredScaledHeight()){screenHeight=this._preferredScaledHeight();}
  278. const defaultDeviceScaleFactor=mobile?Emulation.DeviceModeModel.defaultMobileScaleFactor:0;this._fitScale=this._calculateFitScale(this._widthSetting.get(),this._heightSetting.get());this._appliedUserAgentType=this._uaSetting.get();this._applyDeviceMetrics(new UI.Size(screenWidth,screenHeight),new UI.Insets(0,0,0,0),new UI.Insets(0,0,0,0),this._scaleSetting.get(),this._deviceScaleFactorSetting.get()||defaultDeviceScaleFactor,mobile,screenHeight>=screenWidth?Protocol.Emulation.ScreenOrientationType.PortraitPrimary:Protocol.Emulation.ScreenOrientationType.LandscapePrimary,resetPageScaleFactor);this._applyUserAgent(mobile?Emulation.DeviceModeModel._defaultMobileUserAgent:'');this._applyTouch(this._uaSetting.get()===Emulation.DeviceModeModel.UA.DesktopTouch||this._uaSetting.get()===Emulation.DeviceModeModel.UA.Mobile,this._uaSetting.get()===Emulation.DeviceModeModel.UA.Mobile);}
  279. const overlayModel=this._emulationModel?this._emulationModel.overlayModel():null;if(overlayModel){overlayModel.setShowViewportSizeOnResize(this._type===Emulation.DeviceModeModel.Type.None);}
  280. this.dispatchEventToListeners(Emulation.DeviceModeModel.Events.Updated);}
  281. _calculateFitScale(screenWidth,screenHeight,outline,insets){const outlineWidth=outline?outline.left+outline.right:0;const outlineHeight=outline?outline.top+outline.bottom:0;const insetsWidth=insets?insets.left+insets.right:0;const insetsHeight=insets?insets.top+insets.bottom:0;let scale=Math.min(screenWidth?this._preferredSize.width/(screenWidth+outlineWidth):1,screenHeight?this._preferredSize.height/(screenHeight+outlineHeight):1);scale=Math.min(Math.floor(scale*100),100);let sharpScale=scale;while(sharpScale>scale*0.7){let sharp=true;if(screenWidth){sharp=sharp&&Number.isInteger((screenWidth-insetsWidth)*sharpScale/100);}
  282. if(screenHeight){sharp=sharp&&Number.isInteger((screenHeight-insetsHeight)*sharpScale/100);}
  283. if(sharp){return sharpScale/100;}
  284. sharpScale-=1;}
  285. return scale/100;}
  286. setSizeAndScaleToFit(width,height){this._scaleSetting.set(this._calculateFitScale(width,height));this.setWidth(width);this.setHeight(height);}
  287. _applyUserAgent(userAgent){SDK.multitargetNetworkManager.setUserAgentOverride(userAgent);}
  288. _applyDeviceMetrics(screenSize,insets,outline,scale,deviceScaleFactor,mobile,screenOrientation,resetPageScaleFactor){screenSize.width=Math.max(1,Math.floor(screenSize.width));screenSize.height=Math.max(1,Math.floor(screenSize.height));let pageWidth=screenSize.width-insets.left-insets.right;let pageHeight=screenSize.height-insets.top-insets.bottom;this._emulatedPageSize=new UI.Size(pageWidth,pageHeight);const positionX=insets.left;const positionY=insets.top;const screenOrientationAngle=screenOrientation===Protocol.Emulation.ScreenOrientationType.LandscapePrimary?90:0;this._appliedDeviceSize=screenSize;this._appliedDeviceScaleFactor=deviceScaleFactor||window.devicePixelRatio;this._screenRect=new UI.Rect(Math.max(0,(this._availableSize.width-screenSize.width*scale)/2),outline.top*scale,screenSize.width*scale,screenSize.height*scale);this._outlineRect=new UI.Rect(this._screenRect.left-outline.left*scale,0,(outline.left+screenSize.width+outline.right)*scale,(outline.top+screenSize.height+outline.bottom)*scale);this._visiblePageRect=new UI.Rect(positionX*scale,positionY*scale,Math.min(pageWidth*scale,this._availableSize.width-this._screenRect.left-positionX*scale),Math.min(pageHeight*scale,this._availableSize.height-this._screenRect.top-positionY*scale));this._scale=scale;if(scale===1&&this._availableSize.width>=screenSize.width&&this._availableSize.height>=screenSize.height){pageWidth=0;pageHeight=0;}
  289. if(this._visiblePageRect.width===pageWidth*scale&&this._visiblePageRect.height===pageHeight*scale&&Number.isInteger(pageWidth*scale)&&Number.isInteger(pageHeight*scale)){pageWidth=0;pageHeight=0;}
  290. if(!this._emulationModel){return;}
  291. if(resetPageScaleFactor){this._emulationModel.resetPageScaleFactor();}
  292. if(pageWidth||pageHeight||mobile||deviceScaleFactor||scale!==1||screenOrientation){const metrics={width:pageWidth,height:pageHeight,deviceScaleFactor:deviceScaleFactor,mobile:mobile,scale:scale,screenWidth:screenSize.width,screenHeight:screenSize.height,positionX:positionX,positionY:positionY,dontSetVisibleSize:true};if(screenOrientation){metrics.screenOrientation={type:screenOrientation,angle:screenOrientationAngle};}
  293. this._emulationModel.emulateDevice(metrics);}else{this._emulationModel.emulateDevice(null);}}
  294. async captureScreenshot(fullSize,clip){const screenCaptureModel=this._emulationModel?this._emulationModel.target().model(SDK.ScreenCaptureModel):null;if(!screenCaptureModel){return null;}
  295. const overlayModel=this._emulationModel?this._emulationModel.overlayModel():null;if(overlayModel){overlayModel.setShowViewportSizeOnResize(false);}
  296. let deviceMetrics;if(fullSize){const metrics=await screenCaptureModel.fetchLayoutMetrics();if(!metrics){return null;}
  297. const contentHeight=Math.min((1<<14)/this._appliedDeviceScaleFactor,metrics.contentHeight);deviceMetrics={width:Math.floor(metrics.contentWidth),height:Math.floor(contentHeight),deviceScaleFactor:this._appliedDeviceScaleFactor,mobile:this._isMobile(),};clip={x:0,y:0,width:deviceMetrics.width,height:deviceMetrics.height,scale:1};if(this._device){const screenOrientation=this._mode.orientation===Emulation.EmulatedDevice.Horizontal?Protocol.Emulation.ScreenOrientationType.LandscapePrimary:Protocol.Emulation.ScreenOrientationType.PortraitPrimary;const screenOrientationAngle=screenOrientation===Protocol.Emulation.ScreenOrientationType.LandscapePrimary?90:0;deviceMetrics.screenOrientation={type:screenOrientation,angle:screenOrientationAngle};}
  298. await this._emulationModel.resetPageScaleFactor();await this._emulationModel.emulateDevice(deviceMetrics);}
  299. const screenshot=await screenCaptureModel.captureScreenshot('png',100,clip);if(fullSize){if(this._device){const orientation=this._device.orientationByName(this._mode.orientation);deviceMetrics.width=orientation.width;deviceMetrics.height=orientation.height;}else{deviceMetrics.width=0;deviceMetrics.height=0;}
  300. await this._emulationModel.emulateDevice(deviceMetrics);}
  301. this._calculateAndEmulate(false);return screenshot;}
  302. _applyTouch(touchEnabled,mobile){this._touchEnabled=touchEnabled;this._touchMobile=mobile;for(const emulationModel of SDK.targetManager.models(SDK.EmulationModel)){emulationModel.emulateTouch(touchEnabled,mobile);}}};Emulation.DeviceModeModel.Events={Updated:'Updated'};Emulation.DeviceModeModel.Type={None:'None',Responsive:'Responsive',Device:'Device'};Emulation.DeviceModeModel.UA={Mobile:Common.UIString('Mobile'),MobileNoTouch:Common.UIString('Mobile (no touch)'),Desktop:Common.UIString('Desktop'),DesktopTouch:Common.UIString('Desktop (touch)')};Emulation.DeviceModeModel.MinDeviceSize=50;Emulation.DeviceModeModel.MaxDeviceSize=9999;Emulation.DeviceModeModel.MinDeviceScaleFactor=0;Emulation.DeviceModeModel.MaxDeviceScaleFactor=10;Emulation.DeviceModeModel.MaxDeviceNameLength=50;Emulation.DeviceModeModel._defaultMobileUserAgent='Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/%s Mobile Safari/537.36';Emulation.DeviceModeModel._defaultMobileUserAgent=SDK.MultitargetNetworkManager.patchUserAgentWithChromeVersion(Emulation.DeviceModeModel._defaultMobileUserAgent);Emulation.DeviceModeModel.defaultMobileScaleFactor=2;;Emulation.DeviceModeToolbar=class{constructor(model,showMediaInspectorSetting,showRulersSetting){this._model=model;this._showMediaInspectorSetting=showMediaInspectorSetting;this._showRulersSetting=showRulersSetting;this._deviceOutlineSetting=this._model.deviceOutlineSetting();this._showDeviceScaleFactorSetting=Common.settings.createSetting('emulation.showDeviceScaleFactor',false);this._showDeviceScaleFactorSetting.addChangeListener(this._updateDeviceScaleFactorVisibility,this);this._showUserAgentTypeSetting=Common.settings.createSetting('emulation.showUserAgentType',false);this._showUserAgentTypeSetting.addChangeListener(this._updateUserAgentTypeVisibility,this);this._autoAdjustScaleSetting=Common.settings.createSetting('emulation.autoAdjustScale',true);this._lastMode=new Map();this._element=createElementWithClass('div','device-mode-toolbar');const leftContainer=this._element.createChild('div','device-mode-toolbar-spacer');leftContainer.createChild('div','device-mode-toolbar-spacer');const leftToolbar=new UI.Toolbar('',leftContainer);leftToolbar.makeWrappable();this._fillLeftToolbar(leftToolbar);const mainToolbar=new UI.Toolbar('',this._element);mainToolbar.makeWrappable();this._fillMainToolbar(mainToolbar);const rightContainer=this._element.createChild('div','device-mode-toolbar-spacer');const rightToolbar=new UI.Toolbar('device-mode-toolbar-fixed-size',rightContainer);rightToolbar.makeWrappable();this._fillRightToolbar(rightToolbar);const modeToolbar=new UI.Toolbar('device-mode-toolbar-fixed-size',rightContainer);modeToolbar.makeWrappable();this._fillModeToolbar(modeToolbar);rightContainer.createChild('div','device-mode-toolbar-spacer');const optionsToolbar=new UI.Toolbar('device-mode-toolbar-options',rightContainer);optionsToolbar.makeWrappable();this._fillOptionsToolbar(optionsToolbar);this._emulatedDevicesList=Emulation.EmulatedDevicesList.instance();this._emulatedDevicesList.addEventListener(Emulation.EmulatedDevicesList.Events.CustomDevicesUpdated,this._deviceListChanged,this);this._emulatedDevicesList.addEventListener(Emulation.EmulatedDevicesList.Events.StandardDevicesUpdated,this._deviceListChanged,this);this._persistenceSetting=Common.settings.createSetting('emulation.deviceModeValue',{device:'',orientation:'',mode:''});this._model.toolbarControlsEnabledSetting().addChangeListener(updateToolbarsEnabled);updateToolbarsEnabled();function updateToolbarsEnabled(){const enabled=model.toolbarControlsEnabledSetting().get();leftToolbar.setEnabled(enabled);mainToolbar.setEnabled(enabled);rightToolbar.setEnabled(enabled);modeToolbar.setEnabled(enabled);optionsToolbar.setEnabled(enabled);}}
  303. _fillLeftToolbar(toolbar){toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));this._deviceSelectItem=new UI.ToolbarMenuButton(this._appendDeviceMenuItems.bind(this));this._deviceSelectItem.setGlyph('');this._deviceSelectItem.turnIntoSelect(95);this._deviceSelectItem.setDarkText();toolbar.appendToolbarItem(this._deviceSelectItem);}
  304. _fillMainToolbar(toolbar){const widthInput=UI.createInput('device-mode-size-input','text');widthInput.maxLength=4;widthInput.title=Common.UIString('Width');this._updateWidthInput=UI.bindInput(widthInput,this._applyWidth.bind(this),Emulation.DeviceModeModel.widthValidator,true);this._widthInput=widthInput;this._widthItem=this._wrapToolbarItem(widthInput);toolbar.appendToolbarItem(this._widthItem);const xElement=createElementWithClass('div','device-mode-x');xElement.textContent='\u00D7';this._xItem=this._wrapToolbarItem(xElement);toolbar.appendToolbarItem(this._xItem);const heightInput=UI.createInput('device-mode-size-input','text');heightInput.maxLength=4;heightInput.title=Common.UIString('Height (leave empty for full)');this._updateHeightInput=UI.bindInput(heightInput,this._applyHeight.bind(this),validateHeight,true);this._heightInput=heightInput;this._heightItem=this._wrapToolbarItem(heightInput);toolbar.appendToolbarItem(this._heightItem);function validateHeight(value){if(!value){return{valid:true};}
  305. return Emulation.DeviceModeModel.heightValidator(value);}}
  306. _applyWidth(value){const width=value?Number(value):0;this._model.setWidthAndScaleToFit(width);}
  307. _applyHeight(value){const height=value?Number(value):0;this._model.setHeightAndScaleToFit(height);}
  308. _fillRightToolbar(toolbar){toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));this._scaleItem=new UI.ToolbarMenuButton(this._appendScaleMenuItems.bind(this));this._scaleItem.setTitle(Common.UIString('Zoom'));this._scaleItem.setGlyph('');this._scaleItem.turnIntoSelect();this._scaleItem.setDarkText();toolbar.appendToolbarItem(this._scaleItem);toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));this._deviceScaleItem=new UI.ToolbarMenuButton(this._appendDeviceScaleMenuItems.bind(this));this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());this._deviceScaleItem.setTitle(Common.UIString('Device pixel ratio'));this._deviceScaleItem.setGlyph('');this._deviceScaleItem.turnIntoSelect();this._deviceScaleItem.setDarkText();toolbar.appendToolbarItem(this._deviceScaleItem);toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));this._uaItem=new UI.ToolbarMenuButton(this._appendUserAgentMenuItems.bind(this));this._uaItem.setVisible(this._showUserAgentTypeSetting.get());this._uaItem.setTitle(Common.UIString('Device type'));this._uaItem.setGlyph('');this._uaItem.turnIntoSelect();this._uaItem.setDarkText();toolbar.appendToolbarItem(this._uaItem);this._throttlingConditionsItem=MobileThrottling.throttlingManager().createMobileThrottlingButton();toolbar.appendToolbarItem(this._throttlingConditionsItem);}
  309. _fillModeToolbar(toolbar){toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));this._modeButton=new UI.ToolbarButton('','largeicon-rotate-screen');this._modeButton.addEventListener(UI.ToolbarButton.Events.Click,this._modeMenuClicked,this);toolbar.appendToolbarItem(this._modeButton);}
  310. _fillOptionsToolbar(toolbar){toolbar.appendToolbarItem(this._wrapToolbarItem(createElementWithClass('div','device-mode-empty-toolbar-element')));const moreOptionsButton=new UI.ToolbarMenuButton(this._appendOptionsMenuItems.bind(this));moreOptionsButton.setTitle(Common.UIString('More options'));toolbar.appendToolbarItem(moreOptionsButton);}
  311. _appendScaleMenuItems(contextMenu){if(this._model.type()===Emulation.DeviceModeModel.Type.Device){contextMenu.footerSection().appendItem(Common.UIString('Fit to window (%.0f%%)',this._model.fitScale()*100),this._onScaleMenuChanged.bind(this,this._model.fitScale()),false);}
  312. contextMenu.footerSection().appendCheckboxItem(ls`Auto-adjust zoom`,this._onAutoAdjustScaleChanged.bind(this),this._autoAdjustScaleSetting.get());const boundAppendScaleItem=appendScaleItem.bind(this);boundAppendScaleItem(Common.UIString('50%'),0.5);boundAppendScaleItem(Common.UIString('75%'),0.75);boundAppendScaleItem(Common.UIString('100%'),1);boundAppendScaleItem(Common.UIString('125%'),1.25);boundAppendScaleItem(Common.UIString('150%'),1.5);function appendScaleItem(title,value){contextMenu.defaultSection().appendCheckboxItem(title,this._onScaleMenuChanged.bind(this,value),this._model.scaleSetting().get()===value,false);}}
  313. _onScaleMenuChanged(value){this._model.scaleSetting().set(value);}
  314. _onAutoAdjustScaleChanged(){this._autoAdjustScaleSetting.set(!this._autoAdjustScaleSetting.get());}
  315. _appendDeviceScaleMenuItems(contextMenu){const deviceScaleFactorSetting=this._model.deviceScaleFactorSetting();const defaultValue=this._model.uaSetting().get()===Emulation.DeviceModeModel.UA.Mobile||this._model.uaSetting().get()===Emulation.DeviceModeModel.UA.MobileNoTouch?Emulation.DeviceModeModel.defaultMobileScaleFactor:window.devicePixelRatio;appendDeviceScaleFactorItem(contextMenu.headerSection(),Common.UIString('Default: %.1f',defaultValue),0);appendDeviceScaleFactorItem(contextMenu.defaultSection(),Common.UIString('1'),1);appendDeviceScaleFactorItem(contextMenu.defaultSection(),Common.UIString('2'),2);appendDeviceScaleFactorItem(contextMenu.defaultSection(),Common.UIString('3'),3);function appendDeviceScaleFactorItem(section,title,value){section.appendCheckboxItem(title,deviceScaleFactorSetting.set.bind(deviceScaleFactorSetting,value),deviceScaleFactorSetting.get()===value);}}
  316. _appendUserAgentMenuItems(contextMenu){const uaSetting=this._model.uaSetting();appendUAItem(Emulation.DeviceModeModel.UA.Mobile,Emulation.DeviceModeModel.UA.Mobile);appendUAItem(Emulation.DeviceModeModel.UA.MobileNoTouch,Emulation.DeviceModeModel.UA.MobileNoTouch);appendUAItem(Emulation.DeviceModeModel.UA.Desktop,Emulation.DeviceModeModel.UA.Desktop);appendUAItem(Emulation.DeviceModeModel.UA.DesktopTouch,Emulation.DeviceModeModel.UA.DesktopTouch);function appendUAItem(title,value){contextMenu.defaultSection().appendCheckboxItem(title,uaSetting.set.bind(uaSetting,value),uaSetting.get()===value);}}
  317. _appendOptionsMenuItems(contextMenu){const model=this._model;appendToggleItem(contextMenu.headerSection(),this._deviceOutlineSetting,Common.UIString('Hide device frame'),Common.UIString('Show device frame'),model.type()!==Emulation.DeviceModeModel.Type.Device);appendToggleItem(contextMenu.headerSection(),this._showMediaInspectorSetting,Common.UIString('Hide media queries'),Common.UIString('Show media queries'));appendToggleItem(contextMenu.headerSection(),this._showRulersSetting,Common.UIString('Hide rulers'),Common.UIString('Show rulers'));appendToggleItem(contextMenu.defaultSection(),this._showDeviceScaleFactorSetting,Common.UIString('Remove device pixel ratio'),Common.UIString('Add device pixel ratio'));appendToggleItem(contextMenu.defaultSection(),this._showUserAgentTypeSetting,Common.UIString('Remove device type'),Common.UIString('Add device type'));contextMenu.appendItemsAtLocation('deviceModeMenu');contextMenu.footerSection().appendItem(Common.UIString('Reset to defaults'),this._reset.bind(this));contextMenu.footerSection().appendItem(ls`Close DevTools`,Host.InspectorFrontendHost.closeWindow.bind(Host.InspectorFrontendHost));function appendToggleItem(section,setting,title1,title2,disabled){if(typeof disabled==='undefined'){disabled=model.type()===Emulation.DeviceModeModel.Type.None;}
  318. section.appendItem(setting.get()?title1:title2,setting.set.bind(setting,!setting.get()),disabled);}}
  319. _reset(){this._deviceOutlineSetting.set(false);this._showDeviceScaleFactorSetting.set(false);this._showUserAgentTypeSetting.set(false);this._showMediaInspectorSetting.set(false);this._showRulersSetting.set(false);this._model.reset();}
  320. _wrapToolbarItem(element){const container=createElement('div');const shadowRoot=UI.createShadowRootWithCoreStyles(container,'emulation/deviceModeToolbar.css');shadowRoot.appendChild(element);return new UI.ToolbarItem(container);}
  321. _emulateDevice(device){const scale=this._autoAdjustScaleSetting.get()?undefined:this._model.scaleSetting().get();this._model.emulate(Emulation.DeviceModeModel.Type.Device,device,this._lastMode.get(device)||device.modes[0],scale);}
  322. _switchToResponsive(){this._model.emulate(Emulation.DeviceModeModel.Type.Responsive,null,null);}
  323. _filterDevices(devices){devices=devices.filter(function(d){return d.show();});devices.sort(Emulation.EmulatedDevice.deviceComparator);return devices;}
  324. _standardDevices(){return this._filterDevices(this._emulatedDevicesList.standard());}
  325. _customDevices(){return this._filterDevices(this._emulatedDevicesList.custom());}
  326. _allDevices(){return this._standardDevices().concat(this._customDevices());}
  327. _appendDeviceMenuItems(contextMenu){contextMenu.headerSection().appendCheckboxItem(Common.UIString('Responsive'),this._switchToResponsive.bind(this),this._model.type()===Emulation.DeviceModeModel.Type.Responsive,false);appendGroup.call(this,this._standardDevices());appendGroup.call(this,this._customDevices());contextMenu.footerSection().appendItem(Common.UIString('Edit\u2026'),this._emulatedDevicesList.revealCustomSetting.bind(this._emulatedDevicesList),false);function appendGroup(devices){if(!devices.length){return;}
  328. const section=contextMenu.section();for(const device of devices){section.appendCheckboxItem(device.title,this._emulateDevice.bind(this,device),this._model.device()===device,false);}}}
  329. _deviceListChanged(){const device=this._model.device();if(!device){return;}
  330. const devices=this._allDevices();if(devices.indexOf(device)===-1){if(devices.length){this._emulateDevice(devices[0]);}else{this._model.emulate(Emulation.DeviceModeModel.Type.Responsive,null,null);}}}
  331. _updateDeviceScaleFactorVisibility(){this._deviceScaleItem.setVisible(this._showDeviceScaleFactorSetting.get());}
  332. _updateUserAgentTypeVisibility(){this._uaItem.setVisible(this._showUserAgentTypeSetting.get());}
  333. _modeMenuClicked(event){const device=this._model.device();const model=this._model;const autoAdjustScaleSetting=this._autoAdjustScaleSetting;if(model.type()===Emulation.DeviceModeModel.Type.Responsive){const appliedSize=model.appliedDeviceSize();if(autoAdjustScaleSetting.get()){model.setSizeAndScaleToFit(appliedSize.height,appliedSize.width);}else{model.setWidth(appliedSize.height);model.setHeight(appliedSize.width);}
  334. return;}
  335. if(device.modes.length===2&&device.modes[0].orientation!==device.modes[1].orientation){const scale=autoAdjustScaleSetting.get()?undefined:model.scaleSetting().get();model.emulate(model.type(),model.device(),model.mode()===device.modes[0]?device.modes[1]:device.modes[0],scale);return;}
  336. const contextMenu=new UI.ContextMenu((event.data),false,this._modeButton.element.totalOffsetLeft(),this._modeButton.element.totalOffsetTop()+this._modeButton.element.offsetHeight);addOrientation(Emulation.EmulatedDevice.Vertical,Common.UIString('Portrait'));addOrientation(Emulation.EmulatedDevice.Horizontal,Common.UIString('Landscape'));contextMenu.show();function addOrientation(orientation,title){const modes=device.modesForOrientation(orientation);if(!modes.length){return;}
  337. if(modes.length===1){addMode(modes[0],title);}else{for(let index=0;index<modes.length;index++){addMode(modes[index],title+' \u2013 '+modes[index].title);}}}
  338. function addMode(mode,title){contextMenu.defaultSection().appendCheckboxItem(title,applyMode.bind(null,mode),model.mode()===mode,false);}
  339. function applyMode(mode){const scale=autoAdjustScaleSetting.get()?undefined:model.scaleSetting().get();model.emulate(model.type(),model.device(),mode,scale);}}
  340. element(){return this._element;}
  341. update(){if(this._model.type()!==this._cachedModelType){this._cachedModelType=this._model.type();this._widthInput.disabled=this._model.type()!==Emulation.DeviceModeModel.Type.Responsive;this._heightInput.disabled=this._model.type()!==Emulation.DeviceModeModel.Type.Responsive;this._deviceScaleItem.setEnabled(this._model.type()===Emulation.DeviceModeModel.Type.Responsive);this._uaItem.setEnabled(this._model.type()===Emulation.DeviceModeModel.Type.Responsive);if(this._model.type()===Emulation.DeviceModeModel.Type.Responsive){this._modeButton.setEnabled(true);this._modeButton.setTitle(ls`Rotate`);}else{this._modeButton.setEnabled(false);}}
  342. const size=this._model.appliedDeviceSize();this._updateHeightInput(this._model.type()===Emulation.DeviceModeModel.Type.Responsive&&this._model.isFullHeight()?'':String(size.height));this._updateWidthInput(String(size.width));this._heightInput.placeholder=size.height;if(this._model.scale()!==this._cachedScale){this._scaleItem.setText(Common.UIString('%.0f%%',this._model.scale()*100));this._cachedScale=this._model.scale();}
  343. const deviceScale=this._model.appliedDeviceScaleFactor();if(deviceScale!==this._cachedDeviceScale){this._deviceScaleItem.setText(Common.UIString('DPR: %.1f',deviceScale));this._cachedDeviceScale=deviceScale;}
  344. const uaType=this._model.appliedUserAgentType();if(uaType!==this._cachedUaType){this._uaItem.setText(uaType);this._cachedUaType=uaType;}
  345. let deviceItemTitle=Common.UIString('None');if(this._model.type()===Emulation.DeviceModeModel.Type.Responsive){deviceItemTitle=Common.UIString('Responsive');}
  346. if(this._model.type()===Emulation.DeviceModeModel.Type.Device){deviceItemTitle=this._model.device().title;}
  347. this._deviceSelectItem.setText(deviceItemTitle);if(this._model.device()!==this._cachedModelDevice){const device=this._model.device();if(device){const modeCount=device?device.modes.length:0;this._modeButton.setEnabled(modeCount>=2);this._modeButton.setTitle(modeCount===2?Common.UIString('Rotate'):Common.UIString('Screen options'));}
  348. this._cachedModelDevice=device;}
  349. if(this._model.type()===Emulation.DeviceModeModel.Type.Device){this._lastMode.set((this._model.device()),(this._model.mode()));}
  350. if(this._model.mode()!==this._cachedModelMode&&this._model.type()!==Emulation.DeviceModeModel.Type.None){this._cachedModelMode=this._model.mode();const value=this._persistenceSetting.get();if(this._model.device()){value.device=this._model.device().title;value.orientation=this._model.mode()?this._model.mode().orientation:'';value.mode=this._model.mode()?this._model.mode().title:'';}else{value.device='';value.orientation='';value.mode='';}
  351. this._persistenceSetting.set(value);}}
  352. restore(){for(const device of this._allDevices()){if(device.title===this._persistenceSetting.get().device){for(const mode of device.modes){if(mode.orientation===this._persistenceSetting.get().orientation&&mode.title===this._persistenceSetting.get().mode){this._lastMode.set(device,mode);this._emulateDevice(device);return;}}}}
  353. this._model.emulate(Emulation.DeviceModeModel.Type.Responsive,null,null);}};;Emulation.DeviceModeView=class extends UI.VBox{constructor(){super(true);this.setMinimumSize(150,150);this.element.classList.add('device-mode-view');this.registerRequiredCSS('emulation/deviceModeView.css');UI.Tooltip.addNativeOverrideContainer(this.contentElement);this._model=self.singleton(Emulation.DeviceModeModel);this._model.addEventListener(Emulation.DeviceModeModel.Events.Updated,this._updateUI,this);this._mediaInspector=new Emulation.MediaQueryInspector(()=>this._model.appliedDeviceSize().width,this._model.setWidth.bind(this._model));this._showMediaInspectorSetting=Common.settings.moduleSetting('showMediaQueryInspector');this._showMediaInspectorSetting.addChangeListener(this._updateUI,this);this._showRulersSetting=Common.settings.moduleSetting('emulation.showRulers');this._showRulersSetting.addChangeListener(this._updateUI,this);this._topRuler=new Emulation.DeviceModeView.Ruler(true,this._model.setWidthAndScaleToFit.bind(this._model));this._topRuler.element.classList.add('device-mode-ruler-top');this._leftRuler=new Emulation.DeviceModeView.Ruler(false,this._model.setHeightAndScaleToFit.bind(this._model));this._leftRuler.element.classList.add('device-mode-ruler-left');this._createUI();UI.zoomManager.addEventListener(UI.ZoomManager.Events.ZoomChanged,this._zoomChanged,this);}
  354. _createUI(){this._toolbar=new Emulation.DeviceModeToolbar(this._model,this._showMediaInspectorSetting,this._showRulersSetting);this.contentElement.appendChild(this._toolbar.element());this._contentClip=this.contentElement.createChild('div','device-mode-content-clip vbox');this._responsivePresetsContainer=this._contentClip.createChild('div','device-mode-presets-container');this._populatePresetsContainer();this._mediaInspectorContainer=this._contentClip.createChild('div','device-mode-media-container');this._contentArea=this._contentClip.createChild('div','device-mode-content-area');this._outlineImage=this._contentArea.createChild('img','device-mode-outline-image hidden fill');this._outlineImage.addEventListener('load',this._onImageLoaded.bind(this,this._outlineImage,true),false);this._outlineImage.addEventListener('error',this._onImageLoaded.bind(this,this._outlineImage,false),false);this._screenArea=this._contentArea.createChild('div','device-mode-screen-area');this._screenImage=this._screenArea.createChild('img','device-mode-screen-image hidden');this._screenImage.addEventListener('load',this._onImageLoaded.bind(this,this._screenImage,true),false);this._screenImage.addEventListener('error',this._onImageLoaded.bind(this,this._screenImage,false),false);this._bottomRightResizerElement=this._screenArea.createChild('div','device-mode-resizer device-mode-bottom-right-resizer');this._bottomRightResizerElement.createChild('div','');this._createResizer(this._bottomRightResizerElement,2,1);this._bottomLeftResizerElement=this._screenArea.createChild('div','device-mode-resizer device-mode-bottom-left-resizer');this._bottomLeftResizerElement.createChild('div','');this._createResizer(this._bottomLeftResizerElement,-2,1);this._rightResizerElement=this._screenArea.createChild('div','device-mode-resizer device-mode-right-resizer');this._rightResizerElement.createChild('div','');this._createResizer(this._rightResizerElement,2,0);this._leftResizerElement=this._screenArea.createChild('div','device-mode-resizer device-mode-left-resizer');this._leftResizerElement.createChild('div','');this._createResizer(this._leftResizerElement,-2,0);this._bottomResizerElement=this._screenArea.createChild('div','device-mode-resizer device-mode-bottom-resizer');this._bottomResizerElement.createChild('div','');this._createResizer(this._bottomResizerElement,0,1);this._bottomResizerElement.addEventListener('dblclick',this._model.setHeight.bind(this._model,0),false);this._bottomResizerElement.title=Common.UIString('Double-click for full height');this._pageArea=this._screenArea.createChild('div','device-mode-page-area');this._pageArea.createChild('slot');}
  355. _populatePresetsContainer(){const sizes=[320,375,425,768,1024,1440,2560];const titles=[Common.UIString('Mobile S'),Common.UIString('Mobile M'),Common.UIString('Mobile L'),Common.UIString('Tablet'),Common.UIString('Laptop'),Common.UIString('Laptop L'),Common.UIString('4K')];this._presetBlocks=[];const inner=this._responsivePresetsContainer.createChild('div','device-mode-presets-container-inner');for(let i=sizes.length-1;i>=0;--i){const outer=inner.createChild('div','fill device-mode-preset-bar-outer');const block=outer.createChild('div','device-mode-preset-bar');block.createChild('span').textContent=titles[i]+' \u2013 '+sizes[i]+'px';block.addEventListener('click',applySize.bind(this,sizes[i]),false);block.__width=sizes[i];this._presetBlocks.push(block);}
  356. function applySize(width,e){this._model.emulate(Emulation.DeviceModeModel.Type.Responsive,null,null);this._model.setWidthAndScaleToFit(width);e.consume();}}
  357. _createResizer(element,widthFactor,heightFactor){const resizer=new UI.ResizerWidget();resizer.addElement(element);let cursor=widthFactor?'ew-resize':'ns-resize';if(widthFactor*heightFactor>0){cursor='nwse-resize';}
  358. if(widthFactor*heightFactor<0){cursor='nesw-resize';}
  359. resizer.setCursor(cursor);resizer.addEventListener(UI.ResizerWidget.Events.ResizeStart,this._onResizeStart,this);resizer.addEventListener(UI.ResizerWidget.Events.ResizeUpdate,this._onResizeUpdate.bind(this,widthFactor,heightFactor));resizer.addEventListener(UI.ResizerWidget.Events.ResizeEnd,this._onResizeEnd,this);return resizer;}
  360. _onResizeStart(event){this._slowPositionStart=null;this._resizeStart=this._model.screenRect().size();}
  361. _onResizeUpdate(widthFactor,heightFactor,event){if(event.data.shiftKey!==!!this._slowPositionStart){this._slowPositionStart=event.data.shiftKey?{x:event.data.currentX,y:event.data.currentY}:null;}
  362. let cssOffsetX=event.data.currentX-event.data.startX;let cssOffsetY=event.data.currentY-event.data.startY;if(this._slowPositionStart){cssOffsetX=(event.data.currentX-this._slowPositionStart.x)/10+this._slowPositionStart.x-event.data.startX;cssOffsetY=(event.data.currentY-this._slowPositionStart.y)/10+this._slowPositionStart.y-event.data.startY;}
  363. if(widthFactor){const dipOffsetX=cssOffsetX*UI.zoomManager.zoomFactor();let newWidth=this._resizeStart.width+dipOffsetX*widthFactor;newWidth=Math.round(newWidth/this._model.scale());if(newWidth>=Emulation.DeviceModeModel.MinDeviceSize&&newWidth<=Emulation.DeviceModeModel.MaxDeviceSize){this._model.setWidth(newWidth);}}
  364. if(heightFactor){const dipOffsetY=cssOffsetY*UI.zoomManager.zoomFactor();let newHeight=this._resizeStart.height+dipOffsetY*heightFactor;newHeight=Math.round(newHeight/this._model.scale());if(newHeight>=Emulation.DeviceModeModel.MinDeviceSize&&newHeight<=Emulation.DeviceModeModel.MaxDeviceSize){this._model.setHeight(newHeight);}}}
  365. _onResizeEnd(event){delete this._resizeStart;Host.userMetrics.actionTaken(Host.UserMetrics.Action.ResizedViewInResponsiveMode);}
  366. _updateUI(){function applyRect(element,rect){element.style.left=rect.left+'px';element.style.top=rect.top+'px';element.style.width=rect.width+'px';element.style.height=rect.height+'px';}
  367. if(!this.isShowing()){return;}
  368. const zoomFactor=UI.zoomManager.zoomFactor();let callDoResize=false;const showRulers=this._showRulersSetting.get()&&this._model.type()!==Emulation.DeviceModeModel.Type.None;let contentAreaResized=false;let updateRulers=false;const cssScreenRect=this._model.screenRect().scale(1/zoomFactor);if(!cssScreenRect.isEqual(this._cachedCssScreenRect)){applyRect(this._screenArea,cssScreenRect);updateRulers=true;callDoResize=true;this._cachedCssScreenRect=cssScreenRect;}
  369. const cssVisiblePageRect=this._model.visiblePageRect().scale(1/zoomFactor);if(!cssVisiblePageRect.isEqual(this._cachedCssVisiblePageRect)){applyRect(this._pageArea,cssVisiblePageRect);callDoResize=true;this._cachedCssVisiblePageRect=cssVisiblePageRect;}
  370. const outlineRect=this._model.outlineRect().scale(1/zoomFactor);if(!outlineRect.isEqual(this._cachedOutlineRect)){applyRect(this._outlineImage,outlineRect);callDoResize=true;this._cachedOutlineRect=outlineRect;}
  371. this._contentClip.classList.toggle('device-mode-outline-visible',!!this._model.outlineImage());const resizable=this._model.type()===Emulation.DeviceModeModel.Type.Responsive;if(resizable!==this._cachedResizable){this._rightResizerElement.classList.toggle('hidden',!resizable);this._leftResizerElement.classList.toggle('hidden',!resizable);this._bottomResizerElement.classList.toggle('hidden',!resizable);this._bottomRightResizerElement.classList.toggle('hidden',!resizable);this._bottomLeftResizerElement.classList.toggle('hidden',!resizable);this._cachedResizable=resizable;}
  372. const mediaInspectorVisible=this._showMediaInspectorSetting.get()&&this._model.type()!==Emulation.DeviceModeModel.Type.None;if(mediaInspectorVisible!==this._cachedMediaInspectorVisible){if(mediaInspectorVisible){this._mediaInspector.show(this._mediaInspectorContainer);}else{this._mediaInspector.detach();}
  373. contentAreaResized=true;callDoResize=true;this._cachedMediaInspectorVisible=mediaInspectorVisible;}
  374. if(showRulers!==this._cachedShowRulers){this._contentClip.classList.toggle('device-mode-rulers-visible',showRulers);if(showRulers){this._topRuler.show(this._contentArea);this._leftRuler.show(this._contentArea);}else{this._topRuler.detach();this._leftRuler.detach();}
  375. contentAreaResized=true;callDoResize=true;this._cachedShowRulers=showRulers;}
  376. if(this._model.scale()!==this._cachedScale){updateRulers=true;callDoResize=true;for(const block of this._presetBlocks){block.style.width=block.__width*this._model.scale()+'px';}
  377. this._cachedScale=this._model.scale();}
  378. this._toolbar.update();this._loadImage(this._screenImage,this._model.screenImage());this._loadImage(this._outlineImage,this._model.outlineImage());this._mediaInspector.setAxisTransform(this._model.scale());if(callDoResize){this.doResize();}
  379. if(updateRulers){this._topRuler.render(this._model.scale());this._leftRuler.render(this._model.scale());this._topRuler.element.positionAt(this._cachedCssScreenRect?this._cachedCssScreenRect.left:0,this._cachedCssScreenRect?this._cachedCssScreenRect.top:0);this._leftRuler.element.positionAt(this._cachedCssScreenRect?this._cachedCssScreenRect.left:0,this._cachedCssScreenRect?this._cachedCssScreenRect.top:0);}
  380. if(contentAreaResized){this._contentAreaResized();}}
  381. _loadImage(element,srcset){if(element.getAttribute('srcset')===srcset){return;}
  382. element.setAttribute('srcset',srcset);if(!srcset){element.classList.toggle('hidden',true);}}
  383. _onImageLoaded(element,success){element.classList.toggle('hidden',!success);}
  384. setNonEmulatedAvailableSize(element){if(this._model.type()!==Emulation.DeviceModeModel.Type.None){return;}
  385. const zoomFactor=UI.zoomManager.zoomFactor();const rect=element.getBoundingClientRect();const availableSize=new UI.Size(Math.max(rect.width*zoomFactor,1),Math.max(rect.height*zoomFactor,1));this._model.setAvailableSize(availableSize,availableSize);}
  386. _contentAreaResized(){const zoomFactor=UI.zoomManager.zoomFactor();const rect=this._contentArea.getBoundingClientRect();const availableSize=new UI.Size(Math.max(rect.width*zoomFactor,1),Math.max(rect.height*zoomFactor,1));const preferredSize=new UI.Size(Math.max((rect.width-2*this._handleWidth)*zoomFactor,1),Math.max((rect.height-this._handleHeight)*zoomFactor,1));this._model.setAvailableSize(availableSize,preferredSize);}
  387. _measureHandles(){const hidden=this._rightResizerElement.classList.contains('hidden');this._rightResizerElement.classList.toggle('hidden',false);this._bottomResizerElement.classList.toggle('hidden',false);this._handleWidth=this._rightResizerElement.offsetWidth;this._handleHeight=this._bottomResizerElement.offsetHeight;this._rightResizerElement.classList.toggle('hidden',hidden);this._bottomResizerElement.classList.toggle('hidden',hidden);}
  388. _zoomChanged(){delete this._handleWidth;delete this._handleHeight;if(this.isShowing()){this._measureHandles();this._contentAreaResized();}}
  389. onResize(){if(this.isShowing()){this._contentAreaResized();}}
  390. wasShown(){this._measureHandles();this._toolbar.restore();}
  391. willHide(){this._model.emulate(Emulation.DeviceModeModel.Type.None,null,null);}
  392. async captureScreenshot(){const screenshot=await this._model.captureScreenshot(false);if(screenshot===null){return;}
  393. const pageImage=new Image();pageImage.src='data:image/png;base64,'+screenshot;pageImage.onload=async()=>{const scale=pageImage.naturalWidth/this._model.screenRect().width;const outlineRect=this._model.outlineRect().scale(scale);const screenRect=this._model.screenRect().scale(scale);const visiblePageRect=this._model.visiblePageRect().scale(scale);const contentLeft=screenRect.left+visiblePageRect.left-outlineRect.left;const contentTop=screenRect.top+visiblePageRect.top-outlineRect.top;const canvas=createElement('canvas');canvas.width=Math.floor(outlineRect.width);canvas.height=Math.floor(outlineRect.height);const ctx=canvas.getContext('2d');ctx.imageSmoothingEnabled=false;if(this._model.outlineImage()){await this._paintImage(ctx,this._model.outlineImage(),outlineRect.relativeTo(outlineRect));}
  394. if(this._model.screenImage()){await this._paintImage(ctx,this._model.screenImage(),screenRect.relativeTo(outlineRect));}
  395. ctx.drawImage(pageImage,Math.floor(contentLeft),Math.floor(contentTop));this._saveScreenshot(canvas);};}
  396. async captureFullSizeScreenshot(){const screenshot=await this._model.captureScreenshot(true);if(screenshot===null){return;}
  397. return this._saveScreenshotBase64(screenshot);}
  398. async captureAreaScreenshot(clip){const screenshot=await this._model.captureScreenshot(false,clip);if(screenshot===null){return;}
  399. return this._saveScreenshotBase64(screenshot);}
  400. _saveScreenshotBase64(screenshot){const pageImage=new Image();pageImage.src='data:image/png;base64,'+screenshot;pageImage.onload=()=>{const canvas=createElement('canvas');canvas.width=pageImage.naturalWidth;canvas.height=pageImage.naturalHeight;const ctx=canvas.getContext('2d');ctx.imageSmoothingEnabled=false;ctx.drawImage(pageImage,0,0);this._saveScreenshot(canvas);};}
  401. _paintImage(ctx,src,rect){return new Promise(fulfill=>{const image=new Image();image.crossOrigin='Anonymous';image.srcset=src;image.onerror=fulfill;image.onload=()=>{ctx.drawImage(image,rect.left,rect.top,rect.width,rect.height);fulfill();};});}
  402. _saveScreenshot(canvas){const url=this._model.inspectedURL();let fileName=url?url.trimURL().removeURLFragment():'';if(this._model.type()===Emulation.DeviceModeModel.Type.Device){fileName+=Common.UIString('(%s)',this._model.device().title);}
  403. const link=createElement('a');link.download=fileName+'.png';canvas.toBlob(blob=>{link.href=URL.createObjectURL(blob);link.click();});}};Emulation.DeviceModeView.Ruler=class extends UI.VBox{constructor(horizontal,applyCallback){super();this.element.classList.add('device-mode-ruler');this._contentElement=this.element.createChild('div','device-mode-ruler-content').createChild('div','device-mode-ruler-inner');this._horizontal=horizontal;this._scale=1;this._count=0;this._throttler=new Common.Throttler(0);this._applyCallback=applyCallback;}
  404. render(scale){this._scale=scale;this._throttler.schedule(this._update.bind(this));}
  405. onResize(){this._throttler.schedule(this._update.bind(this));}
  406. _update(){const zoomFactor=UI.zoomManager.zoomFactor();const size=this._horizontal?this._contentElement.offsetWidth:this._contentElement.offsetHeight;if(this._scale!==this._renderedScale||zoomFactor!==this._renderedZoomFactor){this._contentElement.removeChildren();this._count=0;this._renderedScale=this._scale;this._renderedZoomFactor=zoomFactor;}
  407. const dipSize=size*zoomFactor/this._scale;const count=Math.ceil(dipSize/5);let step=1;if(this._scale<0.8){step=2;}
  408. if(this._scale<0.6){step=4;}
  409. if(this._scale<0.4){step=8;}
  410. if(this._scale<0.2){step=16;}
  411. if(this._scale<0.1){step=32;}
  412. for(let i=count;i<this._count;i++){if(!(i%step)){this._contentElement.lastChild.remove();}}
  413. for(let i=this._count;i<count;i++){if(i%step){continue;}
  414. const marker=this._contentElement.createChild('div','device-mode-ruler-marker');if(i){if(this._horizontal){marker.style.left=(5*i)*this._scale/zoomFactor+'px';}else{marker.style.top=(5*i)*this._scale/zoomFactor+'px';}
  415. if(!(i%20)){const text=marker.createChild('div','device-mode-ruler-text');text.textContent=i*5;text.addEventListener('click',this._onMarkerClick.bind(this,i*5),false);}}
  416. if(!(i%10)){marker.classList.add('device-mode-ruler-marker-large');}else if(!(i%5)){marker.classList.add('device-mode-ruler-marker-medium');}}
  417. this._count=count;return Promise.resolve();}
  418. _onMarkerClick(size){this._applyCallback.call(null,size);}};;Emulation.DeviceModeWrapper=class extends UI.VBox{constructor(inspectedPagePlaceholder){super();Emulation.DeviceModeView._wrapperInstance=this;this._inspectedPagePlaceholder=inspectedPagePlaceholder;this._deviceModeView=null;this._toggleDeviceModeAction=UI.actionRegistry.action('emulation.toggle-device-mode');const model=self.singleton(Emulation.DeviceModeModel);this._showDeviceModeSetting=model.enabledSetting();this._showDeviceModeSetting.setRequiresUserAction(!!Root.Runtime.queryParam('hasOtherClients'));this._showDeviceModeSetting.addChangeListener(this._update.bind(this,false));SDK.targetManager.addModelListener(SDK.OverlayModel,SDK.OverlayModel.Events.ScreenshotRequested,this._screenshotRequestedFromOverlay,this);this._update(true);}
  419. _toggleDeviceMode(){this._showDeviceModeSetting.set(!this._showDeviceModeSetting.get());}
  420. _captureScreenshot(fullSize,clip){if(!this._deviceModeView){this._deviceModeView=new Emulation.DeviceModeView();}
  421. this._deviceModeView.setNonEmulatedAvailableSize(this._inspectedPagePlaceholder.element);if(fullSize){this._deviceModeView.captureFullSizeScreenshot();}else if(clip){this._deviceModeView.captureAreaScreenshot(clip);}else{this._deviceModeView.captureScreenshot();}
  422. return true;}
  423. _screenshotRequestedFromOverlay(event){const clip=(event.data);this._captureScreenshot(false,clip);}
  424. _update(force){this._toggleDeviceModeAction.setToggled(this._showDeviceModeSetting.get());if(!force){const showing=this._deviceModeView&&this._deviceModeView.isShowing();if(this._showDeviceModeSetting.get()===showing){return;}}
  425. if(this._showDeviceModeSetting.get()){if(!this._deviceModeView){this._deviceModeView=new Emulation.DeviceModeView();}
  426. this._deviceModeView.show(this.element);this._inspectedPagePlaceholder.clearMinimumSize();this._inspectedPagePlaceholder.show(this._deviceModeView.element);}else{if(this._deviceModeView){this._deviceModeView.detach();}
  427. this._inspectedPagePlaceholder.restoreMinimumSize();this._inspectedPagePlaceholder.show(this.element);}}};Emulation.DeviceModeView._wrapperInstance;Emulation.DeviceModeWrapper.ActionDelegate=class{handleAction(context,actionId){if(Emulation.DeviceModeView._wrapperInstance){switch(actionId){case'emulation.capture-screenshot':return Emulation.DeviceModeView._wrapperInstance._captureScreenshot();case'emulation.capture-node-screenshot':{const node=UI.context.flavor(SDK.DOMNode);if(!node){return true;}
  428. async function captureClip(){const object=await node.resolveToObject();const result=await object.callFunction(function(){const rect=this.getBoundingClientRect();const docRect=this.ownerDocument.documentElement.getBoundingClientRect();return JSON.stringify({x:rect.left-docRect.left,y:rect.top-docRect.top,width:rect.width,height:rect.height,scale:1});});const clip=(JSON.parse((result.object.value)));const response=await node.domModel().target().pageAgent().invoke_getLayoutMetrics({});const page_zoom=!response[Protocol.Error]&&response.visualViewport.zoom||1;clip.x*=page_zoom;clip.y*=page_zoom;clip.width*=page_zoom;clip.height*=page_zoom;Emulation.DeviceModeView._wrapperInstance._captureScreenshot(false,clip);}
  429. captureClip();return true;}
  430. case'emulation.capture-full-height-screenshot':return Emulation.DeviceModeView._wrapperInstance._captureScreenshot(true);case'emulation.toggle-device-mode':Emulation.DeviceModeView._wrapperInstance._toggleDeviceMode();return true;}}
  431. return false;}};;Emulation.GeolocationsSettingsTab=class extends UI.VBox{constructor(){super(true);this.registerRequiredCSS('emulation/geolocationsSettingsTab.css');this.contentElement.createChild('div','header').textContent=Common.UIString('Custom Geolocations');const addButton=UI.createTextButton(Common.UIString('Add location...'),this._addButtonClicked.bind(this),'add-geolocations-button');this.contentElement.appendChild(addButton);this._list=new UI.ListWidget(this);this._list.element.classList.add('geolocations-list');this._list.registerRequiredCSS('emulation/geolocationsSettingsTab.css');this._list.show(this.contentElement);this._customSetting=Common.moduleSetting('emulation.geolocations');this._customSetting.addChangeListener(this._geolocationsUpdated,this);this.setDefaultFocusedElement(addButton);}
  432. wasShown(){super.wasShown();this._geolocationsUpdated();}
  433. _geolocationsUpdated(){this._list.clear();const conditions=this._customSetting.get();for(let i=0;i<conditions.length;++i){this._list.appendItem(conditions[i],true);}
  434. this._list.appendSeparator();}
  435. _addButtonClicked(){this._list.addNewItem(this._customSetting.get().length,{title:'',lat:0,long:0,timezoneId:''});}
  436. renderItem(item,editable){const geolocation=(item);const element=createElementWithClass('div','geolocations-list-item');const title=element.createChild('div','geolocations-list-text geolocations-list-title');const titleText=title.createChild('div','geolocations-list-title-text');titleText.textContent=geolocation.title;titleText.title=geolocation.title;element.createChild('div','geolocations-list-separator');element.createChild('div','geolocations-list-text').textContent=geolocation.lat;element.createChild('div','geolocations-list-separator');element.createChild('div','geolocations-list-text').textContent=geolocation.long;element.createChild('div','geolocations-list-separator');element.createChild('div','geolocations-list-text').textContent=geolocation.timezoneId;return element;}
  437. removeItemRequested(item,index){const list=this._customSetting.get();list.splice(index,1);this._customSetting.set(list);}
  438. commitEdit(item,editor,isNew){const geolocation=(item);geolocation.title=editor.control('title').value.trim();const lat=editor.control('lat').value.trim();geolocation.lat=lat?parseFloat(lat):0;const long=editor.control('long').value.trim();geolocation.long=long?parseFloat(long):0;const timezoneId=editor.control('timezoneId').value.trim();geolocation.timezoneId=timezoneId;const list=this._customSetting.get();if(isNew){list.push(geolocation);}
  439. this._customSetting.set(list);}
  440. beginEdit(item){const geolocation=(item);const editor=this._createEditor();editor.control('title').value=geolocation.title;editor.control('lat').value=String(geolocation.lat);editor.control('long').value=String(geolocation.long);editor.control('timezoneId').value=String(geolocation.timezoneId);return editor;}
  441. _createEditor(){if(this._editor){return this._editor;}
  442. const editor=new UI.ListWidget.Editor();this._editor=editor;const content=editor.contentElement();const titles=content.createChild('div','geolocations-edit-row');titles.createChild('div','geolocations-list-text geolocations-list-title').textContent=Common.UIString('Location name');titles.createChild('div','geolocations-list-separator geolocations-list-separator-invisible');titles.createChild('div','geolocations-list-text').textContent=Common.UIString('Lat');titles.createChild('div','geolocations-list-separator geolocations-list-separator-invisible');titles.createChild('div','geolocations-list-text').textContent=Common.UIString('Long');titles.createChild('div','geolocations-list-separator geolocations-list-separator-invisible');titles.createChild('div','geolocations-list-text').textContent=Common.UIString('Timezone ID');const fields=content.createChild('div','geolocations-edit-row');fields.createChild('div','geolocations-list-text geolocations-list-title').appendChild(editor.createInput('title','text',ls`Location name`,titleValidator));fields.createChild('div','geolocations-list-separator geolocations-list-separator-invisible');let cell=fields.createChild('div','geolocations-list-text');cell.appendChild(editor.createInput('lat','text',ls`Latitude`,latValidator));fields.createChild('div','geolocations-list-separator geolocations-list-separator-invisible');cell=fields.createChild('div','geolocations-list-text');cell.appendChild(editor.createInput('long','text',ls`Longitude`,longValidator));cell=fields.createChild('div','geolocations-list-text');cell.appendChild(editor.createInput('timezoneId','text',ls`Timezone ID`,timezoneIdValidator));return editor;function titleValidator(item,index,input){const maxLength=50;const value=input.value.trim();let errorMessage;if(!value.length){errorMessage=ls`Location name cannot be empty`;}else if(value.length>maxLength){errorMessage=ls`Location name must be less than ${maxLength} characters`;}
  443. if(errorMessage){return{valid:false,errorMessage};}
  444. return{valid:true};}
  445. function latValidator(item,index,input){const minLat=-90;const maxLat=90;const value=input.value.trim();const parsedValue=Number(value);if(!value){return{valid:true};}
  446. let errorMessage;if(Number.isNaN(parsedValue)){errorMessage=ls`Latitude must be a number`;}else if(parseFloat(value)<minLat){errorMessage=ls`Latitude must be greater than or equal to ${minLat}`;}else if(parseFloat(value)>maxLat){errorMessage=ls`Latitude must be less than or equal to ${maxLat}`;}
  447. if(errorMessage){return{valid:false,errorMessage};}
  448. return{valid:true};}
  449. function longValidator(item,index,input){const minLong=-180;const maxLong=180;const value=input.value.trim();const parsedValue=Number(value);if(!value){return{valid:true};}
  450. let errorMessage;if(Number.isNaN(parsedValue)){errorMessage=ls`Longitude must be a number`;}else if(parseFloat(value)<minLong){errorMessage=ls`Longitude must be greater than or equal to ${minLong}`;}else if(parseFloat(value)>maxLong){errorMessage=ls`Longitude must be less than or equal to ${maxLong}`;}
  451. if(errorMessage){return{valid:false,errorMessage};}
  452. return{valid:true};}
  453. function timezoneIdValidator(item,index,input){const value=input.value.trim();if(value===''||/[a-zA-Z]/.test(value)){return{valid:true};}
  454. const errorMessage=ls`Timezone ID must contain alphabet letters`;return{valid:false,errorMessage};}}};Emulation.GeolocationsSettingsTab.Item;;self['InspectorMain']=self['InspectorMain']||{};;Root.Runtime.cachedResources["mobile_throttling/throttlingSettingsTab.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow:hidden;\n}\n\n.header {\n padding: 0 0 6px;\n border-bottom: 1px solid #EEEEEE;\n font-size: 18px;\n font-weight: normal;\n flex: none;\n}\n\n.add-conditions-button {\n flex: none;\n margin: 10px 2px;\n min-width: 140px;\n align-self: flex-start;\n}\n\n.conditions-list {\n max-width: 500px;\n min-width: 340px;\n flex: auto;\n}\n\n.conditions-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n flex: auto 1 1;\n}\n\n.conditions-list-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: 0 0 70px;\n -webkit-user-select: none;\n color: #222;\n text-align: end;\n position: relative;\n}\n\n.conditions-list-title {\n text-align: start;\n flex: auto;\n display: flex;\n align-items: flex-start;\n}\n\n.conditions-list-title-text {\n overflow: hidden;\n flex: auto;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.conditions-list-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.conditions-list-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.conditions-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n}\n\n.conditions-edit-row input {\n width: 100%;\n text-align: inherit;\n}\n\n.conditions-edit-optional {\n position: absolute;\n bottom: -20px;\n right: 0;\n color: rgb(128, 128, 128);\n}\n\n/*# sourceURL=mobile_throttling/throttlingSettingsTab.css */";Root.Runtime.cachedResources["emulation/devicesSettingsTab.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.devices-settings-tab .settings-tab.settings-content {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n height: 100%;\n margin: 0;\n}\n\n.devices-settings-tab .devices-button-row {\n flex: none;\n display: flex;\n}\n\n.devices-settings-tab .devices-button-row button {\n margin-right: 10px;\n min-width: 120px;\n flex: none;\n}\n\n.devices-settings-tab .devices-list {\n width: 350px;\n margin-top: 10px;\n}\n\n.devices-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n flex: auto 1 1;\n cursor: pointer;\n}\n\n.devices-list-checkbox {\n height: 12px;\n width: 12px;\n margin: 3px 5px 2px 2px;\n flex: none;\n pointer-events: none;\n}\n\n.devices-list-checkbox:focus {\n outline: auto 5px -webkit-focus-ring-color;\n}\n\n.devices-list-title {\n overflow: hidden;\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: auto;\n -webkit-user-select: none;\n color: #222;\n}\n\n.devices-edit-fields {\n flex: auto;\n display: flex;\n flex-direction: column;\n align-items: stretch;\n margin-bottom: 5px;\n}\n\n.devices-edit-fields input {\n flex: auto;\n margin: 8px 5px 0 5px;\n}\n\n.devices-edit-fields .device-edit-fixed {\n flex: 0 0 140px;\n}\n\n.devices-edit-fields select {\n margin: 8px 5px 0 5px;\n}\n\n/*# sourceURL=emulation/devicesSettingsTab.css */";Root.Runtime.cachedResources["emulation/deviceModeToolbar.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.device-mode-size-input {\n width: 41px;\n max-height: 18px;\n margin: 0 2px;\n text-align: center;\n}\n\n.device-mode-size-input:focus::-webkit-input-placeholder {\n color: transparent;\n}\n\n.device-mode-size-input:disabled {\n background: transparent;\n -webkit-user-select: none;\n opacity: 0.6;\n}\n\n.device-mode-x {\n margin: 0 1px;\n font-size: 16px;\n}\n\n.device-mode-empty-toolbar-element {\n width: 0;\n}\n\n/*# sourceURL=emulation/deviceModeToolbar.css */";Root.Runtime.cachedResources["emulation/deviceModeView.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow: hidden;\n align-items: stretch;\n flex: auto;\n background-color: hsl(0, 0%, 98%);\n}\n\n.device-mode-toolbar {\n flex: none;\n background-color: hsl(0, 0%, 98%);\n border-bottom: 1px solid #ccc;\n display: flex;\n flex-direction: row;\n align-items: stretch;\n}\n\n.device-mode-toolbar .toolbar {\n overflow: hidden;\n flex: 0 100000 auto;\n padding: 0 5px;\n}\n\n.device-mode-toolbar .toolbar.device-mode-toolbar-fixed-size {\n flex: 0 1 auto;\n}\n\n.device-mode-toolbar-options.toolbar {\n position: sticky;\n right: 0;\n flex: none;\n}\n\n.device-mode-toolbar-spacer {\n flex: 1 1 0;\n display: flex;\n flex-direction: row;\n overflow: hidden;\n}\n\n.device-mode-content-clip {\n overflow: hidden;\n flex: auto;\n}\n\n.device-mode-media-container {\n flex: none;\n overflow: hidden;\n box-shadow: inset 0 -1px #ccc;\n}\n\n.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-media-container {\n margin-bottom: 20px;\n}\n\n.device-mode-presets-container {\n flex: 0 0 20px;\n display: flex;\n}\n\n.device-mode-presets-container-inner {\n flex: auto;\n justify-content: center;\n position: relative;\n background-color: hsl(0, 0%, 90%);\n border: 2px solid hsl(0, 0%, 98%);\n border-bottom: 2px solid hsl(0, 0%, 98%);\n }\n\n.device-mode-presets-container:hover {\n transition: opacity 0.1s;\n transition-delay: 50ms;\n opacity: 1;\n}\n\n.device-mode-preset-bar-outer {\n pointer-events: none;\n display: flex;\n justify-content: center;\n}\n\n.device-mode-preset-bar {\n border-left: 2px solid hsl(0, 0%, 98%);\n border-right: 2px solid hsl(0, 0%, 98%);\n pointer-events: auto;\n text-align: center;\n flex: none;\n cursor: pointer;\n color: #5A5A5A;\n display: flex;\n align-items: center;\n justify-content: center;\n white-space: nowrap;\n margin-bottom: 1px;\n}\n\n.device-mode-preset-bar:hover {\n transition: background-color 0.1s;\n transition-delay: 50ms;\n background-color: #d6d6d6;\n}\n\n.device-mode-preset-bar > span {\n visibility: hidden;\n}\n\n.device-mode-preset-bar:hover > span {\n transition: visibility 0.1s;\n transition-delay: 50ms;\n visibility: visible;\n}\n\n.device-mode-content-area {\n flex: auto;\n position: relative;\n margin: 0;\n}\n\n.device-mode-screen-area {\n position: absolute;\n left: 0;\n right: 0;\n width: 0;\n height: 0;\n background-color: #171717;\n}\n\n.device-mode-content-clip:not(.device-mode-outline-visible) .device-mode-screen-area {\n box-shadow: hsl(240, 3%, 84%) 0 0 0 0.5px, hsla(0, 0%, 80%, 0.4) 0 0 20px;\n}\n\n.device-mode-screen-image {\n position: absolute;\n left: 0;\n top: 0;\n width: 100%;\n height: 100%;\n}\n\n.device-mode-resizer {\n position: absolute;\n display: flex;\n align-items: center;\n justify-content: center;\n overflow: hidden;\n transition: background-color 0.1s ease, opacity 0.1s ease;\n}\n\n.device-mode-resizer:hover {\n background-color: hsla(0, 0%, 0%, 0.1);\n opacity: 1;\n}\n\n.device-mode-resizer > div {\n pointer-events: none;\n}\n\n.device-mode-right-resizer {\n top: 0;\n bottom: -1px;\n right: -20px;\n width: 20px;\n}\n\n.device-mode-left-resizer {\n top: 0;\n bottom: -1px;\n left: -20px;\n width: 20px;\n opacity: 0;\n}\n\n.device-mode-bottom-resizer {\n left: 0;\n right: -1px;\n bottom: -20px;\n height: 20px;\n}\n\n.device-mode-bottom-right-resizer {\n left: 0;\n top: 0;\n right: -20px;\n bottom: -20px;\n background-color: hsla(0, 0%, 0%, 0.02);\n}\n\n.device-mode-bottom-left-resizer {\n left: -20px;\n top: 0;\n right: 0;\n bottom: -20px;\n opacity: 0;\n}\n\n.device-mode-right-resizer > div {\n content: url(Images/resizeHorizontal.png);\n width: 6px;\n height: 26px;\n}\n\n.device-mode-left-resizer > div {\n content: url(Images/resizeHorizontal.png);\n width: 6px;\n height: 26px;\n}\n\n.device-mode-bottom-resizer > div {\n content: url(Images/resizeVertical.png);\n margin-bottom: -2px;\n width: 26px;\n height: 6px;\n}\n\n.device-mode-bottom-right-resizer > div {\n position: absolute;\n bottom: 3px;\n right: 3px;\n width: 13px;\n height: 13px;\n content: url(Images/resizeDiagonal.png);\n}\n\n.device-mode-bottom-left-resizer > div {\n position: absolute;\n bottom: 3px;\n left: 3px;\n width: 13px;\n height: 13px;\n content: url(Images/resizeDiagonal.png);\n transform: rotate(90deg);\n}\n\n@media (-webkit-min-device-pixel-ratio: 1.1) {\n .device-mode-right-resizer > div {\n content: url(Images/resizeHorizontal_2x.png);\n }\n\n .device-mode-left-resizer > div {\n content: url(Images/resizeHorizontal_2x.png);\n }\n\n .device-mode-bottom-resizer > div {\n content: url(Images/resizeVertical_2x.png);\n }\n\n .device-mode-bottom-right-resizer > div {\n content: url(Images/resizeDiagonal_2x.png);\n }\n\n .device-mode-bottom-left-resizer > div {\n content: url(Images/resizeDiagonal_2x.png);\n }\n} /* media */\n\n.device-mode-page-area {\n position: absolute;\n left: 0;\n right: 0;\n width: 0;\n height: 0;\n display: flex;\n background-color: #fcfcfc;\n}\n\n.device-mode-ruler {\n position: absolute;\n overflow: visible;\n}\n\n.device-mode-ruler-top {\n height: 20px;\n right: 0;\n}\n\n.device-mode-ruler-left {\n width: 20px;\n bottom: 0;\n}\n\n.device-mode-ruler-content {\n pointer-events: none;\n position: absolute;\n left: -20px;\n top: -20px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-content {\n border-top: 1px solid transparent;\n right: 0;\n bottom: 20px;\n background-color: hsla(0, 0%, 98%, 0.9);\n}\n\n.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-top .device-mode-ruler-content {\n border-top: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-left .device-mode-ruler-content {\n border-left: 1px solid transparent;\n border-top: 1px solid transparent;\n right: 20px;\n bottom: 0;\n}\n\n.device-mode-content-clip.device-mode-outline-visible .device-mode-ruler-left .device-mode-ruler-content {\n border-left: 1px solid hsl(0, 0%, 50%);\n border-top: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-inner {\n position: absolute;\n}\n\n.device-mode-ruler-top .device-mode-ruler-inner {\n top: 0;\n bottom: 0;\n left: 20px;\n right: 0;\n border-bottom: 1px solid hsl(0, 0%, 50%);\n}\n\n.device-mode-ruler-left .device-mode-ruler-inner {\n left: 0;\n right: 0;\n top: 19px;\n bottom: 0;\n border-right: 1px solid hsl(0, 0%, 50%);\n background-color: hsla(0, 0%, 98%, 0.9);\n}\n\n.device-mode-ruler-marker {\n position: absolute;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker {\n width: 0;\n height: 5px;\n bottom: 0;\n border-right: 1px solid hsl(0, 0%, 50%);\n margin-right: -1px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-medium {\n height: 10px;\n}\n\n.device-mode-ruler-top .device-mode-ruler-marker.device-mode-ruler-marker-large {\n height: 15px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker {\n height: 0;\n width: 5px;\n right: 0;\n border-bottom: 1px solid hsl(0, 0%, 50%);\n margin-bottom: -1px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-medium {\n width: 10px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-marker.device-mode-ruler-marker-large {\n width: 15px;\n}\n\n.device-mode-ruler-text {\n color: hsl(0, 0%, 50%);\n position: relative;\n pointer-events: auto;\n}\n\n.device-mode-ruler-text:hover {\n color: hsl(0, 0%, 10%);\n}\n\n.device-mode-ruler-top .device-mode-ruler-text {\n left: 2px;\n top: -2px;\n}\n\n.device-mode-ruler-left .device-mode-ruler-text {\n left: -4px;\n top: -15px;\n transform: rotate(270deg);\n}\n\n/*# sourceURL=emulation/deviceModeView.css */";Root.Runtime.cachedResources["emulation/geolocationsSettingsTab.css"]="/*\n * Copyright 2018 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n overflow: hidden;\n}\n\n.header {\n padding: 0 0 6px;\n border-bottom: 1px solid #EEEEEE;\n font-size: 18px;\n font-weight: normal;\n flex: none;\n}\n\n.add-geolocations-button {\n flex: none;\n margin: 10px 2px;\n min-width: 140px;\n align-self: flex-start;\n}\n\n.geolocations-list {\n max-width: 600px;\n min-width: 340px;\n flex: auto;\n}\n\n.geolocations-list-item {\n padding: 3px 5px 3px 5px;\n height: 30px;\n display: flex;\n align-items: center;\n position: relative;\n flex: auto 1 1;\n}\n\n.geolocations-list-text {\n white-space: nowrap;\n text-overflow: ellipsis;\n flex: 0 0 70px;\n -webkit-user-select: none;\n color: #222;\n text-align: end;\n position: relative;\n}\n\n.geolocations-list-text:last-child {\n flex: 0 0 170px;\n}\n\n.geolocations-list-title {\n text-align: start;\n flex: auto;\n display: flex;\n align-items: flex-start;\n}\n\n.geolocations-list-title-text {\n overflow: hidden;\n flex: auto;\n white-space: nowrap;\n text-overflow: ellipsis;\n}\n\n.geolocations-list-separator {\n flex: 0 0 1px;\n background-color: rgb(231, 231, 231);\n height: 30px;\n margin: 0 4px;\n}\n\n.geolocations-list-separator-invisible {\n visibility: hidden;\n height: 100% !important;\n}\n\n.geolocations-edit-row {\n flex: none;\n display: flex;\n flex-direction: row;\n margin: 6px 5px;\n}\n\n.geolocations-edit-row input {\n width: 100%;\n text-align: inherit;\n}\n\n/*# sourceURL=emulation/geolocationsSettingsTab.css */";Root.Runtime.cachedResources["emulation/inspectedPagePlaceholder.css"]="/*\n * Copyright 2016 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n background-color: white;\n}\n\n/*# sourceURL=emulation/inspectedPagePlaceholder.css */";Root.Runtime.cachedResources["emulation/mediaQueryInspector.css"]="/*\n * Copyright 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n/* Media query bars */\n\n.media-inspector-view {\n height: 50px;\n}\n\n.media-inspector-marker-container {\n height: 14px;\n margin: 2px 0;\n position: relative;\n}\n\n.media-inspector-bar {\n display: flex;\n flex-direction: row;\n align-items: stretch;\n pointer-events: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n}\n\n.media-inspector-marker {\n flex: none;\n pointer-events: auto;\n margin: 1px 0;\n white-space: nowrap;\n z-index: auto;\n position: relative;\n}\n\n.media-inspector-marker-spacer {\n flex: auto;\n}\n\n.media-inspector-marker:hover {\n margin: -1px 0;\n opacity: 1;\n}\n\n.media-inspector-marker-max-width {\n background-color: hsl(207, 90%, 77%);\n border-right: 2px solid hsl(207, 90%, 61%);\n border-left: 2px solid hsl(207, 90%, 61%);\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-max-width:not(:hover) {\n background-color: hsl(199, 94%, 94%);\n}\n\n.media-inspector-marker-min-max-width {\n background-color: hsl(88, 50%, 76%);\n border-left: 2px solid #689F38;\n border-right: 2px solid hsl(92, 48%, 42%);\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-min-max-width:not(:hover) {\n background-color: hsl(125, 39%, 94%);\n}\n\n.media-inspector-marker-min-max-width:hover {\n z-index: 1;\n}\n\n.media-inspector-marker-min-width {\n background-color: hsl(36, 100%, 75%);\n flex: auto;\n}\n\n.media-inspector-marker-inactive .media-inspector-marker-min-width:not(:hover) {\n background-color: hsl(37, 100%, 94%);\n}\n\n.media-inspector-marker-min-width-right {\n border-left: 2px solid hsl(30, 100%, 48%);\n}\n\n.media-inspector-marker-min-width-left {\n border-right: 2px solid hsl(30, 100%, 48%);\n}\n\n/* Media query labels */\n\n.media-inspector-marker:not(:hover) .media-inspector-marker-label-container {\n display: none;\n}\n\n.media-inspector-marker-label-container {\n position: absolute;\n z-index: 1;\n}\n\n.media-inspector-marker-label-container-left {\n left: -2px;\n}\n\n.media-inspector-marker-label-container-right {\n right: -2px;\n}\n\n.media-inspector-marker-label {\n color: #222;\n position: absolute;\n top: 1px;\n bottom: 0;\n font-size: 12px;\n pointer-events: none;\n}\n\n.media-inspector-label-right {\n right: 4px;\n}\n\n.media-inspector-label-left {\n left: 4px;\n}\n\n/*# sourceURL=emulation/mediaQueryInspector.css */";Root.Runtime.cachedResources["emulation/sensors.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.sensors-view {\n padding: 12px;\n display: block;\n}\n\n.sensors-view input {\n width: 100%;\n max-width: 120px;\n margin: -5px 10px 0px 0px;\n text-align: end;\n}\n\n.sensors-view input[readonly] {\n background-color: rgb(235, 235, 228);\n}\n\n.sensors-view fieldset {\n border: none;\n padding: 10px 0px;\n margin-left: 0;\n flex: 0 0 auto;\n margin: 0;\n}\n\n.sensors-view fieldset[disabled] {\n opacity: 0.5;\n}\n\n.sensors-view input:focus::-webkit-input-placeholder {\n color: transparent !important;\n}\n\n.sensors-view .chrome-select {\n width: 200px;\n}\n\n.sensors-group-title {\n width: 80px;\n line-height: 24px;\n}\n\n.sensors-group {\n display: flex;\n flex-wrap: wrap;\n margin-bottom: 10px;\n}\n\n.geo-fields {\n flex: 2 0 200px;\n}\n\n.latlong-group {\n display: flex;\n margin-bottom: 10px;\n}\n\n.latlong-title {\n width: 70px;\n}\n\n.timezone-error {\n margin-left: 10px;\n color: var(--input-validation-error);\n}\n\n/* Device Orientation */\n\n.orientation-content {\n display: flex;\n flex-wrap: wrap;\n}\n\n.orientation-fields {\n margin-right: 10px;\n}\n\n.orientation-stage {\n -webkit-perspective: 700px;\n -webkit-perspective-origin: 50% 50%;\n width: 160px;\n height: 150px;\n background: linear-gradient(#E1F5FE 0%, #E1F5FE 64%, #b0Ebf3 64%, #DEF6F9 100%);\n transition: 0.2s ease opacity, 0.2s ease -webkit-filter;\n overflow: hidden;\n margin-bottom: 10px;\n}\n\n.orientation-stage.disabled {\n -webkit-filter: grayscale();\n opacity: 0.5;\n cursor: default !important;\n}\n\n.orientation-element,\n.orientation-element::before,\n.orientation-element::after{\n position: absolute;\n box-sizing: border-box;\n transform-style: preserve-3d;\n background: no-repeat;\n background-size: cover;\n backface-visibility: hidden;\n}\n\n.orientation-box {\n width: 62px;\n height: 122px;\n left: 0;\n right: 0;\n top: 0;\n bottom: 0;\n margin: auto;\n transform: rotate3d(1, 0, 0, 90deg);\n}\n\n.orientation-box.is-animating, .is-animating .orientation-layer {\n transition: transform 300ms cubic-bezier(0.4, 0, 0.2, 1) 0ms;\n}\n\n.orientation-layer {\n width: 100%;\n height: 100%;\n transform-style: preserve-3d;\n}\n\n.orientation-front,\n.orientation-back\n{\n width: 62px;\n height: 122px;\n border-radius: 8px;\n}\n\n.orientation-front {\n background-image: url(Images/accelerometer-front.svg);\n}\n\n.orientation-back {\n transform: rotateY(180deg) translateZ(8px);\n background-image: url(Images/accelerometer-back.svg);\n}\n\n\n.orientation-left,\n.orientation-right {\n width: 8px;\n height: 106px;\n top: 8px;\n background-position: center center;\n}\n\n.orientation-left {\n left: -8px;\n transform-origin: right center;\n transform: rotateY(-90deg);\n background-image: url(Images/accelerometer-left.png);\n}\n\n\n.orientation-right {\n right: -8px;\n transform-origin: left center;\n transform: rotateY(90deg);\n background-image: url(Images/accelerometer-right.png);\n}\n\n.orientation-left::before,\n.orientation-left::after,\n.orientation-right::before,\n.orientation-right::after\n{\n content: '';\n width: 8px;\n height: 6px;\n}\n\n.orientation-left::before,\n.orientation-left::after\n{\n background-image: url(Images/accelerometer-left.png);\n}\n\n.orientation-right::before,\n.orientation-right::after\n{\n background-image: url(Images/accelerometer-right.png);\n}\n\n.orientation-left::before,\n.orientation-right::before {\n top: -6px;\n transform-origin: center bottom;\n transform: rotateX(26deg);\n background-position: center top;\n}\n\n.orientation-left::after,\n.orientation-right::after {\n bottom: -6px;\n transform-origin: center top;\n transform: rotateX(-25deg);\n background-position: center bottom;\n}\n\n.orientation-top,\n.orientation-bottom {\n width: 50px;\n height: 8px;\n left: 8px;\n background-position: center center;\n}\n\n.orientation-top {\n top: -8px;\n transform-origin: center bottom;\n transform: rotateX(90deg);\n background-image: url(Images/accelerometer-top.png);\n}\n\n\n.orientation-bottom {\n bottom: -8px;\n transform-origin: center top;\n transform: rotateX(-90deg);\n background-image: url(Images/accelerometer-bottom.png);\n}\n\n\n.orientation-top::before,\n.orientation-top::after,\n.orientation-bottom::before,\n.orientation-bottom::after\n{\n content: '';\n width: 8px;\n height: 8px;\n}\n\n.orientation-top::before,\n.orientation-top::after\n{\n background-image: url(Images/accelerometer-top.png);\n}\n\n.orientation-bottom::before,\n.orientation-bottom::after\n{\n background-image: url(Images/accelerometer-bottom.png);\n}\n\n.orientation-top::before,\n.orientation-bottom::before {\n left: -6px;\n transform-origin: right center;\n transform: rotateY(-26deg);\n background-position: left center;\n}\n\n.orientation-top::after,\n.orientation-bottom::after {\n right: -6px;\n transform-origin: left center;\n transform: rotateY(26deg);\n background-position: right center;\n}\n\n.orientation-axis-input-container {\n margin-bottom: 10px;\n}\n\n.orientation-axis-input-container input {\n max-width: 120px;\n}\n\n.orientation-reset-button {\n min-width: 80px;\n}\n\nfieldset.device-orientation-override-section {\n margin: 0;\n display: flex;\n}\n\n.panel-section-separator {\n height: 2px;\n margin-bottom: 8px;\n background: #f1f1f1;\n}\n\n.reload-warning {\n align-self: center;\n margin-left: 10px;\n}\n\nbutton.text-button {\n margin: 0 10px;\n}\n\n/*# sourceURL=emulation/sensors.css */";Root.Runtime.cachedResources["inspector_main/nodeIcon.css"]="/*\n * Copyright 2017 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n.node-icon {\n width: 28px;\n height: 26px;\n background-image: url(Images/nodeIcon.png);\n background-size: 17px 17px;\n background-repeat: no-repeat;\n background-position: center;\n opacity: 0.8;\n cursor: auto;\n}\n\n.node-icon:hover {\n opacity: 1.0;\n}\n\n.node-icon.inactive {\n filter: grayscale(100%);\n}\n\n/*# sourceURL=inspector_main/nodeIcon.css */";Root.Runtime.cachedResources["inspector_main/renderingOptions.css"]="/*\n * Copyright (c) 2015 The Chromium Authors. All rights reserved.\n * Use of this source code is governed by a BSD-style license that can be\n * found in the LICENSE file.\n */\n\n:host {\n padding: 12px;\n }\n\n[is=dt-checkbox] {\n margin: 0 0 10px 0;\n flex: none;\n}\n\n.panel-section-separator {\n height: 1px;\n margin-bottom: 10px;\n background: #f0f0f0;\n flex: none;\n}\n\n.chrome-select-label {\n margin-bottom: 16px;\n}\n\n/*# sourceURL=inspector_main/renderingOptions.css */";