Migrate to block comments

This commit is contained in:
Kevin Sawicki 2016-01-11 18:03:02 -08:00
parent 630cd091a0
commit 403870a27e
44 changed files with 538 additions and 437 deletions

View file

@ -4,14 +4,16 @@ webViewConstants = require './web-view-constants'
{remote} = require 'electron'
# Helper function to resolve url set in attribute.
### 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.
###
Attribute objects.
Default implementation of a WebView attribute.
###
class WebViewAttribute
constructor: (name, webViewImpl) ->
@name = name
@ -20,29 +22,29 @@ class WebViewAttribute
@defineProperty()
# Retrieves and returns the attribute's value.
### Retrieves and returns the attribute's value. ###
getValue: -> @webViewImpl.webviewNode.getAttribute(@name) || ''
# Sets the attribute's value.
### Sets the attribute's value. ###
setValue: (value) -> @webViewImpl.webviewNode.setAttribute(@name, value || '')
# Changes the attribute's value without triggering its mutation handler.
### Changes the attribute's value without triggering its mutation handler. ###
setValueIgnoreMutation: (value) ->
@ignoreMutation = true
@setValue value
@ignoreMutation = false
# Defines this attribute as a property on the webview node.
### 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.
### Called when the attribute's value changes. ###
handleMutation: ->
# An attribute that is treated as a Boolean.
### An attribute that is treated as a Boolean. ###
class BooleanAttribute extends WebViewAttribute
constructor: (name, webViewImpl) ->
super name, webViewImpl
@ -55,7 +57,7 @@ class BooleanAttribute extends WebViewAttribute
else
@webViewImpl.webviewNode.setAttribute @name, ''
# Attribute that specifies whether transparency is allowed in the webview.
### Attribute that specifies whether transparency is allowed in the webview. ###
class AllowTransparencyAttribute extends BooleanAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_ALLOWTRANSPARENCY, webViewImpl
@ -64,7 +66,7 @@ class AllowTransparencyAttribute extends BooleanAttribute
return unless @webViewImpl.guestInstanceId
guestViewInternal.setAllowTransparency @webViewImpl.guestInstanceId, @getValue()
# Attribute used to define the demension limits of autosizing.
### Attribute used to define the demension limits of autosizing. ###
class AutosizeDimensionAttribute extends WebViewAttribute
constructor: (name, webViewImpl) ->
super name, webViewImpl
@ -82,14 +84,14 @@ class AutosizeDimensionAttribute extends WebViewAttribute
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.
### 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.
### Attribute representing the state of the storage partition. ###
class PartitionAttribute extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_PARTITION, webViewImpl
@ -98,7 +100,7 @@ class PartitionAttribute extends WebViewAttribute
handleMutation: (oldValue, newValue) ->
newValue = newValue || ''
# The partition cannot change if the webview has already navigated.
### The partition cannot change if the webview has already navigated. ###
unless @webViewImpl.beforeFirstNavigation
window.console.error webViewConstants.ERROR_MSG_ALREADY_NAVIGATED
@setValueIgnoreMutation oldValue
@ -108,7 +110,7 @@ class PartitionAttribute extends WebViewAttribute
@validPartitionId = false
window.console.error webViewConstants.ERROR_MSG_INVALID_PARTITION_ATTRIBUTE
# Attribute that handles the location and navigation of the webview.
### Attribute that handles the location and navigation of the webview. ###
class SrcAttribute extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_SRC, webViewImpl
@ -122,28 +124,36 @@ class SrcAttribute extends WebViewAttribute
setValueIgnoreMutation: (value) ->
WebViewAttribute::setValueIgnoreMutation.call(this, value)
# takeRecords() is needed to clear queued up src mutations. Without it, it
# is possible for this change to get picked up asyncronously by src's
# mutation observer |observer|, and then get handled even though we do not
# want to handle this mutation.
###
takeRecords() is needed to clear queued up src mutations. Without it, it
is possible for this change to get picked up asyncronously by src's
mutation observer |observer|, and then get handled even though we do not
want to handle this mutation.
###
@observer.takeRecords()
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.
###
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.
###
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.
###
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
@ -169,7 +179,7 @@ class SrcAttribute extends WebViewAttribute
@webViewImpl.createGuest()
return
# Navigate to |this.src|.
### Navigate to |this.src|. ###
opts = {}
httpreferrer = @webViewImpl.attributes[webViewConstants.ATTRIBUTE_HTTPREFERRER].getValue()
if httpreferrer then opts.httpReferrer = httpreferrer
@ -180,17 +190,17 @@ class SrcAttribute extends WebViewAttribute
guestContents = remote.getGuestWebContents(@webViewImpl.guestInstanceId)
guestContents.loadURL @getValue(), opts
# Attribute specifies HTTP referrer.
### Attribute specifies HTTP referrer. ###
class HttpReferrerAttribute extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_HTTPREFERRER, webViewImpl
# Attribute specifies user agent
### Attribute specifies user agent ###
class UserAgentAttribute extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_USERAGENT, webViewImpl
# Attribute that set preload script.
### Attribute that set preload script. ###
class PreloadAttribute extends WebViewAttribute
constructor: (webViewImpl) ->
super webViewConstants.ATTRIBUTE_PRELOAD, webViewImpl
@ -204,7 +214,7 @@ class PreloadAttribute extends WebViewAttribute
preload = ''
preload
# Sets up all of the webview attributes.
### Sets up all of the webview attributes. ###
WebViewImpl::setupWebViewAttributes = ->
@attributes = {}

View file

@ -1,5 +1,5 @@
module.exports =
# Attributes.
### Attributes. ###
ATTRIBUTE_ALLOWTRANSPARENCY: 'allowtransparency'
ATTRIBUTE_AUTOSIZE: 'autosize'
ATTRIBUTE_MAXHEIGHT: 'maxheight'
@ -17,10 +17,10 @@ module.exports =
ATTRIBUTE_PRELOAD: 'preload'
ATTRIBUTE_USERAGENT: 'useragent'
# Internal attribute.
### Internal attribute. ###
ATTRIBUTE_INTERNALINSTANCEID: 'internalinstanceid'
# Error messages.
### Error messages. ###
ERROR_MSG_ALREADY_NAVIGATED: 'The object has already navigated, so its partition cannot be changed.'
ERROR_MSG_CANNOT_INJECT_SCRIPT: '<webview>: ' +
'Script cannot be injected into content until the page has loaded.'

View file

@ -4,11 +4,11 @@ v8Util = process.atomBinding 'v8_util'
guestViewInternal = require './guest-view-internal'
webViewConstants = require './web-view-constants'
# ID generator.
### ID generator. ###
nextId = 0
getNextId = -> ++nextId
# Represents the internal state of the WebView node.
### Represents the internal state of the WebView node. ###
class WebViewImpl
constructor: (@webviewNode) ->
v8Util.setHiddenValue @webviewNode, 'internal', this
@ -17,7 +17,7 @@ class WebViewImpl
@beforeFirstNavigation = true
# on* Event handlers.
### on* Event handlers. ###
@on = {}
@browserPluginNode = @createBrowserPluginNode()
@ -30,20 +30,24 @@ class WebViewImpl
shadowRoot.appendChild @browserPluginNode
createBrowserPluginNode: ->
# We create BrowserPlugin as a custom element in order to observe changes
# to attributes synchronously.
###
We create BrowserPlugin as a custom element in order to observe changes
to attributes synchronously.
###
browserPluginNode = new WebViewImpl.BrowserPlugin()
v8Util.setHiddenValue browserPluginNode, 'internal', this
browserPluginNode
# Resets some state upon reattaching <webview> element to the DOM.
### Resets some state upon reattaching <webview> element to the DOM. ###
reset: ->
# If guestInstanceId is defined then the <webview> has navigated and has
# already picked up a partition ID. Thus, we need to reset the initialization
# state. However, it may be the case that beforeFirstNavigation is false BUT
# guestInstanceId has yet to be initialized. This means that we have not
# heard back from createGuest yet. We will not reset the flag in this case so
# that we don't end up allocating a second guest.
###
If guestInstanceId is defined then the <webview> has navigated and has
already picked up a partition ID. Thus, we need to reset the initialization
state. However, it may be the case that beforeFirstNavigation is false BUT
guestInstanceId has yet to be initialized. This means that we have not
heard back from createGuest yet. We will not reset the flag in this case so
that we don't end up allocating a second guest.
###
if @guestInstanceId
guestViewInternal.destroyGuest @guestInstanceId
@webContents = null
@ -52,34 +56,38 @@ class WebViewImpl
@attributes[webViewConstants.ATTRIBUTE_PARTITION].validPartitionId = true
@internalInstanceId = 0
# Sets the <webview>.request property.
### Sets the <webview>.request property. ###
setRequestPropertyOnWebViewNode: (request) ->
Object.defineProperty @webviewNode, 'request', value: request, enumerable: true
setupFocusPropagation: ->
unless @webviewNode.hasAttribute 'tabIndex'
# <webview> needs a tabIndex in order to be focusable.
# TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
# to allow <webview> to be focusable.
# See http://crbug.com/231664.
###
<webview> needs a tabIndex in order to be focusable.
TODO(fsamuel): It would be nice to avoid exposing a tabIndex attribute
to allow <webview> to be focusable.
See http://crbug.com/231664.
###
@webviewNode.setAttribute 'tabIndex', -1
@webviewNode.addEventListener 'focus', (e) =>
# Focus the BrowserPlugin when the <webview> takes focus.
### Focus the BrowserPlugin when the <webview> takes focus. ###
@browserPluginNode.focus()
@webviewNode.addEventListener 'blur', (e) =>
# Blur the BrowserPlugin when the <webview> loses focus.
### Blur the BrowserPlugin when the <webview> loses focus. ###
@browserPluginNode.blur()
# This observer monitors mutations to attributes of the <webview> and
# updates the BrowserPlugin properties accordingly. In turn, updating
# a BrowserPlugin property will update the corresponding BrowserPlugin
# attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
# details.
###
This observer monitors mutations to attributes of the <webview> and
updates the BrowserPlugin properties accordingly. In turn, updating
a BrowserPlugin property will update the corresponding BrowserPlugin
attribute, if necessary. See BrowserPlugin::UpdateDOMAttribute for more
details.
###
handleWebviewAttributeMutation: (attributeName, oldValue, newValue) ->
if not @attributes[attributeName] or @attributes[attributeName].ignoreMutation
return
# Let the changed attribute handle its own mutation;
### Let the changed attribute handle its own mutation; ###
@attributes[attributeName].handleMutation oldValue, newValue
handleBrowserPluginAttributeMutation: (attributeName, oldValue, newValue) ->
@ -87,7 +95,7 @@ class WebViewImpl
@browserPluginNode.removeAttribute webViewConstants.ATTRIBUTE_INTERNALINSTANCEID
@internalInstanceId = parseInt newValue
# Track when the element resizes using the element resize callback.
### Track when the element resizes using the element resize callback. ###
webFrame.registerElementResizeCallback @internalInstanceId, @onElementResize.bind(this)
return unless @guestInstanceId
@ -103,8 +111,8 @@ class WebViewImpl
width = node.offsetWidth
height = node.offsetHeight
# Check the current bounds to make sure we do not resize <webview>
# outside of current constraints.
### Check the current bounds to make sure we do not resize <webview> ###
### outside of current constraints. ###
maxWidth = @attributes[webViewConstants.ATTRIBUTE_MAXWIDTH].getValue() | width
maxHeight = @attributes[webViewConstants.ATTRIBUTE_MAXHEIGHT].getValue() | width
minWidth = @attributes[webViewConstants.ATTRIBUTE_MINWIDTH].getValue() | width
@ -120,12 +128,14 @@ class WebViewImpl
newHeight <= maxHeight)
node.style.width = newWidth + 'px'
node.style.height = newHeight + 'px'
# Only fire the DOM event if the size of the <webview> has actually
# changed.
###
Only fire the DOM event if the size of the <webview> has actually
changed.
###
@dispatchEvent webViewEvent
onElementResize: (newSize) ->
# Dispatch the 'resize' event.
### Dispatch the 'resize' event. ###
resizeEvent = new Event('resize', bubbles: true)
resizeEvent.newWidth = newSize.width
resizeEvent.newHeight = newSize.height
@ -141,8 +151,8 @@ class WebViewImpl
dispatchEvent: (webViewEvent) ->
@webviewNode.dispatchEvent webViewEvent
# Adds an 'on<event>' property on the webview, which can be used to set/unset
# an event handler.
### Adds an 'on<event>' property on the webview, which can be used to set/unset ###
### an event handler. ###
setupEventProperty: (eventName) ->
propertyName = 'on' + eventName.toLowerCase()
Object.defineProperty @webviewNode, propertyName,
@ -155,14 +165,16 @@ class WebViewImpl
@webviewNode.addEventListener eventName, value
enumerable: true
# Updates state upon loadcommit.
### Updates state upon loadcommit. ###
onLoadCommit: (webViewEvent) ->
oldValue = @webviewNode.getAttribute webViewConstants.ATTRIBUTE_SRC
newValue = webViewEvent.url
if webViewEvent.isMainFrame and (oldValue != newValue)
# Touching the src attribute triggers a navigation. To avoid
# triggering a page reload on every guest-initiated navigation,
# we do not handle this mutation
###
Touching the src attribute triggers a navigation. To avoid
triggering a page reload on every guest-initiated navigation,
we do not handle this mutation.
###
@attributes[webViewConstants.ATTRIBUTE_SRC].setValueIgnoreMutation newValue
onAttach: (storagePartitionId) ->
@ -174,11 +186,13 @@ class WebViewImpl
userAgentOverride: @userAgentOverride
for own attributeName, attribute of @attributes
params[attributeName] = attribute.getValue()
# When the WebView is not participating in layout (display:none)
# then getBoundingClientRect() would report a width and height of 0.
# However, in the case where the WebView has a fixed size we can
# use that value to initially size the guest so as to avoid a relayout of
# the on display:block.
###
When the WebView is not participating in layout (display:none)
then getBoundingClientRect() would report a width and height of 0.
However, in the case where the WebView has a fixed size we can
use that value to initially size the guest so as to avoid a relayout of
the on display:block.
###
css = window.getComputedStyle @webviewNode, null
elementRect = @webviewNode.getBoundingClientRect()
params.elementWidth = parseInt(elementRect.width) ||
@ -194,14 +208,14 @@ class WebViewImpl
guestViewInternal.attachGuest @internalInstanceId, @guestInstanceId, @buildParams()
# Registers browser plugin <object> custom element.
### Registers browser plugin <object> custom element. ###
registerBrowserPluginElement = ->
proto = Object.create HTMLObjectElement.prototype
proto.createdCallback = ->
@setAttribute 'type', 'application/browser-plugin'
@setAttribute 'id', 'browser-plugin-' + getNextId()
# The <object> node fills in the <webview> container.
### The <object> node fills in the <webview> container. ###
@style.display = 'block'
@style.width = '100%'
@style.height = '100%'
@ -212,7 +226,7 @@ registerBrowserPluginElement = ->
internal.handleBrowserPluginAttributeMutation name, oldValue, newValue
proto.attachedCallback = ->
# Load the plugin immediately.
### Load the plugin immediately. ###
unused = this.nonExistentAttribute
WebViewImpl.BrowserPlugin = webFrame.registerEmbedderCustomElement 'browserplugin',
@ -223,7 +237,7 @@ registerBrowserPluginElement = ->
delete proto.detachedCallback
delete proto.attributeChangedCallback
# Registers <webview> custom element.
### Registers <webview> custom element. ###
registerWebViewElement = ->
proto = Object.create HTMLObjectElement.prototype
@ -250,7 +264,7 @@ registerWebViewElement = ->
internal.elementAttached = true
internal.attributes[webViewConstants.ATTRIBUTE_SRC].parse()
# Public-facing API methods.
### Public-facing API methods. ###
methods = [
'getURL'
'getTitle'
@ -304,7 +318,7 @@ registerWebViewElement = ->
'insertCSS'
]
# Forward proto.foo* method calls to WebViewImpl.foo*.
### Forward proto.foo* method calls to WebViewImpl.foo*. ###
createBlockHandler = (m) ->
(args...) ->
internal = v8Util.getHiddenValue this, 'internal'
@ -318,14 +332,14 @@ registerWebViewElement = ->
proto[m] = createNonBlockHandler m for m in nonblockMethods
# Deprecated.
### Deprecated. ###
deprecate.rename proto, 'getUrl', 'getURL'
window.WebView = webFrame.registerEmbedderCustomElement 'webview',
prototype: proto
# Delete the callbacks so developers cannot call them and produce unexpected
# behavior.
### Delete the callbacks so developers cannot call them and produce unexpected ###
### behavior. ###
delete proto.createdCallback
delete proto.attachedCallback
delete proto.detachedCallback