等待页面加载,并等待页面元素加载,然后将 Svelte 组件挂载上
// 等待页面加载完成
document.addEventListener('DOMContentLoaded', async () => {
  // 检查当前页面是否是 YouTube 视频页面
  if (!location.href.includes("watch")) {
    console.log("Not a video page");
    return;
  }

  // 查找页面上的特定元素
  const secondaryElement = await waitForElement("#secondary");
  if (!secondaryElement) {
    console.log("Element not found");
    return;
  }

  // 创建并插入自定义组件
  const container = document.createElement('div');
  container.id = "crxThumbnailToEagle";
  secondaryElement.insertBefore(container, secondaryElement.firstChild);

  // 挂载 Svelte 组件
  new Ls({ target: container });
});

// 等待元素出现的函数
function waitForElement(selector) {
  return new Promise((resolve) => {
    const element = document.querySelector(selector);
    if (element) {
      resolve(element);
    } else {
      const observer = new MutationObserver((mutations, obs) => {
        const element = document.querySelector(selector);
        if (element) {
          obs.disconnect();
          resolve(element);
        }
      });
      observer.observe(document, { childList: true, subtree: true });
    }
  });
}
引入依赖和工具函数
// 引入wxt/storage用于存储和读取数据
import { defineItem } from 'wxt/storage';

// 引入iconify用于处理图标
import { Icon } from '@iconify/svelte';
定义常量和配置
// 定义常量用于模板替换
const VIDEO_TITLE = "VIDEO_TITLE";
const CHANNEL_NAME = "CHANNEL_NAME";

// 定义存储项用于存储用户自定义的模板
const eagleItemTemplate = defineItem('local:eagleItemTemplate', {
  defaultValue: { title: "VIDEO_TITLE by CHANNEL_NAME", annotation: "" }
});
主要功能函数
or 函数
async function or(title, thumbnailUrl, videoUrl, annotation) {
  const data = {
    type: "image",
    title: title,
    src: thumbnailUrl,
    url: videoUrl,
    annotation: annotation
  };

  // 如果有注释,尝试复制到剪贴板
  if (annotation !== "") {
    try {
      const clipboardItem = [
        new ClipboardItem({
          "text/plain": new Blob([annotation], { type: "text/plain" })
        })
      ];
      await navigator.clipboard.write(clipboardItem);
    } catch (error) {
      console.log("Failed to copy annotation text", error);
    }
  }

  // 发送数据到 Eagle 应用
  const options = {
    method: "POST",
    body: new URLSearchParams(data),
    headers: { "Content-Type": "application/x-www-form-urlencoded" }
  };
  const eagleUrl = "http://localhost:41593";

  try {
    await fetch(eagleUrl, options);
  } catch (error) {
    console.log("Failed to save to Eagle", error);
  }
}
ir 函数
async function ir(videoTitle, thumbnailUrl, videoId) {
  const videoUrl = `https://www.youtube.com/watch?v=${videoId}`;
  const channelName = document.querySelector("span[itemprop='author'] link[itemprop='name']")?.getAttribute("content") || "";
  const { title: templateTitle, annotation: templateAnnotation } = await eagleItemTemplate.getValue();

  const title = templateTitle.replace(VIDEO_TITLE, videoTitle.replace(/ - YouTube$/, "")).replace(CHANNEL_NAME, channelName);
  const annotation = templateAnnotation.replace(VIDEO_TITLE, videoTitle.replace(/ - YouTube$/, "")).replace(CHANNEL_NAME, channelName);

  await or(title, thumbnailUrl, videoUrl, annotation);
}
cr 函数
async function cr(videoId) {
  const resolutions = ["maxresdefault", "sddefault", "hqdefault", "mqdefault", "default"];
  for (const res of resolutions) {
    const url = `https://img.youtube.com/vi/${videoId}/${res}.jpg`;
    try {
      const img = await loadImage(url);
      if (img.width > 120) {
        return url;
      }
    } catch {
      // 忽略错误,尝试下一个分辨率
    }
  }
  return "";

  // 辅助函数:加载图片
  function loadImage(url) {
    return new Promise((resolve, reject) => {
      const img = new Image();
      img.onload = () => resolve(img);
      img.onerror = reject;
      img.src = url;
    });
  }
}
主函数
const Fs = {
  matches: ["https://www.youtube.com/*"],
  async main(e) {
    // 检查当前页面是否是 YouTube 视频页面
    if (!location.href.includes("watch")) {
      console.log("Not a video page");
      return;
    }

    // 查找页面上的特定元素
    const secondaryElement = await waitForElement("#secondary");
    if (!secondaryElement) {
      console.log("Element not found");
      return;
    }

    // 创建并插入自定义组件
    const container = document.createElement('div');
    container.id = "crxThumbnailToEagle";
    secondaryElement.insertBefore(container, secondaryElement.firstChild);

    // 挂载 Svelte 组件
    new Ls({ target: container });
  },
};
等待元素出现的函数
function waitForElement(selector) {
  return new Promise((resolve) => {
    const element = document.querySelector(selector);
    if (element) {
      resolve(element);
    } else {
      const observer = new MutationObserver((mutations, obs) => {
        const element = document.querySelector(selector);
        if (element) {
          obs.disconnect();
          resolve(element);
        }
      });
      observer.observe(document, { childList: true, subtree: true });
    }
  });
}
初始化和启动
// 从Fs对象中解构出main函数和其他属性
const { main: e, ...t } = Fs;

// 创建一个新的内容脚本实例
const n = new Cn("content", t);

// 使用异步函数调用main函数,并处理可能的错误
(async () => {
  try {
    await e(n);
  } catch (error) {
    console.error('The content script "content" crashed on startup!', error);
  }
})();
通过这些代码,你可以实现将 YouTube 视频信息保存到 Eagle 应用的功能,并在 YouTube 视频页面上添加一个自定义组件。
以下是一个简化的 background.js 示例代码,展示了上述功能:

// 引入 browser-polyfill 库
import browser from 'webextension-polyfill';

// 定义一些常量和配置
const VIDEO_TITLE = "VIDEO_TITLE";
const CHANNEL_NAME = "CHANNEL_NAME";

// 定义存储项用于存储用户自定义的模板
const eagleItemTemplate = defineItem('local:eagleItemTemplate', {
  defaultValue: { title: "VIDEO_TITLE by CHANNEL_NAME", annotation: "" }
});

// 消息处理函数
function handleMessage(message, sender, sendResponse) {
  switch (message.type) {
    case 'openOptionsPage':
      browser.runtime.openOptionsPage();
      break;
    // 其他消息类型处理
    default:
      console.log('Unknown message type:', message.type);
  }
}

// 监听消息
browser.runtime.onMessage.addListener(handleMessage);

// 初始化函数
function init() {
  console.log('Background script initialized');
  // 其他初始化操作
}

// 执行初始化
init();
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇