Best-Of-ColdFusion-10 icon indicating copy to clipboard operation
Best-Of-ColdFusion-10 copied to clipboard

Element SELECTOR is undefined in RULE.

Open cjboco opened this issue 7 years ago • 8 comments

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?

cjboco avatar Aug 18 '17 21:08 cjboco

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.)

JamoCA avatar Oct 10 '18 15:10 JamoCA

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.

cjboco avatar Oct 16 '18 16:10 cjboco

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 );
}

JamoCA avatar Oct 16 '18 23:10 JamoCA

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

JamoCA avatar Nov 02 '18 15:11 JamoCA

Interesting.

Did you remove the "suppressErrors" just for testing?

cjboco avatar Nov 02 '18 16:11 cjboco

Updates applied and so far no errors. I think you figured it out!

cjboco avatar Nov 02 '18 16:11 cjboco

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.)

JamoCA avatar Nov 02 '18 17:11 JamoCA

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 );

JamoCA avatar Nov 20 '18 15:11 JamoCA