This repository has been archived by the owner on Jun 7, 2024. It is now read-only.
forked from speced/respec
-
Notifications
You must be signed in to change notification settings - Fork 0
/
jquery-enhanced.js
173 lines (167 loc) · 6.61 KB
/
jquery-enhanced.js
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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
define(["jquery","core/utils"], function($, utils) {
// --- JQUERY EXTRAS -----------------------------------------------------------------------
// Applies to any jQuery object containing elements, changes their name to the one give, and
// return a jQuery object containing the new elements
$.fn.renameElement = function(name) {
var arr = [];
this.each(function() {
var $newEl = $(this.ownerDocument.createElement(name));
// I forget why this didn't work, maybe try again
// $newEl.attr($(this).attr());
for (var i = 0, n = this.attributes.length; i < n; i++) {
var at = this.attributes[i];
$newEl[0].setAttributeNS(at.namespaceURI, at.name, at.value);
}
$(this).contents().appendTo($newEl);
$(this).replaceWith($newEl);
arr.push($newEl[0]);
});
return $(arr);
};
// For any element, returns an array of title strings that applies
// the algorithm used for determining the
// actual title of a <dfn> element (but can apply to other as well).
//
// if args.isDefinition is true, then the element is a definition, not a
// reference to a definition. Any @title or @lt will be replaced with
// @data-lt to be consistent with Bikeshed / Shepherd.
//
// This method now *prefers* the data-lt attribute for the list of
// titles. That attribute is added by this method to dfn elements, so
// subsequent calls to this method will return the data-lt based list.
//
// This method will publish a warning if a title is used on a definition
// instead of an @lt (as per specprod mailing list discussion).
$.fn.getDfnTitles = function(args) {
var titles = [];
var theAttr = "";
var titleString = "";
var normalizedText = "";
//data-lt-noDefault avoid using the text content of a definition
//in the definition list.
if (this.attr("data-lt-noDefault") === undefined) {
normalizedText = utils.norm(this.text()).toLowerCase();
}
// allow @lt to be consistent with bikeshed
if (this.attr("data-lt") || this.attr("lt")) {
theAttr = this.attr("data-lt") ? "data-lt" : "lt";
// prefer @data-lt for the list of title aliases
titleString = this.attr(theAttr).toLowerCase();
if (normalizedText !== "") {
//Regex: starts with the "normalizedText|"
var startsWith = new RegExp("^" + normalizedText + "\\|");
// Use the definition itself as first item, so to avoid
// having to declare the definition twice.
if (!startsWith.test(titleString)) {
titleString = normalizedText + "|" + titleString;
}
}
} else if (this.attr("title")) {
// allow @title for backward compatibility
titleString = this.attr("title");
theAttr = "title";
respecEvents.pub("warn", "Using deprecated attribute @title for '" + this.text() + "': see http://w3.org/respec/guide.html#definitions-and-linking");
} else if (this.contents().length == 1 && this.children("abbr, acronym").length == 1 && this.find(":first-child").attr("title")) {
titleString = this.find(":first-child").attr("title");
} else {
titleString = this.text();
}
// now we have a string of one or more titles
titleString = utils.norm(titleString).toLowerCase();
if (args && args.isDefinition === true) {
// if it came from an attribute, replace that with data-lt as per contract with Shepherd
if (theAttr) {
this.attr("data-lt", titleString);
this.removeAttr(theAttr);
}
// if there is no pre-defined type, assume it is a 'dfn'
if (!this.attr("dfn-type")) {
this.attr("data-dfn-type", "dfn");
} else {
this.attr("data-dfn-type", this.attr("dfn-type"));
this.removeAttr("dfn-type");
}
}
titleString.split('|').forEach(function(item) {
if (item != "") {
titles.push(item);
}
});
return titles;
};
// For any element (usually <a>), returns an array of targets that
// element might refer to, of the form
// {for_: 'interfacename', title: 'membername'}.
//
// For an element like:
// <p link-for="Int1"><a for="Int2">Int3.member</a></p>
// we'll return:
// * {for_: "int2", title: "int3.member"}
// * {for_: "int3", title: "member"}
// * {for_: "", title: "int3.member"}
$.fn.linkTargets = function() {
var elem = this;
var link_for = (elem.attr("for") || elem.attr("data-for") || elem.closest("[link-for]").attr("link-for") || elem.closest("[data-link-for]").attr("data-link-for") || "").toLowerCase();
var titles = elem.getDfnTitles();
var result = [];
$.each(titles, function() {
result.push({
for_: link_for,
title: this
});
var split = this.split('.');
if (split.length === 2) {
// If there are multiple '.'s, this won't match an
// Interface/member pair anyway.
result.push({
for_: split[0],
title: split[1]
});
}
result.push({
for_: "",
title: this
});
});
return result;
};
// Applied to an element, sets an ID for it (and returns it), using a specific prefix
// if provided, and a specific text if given.
$.fn.makeID = function(pfx, txt, noLC) {
if (this.attr("id")) return this.attr("id");
if (!txt) txt = this.attr("title") ? this.attr("title") : this.text();
txt = txt.replace(/^\s+/, "").replace(/\s+$/, "");
var id = noLC ? txt : txt.toLowerCase();
id = id.split(/[^\-.0-9a-z_]+/i).join("-").replace(/^-+/, "").replace(/-+$/, "");
if (/\.$/.test(id)) id += "x"; // trailing . doesn't play well with jQuery
if (id.length > 0 && /^[^a-z]/i.test(id)) id = "x" + id;
if (id.length === 0) id = "generatedID";
if (pfx) id = pfx + "-" + id;
var inc = 1,
doc = this[0].ownerDocument;
if ($("#" + id, doc).length) {
while ($("#" + id + "-" + inc, doc).length) inc++;
id += "-" + inc;
}
this.attr("id", id);
return id;
};
// Returns all the descendant text nodes of an element. Note that those nodes aren't
// returned as a jQuery array since I'm not sure if that would make too much sense.
$.fn.allTextNodes = function(exclusions) {
var textNodes = [],
excl = {};
for (var i = 0, n = exclusions.length; i < n; i++) excl[exclusions[i]] = true;
function getTextNodes(node) {
if (node.nodeType === 1 && excl[node.localName.toLowerCase()]) return;
if (node.nodeType === 3) textNodes.push(node);
else {
for (var i = 0, len = node.childNodes.length; i < len; ++i) getTextNodes(node.childNodes[i]);
}
}
getTextNodes(this[0]);
return textNodes;
};
window.$ = $;
return $;
});