📄 microformats.js
字号:
if (s.length > 0) { return s; } } }, /** * Used to specifically retrieve a date in a microformat node. * After getting the default text, it normalizes it to an ISO8601 date. * * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with the normalized date. */ dateTimeGetter: function(propnode, parentnode) { var date = Microformats.parser.textGetter(propnode, parentnode); if (date) { return Microformats.parser.normalizeISO8601(date); } }, /** * Used to specifically retrieve a URI in a microformat node. This includes * looking at an href/img/object/area to get the fully qualified URI. * * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with the fully qualified URI. */ uriGetter: function(propnode, parentnode) { var pairs = {"a":"href", "img":"src", "object":"data", "area":"href"}; var name = propnode.nodeName.toLowerCase(); if (pairs.hasOwnProperty(name)) { return propnode[pairs[name]]; } return Microformats.parser.textGetter(propnode, parentnode); }, /** * Used to specifically retrieve a telephone number in a microformat node. * Basically this is to handle the face that telephone numbers use value * as the name as one of their subproperties, but value is also used for * value excerpting (http://microformats.org/wiki/hcard#Value_excerpting) * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with the telephone number */ telGetter: function(propnode, parentnode) { var pairs = {"a":"href", "object":"data", "area":"href"}; var name = propnode.nodeName.toLowerCase(); if (pairs.hasOwnProperty(name)) { var protocol; if (propnode[pairs[name]].indexOf("tel:") == 0) { protocol = "tel:"; } if (propnode[pairs[name]].indexOf("fax:") == 0) { protocol = "fax:"; } if (propnode[pairs[name]].indexOf("modem:") == 0) { protocol = "modem:"; } if (protocol) { if (propnode[pairs[name]].indexOf('?') > 0) { return unescape(propnode[pairs[name]].substring(protocol.length, propnode[pairs[name]].indexOf('?'))); } else { return unescape(propnode[pairs[name]].substring(protocol.length)); } } } /* Special case - if this node is a value, use the parent node to get all the values */ if (Microformats.matchClass(propnode, "value")) { return Microformats.parser.textGetter(parentnode, parentnode); } else { return Microformats.parser.textGetter(propnode, parentnode); } }, /** * Used to specifically retrieve an email address in a microformat node. * This includes at an href, as well as removing subject if specified and * the mailto prefix. * * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with the email address. */ emailGetter: function(propnode, parentnode) { if ((propnode.nodeName.toLowerCase() == "a") || (propnode.nodeName.toLowerCase() == "area")) { var mailto = propnode.href; /* IO Service won't fully parse mailto, so we do it manually */ if (mailto.indexOf('?') > 0) { return unescape(mailto.substring("mailto:".length, mailto.indexOf('?'))); } else { return unescape(mailto.substring("mailto:".length)); } } else { /* Special case - if this node is a value, use the parent node to get all the values */ /* If this case gets executed, per the value design pattern, the result */ /* will be the EXACT email address with no extra parsing required */ if (Microformats.matchClass(propnode, "value")) { return Microformats.parser.textGetter(parentnode, parentnode); } else { return Microformats.parser.textGetter(propnode, parentnode); } } }, /** * Used when a caller needs the text inside a particular DOM node. * It calls defaultGetter to handle all the subtleties of getting * text from a microformat. * * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with just the text including all tags. */ textGetter: function(propnode, parentnode) { return Microformats.parser.defaultGetter(propnode, parentnode, "text"); }, /** * Used when a caller needs the HTML inside a particular DOM node. * * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return An emulated string object that also has a new function called toHTML */ HTMLGetter: function(propnode, parentnode) { /* This is so we can have a string that behaves like a string */ /* but also has a new function that can return the HTML that corresponds */ /* to the string. */ function mfHTML(value) { this.valueOf = function() {return value.valueOf();} this.toString = function() {return value.toString();} } mfHTML.prototype = new String; mfHTML.prototype.toHTML = function() { return Microformats.parser.defaultGetter(propnode, parentnode, "HTML"); } return new mfHTML(Microformats.parser.defaultGetter(propnode, parentnode, "text")); }, /** * Internal parser API used to determine which getter to call based on the * datatype specified in the microformat definition. * * @param prop The microformat property in the definition * @param propnode The DOMNode to check * @param parentnode The parent node of the property. If it is a subproperty, * this is the parent property node. If it is not, this is the * microformat node. * @return A string with the property value. */ datatypeHelper: function(prop, node, parentnode) { var result; var datatype = prop.datatype; if (prop.implied) { datatype = prop.subproperties[prop.implied].datatype; } switch (datatype) { case "dateTime": result = Microformats.parser.dateTimeGetter(node, parentnode); break; case "anyURI": result = Microformats.parser.uriGetter(node, parentnode); break; case "email": result = Microformats.parser.emailGetter(node, parentnode); break; case "tel": result = Microformats.parser.telGetter(node, parentnode); break; case "HTML": result = Microformats.parser.HTMLGetter(node, parentnode); break; case "float": var asText = Microformats.parser.textGetter(node, parentnode); if (!isNaN(asText)) { result = parseFloat(asText); } break; case "custom": result = prop.customGetter(node, parentnode); break; case "microformat": try { result = new Microformats[prop.microformat].mfObject(node); } catch (ex) { /* We can swallow this exception. If the creation of the */ /* mf object fails, then the node isn't a microformat */ } if (result != undefined) { if (prop.microformat_property) { result = result[prop.microformat_property]; } break; } default: result = Microformats.parser.textGetter(node, parentnode); break; } /* This handles the case where one property implies another property */ /* For instance, org by itself is actually org.organization-name */ if (prop.implied && (result != undefined)) { var temp = result; result = {}; result[prop.implied] = temp; } if (prop.values && (result != undefined)) { var validType = false; for (let value in prop.values) { if (result.toLowerCase() == prop.values[value]) { validType = true; break; } } if (!validType) { return; } } return result; }, newMicroformat: function(object, in_node, microformat, validate) { /* check to see if we are even valid */ if (!Microformats[microformat]) { throw("Invalid microformat - " + microformat); } if (in_node.ownerDocument) { if (Microformats[microformat].attributeName) { if (!(in_node.getAttribute(Microformats[microformat].attributeName))) { throw("Node is not a microformat (" + microformat + ")"); } } else { if (!Microformats.matchClass(in_node, Microformats[microformat].className)) { throw("Node is not a microformat (" + microformat + ")"); } } } var node = in_node; if ((Microformats[microformat].className) && in_node.ownerDocument) { node = Microformats.parser.preProcessMicroformat(in_node); } for (let i in Microformats[microformat].properties) { object.__defineGetter__(i, Microformats.parser.getMicroformatPropertyGenerator(node, microformat, i, object)); } /* The node in the object should be the original node */ object.node = in_node; /* we also store the node that has been "resolved" */ object.resolvedNode = node; object.semanticType = microformat; if (validate) { Microformats.parser.validate(node, microformat); } }, getMicroformatPropertyGenerator: function getMicroformatPropertyGenerator(node, name, property, microformat) { return function() { var result = Microformats.parser.getMicroformatProperty(node, name, property);// delete microformat[property];// microformat[property] = result; return result; }; }, getPropertyInternal: function getPropertyInternal(propnode, parentnode, propobj, propname, mfnode) { var result; if (propobj.subproperties) { for (let subpropname in propobj.subproperties) { var subpropnodes; var subpropobj = propobj.subproperties[subpropname]; if (subpropobj.rel == true) { subpropnodes = Microformats.getElementsByAttribute(propnode, "rel", subpropname); } else { subpropnodes = Microformats.getElementsByClassName(propnode, subpropname); } var resultArray = []; var subresult; for (let i = 0; i < subpropnodes.length; i++) { subresult = Microformats.parser.getPropertyInternal(subpropnodes[i], propnode, subpropobj, subpropname, mfnode); if (subresult != undefined) { resultArray.push(subresult); /* If we're not a plural property, don't bother getting more */ if (!subpropobj.plural) { break; } } } if (resultArray.length == 0) { subresult = Microformats.parser.getPropertyInternal(propnode, null, subpropobj, subpropname, mfnode); if (subresult != undefined) { resultArray.push(subresult); } } if (resultArray.length > 0) { result = result || {}; if (subpropobj.plural) { result[subpropname] = resultArray; } else { result[subpropname] = resultArray[0]; } } } } if (!parentnode || (!result && propobj.subproperties)) { if (propobj.virtual) { if (propobj.virtualGetter) { result = propobj.virtualGetter(mfnode || propnode); } else { result = Microformats.parser.datatypeHelper(propobj, propnode); } } else if (propobj.implied) { result = Microformats.parser.datatypeHelper(propobj, propnode); } } else if (!result) { result = Microformats.parser.datatypeHelper(propobj, propnode, parentnode); } return result; }, getMicroformatProperty: function getMicroformatProperty(in_mfnode, mfname, propname) { var mfnode = in_mfnode; /* If the node has not been preprocessed, the requested microformat */ /* is a class based microformat and the passed in node is not the */ /* entire document, preprocess it. Preprocessing the node involves */ /* creating a duplicate of the node and taking care of things like */ /* the include and header design patterns */ if (!in_mfnode.origNode && Microformats[mfname].className && in_mfnode.ownerDocument) { mfnode = Microformats.parser.preProcessMicroformat(in_mfnode); } /* propobj is the corresponding property object in the microformat */ var propobj; /* If there is a corresponding property in the microformat, use it */ if (Microformats[mfname].properties[propname]) { propobj = Microformats[mfname].properties[propname]; } else { /* If we didn't get a property, bail */ return; } /* Query the correct set of nodes (rel or class) based on the setting */ /* in the property */ var propnodes; if (propobj.rel == true) { propnodes = Microformats.getElementsByAttribute(mfnode, "rel", propname); } else { propnodes = Microformats.getElementsByClassName(mfnode, propname); } for (let i=propnodes.length-1; i >= 0; i--) { /* The reason getParent is not used here is because this code does */ /* not apply to attribute based microformats, plus adr and geo */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -