Got rid of the internal copies of webview attributes

Imported from:
abb035a09b%5E%21/
This commit is contained in:
Cheng Zhao 2014-12-08 16:56:14 -08:00
parent d7eae69587
commit 2c27b953b5
2 changed files with 75 additions and 91 deletions

View file

@ -6,46 +6,52 @@ webViewConstants = require './web-view-constants'
class WebViewAttribute
constructor: (name, webViewImpl) ->
@name = name
@value = ''
@webViewImpl = webViewImpl
@ignoreNextMutation = false
getValue: -> @value || ''
# Retrieves and returns the attribute's value.
getValue: -> @webViewImpl.webviewNode.getAttribute(@name) || ''
setValue: (value) -> @value = value
# Sets the attribute's value.
setValue: (value) -> @webViewImpl.webviewNode.setAttribute(@name, value || '')
# Called when the attribute's value changes.
handleMutation: ->
# Attribute specifying whether transparency is allowed in the webview.
class BooleanAttribute extends WebViewAttribute
constructor: (name, webViewImpl) ->
super name, webViewImpl
getValue: ->
# This attribute is treated as a boolean, and is retrieved as such.
@webViewImpl.webviewNode.hasAttribute @name
setValue: (value) ->
unless value
@webViewImpl.webviewNode.removeAttribute @name
else
@webViewImpl.webviewNode.setAttribute @name, ''
# Attribute representing the state of the storage partition.
class Partition extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_PARTITION, webViewImpl
@validPartitionId = true
@persistStorage = false
@storagePartitionId = ''
@webViewImpl = webViewImpl
getValue: ->
return '' unless @validPartitionId
(if @persistStorage then 'persist:' else '') + @storagePartitionId
handleMutation: (oldValue, newValue) ->
newValue = newValue || ''
setValue: (value) ->
result = {}
hasNavigated = !@webViewImpl.beforeFirstNavigation
if hasNavigated
result.error = webViewConstants.ERROR_MSG_ALREADY_NAVIGATED
return result
value = '' unless value
LEN = 'persist:'.length
if value.substr(0, LEN) == 'persist:'
value = value.substr LEN
unless value
@validPartitionId = false
result.error = webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE
return result
@persistStorage = true
else
@persistStorage = false
@storagePartitionId = value
result
# The partition cannot change if the webview has already navigated.
unless @webViewImpl.beforeFirstNavigation
window.console.error webViewConstants.ERROR_MSG_ALREADY_NAVIGATED
@ignoreNextMutation = true
@webViewImpl.webviewNode.setAttribute @name, oldValue
return
if newValue is 'persist:'
@validPartitionId = false
window.console.error webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE
# Sets up all of the webview attributes.
WebView::setupWebViewAttributes = ->
@ -53,12 +59,14 @@ WebView::setupWebViewAttributes = ->
# Initialize the attributes with special behavior (and custom attribute
# objects).
@attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY] =
new BooleanAttribute(webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, this)
@attributes[webViewConstants.ATTRIBUTE_AUTOSIZE] =
new BooleanAttribute(webViewConstants.ATTRIBUTE_AUTOSIZE, this)
@attributes[webViewConstants.ATTRIBUTE_PARTITION] = new Partition(this)
# Initialize the remaining attributes, which have default behavior.
defaultAttributes = [
webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY
webViewConstants.ATTRIBUTE_AUTOSIZE
webViewConstants.ATTRIBUTE_MAXHEIGHT
webViewConstants.ATTRIBUTE_MAXWIDTH
webViewConstants.ATTRIBUTE_MINHEIGHT

View file

@ -27,7 +27,6 @@ class WebView
@beforeFirstNavigation = true
@contentWindow = null
@validPartitionId = true
# Used to save some state upon deferred attachment.
# If <object> bindings is not available, we defer attachment.
# This state contains whether or not the attachment request was for
@ -74,7 +73,6 @@ class WebView
guestViewInternal.destroyGuest @guestInstanceId
@guestInstanceId = undefined
@beforeFirstNavigation = true
@validPartitionId = true
@attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true
@contentWindow = null
@internalInstanceId = 0
@ -103,10 +101,9 @@ class WebView
setupAutoSizeProperties: ->
for attributeName in AUTO_SIZE_ATTRIBUTES
@attributes[attributeName].setValue @webviewNode.getAttribute(attributeName)
Object.defineProperty @webviewNode, attributeName,
get: => @attributes[attributeName].getValue()
set: (value) => @webviewNode.setAttribute attributeName, value
set: (value) => @attributes[attributeName].setValue value
enumerable: true
setupWebviewNodeProperties: ->
@ -114,8 +111,7 @@ class WebView
Object.defineProperty @webviewNode, webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY,
get: => @attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue()
set: (value) =>
@webviewNode.setAttribute webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, value
set: (value) => @attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].setValue value
enumerable: true
# We cannot use {writable: true} property descriptor because we want a
@ -129,22 +125,17 @@ class WebView
Object.defineProperty @webviewNode, webViewConstants.ATTRIBUTE_PARTITION,
get: => @attributes[webViewConstants.ATTRIBUTE_PARTITION].getValue()
set: (value) =>
result = @attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue value
throw result.error if result.error?
@webviewNode.setAttribute webViewConstants.ATTRIBUTE_PARTITION, value
set: (value) => @attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue value
enumerable: true
@attributes[webViewConstants.ATTRIBUTE_SRC].setValue @webviewNode.getAttribute(webViewConstants.ATTRIBUTE_SRC)
Object.defineProperty @webviewNode, webViewConstants.ATTRIBUTE_SRC,
get: => @attributes[webViewConstants.ATTRIBUTE_SRC].getValue()
set: (value) => @webviewNode.setAttribute webViewConstants.ATTRIBUTE_SRC, value
set: (value) => @attributes[webViewConstants.ATTRIBUTE_SRC].setValue value
enumerable: true
@attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].setValue @webviewNode.getAttribute(webViewConstants.ATTRIBUTE_HTTPREFERRER)
Object.defineProperty @webviewNode, webViewConstants.ATTRIBUTE_HTTPREFERRER,
get: => @attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue()
set: (value) => @webviewNode.setAttribute webViewConstants.ATTRIBUTE_HTTPREFERRER, value
set: (value) => @attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].setValue value
enumerable: true
# The purpose of this mutation observer is to catch assignment to the src
@ -155,7 +146,7 @@ class WebView
@srcAndPartitionObserver = new MutationObserver (mutations) =>
for mutation in mutations
oldValue = mutation.oldValue
newValue = @webviewNode.getAttribute mutation.attributeName
newValue = @attributes[mutation.attributeName].getValue()
return if oldValue isnt newValue
@handleWebviewAttributeMutation mutation.attributeName, oldValue, newValue
params =
@ -173,33 +164,33 @@ class WebView
# a BrowserPlugin property will update the corresponding BrowserPlugin
# attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
# details.
handleWebviewAttributeMutation: (name, oldValue, newValue) ->
if name in AUTO_SIZE_ATTRIBUTES
@attributes[name].setValue newValue
handleWebviewAttributeMutation: (attributeName, oldValue, newValue) ->
# Certain changes (such as internally-initiated changes) to attributes should
# not be handled normally.
if @attributes[attributeName]?.ignoreNextMutation
@attributes[attributeName].ignoreNextMutation = false
return
if attributeName in AUTO_SIZE_ATTRIBUTES
return unless @guestInstanceId
# Convert autosize attribute to boolean.
autosize = @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_AUTOSIZE
guestViewInternal.setAutoSize @guestInstanceId,
enableAutoSize: autosize,
enableAutoSize: @attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue(),
min:
width: parseInt @attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() || 0
height: parseInt @attributes[webViewConstants.ATTRIBUTE_MINHEIGHT].getValue() || 0
max:
width: parseInt @attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0
height: parseInt @attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0
else if name is webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY
else if attributeName is webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY
# We treat null attribute (attribute removed) and the empty string as
# one case.
oldValue ?= ''
newValue ?= ''
return if oldValue is newValue
@attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].setValue(newValue != '')
return unless @guestInstanceId
return if oldValue is newValue and not @guestInstanceId
guestViewInternal.setAllowTransparency @guestInstanceId, @attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue()
else if name is webViewConstants.ATTRIBUTE_HTTPREFERRER
else if attributeName is webViewConstants.ATTRIBUTE_HTTPREFERRER
oldValue ?= ''
newValue ?= ''
@ -208,19 +199,16 @@ class WebView
@attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].setValue newValue
result = {}
# If the httpreferrer changes treat it as though the src changes and reload
# the page with the new httpreferrer.
@parseSrcAttribute result
throw result.error if result.error?
else if name is webViewConstants.ATTRIBUTE_SRC
@parseSrcAttribute()
else if attributeName is webViewConstants.ATTRIBUTE_SRC
# We treat null attribute (attribute removed) and the empty string as
# one case.
oldValue ?= ''
newValue ?= ''
# Once we have navigated, we don't allow clearing the src attribute.
# Once <webview> enters a navigated state, it cannot be return back to a
# Once <webview> enters a navigated state, it cannot return to a
# placeholder state.
if newValue == '' and oldValue != ''
# src attribute changes normally initiate a navigation. We suppress
@ -228,22 +216,19 @@ class WebView
# on every guest-initiated navigation.
@ignoreNextSrcAttributeChange = true
@webviewNode.setAttribute webViewConstants.ATTRIBUTE_SRC, oldValue
@src = newValue
return
if @ignoreNextSrcAttributeChange
# Don't allow the src mutation observer to see this change.
@srcAndPartitionObserver.takeRecords()
@ignoreNextSrcAttributeChange = false
return
result = {}
@parseSrcAttribute result
@parseSrcAttribute()
else if attributeName is webViewConstants.ATTRIBUTE_PARTITION
@attributes[webViewConstants.ATTRIBUTE_PARTITION].handleMutation oldValue, newValue
throw result.error if result.error?
else if name is webViewConstants.ATTRIBUTE_PARTITION
# Note that throwing error here won't synchronously propagate.
@attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue newValue
handleBrowserPluginAttributeMutation: (name, oldValue, newValue) ->
if name is webViewConstants.ATTRIBUTE_INTERNALINSTANCEID and !oldValue and !!newValue
handleBrowserPluginAttributeMutation: (attributeName, oldValue, newValue) ->
if attributeName is webViewConstants.ATTRIBUTE_INTERNALINSTANCEID and !oldValue and !!newValue
@browserPluginNode.removeAttribute webViewConstants.ATTRIBUTE_INTERNALINSTANCEID
@internalInstanceId = parseInt newValue
@ -289,7 +274,7 @@ class WebView
minHeight = height
minHeight = maxHeight if minHeight > maxHeight
if not @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_AUTOSIZE or
if not @attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue() or
(newWidth >= minWidth and
newWidth <= maxWidth and
newHeight >= minHeight and
@ -307,13 +292,10 @@ class WebView
hasNavigated: ->
not @beforeFirstNavigation
parseSrcAttribute: (result) ->
unless @attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId
result.error = webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE
parseSrcAttribute: ->
if not @attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId or
not @attributes[webViewConstants.ATTRIBUTE_SRC].getValue()
return
@attributes[webViewConstants.ATTRIBUTE_SRC].setValue @webviewNode.getAttribute(webViewConstants.ATTRIBUTE_SRC)
return unless @attributes[webViewConstants.ATTRIBUTE_SRC].getValue()
unless @guestInstanceId?
if @beforeFirstNavigation
@ -329,17 +311,12 @@ class WebView
parseAttributes: ->
return unless @elementAttached
hasNavigated = @hasNavigated()
attributeValue = @webviewNode.getAttribute webViewConstants.ATTRIBUTE_PARTITION
result = @attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue attributeValue
@parseSrcAttribute result
@parseSrcAttribute()
createGuest: ->
return if @pendingGuestCreation
storagePartitionId =
@webviewNode.getAttribute(webViewConstants.ATTRIBUTE_PARTITION) or
@webviewNode[webViewConstants.ATTRIBUTE_PARTITION]
params =
storagePartitionId: storagePartitionId
storagePartitionId: @attributes[webViewConstants.ATTRIBUTE_PARTITION].getValue()
nodeIntegration: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_NODEINTEGRATION
plugins: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PLUGINS
if @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_PRELOAD
@ -390,12 +367,11 @@ class WebView
this.webviewNode.setAttribute webViewConstants.ATTRIBUTE_SRC, newValue
onAttach: (storagePartitionId) ->
@webviewNode.setAttribute webViewConstants.ATTRIBUTE_PARTITION, storagePartitionId
@attributes[webViewConstants.ATTRIBUTE_PARTITION].setValue storagePartitionId
buildAttachParams: (isNewWindow) ->
allowtransparency: @attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue() || false
autosize: @webviewNode.hasAttribute webViewConstants.ATTRIBUTE_AUTOSIZE
allowtransparency: @attributes[webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY].getValue()
autosize: @attributes[webViewConstants.ATTRIBUTE_AUTOSIZE].getValue()
instanceId: @viewInstanceId
maxheight: parseInt @attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() || 0
maxwidth: parseInt @attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() || 0