|
218 | 218 | return path; |
219 | 219 | } |
220 | 220 |
|
221 | | - function queryDocumentSelectorAll(selector) { |
222 | | - let elements = []; |
| 221 | + function queryElements({ element, prefix, type, selector }) { |
| 222 | + let elements = new Map() |
| 223 | + if (!element) |
| 224 | + element = document |
| 225 | + let hasAttribute = false |
223 | 226 |
|
224 | 227 | if (selector) { |
225 | | - let selectors = [selector]; |
226 | | - if (selector.indexOf(',') !== -1) { |
227 | | - selectors = selector.split(','); |
| 228 | + if (!type) |
| 229 | + type = ['selector'] |
| 230 | + else if (!Array.isArray(type)) |
| 231 | + type = [type] |
| 232 | + } else |
| 233 | + type = ['selector', 'closest', 'parent', 'next', 'previous'] |
| 234 | + |
| 235 | + for (let i = 0; i < type.length; i++) { |
| 236 | + let Selector = selector |
| 237 | + if (!Selector) { |
| 238 | + let name = prefix + '-' + type[i] |
| 239 | + if (!element.hasAttribute(name)) |
| 240 | + continue |
| 241 | + hasAttribute = true |
| 242 | + Selector = element.getAttribute(name); |
228 | 243 | } |
229 | | - for (let selector of selectors) { |
230 | | - let els; |
231 | | - if (selector.indexOf(';') !== -1) { |
232 | | - let targetDocument; |
233 | | - let [documentSelector, targetSelector] = selector.split(';'); |
234 | | - if (['parent', 'parentDocument'].includes(documentSelector)) |
235 | | - targetDocument = window.parent.document; |
236 | | - else { |
237 | | - let frame = document.querySelector(documentSelector); |
238 | | - if (frame) |
239 | | - targetDocument = frame.contentDocument; |
240 | | - } |
241 | | - if (targetDocument) { |
242 | | - if (targetSelector) |
243 | | - els = targetDocument.querySelectorAll(targetSelector); |
244 | | - else |
245 | | - if (targetDocument.clickedElement) |
246 | | - els = [targetDocument.clickedElement]; |
247 | | - } |
248 | | - } |
249 | | - else |
250 | | - els = document.querySelectorAll(selector); |
251 | | - if (els) { |
252 | | - els = Array.prototype.slice.call(els); |
253 | | - elements = elements.concat(els); |
254 | | - } |
255 | | - } |
256 | | - } |
257 | | - return elements; |
258 | | - } |
259 | 244 |
|
260 | | - function queryDocumentSelector(selector) { |
261 | | - if (selector) { |
262 | | - let selectors = [selector]; |
263 | | - if (selector.indexOf(',') !== -1) { |
264 | | - selectors = selector.split(','); |
265 | | - } |
266 | | - for (let selector of selectors) { |
267 | | - let el; |
268 | | - if (selector.indexOf(';') !== -1) { |
269 | | - let targetDocument; |
270 | | - let [documentSelector, targetSelector] = selector.split(';'); |
271 | | - if (['parent', 'parentDocument'].includes(documentSelector)) |
272 | | - targetDocument = window.parent.document; |
273 | | - else { |
274 | | - let frame = document.querySelector(documentSelector); |
275 | | - if (frame) |
276 | | - targetDocument = frame.contentDocument; |
| 245 | + if (Selector) { |
| 246 | + |
| 247 | + let selectors = Selector.split(','); |
| 248 | + for (let j = 0; j < selectors.length; j++) { |
| 249 | + let queriedElement = element |
| 250 | + let specialSelectors = selectors[j].split(';') |
| 251 | + for (let k = 0; k < specialSelectors.length; k++) { |
| 252 | + |
| 253 | + // TODO: Support an array of queried elements and branch off to return matches for each |
| 254 | + // if (!Array.isArray(queriedElement)) { |
| 255 | + // queriedElement = [queriedElement] |
| 256 | + // } |
| 257 | + if (k === 0) { |
| 258 | + if (type[i] === 'parent') |
| 259 | + queriedElement = queriedElement.parentElement |
| 260 | + else if (type[i] === 'next') |
| 261 | + queriedElement = queriedElement.nextElementSibling |
| 262 | + else if (type[i] === 'previous') |
| 263 | + queriedElement = queriedElement.previousElementSibling |
| 264 | + } |
| 265 | + |
| 266 | + switch (specialSelectors[k]) { |
| 267 | + case 'top': |
| 268 | + queriedElement = window.top.document |
| 269 | + break; |
| 270 | + case 'frame': |
| 271 | + if (queriedElement.nodeType === 9) |
| 272 | + queriedElement = queriedElement.window.frameElement; |
| 273 | + else if (queriedElement.contentDocument) |
| 274 | + queriedElement = queriedElement.contentDocument; |
| 275 | + break; |
| 276 | + case 'document': |
| 277 | + queriedElement = document |
| 278 | + break; |
| 279 | + case 'parent': |
| 280 | + queriedElement = queriedElement.parentElement |
| 281 | + break; |
| 282 | + case 'next': |
| 283 | + queriedElement = queriedElement.nextElementSibling |
| 284 | + break; |
| 285 | + case 'previous': |
| 286 | + queriedElement = queriedElement.previousElementSibling |
| 287 | + break; |
| 288 | + default: |
| 289 | + if (k === 0 && type[i] === 'closest') |
| 290 | + queriedElement = queriedElement.closest(specialSelectors[k]) |
| 291 | + else if (specialSelectors[k].endsWith('[]')) |
| 292 | + queriedElement = queriedElement.querySelectorAll(specialSelectors[k].slice(0, -2)) |
| 293 | + else |
| 294 | + queriedElement = queriedElement.querySelector(specialSelectors[k]) |
| 295 | + } |
277 | 296 | } |
278 | | - if (targetDocument) { |
279 | | - if (targetSelector) |
280 | | - el = targetDocument.querySelector(targetSelector); |
281 | | - else |
282 | | - if (targetDocument.clickedElement) |
283 | | - el = [targetDocument.clickedElement]; |
| 297 | + |
| 298 | + if (Array.isArray(queriedElement) || queriedElement instanceof HTMLCollection || queriedElement instanceof NodeList) { |
| 299 | + for (let el of queriedElement) |
| 300 | + elements.set(el, '') |
| 301 | + } else if (queriedElement) { |
| 302 | + elements.set(queriedElement, '') |
284 | 303 | } |
285 | 304 | } |
286 | | - else |
287 | | - el = document.querySelector(selector); |
288 | | - if (el) |
289 | | - return el |
| 305 | + } else if (Selector === '') { |
| 306 | + if (type[i] === 'parent') |
| 307 | + elements.set(element.parentElement, '') |
| 308 | + else if (type[i] === 'next') |
| 309 | + elements.set(element.nextElementSibling, '') |
| 310 | + else if (type[i] === 'previous') |
| 311 | + elements.set(element.previousElementSibling, '') |
290 | 312 | } |
291 | 313 | } |
292 | | - return; |
293 | | - } |
294 | 314 |
|
295 | | - function getElements(element, prefix) { |
296 | | - let elements = []; |
297 | | - |
298 | | - let selectors = ['selector', 'closest', 'parent', 'next', 'previous'] |
299 | | - for (let i = 0; i < selectors.length; i++) { |
300 | | - let name = prefix + '-' + selectors[i] |
301 | | - const selector = element.getAttribute(name); |
302 | | - if (selector) { |
303 | | - if (selectors[i] === 'selector') |
304 | | - elements = document.querySelectorAll(selector) |
305 | | - else if (selectors[i] === 'closest') |
306 | | - elements = element.closest(selector) |
307 | | - else if (selectors[i] === 'parent') |
308 | | - elements = element.parentElement.querySelectorAll(selector) |
309 | | - else if (selectors[i] === 'next') |
310 | | - elements = element.nextElementSibling.querySelectorAll(selector) |
311 | | - else if (selectors[i] === 'previous') |
312 | | - elements = element.previousElementSibling.querySelectorAll(selector) |
313 | | - } else if (selector === '') { |
314 | | - if (selectors[i] === 'parent') |
315 | | - elements = element.parentElement |
316 | | - else if (selectors[i] === 'next') |
317 | | - elements = element.nextElementSibling |
318 | | - else if (selectors[i] === 'previous') |
319 | | - elements = element.previousElementSibling |
320 | | - } |
321 | | - } |
| 315 | + if (!hasAttribute && !selector) |
| 316 | + elements = false |
| 317 | + else |
| 318 | + elements = Array.from(elements.keys()) |
322 | 319 |
|
323 | 320 | return elements |
324 | 321 | } |
325 | 322 |
|
326 | | - |
327 | 323 | function queryData(data, query) { |
328 | 324 | if (!data) |
329 | 325 | return false; |
|
603 | 599 | parseTextToHtml, |
604 | 600 | escapeHtml, |
605 | 601 | cssPath, |
606 | | - queryDocumentSelector, |
607 | | - queryDocumentSelectorAll, |
608 | | - getElements, |
| 602 | + queryElements, |
609 | 603 | queryData, |
610 | 604 | searchData, |
611 | 605 | sortData, |
|
0 commit comments