<commit_before>Utils = require "../Utils"
{_}   = require "../Underscore"

{BaseClass} = require "../BaseClass"
{Layer} = require "../Layer"
{Defaults} = require "../Defaults"
{Events} = require "../Events"

###

Device._setup()
Device._update()
Device._setupContext()

Device.fullScreen bool
Device.deviceType str
Device.padding int

Device.orientation(orientation:float)
Device.orientationName landscape|portrait|unknown
Device.rotateLeft()
Device.rotateRight()

Device.setDeviceScale(zoom:float, animate:bool)
Device.setContentScale(zoom:float, animate:bool)

Device.nextHand()

# Events
Events.DeviceTypeDidChange
Events.DeviceFullScreenDidChange


###

# _.extend Events,
# 	DeviceTypeDidChange: "change:deviceType"
# 	DeviceScaleDidChange: "change:deviceScale"
# 	DeviceContentScaleDidChange: "change:contentScale"
# 	DeviceFullScreenDidChange: ""

class exports.DeviceComponent extends BaseClass

	@define "context", get: -> @_context

	constructor: (options={}) ->

		defaults = Defaults.getDefaults("DeviceComponent", options)

		# If we have defaults for DeviceView, we are likely using an older version of
		# Framer Studio. It's best to default to those then for now.
		if Framer.Defaults.hasOwnProperty("DeviceView")
			defaults = _.extend(defaults, Framer.Defaults.DeviceView)

		@_setup()

		@animationOptions = defaults.animationOptions
		@deviceType = defaults.deviceType

		_.extend(@, _.defaults(options, defaults))

		@Type =
			Tablet: "tablet"
			Phone: "phone"
			Computer: "computer"

	_setup: ->

		if @_setupDone
			return

		@_setupDone = true

		@background = new Layer
		@background.clip = true
		@background.backgroundColor = "transparent"
		@background.classList.add("DeviceBackground")

		@hands    = new Layer
		@handsImageLayer = new Layer parent: @hands
		@phone    = new Layer parent: @hands
		@screen   = new Layer parent: @phone
		@viewport = new Layer parent: @screen
		@content  = new Layer parent: @viewport

		@hands.backgroundColor = "transparent"
		@hands._alwaysUseImageCache = true
		@handsImageLayer.backgroundColor = "transparent"

		@phone.backgroundColor = "transparent"
		@phone.classList.add("DevicePhone")

		@screen.classList.add("DeviceScreen")
		@screen.clip = true

		@viewport.backgroundColor = "transparent"
		@viewport.classList.add("DeviceComponentPort")

		@content.backgroundColor = "transparent"
		@content.classList.add("DeviceContent")

		@content.originX = 0
		@content.originY = 0

		Framer.CurrentContext.domEventManager.wrap(window).addEventListener("resize", @_update) unless Utils.isMobile()
		Framer.CurrentContext.domEventManager.wrap(window).addEventListener("resize", @_orientationChange) if Utils.isMobile()

		# This avoids rubber banding on mobile
		for layer in [@background, @phone, @viewport, @content, @screen]
			layer.on "touchmove", (event) -> event.preventDefault()

		@_context = new Framer.Context(parent: @content, name: "DeviceScreen")
		@_context.perspective = 1200
		@_context.device = @

	_update: =>

		# Todo: pixel align at zoom level 1, 0.5

		contentScaleFactor = @contentScale
		contentScaleFactor = 1 if contentScaleFactor > 1

		if @_shouldRenderFullScreen()

			width = window.innerWidth / contentScaleFactor
			height = window.innerHeight / contentScaleFactor

			for layer in [@background, @hands, @phone, @viewport, @content, @screen]
				layer.x = layer.y = 0
				layer.width = width
				layer.height = height
				layer.scale = 1

			@content.scale = contentScaleFactor

		else
			backgroundOverlap = 100

			@background.x = 0 - backgroundOverlap
			@background.y = 0 - backgroundOverlap
			@background.width  = window.innerWidth  + (2 * backgroundOverlap)
			@background.height = window.innerHeight + (2 * backgroundOverlap)

			@_updateDeviceImage()
			@hands.scale = @_calculatePhoneScale()
			@hands.center()
			@phone.center()

			[width, height] = @_getOrientationDimensions(
				@_device.screenWidth / contentScaleFactor,
				@_device.screenHeight / contentScaleFactor)

			@screen.width  = @viewport.width = @_device.screenWidth
			@screen.height = @viewport.height = @_device.screenHeight

			@content.width  = width
			@content.height = height
			@screen.center()

			@setHand(@selectedHand) if @selectedHand and @_orientation is 0

	_shouldRenderFullScreen: ->

		if Utils.isInsideIframe()
			return false

		if not @_device
			return true

		if @fullScreen is true
			return true

		if @deviceType is "fullscreen"
			return true

		if Utils.deviceType() is "phone" and Utils.deviceType() is @_device.deviceType
			return true

		if Utils.deviceType() is "tablet" and Utils.deviceType() is @_device.deviceType
			return true

		if Utils.deviceType() is "phone" and @_device.deviceType is "tablet"<commit_msg>Fix display of fullscreen device when embedded in an in iframe.<commit_after>Utils = require "../Utils"
{_}   = require "../Underscore"

{BaseClass} = require "../BaseClass"
{Layer} = require "../Layer"
{Defaults} = require "../Defaults"
{Events} = require "../Events"

###

Device._setup()
Device._update()
Device._setupContext()

Device.fullScreen bool
Device.deviceType str
Device.padding int

Device.orientation(orientation:float)
Device.orientationName landscape|portrait|unknown
Device.rotateLeft()
Device.rotateRight()

Device.setDeviceScale(zoom:float, animate:bool)
Device.setContentScale(zoom:float, animate:bool)

Device.nextHand()

# Events
Events.DeviceTypeDidChange
Events.DeviceFullScreenDidChange


###

# _.extend Events,
# 	DeviceTypeDidChange: "change:deviceType"
# 	DeviceScaleDidChange: "change:deviceScale"
# 	DeviceContentScaleDidChange: "change:contentScale"
# 	DeviceFullScreenDidChange: ""

class exports.DeviceComponent extends BaseClass

	@define "context", get: -> @_context

	constructor: (options={}) ->

		defaults = Defaults.getDefaults("DeviceComponent", options)

		# If we have defaults for DeviceView, we are likely using an older version of
		# Framer Studio. It's best to default to those then for now.
		if Framer.Defaults.hasOwnProperty("DeviceView")
			defaults = _.extend(defaults, Framer.Defaults.DeviceView)

		@_setup()

		@animationOptions = defaults.animationOptions
		@deviceType = defaults.deviceType

		_.extend(@, _.defaults(options, defaults))

		@Type =
			Tablet: "tablet"
			Phone: "phone"
			Computer: "computer"

	_setup: ->

		if @_setupDone
			return

		@_setupDone = true

		@background = new Layer
		@background.clip = true
		@background.backgroundColor = "transparent"
		@background.classList.add("DeviceBackground")

		@hands    = new Layer
		@handsImageLayer = new Layer parent: @hands
		@phone    = new Layer parent: @hands
		@screen   = new Layer parent: @phone
		@viewport = new Layer parent: @screen
		@content  = new Layer parent: @viewport

		@hands.backgroundColor = "transparent"
		@hands._alwaysUseImageCache = true
		@handsImageLayer.backgroundColor = "transparent"

		@phone.backgroundColor = "transparent"
		@phone.classList.add("DevicePhone")

		@screen.classList.add("DeviceScreen")
		@screen.clip = true

		@viewport.backgroundColor = "transparent"
		@viewport.classList.add("DeviceComponentPort")

		@content.backgroundColor = "transparent"
		@content.classList.add("DeviceContent")

		@content.originX = 0
		@content.originY = 0

		Framer.CurrentContext.domEventManager.wrap(window).addEventListener("resize", @_update) unless Utils.isMobile()
		Framer.CurrentContext.domEventManager.wrap(window).addEventListener("resize", @_orientationChange) if Utils.isMobile()

		# This avoids rubber banding on mobile
		for layer in [@background, @phone, @viewport, @content, @screen]
			layer.on "touchmove", (event) -> event.preventDefault()

		@_context = new Framer.Context(parent: @content, name: "DeviceScreen")
		@_context.perspective = 1200
		@_context.device = @

	_update: =>

		# Todo: pixel align at zoom level 1, 0.5

		contentScaleFactor = @contentScale
		contentScaleFactor = 1 if contentScaleFactor > 1

		if @_shouldRenderFullScreen()

			width = window.innerWidth / contentScaleFactor
			height = window.innerHeight / contentScaleFactor

			for layer in [@background, @hands, @phone, @viewport, @content, @screen]
				layer.x = layer.y = 0
				layer.width = width
				layer.height = height
				layer.scale = 1

			@content.scale = contentScaleFactor

		else
			backgroundOverlap = 100

			@background.x = 0 - backgroundOverlap
			@background.y = 0 - backgroundOverlap
			@background.width  = window.innerWidth  + (2 * backgroundOverlap)
			@background.height = window.innerHeight + (2 * backgroundOverlap)

			@_updateDeviceImage()
			@hands.scale = @_calculatePhoneScale()
			@hands.center()
			@phone.center()

			[width, height] = @_getOrientationDimensions(
				@_device.screenWidth / contentScaleFactor,
				@_device.screenHeight / contentScaleFactor)

			@screen.width  = @viewport.width = @_device.screenWidth
			@screen.height = @viewport.height = @_device.screenHeight

			@content.width  = width
			@content.height = height
			@screen.center()

			@setHand(@selectedHand) if @selectedHand and @_orientation is 0

	_shouldRenderFullScreen: ->

		if not @_device
			return true

		if @fullScreen is true
			return true

		if @deviceType is "fullscreen"
			return true

		if Utils.isInsideIframe()
			return false

		if Utils.deviceType() is "phone" and Utils.deviceType() is @_device.deviceType
			return true

		if Utils.deviceType() is "tablet" and Utils.deviceType() is @_device.deviceType
			return true

		if Utils.deviceType() is "phone" and @_device.deviceType is "tablet"
{'fraction_non_alphanumeric': 0.11523889707430014, 'fraction_numerical': 0.004420122079562197, 'mean_word_length': 4.4179019384264535, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1676288', 'n_tokens_mistral': 3292, 'n_tokens_neox': 2836, 'n_words': 701}