23afffa46d
Previously changing src to the same value won't have any effect, which does not follow the behavior of browsers.
205 lines
7.9 KiB
CoffeeScript
205 lines
7.9 KiB
CoffeeScript
WebViewImpl = require './web-view'
|
|
guestViewInternal = require './guest-view-internal'
|
|
webViewConstants = require './web-view-constants'
|
|
remote = require 'remote'
|
|
|
|
# Helper function to resolve url set in attribute.
|
|
a = document.createElement 'a'
|
|
resolveUrl = (url) ->
|
|
a.href = url
|
|
a.href
|
|
|
|
# Attribute objects.
|
|
# Default implementation of a WebView attribute.
|
|
class WebViewAttribute
|
|
constructor: (name, webViewImpl) ->
|
|
@name = name
|
|
@webViewImpl = webViewImpl
|
|
@ignoreMutation = false
|
|
|
|
@defineProperty()
|
|
|
|
# Retrieves and returns the attribute's value.
|
|
getValue: -> @webViewImpl.webviewNode.getAttribute(@name) || ''
|
|
|
|
# Sets the attribute's value.
|
|
setValue: (value) -> @webViewImpl.webviewNode.setAttribute(@name, value || '')
|
|
|
|
# Changes the attribute's value without triggering its mutation handler.
|
|
setValueIgnoreMutation: (value) ->
|
|
@ignoreMutation = true
|
|
@webViewImpl.webviewNode.setAttribute(@name, value || '')
|
|
@ignoreMutation = false
|
|
|
|
# Defines this attribute as a property on the webview node.
|
|
defineProperty: ->
|
|
Object.defineProperty @webViewImpl.webviewNode, @name,
|
|
get: => @getValue()
|
|
set: (value) => @setValue value
|
|
enumerable: true
|
|
|
|
# Called when the attribute's value changes.
|
|
handleMutation: ->
|
|
|
|
# An attribute that is treated as a Boolean.
|
|
class BooleanAttribute extends WebViewAttribute
|
|
constructor: (name, webViewImpl) ->
|
|
super name, webViewImpl
|
|
|
|
getValue: -> @webViewImpl.webviewNode.hasAttribute @name
|
|
|
|
setValue: (value) ->
|
|
unless value
|
|
@webViewImpl.webviewNode.removeAttribute @name
|
|
else
|
|
@webViewImpl.webviewNode.setAttribute @name, ''
|
|
|
|
# Attribute that specifies whether transparency is allowed in the webview.
|
|
class AllowTransparencyAttribute extends BooleanAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl
|
|
|
|
handleMutation: (oldValue, newValue) ->
|
|
return unless @webViewImpl.guestInstanceId
|
|
guestViewInternal.setAllowTransparency @webViewImpl.guestInstanceId, @getValue()
|
|
|
|
# Attribute used to define the demension limits of autosizing.
|
|
class AutosizeDimensionAttribute extends WebViewAttribute
|
|
constructor: (name, webViewImpl) ->
|
|
super name, webViewImpl
|
|
|
|
getValue: -> parseInt(@webViewImpl.webviewNode.getAttribute(@name)) || 0
|
|
|
|
handleMutation: (oldValue, newValue) ->
|
|
return unless @webViewImpl.guestInstanceId
|
|
guestViewInternal.setAutoSize @webViewImpl.guestInstanceId,
|
|
enableAutoSize: @webViewImpl.attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue()
|
|
min:
|
|
width: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0
|
|
height: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0
|
|
max:
|
|
width: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0
|
|
height: parseInt @webViewImpl.attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0
|
|
|
|
# Attribute that specifies whether the webview should be autosized.
|
|
class AutosizeAttribute extends BooleanAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_AUTOSIZE, webViewImpl
|
|
|
|
handleMutation: AutosizeDimensionAttribute::handleMutation
|
|
|
|
# Attribute representing the state of the storage partition.
|
|
class PartitionAttribute extends WebViewAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_PARTITION, webViewImpl
|
|
@validPartitionId = true
|
|
|
|
handleMutation: (oldValue, newValue) ->
|
|
newValue = newValue || ''
|
|
|
|
# The partition cannot change if the webview has already navigated.
|
|
unless @webViewImpl.beforeFirstNavigation
|
|
window.console.error webViewConstants.ERROR_MSG_ALREADY_NAVIGATED
|
|
@setValueIgnoreMutation oldValue
|
|
return
|
|
|
|
if newValue is 'persist:'
|
|
@validPartitionId = false
|
|
window.console.error webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE
|
|
|
|
# Attribute that handles the location and navigation of the webview.
|
|
class SrcAttribute extends WebViewAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_SRC, webViewImpl
|
|
@setupMutationObserver()
|
|
|
|
getValue: ->
|
|
if @webViewImpl.webviewNode.hasAttribute @name
|
|
resolveUrl @webViewImpl.webviewNode.getAttribute(@name)
|
|
else
|
|
''
|
|
|
|
handleMutation: (oldValue, newValue) ->
|
|
# Once we have navigated, we don't allow clearing the src attribute.
|
|
# Once <webview> enters a navigated state, it cannot return to a
|
|
# placeholder state.
|
|
if not newValue and oldValue
|
|
# src attribute changes normally initiate a navigation. We suppress
|
|
# the next src attribute handler call to avoid reloading the page
|
|
# on every guest-initiated navigation.
|
|
@setValueIgnoreMutation oldValue
|
|
return
|
|
@parse()
|
|
|
|
# The purpose of this mutation observer is to catch assignment to the src
|
|
# attribute without any changes to its value. This is useful in the case
|
|
# where the webview guest has crashed and navigating to the same address
|
|
# spawns off a new process.
|
|
setupMutationObserver: ->
|
|
@observer = new MutationObserver (mutations) =>
|
|
for mutation in mutations
|
|
@handleMutation mutation.oldValue, @getValue()
|
|
params =
|
|
attributes: true,
|
|
attributeOldValue: true,
|
|
attributeFilter: [@name]
|
|
@observer.observe @webViewImpl.webviewNode, params
|
|
|
|
parse: ->
|
|
if not @webViewImpl.elementAttached or
|
|
not @webViewImpl.attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId or
|
|
not @.getValue()
|
|
return
|
|
|
|
unless @webViewImpl.guestInstanceId?
|
|
if @webViewImpl.beforeFirstNavigation
|
|
@webViewImpl.beforeFirstNavigation = false
|
|
@webViewImpl.createGuest()
|
|
return
|
|
|
|
# Navigate to |this.src|.
|
|
httpreferrer = @webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue()
|
|
urlOptions = if httpreferrer then {httpreferrer} else {}
|
|
remote.getGuestWebContents(@webViewImpl.guestInstanceId).loadUrl @getValue(), urlOptions
|
|
|
|
# Attribute specifies HTTP referrer.
|
|
class HttpReferrerAttribute extends WebViewAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_HTTPREFERRER, webViewImpl
|
|
|
|
# Attribute that set preload script.
|
|
class PreloadAttribute extends WebViewAttribute
|
|
constructor: (webViewImpl) ->
|
|
super webViewConstants.ATTRIBUTE_PRELOAD, webViewImpl
|
|
|
|
getValue: ->
|
|
return '' unless @webViewImpl.webviewNode.hasAttribute @name
|
|
preload = resolveUrl @webViewImpl.webviewNode.getAttribute(@name)
|
|
protocol = preload.substr 0, 5
|
|
unless protocol is 'file:'
|
|
console.error webViewConstants.ERROR_MSG_INVALID_PRELOAD_ATTRIBUTE
|
|
preload = ''
|
|
preload
|
|
|
|
# Sets up all of the webview attributes.
|
|
WebViewImpl::setupWebViewAttributes = ->
|
|
@attributes = {}
|
|
|
|
@attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] = new AllowTransparencyAttribute(this)
|
|
@attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] = new AutosizeAttribute(this)
|
|
@attributes[webViewConstants.ATTRIBUTE_PARTITION] = new PartitionAttribute(this)
|
|
@attributes[webViewConstants.ATTRIBUTE_SRC] = new SrcAttribute(this)
|
|
@attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER] = new HttpReferrerAttribute(this)
|
|
@attributes[webViewConstants.ATTRIBUTE_NODEINTEGRATION] = new BooleanAttribute(webViewConstants.ATTRIBUTE_NODEINTEGRATION, this)
|
|
@attributes[webViewConstants.ATTRIBUTE_PLUGINS] = new BooleanAttribute(webViewConstants.ATTRIBUTE_PLUGINS, this)
|
|
@attributes[webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY] = new BooleanAttribute(webViewConstants.ATTRIBUTE_DISABLEWEBSECURITY, this)
|
|
@attributes[webViewConstants.ATTRIBUTE_PRELOAD] = new PreloadAttribute(this)
|
|
|
|
autosizeAttributes = [
|
|
webViewConstants.ATTRIBUTE_MAXHEIGHT
|
|
webViewConstants.ATTRIBUTE_MAXWIDTH
|
|
webViewConstants.ATTRIBUTE_MINHEIGHT
|
|
webViewConstants.ATTRIBUTE_MINWIDTH
|
|
]
|
|
for attribute in autosizeAttributes
|
|
@attributes[attribute] = new AutosizeDimensionAttribute(attribute, this)
|