Best-Of-ColdFusion-10
Best-Of-ColdFusion-10 copied to clipboard
Element SELECTOR is undefined in RULE.
I know this project is years old, but I've been using this code to help parse CSS for order receipts on a site of mine. It works most of the time, but occasionally it will throw this error:
Element SELECTOR is undefined in RULE.
It's around line 110 on DOMWrapper.cfc. I've done everything I can think of to ensure that it's testing for the selector, but it keeps throwing the error. I've added structKeyExists(rule, "selector") in front of every call you make to that, but it still throws the error.
Would you have any information as why this would be happening and perhaps a way to patch it?
I encountered this too. It's because your application.cfc settings don't enable invokeImplicitAccessor
on a global level. You can set this on a per-cfc basis by adding the following parameter to each of the CFCs.
invokeImplicitAccessor = "true"
After adding this to each of the CFCs, the error you reported does not occur. (Please note that this only works on CF10+. If you are using this on CF9, it will require a rewrite to add setters & getters.)
I had already set this in the application.cfc, but you're saying this needs to be set in the CFC's? Do you mean this needs to be passed as a parameter to each function call? Or set
component
accessors=true
{
...
}
for each component? I already see that it IS set in the HTMLEmailUtility.cfc.
Not sure... I believe that the invokeImplicitAccessor
setting is a requirement. I eventually added the setting to each CFC as some older projects I'm working on don't use application.cfc yet.
I troubleshot it further and added this to the applyCSSRules method in the DOMWrapper.cfc. The related error message won't be added as a comment in the HTML, but at least it doesn't throw a show-stopping CFError.
if (structKeyExists(rule, "selector")){
this.addSelectorError( rule.selector, error );
}
I think I may have figured it out. I was encountering issues where no CSS rules were being inlined because of undefined selector. I switched ouf the jsoup methods selector
for getSelector()
, style
for getStyle()
, specificity
for getSpecificity()
and all the errors I was encountering went away. (Not sure if was due to invokeImplicitAccessor
not working in correctly in my application.)
Here's the updates that I made. https://gist.github.com/JamoCA/db543885de0c4a010d10f5848b365140
Interesting.
Did you remove the "suppressErrors" just for testing?
Updates applied and so far no errors. I think you figured it out!
Interesting.
Did you remove the "suppressErrors" just for testing?
Yes... I removed all CFTRY/CFCATCH blocks and dumped the "rule" to the hard drive to manually inspect. I looked at the returned methods, changing the script to support the methods listed in the dump, reloaded & received a brand new error. (Yay!) After updating the 3 methods, it worked with error catching disabled.
I customed the HTMLEmailUtility.cfc
to add a "strip" argument to optionally remove additional unwanted elements:
http://cflove.org/2009/12/remove-javascript-and-other-unwanted-codes-from-a-coldfusion-string.cfm
newHTML = dom.html();
if (listfindnocase(Arguments.Strip, "scripts")){
newHTML = ReReplaceNoCase(newHTML, "<script.*?</*.script*.>|<applet.*?</*.applet*.>|<embed.*?</*.embed*.>|<ilayer.*?</*.ilayer*.>|<frame.*?</*.frame*.>|<object.*?</*.object*.>|<iframe.*?</*.iframe*.>|<style.*?</*.style*.>|<meta([^>]*[^/])>|<link([^>]*[^/])>|<script([^>]*[^/])>", "", "ALL");
newHTML = newHTML.ReplaceAll("<\w+[^>]*\son\w+=.*[ /]*>|<script.*/*>|</*.script>|<[^>]*(javascript:)[^>]*>|<[^>]*(onClick:)[^>]*>|<[^>]*(onDblClick:)[^>]*>|<[^>]*(onMouseDown:)[^>]*>|<[^>]*(onMouseOut:)[^>]*>|<[^>]*(onMouseUp:)[^>]*>|<[^>]*(onMouseOver:)[^>]*>|<[^>]*(onBlur:)[^>]*>|<[^>]*(onFocus:)[^>]*>|<[^>]*(onSelect:)[^>]*>","");
newHTML = reReplaceNoCase(newHTML, "</?(script|applet|embed|ilayer|frame|iframe|frameset|style|link)[^>]*>","","all");
}
return( newHTML );
I added an option to remove comments (as it's not necessary to know know which rules failed, if any.):
if (listfindnocase(Arguments.Strip, "comments")){
newHTML = rereplace(newHTML, "<!--.*?-->", "", "all");
}
I'm using this CFC as an option to use with a newer, faster DumpLite custom tag/UDF I'm developing that works with content security policy (CSP). (Adobe's built-in tag doesn't work if CSP unsafe-inline (onclick, etc) is blocked.)
FYI, 18 days later and I encountered a minor bug on line 103 and have updated the gist that I shared.
https://gist.github.com/JamoCA/db543885de0c4a010d10f5848b365140
103 this.addSelectorError( rule.selector, error );
changed to
103 this.addSelectorError( rule.getSelector(), error );