From 8dd10f7e77eb507c1f354a9fbe9021989c2f9c43 Mon Sep 17 00:00:00 2001 From: DebaucheryLibrarian Date: Tue, 29 Dec 2020 00:42:02 +0100 Subject: [PATCH] Adjusting tooltip arrow position, added open and close events. Fixed search tooltip layout. --- assets/components/header/header.vue | 18 ++++---- assets/components/header/search.vue | 13 +++--- assets/components/tooltip/tooltip.vue | 61 ++++++++++++++++++--------- src/scrapers/mikeadriano.js | 41 +++++++++++++++--- src/utils/http.js | 10 ++++- src/utils/qu.js | 34 ++++++++++----- 6 files changed, 123 insertions(+), 54 deletions(-) diff --git a/assets/components/header/header.vue b/assets/components/header/header.vue index 71efdbd5..bbd654a8 100644 --- a/assets/components/header/header.vue +++ b/assets/components/header/header.vue @@ -162,8 +162,8 @@ - + diff --git a/assets/components/header/search.vue b/assets/components/header/search.vue index 66e734fb..92eba890 100644 --- a/assets/components/header/search.vue +++ b/assets/components/header/search.vue @@ -27,10 +27,7 @@ async function search() { function searching(to) { if (to) { - setTimeout(() => { - // nextTick does not seem to work - this.$refs.search.focus(); - }, 20); + this.$refs.search.focus(); } } @@ -79,12 +76,12 @@ export default { padding: 0; border: none; - .search-input { - border: solid 1px var(--shadow-hint); - } + .search-input { + padding: .75rem .5rem .75rem .75rem; + } .search-button { - padding: 0 .5rem 0 1rem; + padding: 1rem 1rem .75rem .25rem; margin: 0; } } diff --git a/assets/components/tooltip/tooltip.vue b/assets/components/tooltip/tooltip.vue index 8845c4a4..69f75ab0 100644 --- a/assets/components/tooltip/tooltip.vue +++ b/assets/components/tooltip/tooltip.vue @@ -19,6 +19,11 @@
+ +
@@ -30,19 +35,29 @@ import { nextTick } from 'vue'; function getX(triggerBoundary, tooltipBoundary) { const idealPosition = triggerBoundary.left + (triggerBoundary.width / 2) - (tooltipBoundary.width / 2); + const rightEdgeOverflow = Math.max((idealPosition + tooltipBoundary.width) - window.innerWidth, 0); // don't overflow left edge if (idealPosition < 0) { - return 0; + return { + tooltipX: 0, + arrowOffset: idealPosition, + }; } // don't overflow right edge - if (idealPosition + tooltipBoundary.width > window.innerWidth) { - return window.innerWidth - tooltipBoundary.width; + if (rightEdgeOverflow > 0) { + return { + tooltipX: window.innerWidth - tooltipBoundary.width, + arrowOffset: rightEdgeOverflow, + }; } // position at the center of trigger - return idealPosition; + return { + tooltipX: idealPosition, + arrowOffset: 0, + }; } async function calculate() { @@ -53,8 +68,11 @@ async function calculate() { const triggerBoundary = this.$refs.trigger.getBoundingClientRect(); const tooltipBoundary = this.$refs.tooltip.getBoundingClientRect(); + const { tooltipX, arrowOffset } = this.getX(triggerBoundary, tooltipBoundary); + this.tooltipY = triggerBoundary.top + triggerBoundary.height; - this.tooltipX = this.getX(triggerBoundary, tooltipBoundary); + this.tooltipX = tooltipX; + this.arrowOffset = arrowOffset; } async function open() { @@ -66,6 +84,7 @@ async function open() { await nextTick(); this.calculate(); + this.$emit('open'); } function close() { @@ -73,6 +92,9 @@ function close() { this.tooltipY = 0; this.tooltipX = 0; + this.arrowOffset = 0; + + this.$emit('close'); } function toggle() { @@ -100,6 +122,7 @@ export default { opened: false, tooltipX: 0, tooltipY: 0, + arrowOffset: 0, }; }, mounted, @@ -127,24 +150,24 @@ export default { .tooltip-inner { position: relative; box-shadow: 0 0 3px var(--darken-weak); - - &:after { - content: ''; - width: 0; - height: 0; - position: absolute; - top: -.5rem; - left: calc(50% - .5rem); - border-left: .5rem solid transparent; - border-right: .5rem solid transparent; - border-bottom: .5rem solid var(--background-light); - margin: 0 auto; - filter: drop-shadow(0 0 3px var(--darken-weak)); - } } .tooltip { position: relative; background: var(--background-light); } + +.tooltip-arrow { + content: ''; + width: 0; + height: 0; + position: absolute; + top: -.5rem; + left: calc(50% - .5rem); + border-left: .5rem solid transparent; + border-right: .5rem solid transparent; + border-bottom: .5rem solid var(--background-light); + margin: 0 auto; + filter: drop-shadow(0 0 3px var(--darken-weak)); +} diff --git a/src/scrapers/mikeadriano.js b/src/scrapers/mikeadriano.js index f11142c0..e27c671b 100644 --- a/src/scrapers/mikeadriano.js +++ b/src/scrapers/mikeadriano.js @@ -1,6 +1,7 @@ 'use strict'; const qu = require('../utils/qu'); +const http = require('../utils/http'); function scrapeAll(scenes) { return scenes.map(({ query }) => { @@ -33,13 +34,11 @@ function scrapeAll(scenes) { async function scrapeScene({ query }, url) { const release = { director: 'Mike Adriano' }; - if (query.exists('a[href*="stackpath.com"]')) { - throw new Error('URL blocked by StackPath'); - } - const pathname = new URL(url).pathname; release.entryId = pathname.match(/\/view\/(\d+)/)?.[1] || pathname.match(/\/view\/([\w-]+)/)?.[1]; + console.log(release); + release.title = query.cnt('.content-page-info .title'); release.description = query.cnt('.content-page-info .desc'); release.date = query.date('.content-page-info .date, .content-page-info .hide, .post-date', 'Do MMM YYYY'); @@ -71,10 +70,40 @@ async function fetchLatest(channel, page = 1) { } async function fetchScene(url, channel) { - const res = await qu.get(url); + const cookieJar = http.cookieJar(); + const session = http.session({ cookieJar }); + + console.log(cookieJar); + + const resA = await http.get(url, { + session, + extract: { + cookieJar, + // runScripts: 'dangerously', + }, + }); + + console.log(resA.headers, cookieJar.getCookiesSync(url)); + const cookie = cookieJar.getCookieStringSync(url); + + console.log(cookie); + + const res = await http.get(url, { + headers: { + cookie, + }, + }); + + // console.log(res.req); if (res.ok) { - return scrapeScene(res.item, url, channel); + const item = qu.init(res.document); + + if (item.query.exists('a[href*="stackpath.com"]')) { + throw new Error('URL blocked by StackPath'); + } + + return scrapeScene(item, url, channel); } return res.status; diff --git a/src/utils/http.js b/src/utils/http.js index 3b80acaa..19a9870c 100644 --- a/src/utils/http.js +++ b/src/utils/http.js @@ -6,7 +6,7 @@ const util = require('util'); const stream = require('stream'); const tunnel = require('tunnel'); const Bottleneck = require('bottleneck'); -const { JSDOM } = require('jsdom'); +const { JSDOM, CookieJar } = require('jsdom'); const logger = require('../logger')(__filename); const virtualConsole = require('./virtual-console')(__filename); @@ -110,7 +110,7 @@ async function request(method = 'get', url, body, requestOptions = {}, limiter) if (Buffer.isBuffer(res.body)) { const html = res.body.toString(); - const window = new JSDOM(html, { virtualConsole }).window; + const window = new JSDOM(html, { virtualConsole, ...options.extract }).window; return { ...res, @@ -165,6 +165,10 @@ function getSession(options) { return bhttp.session({ ...defaultOptions, ...options }); } +function getCookieJar(store, options) { + return new CookieJar(store, options); +} + module.exports = { get, head, @@ -173,5 +177,7 @@ module.exports = { put, patch, session: getSession, + cookieJar: getCookieJar, getSession, + getCookieJar, }; diff --git a/src/utils/qu.js b/src/utils/qu.js index d16f16d8..907bbab3 100644 --- a/src/utils/qu.js +++ b/src/utils/qu.js @@ -118,6 +118,12 @@ function html(context, selector) { return el && el.innerHTML; } +function htmls(context, selector) { + const els = all(context, selector, null, true); + + return els.map(el => el.innerHTML); +} + function texts(context, selector, applyTrim = true, filter = true) { const el = q(context, selector, null, applyTrim); if (!el) return null; @@ -363,27 +369,28 @@ const legacyFuncs = { const quFuncs = { all, - html, - content, - contents, cnt: content, cnts: contents, + content, + contents, count, date, dateAgo, dur: duration, duration, - element: q, el: q, + element: q, exists, + html, + htmls, image, images, img: image, imgs: images, length: duration, meta, - number, num: number, + number, poster, q, sourceSet, @@ -444,8 +451,8 @@ function initAll(context, selector, window) { .map(element => init(element, window)); } -function extract(htmlValue, selector) { - const { window } = new JSDOM(htmlValue, { virtualConsole }); +function extract(htmlValue, selector, options) { + const { window } = new JSDOM(htmlValue, { virtualConsole, ...options }); if (selector) { return init(window.document.querySelector(selector), window); @@ -454,8 +461,8 @@ function extract(htmlValue, selector) { return init(window.document, window); } -function extractAll(htmlValue, selector) { - const { window } = new JSDOM(htmlValue, { virtualConsole }); +function extractAll(htmlValue, selector, options) { + const { window } = new JSDOM(htmlValue, { virtualConsole, ...options }); return initAll(window.document, selector, window); } @@ -467,8 +474,8 @@ async function request(method = 'get', urlValue, body, selector, headers, option if (res.ok) { const item = queryAll - ? extractAll(res.body.toString(), selector) - : extract(res.body.toString(), selector); + ? initAll(res.document, selector, res.window) + : init(res.document, selector, res.window); return { item, @@ -506,6 +513,10 @@ async function postAll(urlValue, body, selector, headers, options) { return request('post', urlValue, body, selector, headers, options, true); } +function session(headers, options) { + return http.session(headers, options); +} + module.exports = { extractDate, extract, @@ -532,5 +543,6 @@ module.exports = { post, postAll, prefixUrl, + session, ...legacyFuncs, };