', {
text: '没有匹配选项',
class: 'bgm-dropdown-item',
css: { color: '#999', cursor: 'default' }
}).appendTo($dropdownContent);
}
};
// 将选项值插入到输入框
function insertOptionValue(inputElem, value) {
const text = inputElem.value;
const pos = inputElem.selectionStart;
const mode = inputElem.dataset.dropdownMode || 'append'; // 获取插入模式
const conn = inputElem.dataset.dropdownConnector || '、';
// 根据不同的插入模式处理
if (mode === 'replace') {
// 直接替换
inputElem.value = value;
} else if (mode === 'append') {
// 自动补全逻辑改进
if (text) {
const currentWord = text.slice(0, pos).toLowerCase();
if (value.toLowerCase().startsWith(currentWord)) {
// 如果当前输入是目标值的开头,直接替换整个值
inputElem.value = value + text.slice(pos);
inputElem.setSelectionRange(value.length, value.length);
inputElem.focus();
return;
}
// 处理分隔符和空格
const lastChar = text.slice(-1);
if (['、',',',',','+',' '].includes(lastChar)) {
// 如果最后一个字符是分隔符,直接添加新值
inputElem.value = text.trimRight() + value;
} else {
// 否则添加分隔符和新值
inputElem.value = text + conn + value;
}
} else {
// 如果输入框为空,直接设置值
inputElem.value = value;
}
}
inputElem.focus();
}
// 处理所有字段
const processAllFields = () => {
const $ = window.jQuery || window.$;
// 处理ID字段和对应的属性字段
$('input.inputtext.id').each(function() {
const $idInput = $(this);
const idValue = $idInput.val().trim();
const $propInput = $idInput.next('.inputtext.prop');
// 为空ID字段添加下拉菜单(如果配置了)
if (idValue === '' && config[''] && !$idInput.data('dropdownAdded')) {
createDropdown(this, config[''].options, config[''].mode);
}
// 为其他配置的字段添加下拉菜单
if ($propInput.length) {
Object.entries(config).forEach(([key, options]) => {
const keys = key.split(',').map(k => k.trim());
if (keys.includes(idValue) && !$propInput.data('dropdownAdded')) {
createDropdown($propInput[0], options.options, options.mode, options.connector);
}
});
}
});
};
// 处理动态添加的字段
const processDynamicField = (element) => {
const $ = window.jQuery || window.$;
const $element = $(element);
// 如果元素本身是输入框
if ($element.is('input.inputtext.id')) {
const $idInput = $element;
const idValue = $idInput.val().trim();
const $propInput = $idInput.next('.inputtext.prop');
// 空ID字段处理
if (idValue === '' && config['']) {
createDropdown($idInput[0], config[''].options, config[''].mode);
}
// 属性字段处理
if ($propInput.length) {
Object.entries(config).forEach(([key, options]) => {
const keys = key.split(',').map(k => k.trim());
if (keys.includes(idValue)) {
createDropdown($propInput[0], options.options, options.mode, options.connector);
}
});
}
}
// 如果元素是容器
else {
// 处理常规ID字段
$element.find('input.inputtext.id').each(function() {
const $idInput = $(this);
const idValue = $idInput.val().trim();
const $propInput = $idInput.next('.inputtext.prop');
// 空ID字段处理
if (idValue === '' && config['']) {
createDropdown($idInput[0], config[''].options, config[''].mode);
}
// 属性字段处理
if ($propInput.length) {
Object.entries(config).forEach(([key, options]) => {
const keys = key.split(',').map(k => k.trim());
if (keys.includes(idValue)) {
createDropdown($propInput[0], options.options, options.mode, options.connector);
}
});
}
});
}
};
// 初始化函数
const init = () => {
const $ = window.jQuery || window.$;
// 添加样式
// injectStyles(); // 已移除,按照要求不包含样式相关代码
// 添加设置按钮
addSettingsButton();
// 初始处理所有字段
$(document).ready(function() {
processAllFields();
// 监听动态添加的字段
$(document).on('DOMNodeInserted', function(e) {
const $target = $(e.target);
if ($target.find('input.inputtext.id').length || $target.is('input.inputtext.id')) {
setTimeout(() => processDynamicField(e.target), 100);
}
});
// 点击页面其他位置时隐藏所有下拉框
$(document).on('click', function(e) {
if (!$(e.target).closest('.bgm-input-wrapper').length && !$(e.target).closest('.bgm-config-modal').length) {
$('.bgm-dropdown-content').removeClass('bgm-dropdown-active');
}
});
});
// 监听添加新行的按钮点击事件
$(document).on('click', '.newbtn', function() {
setTimeout(processAllFields, 100);
});
// 处理现有字段ID值变化的情况
$(document).on('change', 'input.inputtext.id', function() {
const $idInput = $(this);
const idValue = $idInput.val().trim();
const $propInput = $idInput.next('.inputtext.prop');
// 若属性字段已有下拉菜单,需要移除
if ($propInput.data('dropdownAdded')) {
if ($propInput.next('.bgm-dropdown-content').length) {
$propInput.next('.bgm-dropdown-content').remove();
}
$propInput.data('dropdownAdded', false);
// 如果输入框被包装了,尝试解包
if ($propInput.parent().hasClass('bgm-input-wrapper')) {
$propInput.unwrap();
}
}
// 添加新的下拉菜单
if ($propInput.length) {
Object.entries(config).forEach(([key, options]) => {
const keys = key.split(',').map(k => k.trim());
if (keys.includes(idValue)) {
createDropdown($propInput[0], options.options, options.mode, options.connector);
}
});
}
});
};
// 执行初始化
init();
}
/* =============
单行本快捷创建
===============*/
function initBgmCreateSubject() {
// 调试日志函数
function log(message) {
console.log(`[BGM助手] ${message}`);
}
// 添加通知区域
function addNotificationArea() {
// 检查是否已存在通知区域
if (document.querySelector('#bgm-notification-area')) return;
// 创建通知区域
const notificationArea = document.createElement('div');
notificationArea.id = 'bgm-notification-area';
notificationArea.style.position = 'fixed';
notificationArea.style.top = '10px';
notificationArea.style.right = '10px';
notificationArea.style.padding = '8px 15px';
notificationArea.style.backgroundColor = '#369CF8';
notificationArea.style.color = 'white';
notificationArea.style.borderRadius = '5px';
notificationArea.style.zIndex = '9999';
notificationArea.style.display = 'none';
notificationArea.style.boxShadow = '0 2px 5px rgba(0,0,0,0.2)';
document.body.appendChild(notificationArea);
}
// 显示通知
function showNotification(message, isError = false) {
// 确保通知区域存在
if (!document.querySelector('#bgm-notification-area')) {
addNotificationArea();
}
const notificationArea = document.querySelector('#bgm-notification-area');
notificationArea.textContent = message;
notificationArea.style.backgroundColor = isError ? '#FF5151' : '#369CF8';
notificationArea.style.display = 'block';
// 3秒后隐藏通知
setTimeout(() => {
notificationArea.style.display = 'none';
}, 3000);
// 如果支持GM通知,也显示一个
if (typeof GM_notification !== 'undefined') {
GM_notification({
title: 'Bangumi 条目创建助手',
text: message,
timeout: 3000
});
}
// 同时在控制台输出
log(message);
}
// 解决跨域存储问题 - 使用GM储存而不是localStorage
function saveData(key, value) {
if (typeof GM_setValue !== 'undefined') {
GM_setValue(key, value);
log(`使用GM_setValue保存数据: ${key}`);
return true;
} else if (typeof localStorage !== 'undefined') {
try {
localStorage.setItem(key, value);
log(`使用localStorage保存数据: ${key}`);
return true;
} catch (e) {
log(`localStorage保存失败: ${e.message}`);
return false;
}
}
return false;
}
function getData(key) {
if (typeof GM_getValue !== 'undefined') {
const value = GM_getValue(key);
log(`使用GM_getValue获取数据: ${key}=${value ? '有数据' : '无数据'}`);
return value;
} else if (typeof localStorage !== 'undefined') {
try {
const value = localStorage.getItem(key);
log(`使用localStorage获取数据: ${key}=${value ? '有数据' : '无数据'}`);
return value;
} catch (e) {
log(`localStorage获取失败: ${e.message}`);
return null;
}
}
return null;
}
function removeData(key) {
if (typeof GM_deleteValue !== 'undefined') {
GM_deleteValue(key);
log(`使用GM_deleteValue删除数据: ${key}`);
} else if (typeof localStorage !== 'undefined') {
try {
localStorage.removeItem(key);
log(`使用localStorage删除数据: ${key}`);
} catch (e) {
log(`localStorage删除失败: ${e.message}`);
}
}
}
// 在条目页面添加"新条目"按钮
function addCreateButton() {
const currentPath = location.pathname;
// 只有精确匹配 /subject/数字 时才继续
const matchSubject = currentPath.match(/^\/subject\/(\d+)$/);
if (!matchSubject) {
log("当前页面不是条目页面,不添加按钮");
return;
}
// 确保作品类型是"小说"或"漫画"
const genreSmall = document.querySelector('small.grey');
if (!genreSmall) {
log("未找到类型标签");
return;
}
const genre = genreSmall.textContent.trim();
if (!(genre === '小说' || genre === '漫画')) {
log(`条目类型不是小说或漫画: ${genre}`);
return;
}
// 查找导航栏,并避免重复添加按钮
const nav = document.querySelector(".subjectNav .navTabs, .navTabs");
if (!nav) {
log("未找到导航栏");
return;
}
if (nav.querySelector(".create-button")) {
log("按钮已存在,不重复添加");
return;
}
// 添加通知区域,确保在点击按钮前已准备好
addNotificationArea();
// 创建"新条目"按钮并插入导航栏
const createLi = document.createElement("li");
createLi.className = "create-button";
const subjectId = matchSubject[1];
createLi.innerHTML = `
新条目`;
// 按钮点击事件:拉取编辑页信息并跳转到创建页
createLi.querySelector("a").addEventListener("click", () => {
// 先显示通知:正在准备打开新页面
showNotification("正在获取条目内容...");
// 检测当前域名,统一使用同一域名请求和跳转
const currentHost = window.location.hostname; // 获取当前域名
log(`当前域名: ${currentHost}`);
const editUrl = `//${currentHost}/subject/${subjectId}/edit`;
const title = document.querySelector('h1 a[property="v:itemreviewed"]')?.textContent?.trim() ||
document.querySelector('h1.nameSingle a')?.textContent?.trim() ||
'';
if (!title) {
log("未找到条目标题");
}
// 直接使用fetch API,如果可用
const fetchData = () => {
log(`使用fetch请求: ${editUrl}`);
fetch(editUrl)
.then(response => {
if (!response.ok) {
throw new Error(`HTTP状态码: ${response.status}`);
}
return response.text();
})
.then(html => processEditPage(html))
.catch(e => {
showNotification(`获取内容失败: ${e.message}`, true);
log(`Fetch错误: ${e.message}`);
// 如果fetch失败,尝试使用GM_xmlhttpRequest
if (typeof GM_xmlhttpRequest !== 'undefined') {
useGMRequest();
}
});
};
// 使用GM_xmlhttpRequest作为备选
const useGMRequest = () => {
if (typeof GM_xmlhttpRequest === 'undefined') {
showNotification("脚本缺少必要的GM_xmlhttpRequest权限,请检查脚本管理器设置", true);
return;
}
log(`使用GM_xmlhttpRequest请求: ${window.location.protocol}${editUrl}`);
GM_xmlhttpRequest({
method: "GET",
url: window.location.protocol + editUrl,
timeout: 10000, // 10秒超时
onload: function (response) {
if (response.status !== 200) {
showNotification(`请求失败,状态码: ${response.status}`, true);
return;
}
processEditPage(response.responseText);
},
onerror: function (error) {
showNotification("网络请求失败,请检查网络连接", true);
console.error("请求失败", error);
},
ontimeout: function () {
showNotification("请求超时,请稍后重试", true);
}
});
};
// 处理编辑页数据
const processEditPage = (html) => {
try {
const parser = new DOMParser();
const doc = parser.parseFromString(html, "text/html");
// 检查是否需要登录
const loginForm = doc.querySelector('form[action="/FollowTheRabbit"]');
if (loginForm) {
showNotification("获取失败,请先登录Bangumi", true);
return;
}
const textarea = doc.querySelector('#subject_summary');
if (!textarea) {
showNotification("未找到条目内容,可能没有编辑权限", true);
return;
}
const content = textarea.value;
if (!content) {
showNotification("条目内容为空", true);
return;
}
// 识别条目类型
let type = "Unknown";
if (content.includes("Infobox animanga/Novel")) {
type = "Novel";
} else if (content.includes("Infobox animanga/Manga")) {
type = "Manga";
}
// 如果无法识别类型则提示
if (type === "Unknown") {
showNotification("未识别 Infobox 类型(支持 Novel 或 Manga)", true);
return;
}
// 使用全局唯一标识符,解决域名问题
const uniqueId = Date.now().toString();
const keyPrefix = `bgm_infobox_${uniqueId}`;
// 保存数据
const savedContent = saveData(`${keyPrefix}_content`, content);
const savedType = saveData(`${keyPrefix}_type`, type);
const savedTitle = saveData(`${keyPrefix}_title`, title);
if (!savedContent || !savedType) {
showNotification("保存数据失败,请检查浏览器权限", true);
return;
}
// 显示成功通知
showNotification("条目内容获取成功,正在打开创建页面...");
// 调试输出所有存储数据
log(`保存的数据ID: ${uniqueId}`);
log(`保存的类型: ${type}`);
log(`保存的标题: ${title}`);
log(`保存的内容长度: ${content.length} 字符`);
// 在新标签页打开新建条目页面
window.open(`//${currentHost}/new_subject/1?source=${uniqueId}`, "_blank");
} catch (e) {
showNotification(`解析页面失败: ${e.message}`, true);
console.error(e);
}
};
// 开始请求,优先使用fetch
try {
if (window.fetch) {
fetchData();
} else if (typeof GM_xmlhttpRequest !== 'undefined') {
useGMRequest();
} else {
showNotification("浏览器不支持所需的请求方法", true);
}
} catch (e) {
showNotification(`发起请求时出错: ${e.message}`, true);
console.error(e);
}
});
nav.appendChild(createLi); // 将按钮添加到导航栏
log("成功添加新条目按钮");
}
// 自动填充新建条目的表单内容
function fillNewSubjectForm() {
// 获取 URL 中传递的 source 参数
function getQueryParam(param) {
const url = new URL(window.location.href);
return url.searchParams.get(param);
}
const sourceId = getQueryParam("source");
if (!sourceId) {
log("没有找到source参数,不执行填充");
return;
}
log(`检测到source参数: ${sourceId}`);
// 确保通知区域已创建
addNotificationArea();
// 构建键名前缀
const keyPrefix = `bgm_infobox_${sourceId}`;
// 获取存储的数据
const content = getData(`${keyPrefix}_content`);
const type = getData(`${keyPrefix}_type`);
const originalTitle = getData(`${keyPrefix}_title`);
if (!content || !type) {
log(`未找到数据: ${keyPrefix}`);
// 尝试使用旧版键名
const oldKeyPrefix = `infobox_${sourceId}`;
const oldContent = getData(`${oldKeyPrefix}_content`);
const oldType = getData(`${oldKeyPrefix}_type`);
const oldTitle = getData(`${oldKeyPrefix}_title`);
if (oldContent && oldType) {
log(`找到旧版数据: ${oldKeyPrefix}`);
// 使用找到的旧数据
fillForm(oldContent, oldType, oldTitle);
return;
}
// 检查有没有任何bgm_infobox开头的键,可能是跨域问题
if (typeof localStorage !== 'undefined') {
log("检查localStorage中的所有键");
let foundKeys = [];
for (let i = 0; i < localStorage.length; i++) {
const key = localStorage.key(i);
if (key.startsWith('bgm_infobox_') || key.startsWith('infobox_')) {
foundKeys.push(key);
}
}
if (foundKeys.length > 0) {
log(`找到相关键: ${foundKeys.join(', ')}`);
// 尝试使用最近的一个键
foundKeys.sort();
const latestKey = foundKeys[foundKeys.length - 1];
const keyBase = latestKey.split('_').slice(0, -1).join('_');
log(`尝试使用最近的键前缀: ${keyBase}`);
const latestContent = getData(`${keyBase}_content`);
const latestType = getData(`${keyBase}_type`);
const latestTitle = getData(`${keyBase}_title`);
if (latestContent && latestType) {
log(`使用找到的最近数据`);
fillForm(latestContent, latestType, latestTitle);
return;
}
} else {
log("未找到任何相关键");
}
}
showNotification("未找到条目内容,请重试", true);
return;
}
fillForm(content, type, originalTitle);
function fillForm(content, type, title) {
// 定义类型与分类选项的映射
const typeMap = {
"Novel": { id: "cat_novel", tpl: "Novel" },
"Manga": { id: "cat_comic", tpl: "Manga" }
};
const category = typeMap[type];
if (!category) {
log(`未知条目类型: ${type}`);
return;
}
// 新页面显示填充通知
showNotification("正在填充条目信息...");
log(`准备填充 ${type} 类型的条目,标题: ${title || '无标题'}`);
// 当表单加载好后执行填充
waitForFormLoaded();
function waitForFormLoaded() {
// 添加一个检查函数,看看表格是否都加载出来了
const checkForm = () => {
const infoboxInput = document.querySelector("#subject_infobox");
const titleInput = document.querySelector('input[name="subject_title"]');
const typeRadio = document.getElementById(category.id);
return infoboxInput && titleInput && typeRadio;
};
// 检查表单是否已加载
if (checkForm()) {
doFillForm();
return;
}
// 观察DOM变化等待表单加载
log("等待表单加载...");
let attempts = 0;
const maxAttempts = 30; // 最多等待30*200ms = 6秒
const waitInterval = setInterval(() => {
attempts++;
if (checkForm()) {
clearInterval(waitInterval);
log("表单已加载,开始填充");
doFillForm();
return;
}
if (attempts >= maxAttempts) {
clearInterval(waitInterval);
log("表单加载超时");
showNotification("表单加载超时,请手动填写", true);
}
if (attempts % 5 === 0) {
log(`等待表单加载中... ${attempts}/${maxAttempts}`);
}
}, 200);
}
function doFillForm() {
try {
// 选择分类
const typeRadio = document.getElementById(category.id);
if (typeRadio) {
typeRadio.click();
log(`已选择类型: ${type}`);
} else {
log(`未找到类型选择框: ${category.id}`);
}
// 等待分类选择完成后,填充表单
setTimeout(() => {
try {
// 填充内容
const infobox = document.querySelector("#subject_infobox");
if (infobox) {
infobox.value = content;
log("已填充Infobox内容");
// 确保触发表单的change事件
const event = new Event('change', { bubbles: true });
infobox.dispatchEvent(event);
} else {
log("未找到Infobox输入框");
}
// 填充标题
const titleInput = document.querySelector('input[name="subject_title"]');
if (titleInput && title) {
let newTitle = title;
const match = title.match(/\((\d+)\)$/);
if (match) {
const num = parseInt(match[1], 10) + 1;
newTitle = title.replace(/\(\d+\)$/, `(${num})`);
} else {
newTitle = `${title} (1)`;
}
titleInput.value = newTitle;
log(`已填充标题: ${newTitle}`);
// 触发change事件
const event = new Event('change', { bubbles: true });
titleInput.dispatchEvent(event);
} else {
log("未找到标题输入框或没有标题");
}
// 尝试根据需要切换模式
const currentMode = document.querySelector('#header_infobox');
const wikiModeLink = document.querySelector('a[onclick*="NormaltoWCODE"]');
const simpleModeLink = document.querySelector('a[onclick*="WCODEtoNormal"]');
// 判断当前是否在wiki模式
const isInWikiMode = currentMode && currentMode.textContent.includes('WCODE');
// 如果用户想要wiki模式但当前不是wiki模式
if (!isInWikiMode && wikiModeLink) {
wikiModeLink.click();
log("已切换到wiki模式");
}
// 如果用户想要普通模式但当前是wiki模式
else if (isInWikiMode && simpleModeLink) {
simpleModeLink.click();
log("已切换到普通模式");
}
else {
log("未找到模式切换链接或已经是所需模式");
}
// 显示成功通知
showNotification("条目信息填充完成");
// 填充完毕后删除 localStorage 中的数据
removeData(`${keyPrefix}_content`);
removeData(`${keyPrefix}_type`);
removeData(`${keyPrefix}_title`);
log("已清理临时数据");
} catch (e) {
showNotification(`填充表单时出错: ${e.message}`, true);
console.error(e);
}
}, 500);
} catch (e) {
showNotification(`选择分类时出错: ${e.message}`, true);
console.error(e);
}
}
}
}
// 从当前新建条目页面添加"复制创建"功能
function addCloneButton() {
// 确保当前页面是新建条目页面
if (!location.pathname.includes("/new_subject/")) {
log("当前不是新建条目页面,不添加克隆按钮");
return;
}
// 查找标题元素 - 兼容多种可能的标题文本
const titleHeader = document.querySelector('h1');
if (!titleHeader) {
log("未找到标题元素");
return;
}
// 检查标题是否包含"添加"字样
if (!titleHeader.textContent.includes('添加')) {
log(`标题内容不匹配: ${titleHeader.textContent}`);
return;
}
// 确保按钮未重复添加
if (document.querySelector('#clone-entry-button')) {
log("克隆按钮已存在,不重复添加");
return;
}
// 添加通知区域
addNotificationArea();
// 创建按钮
const cloneButton = document.createElement('button');
cloneButton.id = 'clone-entry-button';
cloneButton.textContent = '新条目';
cloneButton.style.backgroundColor = '#F09199';
cloneButton.style.color = 'white';
cloneButton.style.border = 'none';
cloneButton.style.padding = '5px 10px';
cloneButton.style.borderRadius = '4px';
cloneButton.style.marginLeft = '10px';
cloneButton.style.cursor = 'pointer';
cloneButton.style.fontWeight = 'bold';
cloneButton.style.textAlign = 'center';
// 添加按钮到标题旁边
titleHeader.appendChild(cloneButton);
log("成功添加克隆按钮");
// 添加点击事件
cloneButton.addEventListener('click', () => {
// 获取当前表单内容
const infobox = document.querySelector("#subject_infobox");
const titleInput = document.querySelector('input[name="subject_title"]');
if (!infobox || !titleInput) {
showNotification("无法获取表单内容", true);
return;
}
const content = infobox.value;
const title = titleInput.value;
if (!content) {
showNotification("Infobox内容为空", true);
return;
}
// 识别类型
let type = "Unknown";
if (content.includes("Infobox animanga/Novel")) {
type = "Novel";
} else if (content.includes("Infobox animanga/Manga")) {
type = "Manga";
}
if (type === "Unknown") {
showNotification("未识别 Infobox 类型(支持 Novel 或 Manga)", true);
return;
}
// 生成唯一ID作为存储键
const cloneId = 'clone_' + Date.now();
// 保存内容
const savedContent = saveData(`bgm_infobox_${cloneId}_content`, content);
const savedType = saveData(`bgm_infobox_${cloneId}_type`, type);
const savedTitle = saveData(`bgm_infobox_${cloneId}_title`, title);
if (!savedContent || !savedType) {
showNotification("保存数据失败,请检查浏览器权限", true);
return;
}
log(`已复制条目内容, ID: ${cloneId}`);
// 显示通知
showNotification("已复制条目内容,正在打开新建页面...");
// 获取当前主机名用于跳转
const currentHost = window.location.hostname;
// 打开新的条目创建页面
window.open(`//${currentHost}/new_subject/1?source=${cloneId}`, "_blank");
});
}
// 初始化
function init() {
log("Bangumi条目创建助手初始化中...");
// 若当前页面是条目页面,添加"新条目"按钮
if (location.pathname.match(/^\/subject\/\d+$/)) {
log("检测到条目页面");
addCreateButton();
}
// 若当前页面是创建条目页,添加功能
if (location.pathname.includes("/new_subject/")) {
log("检测到新建条目页面");
addCloneButton();
// 如果有source参数,则填充表单
if (location.search.includes("source=")) {
log("检测到source参数,准备填充表单");
// 稍微延迟执行填充,确保页面已完全加载
setTimeout(fillNewSubjectForm, 500);
}
}
log("初始化完成");
}
// 页面加载完成后执行初始化
window.addEventListener("load", init);
// 也可以在DOM加载完成后就执行,提高响应速度
if (document.readyState === "interactive" || document.readyState === "complete") {
init();
} else {
document.addEventListener("DOMContentLoaded", init);
}
}
/*===========
启动所有功能
============*/
function startEnhancer() {
initNavButtons();
observeURLChanges();
initCoverUpload();
initBatchRelation();
initBgmDropdownMenu();
initBgmCreateSubject();
console.log("Bangumi Ultimate Enhancer 已启动");
}
// 在DOM加载完成后启动脚本
if (document.readyState === 'loading') {
document.addEventListener('DOMContentLoaded', startEnhancer);
} else {
startEnhancer();
}
})();