Skip to content

Commit

Permalink
Merge pull request lift#1701 from lift/ajk_datalift-fixedattrs
Browse files Browse the repository at this point in the history
Add LiftRules.attributeForRemovedEventAttributes

This PR adds a LiftRule, LiftRules.attributeForRemovedEventAttributes.
When we remove a JavaScript event from an element for separate
application via the page's JS file, if this rule is set, the attribute it specified
is populated with the names of the attributes that were removed from the
element. If no attributes were removed, no attribute is added to the element.

The default for the LiftRule is to be None, meaning this information is never
added to the output.
  • Loading branch information
Shadowfiend committed Jul 6, 2015
2 parents 3d4bb6e + f380911 commit 6b1429e
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 3 deletions.
19 changes: 16 additions & 3 deletions web/webkit/src/main/scala/net/liftweb/http/LiftMerge.scala
Original file line number Diff line number Diff line change
Expand Up @@ -203,11 +203,24 @@ private[http] trait LiftMerge {
def fixElementAndAttributes(element: Elem, attributeToFix: String, fixURL: Boolean, fixedChildren: NodeSeq) = {
val (id, fixedAttributes, eventAttributes) = fixAttrs(attributeToFix, element.attributes, fixURL)

val attributesIncludingEventsAsData =
LiftRules.attributeForRemovedEventAttributes match {
case Some(attribute) if eventAttributes.nonEmpty =>
val removedAttributes = eventAttributes.map {
case EventAttribute(event, _) =>
s"on$event"
}
new UnprefixedAttribute(attribute, removedAttributes.join(" "), fixedAttributes)

case _ =>
fixedAttributes
}

id.map { foundId =>
eventAttributesByElementId += (foundId -> eventAttributes)

element.copy(
attributes = fixedAttributes,
attributes = attributesIncludingEventsAsData,
child = fixedChildren
)
} getOrElse {
Expand All @@ -216,12 +229,12 @@ private[http] trait LiftMerge {
eventAttributesByElementId += (generatedId -> eventAttributes)

element.copy(
attributes = new UnprefixedAttribute("id", generatedId, fixedAttributes),
attributes = new UnprefixedAttribute("id", generatedId, attributesIncludingEventsAsData),
child = fixedChildren
)
} else {
element.copy(
attributes = fixedAttributes,
attributes = attributesIncludingEventsAsData,
child = fixedChildren
)
}
Expand Down
59 changes: 59 additions & 0 deletions web/webkit/src/main/scala/net/liftweb/http/LiftRules.scala
Original file line number Diff line number Diff line change
Expand Up @@ -561,6 +561,65 @@ class LiftRules() extends Factory with FormVendor with LazyLoggable {
*/
@volatile var displayHelpfulSiteMapMessages_? = true

/**
* The attribute used to expose the names of event attributes that
* were removed from a given element for separate processing in JS.
* By default, Lift removes event attributes and attaches those
* behaviors via a separate JS file, to avoid inline JS invocations so
* that a restrictive Content-Security-Policy can be used.
*
* You can set this variable so that the resulting HTML will have
* attribute information about the removed attributes, in case you
* need them for e.g. CSS selector matching. The attribute will
* contain a space-separated list of JS attributes that were removed
* by Lift's processing.
*
* For example, if you needed to match elements with an `onclick`
* attribute in CSS, you would usually do:
*
* {{{
* [onclick] {
* text-decoration: underline;
* }
* }}}
*
* And have an element:
*
* {{{
* <span onclick="jsCode()">Do something!</span>
* }}}
*
* In Lift 3, this would not work, as the onclick attribute would be
* removed before HTML serialization, so your HTML would be:
*
* {{{
* <span id="lift-event-js-F827001738725NKMEQNF">Do something!</span>
* }}}
*
* Instead, you could set:
*
* {{{
* LiftRules.attributeForRemovedEventAttributes = Some("data-lift-removed-attributes")
* }}}
*
* The HTML Lift emitted would then look like:
*
* {{{
* <span id="lift-event-js-F827001738725NKMEQNF"
* data-lift=removed-attributes="onclick">Do something!</span>
* }}}
*
* This makes it possible to replace the old CSS with with similar
* matching for the `data-lift-removed-attributes` attribute:
*
* {{{
* [data-lift-removed-attributes~=onclick] {
* text-decoration: underline;
* }
* }}}
*/
@volatile var attributeForRemovedEventAttributes: Option[String] = None

/**
* The default location to send people if SiteMap access control fails. The path is
* expressed a a List[String]
Expand Down

0 comments on commit 6b1429e

Please sign in to comment.