1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
package nokogiri;
import static nokogiri.internals.NokogiriHelpers.getNokogiriClass;
import static nokogiri.internals.NokogiriHelpers.rubyStringToString;
import nokogiri.internals.NokogiriHelpers;
import nokogiri.internals.SaveContextVisitor;
import org.jruby.Ruby;
import org.jruby.RubyClass;
import org.jruby.RubyString;
import org.jruby.anno.JRubyClass;
import org.jruby.anno.JRubyMethod;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
import org.w3c.dom.Attr;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
/**
* Class for Nokogiri::XML::Attr
*
* @author sergio
* @author Yoko Harada <yokolet@gmail.com>
*/
@JRubyClass(name = "Nokogiri::XML::Attr", parent = "Nokogiri::XML::Node")
public class XmlAttr extends XmlNode
{
public static final String[] HTML_BOOLEAN_ATTRS = {
"checked", "compact", "declare", "defer", "disabled", "ismap",
"multiple", "nohref", "noresize", "noshade", "nowrap", "readonly",
"selected"
};
public
XmlAttr(Ruby ruby, Node attr)
{
super(ruby, getNokogiriClass(ruby, "Nokogiri::XML::Attr"), attr);
}
public
XmlAttr(Ruby ruby, RubyClass rubyClass)
{
super(ruby, rubyClass);
}
public
XmlAttr(Ruby ruby, RubyClass rubyClass, Node attr)
{
super(ruby, rubyClass, attr);
}
@Override
protected void
init(ThreadContext context, IRubyObject[] args)
{
if (args.length < 2) {
throw context.runtime.newArgumentError(args.length, 2);
}
IRubyObject doc = args[0];
IRubyObject content = args[1];
if (!(doc instanceof XmlDocument)) {
throw context.runtime.newArgumentError("document must be an instance of Nokogiri::XML::Document");
}
XmlDocument xmlDoc = (XmlDocument)doc;
String str = rubyStringToString(content);
Node attr = xmlDoc.getDocument().createAttribute(str);
setNode(context.runtime, attr);
}
// this method is called from XmlNode.setNode()
// if the node is attribute, and its name has prefix "xml"
// the default namespace should be registered for this attribute
void
setNamespaceIfNecessary(Ruby runtime)
{
if ("xml".equals(node.getPrefix())) {
XmlNamespace.createDefaultNamespace(runtime, node);
}
}
@Override
@JRubyMethod(name = {"content", "value", "to_s"})
public IRubyObject
content(ThreadContext context)
{
if (content != null && !content.isNil()) { return content; }
if (node == null) { return context.getRuntime().getNil(); }
String attrValue = ((Attr)node).getValue();
if (attrValue == null) { return context.getRuntime().getNil(); }
return RubyString.newString(context.getRuntime(), attrValue);
}
@JRubyMethod(name = {"value=", "content="})
public IRubyObject
value_set(ThreadContext context, IRubyObject content)
{
Attr attr = (Attr) node;
if (content != null && !content.isNil()) {
attr.setValue(rubyStringToString(XmlNode.encode_special_chars(context, content)));
}
setContent(content);
return content;
}
@Override
protected IRubyObject
getNodeName(ThreadContext context)
{
if (name != null) { return name; }
String attrName = ((Attr) node).getName();
if (attrName == null) { return context.nil; }
if (node.getNamespaceURI() != null && !(document(context.runtime) instanceof Html4Document)) {
attrName = NokogiriHelpers.getLocalPart(attrName);
if (attrName == null) { return context.nil; }
}
return name = RubyString.newString(context.runtime, attrName);
}
@Override
public void
accept(ThreadContext context, SaveContextVisitor visitor)
{
visitor.enter((Attr)node);
visitor.leave((Attr)node);
}
private boolean
isHtml(ThreadContext context)
{
return document(context).getMetaClass().isKindOfModule(getNokogiriClass(context.getRuntime(),
"Nokogiri::HTML4::Document"));
}
@Override
public IRubyObject
unlink(ThreadContext context)
{
Attr attr = (Attr) node;
Element parent = attr.getOwnerElement();
parent.removeAttributeNode(attr);
return this;
}
}
|