public void IsMatchMethod(object value, ExpressionToken token, IsMatchResult isMatchResult) { IHTMLElement elem = (IHTMLElement)value; string copyOfAttribute = token.Attribute; while (copyOfAttribute.StartsWith("parentElement.")) { if (elem.parentElement == null) { isMatchResult.ContinueChecking = false; isMatchResult.ReturnValue = false; return; } elem = elem.parentElement; copyOfAttribute = copyOfAttribute.Remove(0, "parentElement.".Length); } if (!token.Attribute.Equals(copyOfAttribute)) //if we removed parentElement we should re-normalize. copyOfAttribute = AttributeNormalizer.Normalize(copyOfAttribute); if (copyOfAttribute.StartsWith("parentWindow")) { string attr; isMatchResult.ContinueChecking = false; isMatchResult.ReturnValue = false; try { attr = copyOfAttribute.Split('.')[1]; } catch (Exception ex) { //need to throw expression wrong format exception throw ex; } if (attr == "location") { if (token.IsMatch(((HTMLDocument)elem.document).parentWindow.location.href)) { isMatchResult.ContinueChecking = true; isMatchResult.ReturnValue = true; } } if (attr == "name") { if (token.IsMatch(((HTMLDocument)elem.document).parentWindow.name)) { isMatchResult.ContinueChecking = true; isMatchResult.ReturnValue = true; } } } else { if (elem != null && !(elem is IHTMLUnknownElement)) { string attr; if (copyOfAttribute.Equals("style", StringComparison.OrdinalIgnoreCase)) { //the border, padding, and margin attributes if specified inline get applied to all 4 sides: //EG: border-right, border-left, border-top, border-bottom //Assumption: use -right for the global search if (token.Value.ToLower().Contains("border:")) token.Value = token.Value.Replace("border:", "border-right:"); if (token.Value.ToLower().Contains("padding:")) token.Value = token.Value.Replace("padding:", "padding-right:"); if (token.Value.ToLower().Contains("margin:")) token.Value = token.Value.Replace("margin:", "margin-right:"); attr = elem.style.cssText; } else { object elemAttribute = elem.getAttribute(copyOfAttribute, 0); if (!(elem.getAttribute(token.Attribute, 0) is string) && !(elemAttribute is Boolean) && !(elemAttribute is int)) if (((IHTMLElement4)elem).getAttributeNode(copyOfAttribute) != null && ((IHTMLElement4)elem).getAttributeNode(copyOfAttribute).nodeValue != null) attr = ((IHTMLElement4)elem).getAttributeNode(copyOfAttribute).nodeValue.ToString(); else attr = elemAttribute != null ? elemAttribute.ToString() : string.Empty; else attr = elemAttribute.ToString(); } if (token.IsMatch(attr)) { isMatchResult.ContinueChecking = true; isMatchResult.ReturnValue = true; } else { if (token.IsPartOfStyle) { string origAttr = token.Attribute; string origValue = token.Value; if (token.Attribute == "style" && token.Value.Contains(":")) { token.Attribute = token.Value.Split(new char[] { ':' })[0]; token.Value = token.Value.Split(new char[] { ':' })[1]; } if (((IHTMLElement2)elem).currentStyle.getAttribute(token.Attribute, 0) != null) attr = ((IHTMLElement2)elem).currentStyle.getAttribute(token.Attribute, 0).ToString(); if (token.IsMatch(attr)) { isMatchResult.ContinueChecking = true; isMatchResult.ReturnValue = true; } else { isMatchResult.ContinueChecking = false; isMatchResult.ReturnValue = false; } token.Attribute = origAttr; token.Value = origValue; } else { isMatchResult.ContinueChecking = false; isMatchResult.ReturnValue = false; } } } else { isMatchResult.ContinueChecking = false; isMatchResult.ReturnValue = false; } } }