1 /* 2 * jQuery RDFa @VERSION 3 * 4 * Copyright (c) 2008,2009 Jeni Tennison 5 * Licensed under the MIT (MIT-LICENSE.txt) 6 * 7 * Depends: 8 * jquery.uri.js 9 * jquery.xmlns.js 10 * jquery.curie.js 11 * jquery.datatype.js 12 * jquery.rdf.js 13 */ 14 /** 15 * @fileOverview jQuery RDFa processing 16 * @author <a href="mailto:jeni@jenitennison.com">Jeni Tennison</a> 17 * @copyright (c) 2008,2009 Jeni Tennison 18 * @license MIT license (MIT-LICENSE.txt) 19 * @version 1.0 20 * @requires jquery.uri.js 21 * @requires jquery.xmlns.js 22 * @requires jquery.curie.js 23 * @requires jquery.datatype.js 24 * @requires jquery.rdf.js 25 */ 26 (function ($) { 27 28 var 29 ns = { 30 rdf: "http://www.w3.org/1999/02/22-rdf-syntax-ns#", 31 xsd: "http://www.w3.org/2001/XMLSchema#" 32 }, 33 34 rdfXMLLiteral = ns.rdf + 'XMLLiteral', 35 36 rdfaCurieDefaults = $.fn.curie.defaults, 37 38 attRegex = /\s([^ =]+)\s*=\s*(?:"([^"]*)"|'([^']*)'|([^ >]+))/g, 39 40 docResource = $.rdf.resource('<>'), 41 42 parseEntities = function (string) { 43 var result = "", m, entity; 44 if (!/&/.test(string)) { 45 return string; 46 } 47 while (string.length > 0) { 48 m = /([^&]*)(&([^;]+);)(.*)/g.exec(string); 49 if (m === null) { 50 result += string; 51 break; 52 } 53 result += m[1]; 54 entity = m[3]; 55 string = m[4]; 56 if (entity.charAt(0) === '#') { 57 if (entity.charAt(1) === 'x') { 58 result += String.fromCharCode(parseInt(entity.substring(2), 16)); 59 } else { 60 result += String.fromCharCode(parseInt(entity.substring(1), 10)); 61 } 62 } else { 63 switch(entity) { 64 case 'amp': 65 result += '&'; 66 break; 67 case 'nbsp': 68 result += String.fromCharCode(160); 69 break; 70 case 'quot': 71 result += '"'; 72 break; 73 case 'apos': 74 result += "'"; 75 break; 76 default: 77 result += '&' + entity + ';'; 78 } 79 } 80 } 81 return result; 82 }, 83 84 getAttributes = function (elem) { 85 var i, e, a, tag, name, value, attMap, prefix, 86 ns = {}, atts = {}; 87 e = elem[0]; 88 ns[':length'] = 0; 89 if (e.attributes && e.attributes.getNamedItemNS) { 90 attMap = e.attributes; 91 for (i = 0; i < attMap.length; i += 1) { 92 a = attMap[i]; 93 if (/^xmlns(:(.+))?$/.test(a.nodeName) && a.nodeValue !== '') { 94 prefix = /^xmlns(:(.+))?$/.exec(a.nodeName)[2] || ''; 95 ns[prefix] = $.uri(a.nodeValue); 96 ns[':length'] += 1; 97 } else if (/rel|rev|lang|xml:lang/.test(a.nodeName)) { 98 atts[a.nodeName] = a.nodeValue === '' ? undefined : a.nodeValue; 99 } else if (/about|href|src|resource|property|typeof|content|datatype/.test(a.nodeName)) { 100 atts[a.nodeName] = a.nodeValue === null ? undefined : a.nodeValue; 101 } 102 } 103 } else { 104 tag = /<[^>]+>/.exec(e.outerHTML); 105 a = attRegex.exec(tag); 106 while (a !== null) { 107 name = a[1]; 108 value = a[2] || a[3] || a[4]; 109 if (/^xmlns/.test(name) && name !== 'xmlns:' && value !== '') { 110 prefix = /^xmlns(:(.+))?$/.exec(name)[2] || ''; 111 ns[prefix] = $.uri(value); 112 ns[':length'] += 1; 113 } else if (/about|href|src|resource|property|typeof|content|datatype|rel|rev|lang|xml:lang/.test(name)) { 114 atts[name] = parseEntities(value); 115 } 116 a = attRegex.exec(tag); 117 } 118 attRegex.lastIndex = 0; 119 } 120 return { atts: atts, namespaces: ns }; 121 }, 122 123 getAttribute = function (elem, attr) { 124 var val = elem[0].getAttribute(attr); 125 if (attr === 'rev' || attr === 'rel' || attr === 'lang' || attr === 'xml:lang') { 126 val = val === '' ? undefined : val; 127 } 128 return val === null ? undefined : val; 129 }, 130 131 resourceFromUri = function (uri) { 132 return $.rdf.resource(uri); 133 }, 134 135 resourceFromCurie = function (curie, elem, options) { 136 if (curie.substring(0, 2) === '_:') { 137 return $.rdf.blank(curie); 138 } else { 139 try { 140 return resourceFromUri($.curie(curie, options)); 141 } catch (e) { 142 return undefined; 143 } 144 } 145 }, 146 147 resourceFromSafeCurie = function (safeCurie, elem, options) { 148 var m = /^\[([^\]]+)\]$/.exec(safeCurie), 149 base = options.base || elem.base(); 150 return m ? resourceFromCurie(m[1], elem, options) : resourceFromUri($.uri(safeCurie, base)); 151 }, 152 153 resourcesFromCuries = function (curies, elem, options) { 154 var i, resource, resources = []; 155 curies = curies && curies.split ? curies.split(/[ \t\n\r\x0C]+/g) : []; 156 for (i = 0; i < curies.length; i += 1) { 157 if (curies[i] !== '') { 158 resource = resourceFromCurie(curies[i], elem, options); 159 if (resource !== undefined) { 160 resources.push(resource); 161 } 162 } 163 } 164 return resources; 165 }, 166 167 removeCurie = function (curies, resource, options) { 168 var i, r, newCuries = []; 169 resource = resource.type === 'uri' ? resource : $.rdf.resource(resource, options); 170 curies = curies && curies.split ? curies.split(/\s+/) : []; 171 for (i = 0; i < curies.length; i += 1) { 172 if (curies[i] !== '') { 173 r = resourceFromCurie(curies[i], null, options); 174 if (r !== resource) { 175 newCuries.push(curies[i]); 176 } 177 } 178 } 179 return newCuries.reverse().join(' '); 180 }, 181 182 getObjectResource = function (elem, context, relation) { 183 var r, resource, atts, curieOptions; 184 context = context || {}; 185 atts = context.atts || getAttributes(elem).atts; 186 r = relation === undefined ? atts.rel !== undefined || atts.rev !== undefined : relation; 187 resource = atts.resource; 188 resource = resource === undefined ? atts.href : resource; 189 if (resource === undefined) { 190 resource = r ? $.rdf.blank('[]') : resource; 191 } else { 192 curieOptions = context.curieOptions || $.extend({}, rdfaCurieDefaults, { namespaces: elem.xmlns() }); 193 resource = resourceFromSafeCurie(resource, elem, curieOptions); 194 } 195 return resource; 196 }, 197 198 getSubject = function (elem, context, relation) { 199 var r, atts, curieOptions, subject, skip = false; 200 context = context || {}; 201 atts = context.atts || getAttributes(elem).atts; 202 curieOptions = context.curieOptions || $.extend({}, rdfaCurieDefaults, { namespaces: elem.xmlns(), base: elem.base() }); 203 r = relation === undefined ? atts.rel !== undefined || atts.rev !== undefined : relation; 204 if (atts.about !== undefined) { 205 subject = resourceFromSafeCurie(atts.about, elem, curieOptions); 206 } 207 if (subject === undefined && atts.src !== undefined) { 208 subject = resourceFromSafeCurie(atts.src, elem, curieOptions); 209 } 210 if (!r && subject === undefined && atts.resource !== undefined) { 211 subject = resourceFromSafeCurie(atts.resource, elem, curieOptions); 212 } 213 if (!r && subject === undefined && atts.href !== undefined) { 214 subject = resourceFromSafeCurie(atts.href, elem, curieOptions); 215 } 216 if (subject === undefined) { 217 if (/head|body/i.test(elem[0].nodeName)) { 218 subject = docResource; 219 } else if (atts['typeof'] !== undefined) { 220 subject = $.rdf.blank('[]'); 221 } else if (elem[0].parentNode.nodeType === 1) { 222 subject = context.object || getObjectResource(elem.parent()) || getSubject(elem.parent()).subject; 223 skip = !r && atts.property === undefined; 224 } else { 225 subject = docResource; 226 } 227 } 228 return { subject: subject, skip: skip }; 229 }, 230 231 getLang = function (elem, context) { 232 var lang; 233 context = context || {}; 234 if (context.atts) { 235 lang = context.atts.lang; 236 lang = lang || context.atts['xml:lang']; 237 } else { 238 lang = elem[0].getAttribute('lang'); 239 lang = (lang === null || lang === '') ? elem[0].getAttribute('xml:lang') : lang; 240 lang = (lang === null || lang === '') ? undefined : lang; 241 } 242 if (lang === undefined) { 243 if (context.lang) { 244 lang = context.lang; 245 } else { 246 if (elem[0].parentNode.nodeType === 1) { 247 lang = getLang(elem.parent()); 248 } 249 } 250 } 251 return lang; 252 }, 253 254 entity = function (c) { 255 switch (c) { 256 case '<': 257 return '<'; 258 case '"': 259 return '"'; 260 case '&': 261 return '&'; 262 } 263 }, 264 265 serialize = function (elem, ignoreNs) { 266 var i, string = '', atts, a, name, ns, tag; 267 elem.contents().each(function () { 268 var j = $(this), 269 e = j[0]; 270 if (e.nodeType === 1) { // tests whether the node is an element 271 name = e.nodeName.toLowerCase(); 272 string += '<' + name; 273 if (e.outerHTML) { 274 tag = /<[^>]+>/.exec(e.outerHTML); 275 a = attRegex.exec(tag); 276 while (a !== null) { 277 if (!/^jQuery/.test(a[1])) { 278 string += ' ' + a[1] + '='; 279 string += a[2] ? a[3] : '"' + a[1] + '"'; 280 } 281 a = attRegex.exec(tag); 282 } 283 attRegex.lastIndex = 0; 284 } else { 285 atts = e.attributes; 286 for (i = 0; i < atts.length; i += 1) { 287 a = atts.item(i); 288 string += ' ' + a.nodeName + '="'; 289 string += a.nodeValue.replace(/[<"&]/g, entity); 290 string += '"'; 291 } 292 } 293 if (!ignoreNs) { 294 ns = j.xmlns(''); 295 if (ns !== undefined && j.attr('xmlns') === undefined) { 296 string += ' xmlns="' + ns + '"'; 297 } 298 } 299 string += '>'; 300 string += serialize(j, true); 301 string += '</' + name + '>'; 302 } else if (e.nodeType === 8) { // tests whether the node is a comment 303 string += '<!--'; 304 string += e.nodeValue; 305 string += '-->'; 306 } else { 307 string += e.nodeValue; 308 } 309 }); 310 return string; 311 }, 312 313 rdfa = function (context) { 314 var i, subject, resource, lang, datatype, content, 315 types, object, triple, parent, 316 properties, rels, revs, 317 forward, backward, 318 triples = [], 319 attsAndNs, atts, namespaces, ns, 320 children = this.children(); 321 context = context || {}; 322 forward = context.forward || []; 323 backward = context.backward || []; 324 attsAndNs = getAttributes(this); 325 atts = attsAndNs.atts; 326 context.atts = atts; 327 namespaces = context.namespaces || this.xmlns(); 328 if (attsAndNs.namespaces[':length'] > 0) { 329 namespaces = $.extend({}, namespaces); 330 for (ns in attsAndNs.namespaces) { 331 if (ns !== ':length') { 332 namespaces[ns] = attsAndNs.namespaces[ns]; 333 } 334 } 335 } 336 context.curieOptions = $.extend({}, rdfaCurieDefaults, { namespaces: namespaces, base: this.base() }); 337 subject = getSubject(this, context); 338 lang = getLang(this, context); 339 if (subject.skip) { 340 rels = context.forward; 341 revs = context.backward; 342 subject = context.subject; 343 resource = context.object; 344 } else { 345 subject = subject.subject; 346 if (forward.length > 0 || backward.length > 0) { 347 parent = context.subject || getSubject(this.parent()).subject; 348 for (i = 0; i < forward.length; i += 1) { 349 triple = $.rdf.triple(parent, forward[i], subject, { source: this[0] }); 350 triples.push(triple); 351 } 352 for (i = 0; i < backward.length; i += 1) { 353 triple = $.rdf.triple(subject, backward[i], parent, { source: this[0] }); 354 triples.push(triple); 355 } 356 } 357 resource = getObjectResource(this, context); 358 types = resourcesFromCuries(atts['typeof'], this, context.curieOptions); 359 for (i = 0; i < types.length; i += 1) { 360 triple = $.rdf.triple(subject, $.rdf.type, types[i], { source: this[0] }); 361 triples.push(triple); 362 } 363 properties = resourcesFromCuries(atts.property, this, context.curieOptions); 364 if (properties.length > 0) { 365 datatype = atts.datatype; 366 content = atts.content; 367 if (datatype !== undefined && datatype !== '') { 368 datatype = $.curie(datatype, context.curieOptions); 369 if (datatype === rdfXMLLiteral) { 370 object = $.rdf.literal(serialize(this), { datatype: rdfXMLLiteral }); 371 } else if (content !== undefined) { 372 object = $.rdf.literal(content, { datatype: datatype }); 373 } else { 374 object = $.rdf.literal(this.text(), { datatype: datatype }); 375 } 376 } else if (content !== undefined) { 377 if (lang === undefined) { 378 object = $.rdf.literal('"' + content + '"'); 379 } else { 380 object = $.rdf.literal(content, { lang: lang }); 381 } 382 } else if (children.length === 0 || 383 datatype === '') { 384 lang = getLang(this, context); 385 if (lang === undefined) { 386 object = $.rdf.literal('"' + this.text() + '"'); 387 } else { 388 object = $.rdf.literal(this.text(), { lang: lang }); 389 } 390 } else { 391 object = $.rdf.literal(serialize(this), { datatype: rdfXMLLiteral }); 392 } 393 for (i = 0; i < properties.length; i += 1) { 394 triple = $.rdf.triple(subject, properties[i], object, { source: this[0] }); 395 triples.push(triple); 396 } 397 } 398 rels = resourcesFromCuries(atts.rel, this, context.curieOptions); 399 revs = resourcesFromCuries(atts.rev, this, context.curieOptions); 400 if (atts.resource !== undefined || atts.href !== undefined) { 401 // make the triples immediately 402 if (rels !== undefined) { 403 for (i = 0; i < rels.length; i += 1) { 404 triple = $.rdf.triple(subject, rels[i], resource, { source: this[0] }); 405 triples.push(triple); 406 } 407 } 408 rels = []; 409 if (revs !== undefined) { 410 for (i = 0; i < revs.length; i += 1) { 411 triple = $.rdf.triple(resource, revs[i], subject, { source: this[0] }); 412 triples.push(triple); 413 } 414 } 415 revs = []; 416 } 417 } 418 children.each(function () { 419 triples = triples.concat(rdfa.call($(this), { forward: rels, backward: revs, subject: subject, object: resource || subject, lang: lang, namespaces: namespaces })); 420 }); 421 return triples; 422 }, 423 424 gleaner = function (options) { 425 var type, atts; 426 if (options && options.about !== undefined) { 427 atts = getAttributes(this).atts; 428 if (options.about === null) { 429 return atts.property !== undefined || 430 atts.rel !== undefined || 431 atts.rev !== undefined || 432 atts['typeof'] !== undefined; 433 } else { 434 return getSubject(this, {atts: atts}).subject.value === options.about; 435 } 436 } else if (options && options.type !== undefined) { 437 type = getAttribute(this, 'typeof'); 438 if (type !== undefined) { 439 return options.type === null ? true : this.curie(type) === options.type; 440 } 441 return false; 442 } else { 443 return rdfa.call(this); 444 } 445 }, 446 447 nsCounter = 1, 448 449 createCurieAttr = function (elem, attr, uri) { 450 var m, curie, value; 451 try { 452 curie = elem.createCurie(uri); 453 } catch (e) { 454 if (uri.toString() === rdfXMLLiteral) { 455 elem.attr('xmlns:rdf', ns.rdf); 456 curie = 'rdf:XMLLiteral'; 457 } else { 458 m = /^(.+[\/#])([^#]+)$/.exec(uri); 459 elem.attr('xmlns:ns' + nsCounter, m[1]); 460 curie = 'ns' + nsCounter + ':' + m[2]; 461 nsCounter += 1; 462 } 463 } 464 value = getAttribute(elem, attr); 465 if (value !== undefined) { 466 if ($.inArray(curie, value.split(/\s+/)) === -1) { 467 elem.attr(attr, value + ' ' + curie); 468 } 469 } else { 470 elem.attr(attr, curie); 471 } 472 }, 473 474 createResourceAttr = function (elem, attr, resource) { 475 var ref; 476 if (resource.type === 'bnode') { 477 ref = '[_:' + resource.id + ']'; 478 } else { 479 ref = $(elem).base().relative(resource.value); 480 } 481 elem.attr(attr, ref); 482 }, 483 484 createSubjectAttr = function (elem, subject) { 485 var s = getSubject(elem).subject; 486 if (subject !== s) { 487 createResourceAttr(elem, 'about', subject); 488 } 489 elem.removeData('rdfa.subject'); 490 }, 491 492 createObjectAttr = function (elem, object) { 493 var o = getObjectResource(elem); 494 if (object !== o) { 495 createResourceAttr(elem, 'resource', object); 496 } 497 elem.removeData('rdfa.objectResource'); 498 }, 499 500 resetLang = function (elem, lang) { 501 elem.wrapInner('<span></span>') 502 .children('span') 503 .attr('lang', lang); 504 return elem; 505 }, 506 507 addRDFa = function (triple) { 508 var hasContent, hasRelation, hasRDFa, overridableObject, span, 509 subject, sameSubject, 510 object, sameObject, 511 lang, content, 512 i, atts, 513 ns = this.xmlns(); 514 span = this; 515 atts = getAttributes(this).atts; 516 if (typeof triple === 'string') { 517 triple = $.rdf.triple(triple, { namespaces: ns, base: this.base() }); 518 } else if (triple.rdfquery) { 519 addRDFa.call(this, triple.sources().get(0)); 520 return this; 521 } else if (triple.length) { 522 for (i = 0; i < triple.length; i += 1) { 523 addRDFa.call(this, triple[i]); 524 } 525 return this; 526 } 527 hasRelation = atts.rel !== undefined || atts.rev !== undefined; 528 hasRDFa = hasRelation || atts.property !== undefined || atts['typeof'] !== undefined; 529 if (triple.object.type !== 'literal') { 530 subject = getSubject(this, {atts: atts}, true).subject; 531 object = getObjectResource(this, {atts: atts}, true); 532 overridableObject = !hasRDFa && atts.resource === undefined; 533 sameSubject = subject === triple.subject; 534 sameObject = object === triple.object; 535 if (triple.property === $.rdf.type) { 536 if (sameSubject) { 537 createCurieAttr(this, 'typeof', triple.object.value); 538 } else if (hasRDFa) { 539 span = this.wrapInner('<span />').children('span'); 540 createCurieAttr(span, 'typeof', triple.object.value); 541 if (object !== triple.subject) { 542 createSubjectAttr(span, triple.subject); 543 } 544 } else { 545 createCurieAttr(this, 'typeof', triple.object.value); 546 createSubjectAttr(this, triple.subject); 547 } 548 } else if (sameSubject) { 549 // use a rel 550 if (sameObject) { 551 createCurieAttr(this, 'rel', triple.property.value); 552 } else if (overridableObject || !hasRDFa) { 553 createCurieAttr(this, 'rel', triple.property.value); 554 createObjectAttr(this, triple.object); 555 } else { 556 span = this.wrap('<span />').parent(); 557 createCurieAttr(span, 'rev', triple.property.value); 558 createSubjectAttr(span, triple.object); 559 } 560 } else if (subject === triple.object) { 561 if (object === triple.subject) { 562 // use a rev 563 createCurieAttr(this, 'rev', triple.property.value); 564 } else if (overridableObject || !hasRDFa) { 565 createCurieAttr(this, 'rev', triple.property.value); 566 createObjectAttr(this, triple.subject); 567 } else { 568 // wrap in a span with a rel 569 span = this.wrap('<span />').parent(); 570 createCurieAttr(span, 'rel', triple.property.value); 571 createSubjectAttr(span, triple.subject); 572 } 573 } else if (sameObject) { 574 if (hasRDFa) { 575 // use a rev on a nested span 576 span = this.wrapInner('<span />').children('span'); 577 createCurieAttr(span, 'rev', triple.property.value); 578 createObjectAttr(span, triple.subject); 579 span = span.wrapInner('<span />').children('span'); 580 createSubjectAttr(span, triple.object); 581 span = this; 582 } else { 583 createSubjectAttr(this, triple.subject); 584 createCurieAttr(this, 'rel', triple.property.value); 585 } 586 } else if (object === triple.subject) { 587 if (hasRDFa) { 588 // wrap the contents in a span and use a rel 589 span = this.wrapInner('<span />').children('span'); 590 createCurieAttr(span, 'rel', this.property.value); 591 createObjectAttr(span, triple.object); 592 span = span.wrapInner('<span />').children('span'); 593 createSubjectAttr(span, object); 594 span = this; 595 } else { 596 // use a rev on this element 597 createSubjectAttr(this, triple.object); 598 createCurieAttr(this, 'rev', triple.property.value); 599 } 600 } else if (hasRDFa) { 601 span = this.wrapInner('<span />').children('span'); 602 createCurieAttr(span, 'rel', triple.property.value); 603 createSubjectAttr(span, triple.subject); 604 createObjectAttr(span, triple.object); 605 if (span.children('*').length > 0) { 606 span = this.wrapInner('<span />').children('span'); 607 createSubjectAttr(span, subject); 608 } 609 span = this; 610 } else { 611 createCurieAttr(span, 'rel', triple.property.value); 612 createSubjectAttr(this, triple.subject); 613 createObjectAttr(this, triple.object); 614 if (this.children('*').length > 0) { 615 span = this.wrapInner('<span />').children('span'); 616 createSubjectAttr(span, subject); 617 span = this; 618 } 619 } 620 } else { 621 subject = getSubject(this, {atts: atts}).subject; 622 object = getObjectResource(this, {atts: atts}); 623 sameSubject = subject === triple.subject; 624 hasContent = this.text() !== triple.object.value; 625 if (atts.property !== undefined) { 626 content = atts.content; 627 sameObject = content !== undefined ? content === triple.object.value : !hasContent; 628 if (sameSubject && sameObject) { 629 createCurieAttr(this, 'property', triple.property.value); 630 } else { 631 span = this.wrapInner('<span />').children('span'); 632 return addRDFa.call(span, triple); 633 } 634 } else { 635 if (object === triple.subject) { 636 span = this.wrapInner('<span />').children('span'); 637 return addRDFa.call(span, triple); 638 } 639 createCurieAttr(this, 'property', triple.property.value); 640 createSubjectAttr(this, triple.subject); 641 if (hasContent) { 642 if (triple.object.datatype && triple.object.datatype.toString() === rdfXMLLiteral) { 643 this.html(triple.object.value); 644 } else { 645 this.attr('content', triple.object.value); 646 } 647 } 648 lang = getLang(this); 649 if (triple.object.lang) { 650 if (lang !== triple.object.lang) { 651 this.attr('lang', triple.object.lang); 652 if (hasContent) { 653 resetLang(this, lang); 654 } 655 } 656 } else if (triple.object.datatype) { 657 createCurieAttr(this, 'datatype', triple.object.datatype); 658 } else { 659 // the empty datatype ensures that any child elements that might be added won't mess up this triple 660 if (!hasContent) { 661 this.attr('datatype', ''); 662 } 663 // the empty lang ensures that a language won't be assigned to the literal 664 if (lang !== undefined) { 665 this.attr('lang', ''); 666 if (hasContent) { 667 resetLang(this, lang); 668 } 669 } 670 } 671 } 672 } 673 this.parents().andSelf().trigger("rdfChange"); 674 return span; 675 }, 676 677 removeRDFa = function (what) { 678 var span, atts, property, rel, rev, type, 679 ns = this.xmlns(); 680 atts = getAttributes(this).atts; 681 if (what.length) { 682 for (i = 0; i < what.length; i += 1) { 683 removeRDFa.call(this, what[i]); 684 } 685 return this; 686 } 687 hasRelation = atts.rel !== undefined || atts.rev !== undefined; 688 hasRDFa = hasRelation || atts.property !== undefined || atts['typeof'] !== undefined; 689 if (hasRDFa) { 690 if (what.property !== undefined) { 691 if (atts.property !== undefined) { 692 property = removeCurie(atts.property, what.property, { namespaces: ns }); 693 if (property === '') { 694 this.removeAttr('property'); 695 } else { 696 this.attr('property', property); 697 } 698 } 699 if (atts.rel !== undefined) { 700 rel = removeCurie(atts.rel, what.property, { namespaces: ns }); 701 if (rel === '') { 702 this.removeAttr('rel'); 703 } else { 704 this.attr('rel', rel); 705 } 706 } 707 if (atts.rev !== undefined) { 708 rev = removeCurie(atts.rev, what.property, { namespaces: ns }); 709 if (rev === '') { 710 this.removeAttr('rev'); 711 } else { 712 this.attr('rev', rev); 713 } 714 } 715 } 716 if (what.type !== undefined) { 717 if (atts['typeof'] !== undefined) { 718 type = removeCurie(atts['typeof'], what.type, { namespaces: ns }); 719 if (type === '') { 720 this.removeAttr('typeof'); 721 } else { 722 this.attr('typeof', type); 723 } 724 } 725 } 726 if (atts.property === this.attr('property') && atts.rel === this.attr('rel') && atts.rev === this.attr('rev') && atts['typeof'] === this.attr('typeof')) { 727 return removeRDFa.call(this.parent(), what); 728 } 729 } 730 this.parents().andSelf().trigger("rdfChange"); 731 return this; 732 }; 733 734 /** 735 * Creates a {@link jQuery.rdf} object containing the RDF triples parsed from the RDFa found in the current jQuery selection or adds the specified triple as RDFa markup on each member of the current jQuery selection. To create an {@link jQuery.rdf} object, you will usually want to use {@link jQuery#rdf} instead, as this may perform other useful processing (such as of microformats used within the page). 736 * @methodOf jQuery# 737 * @name jQuery#rdfa 738 * @param {jQuery.rdf.triple} [triple] The RDF triple to be added to each item in the jQuery selection. 739 * @returns {jQuery.rdf} 740 * @example 741 * // Extract RDFa markup from all span elements contained inside #main 742 * rdf = $('#main > span').rdfa(); 743 * @example 744 * // Add RDFa markup to a particular element 745 * var span = $('#main > p > span'); 746 * span.rdfa('<> dc:date "2008-10-19"^^xsd:date .'); 747 */ 748 $.fn.rdfa = function (triple) { 749 if (triple === undefined) { 750 var triples = $.map($(this), function (elem) { 751 return rdfa.call($(elem)); 752 }); 753 return $.rdf({ triples: triples }); 754 } else { 755 $(this).each(function () { 756 addRDFa.call($(this), triple); 757 }); 758 return this; 759 } 760 }; 761 762 /** 763 * Removes the specified RDFa markup from each of the items in the current jQuery selection. The input parameter can be either an object or an array of objects. The objects can either have a <code>type</code> property, in which case the specified type is removed from the RDFa provided on the selected elements, or a <code>property</code> property, in which case the specified property is removed from the RDFa provided on the selected elements. 764 * @methodOf jQuery# 765 * @name jQuery#removeRdfa 766 * @param {Object|Object[]} triple The RDFa markup items to be removed 767 * from the items in the jQuery selection. 768 * @returns {jQuery} The original jQuery object. 769 * @example 770 * // To remove a property resource or relation from an element 771 * $('#main > p > a').removeRdfa({ property: "dc:creator" }); 772 * @example 773 * // To remove a type from an element 774 * $('#main >p > a').removeRdfa({ type: "foaf:Person" }); 775 * @example 776 * // To remove multiple triples from an element 777 * $('#main > p > a').removeRdfa([{ property: "foaf:depicts" }, { property: "dc:creator" }]); 778 */ 779 $.fn.removeRdfa = function (triple) { 780 $(this).each(function () { 781 removeRDFa.call($(this), triple); 782 }); 783 return this; 784 }; 785 786 $.rdf.gleaners.push(gleaner); 787 788 })(jQuery); 789