Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 80 additions & 0 deletions example/gm_add_element.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,89 @@
* 2. 元素标签名
* 3. 属性对象
*/

// ------------- 基础用法(TM) B1 ----------------

const el = GM_addElement(document.querySelector('.BorderGrid-cell'), "img", {
src: "https://bbs.tampermonkey.net.cn/uc_server/avatar.php?uid=4&size=small&ts=1"
});

// 打印创建出来的 DOM 元素
console.log(el);

// ------------- 基础用法(TM) B2 - textContent ----------------


const span3 = GM_addElement('span', {
textContent: 'Hello',
});

console.log(`span text: ${span3.textContent}`);

// ------------- 基础用法(TM) B3 - onload & onerror ----------------


new Promise((resolve, reject) => {
img = GM_addElement(document.body, 'img', {
src: 'https://www.tampermonkey.net/favicon.ico',
onload: resolve,
onerror: reject
});
}).then(() => {
console.log("img insert ok");
}).catch(() => {
console.log("img insert failed")
});


if (GM?.info.scriptHandler === "ScriptCat") {

// ------------- 額外用法(SC) E1 - value ----------------


const textarea = GM_addElement('textarea', {
value: "myText",
});

console.log(`Textarea Value: ${textarea.value}`);

// ------------- 額外用法(SC) E2 - innerHTML ----------------

const div3 = GM_addElement('div', {
innerHTML: '<div id="test777">World</div>',
});

console.log(`div text: ${div3.textContent}`);


// ------------- 額外用法(SC) E3 - className ----------------
Copy link
Copy Markdown
Member

@CodFrm CodFrm Feb 18, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不要破坏兼容性的,也不应该分SC和TM的测试版本,可以集中到gm_api_test.js



const span4 = GM_addElement(document.getElementById("test777"), 'span', {
className: "test777-span",
textContent: 'Hello World!',
});

console.log(`span class: ${span4.classList.contains("test777-span")}`)



// ------------- 額外用法(SC) E4 - native ----------------

// 在目前环境生成元素

const elementA = GM_addElement('div', {
native: true,
textContent: "DEF",
});


// ------------- 額外用法(SC) E5 - insertBefore ----------------

// 插入在某元素前面 = parentNdoe.insertBefore(node, referenceNode)

const elementB = GM_addElement('textarea', {
value: "ABC",
}, elementA);

}
106 changes: 106 additions & 0 deletions example/tests/gm_add_element_SC.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// ==UserScript==
// @name GM_addElement test
// @match *://*/*?test_GM_addElement
// @grant GM_addElement
// @version 0
// ==/UserScript==

/*
### Example Sites
* https://content-security-policy.com/?test_GM_addElement (CSP)
* https://github.com/scriptscat/scriptcat/?test_GM_addElement (CSP)
* https://www.youtube.com/account_playback/?test_GM_addElement (TTP)
*/

const logSection = (title) => {
console.log(`\n=== ${title} ===`);
};

const logStep = (message, data) => {
if (data !== undefined) {
console.log(`→ ${message}:`, data);
} else {
console.log(`→ ${message}`);
}
};


// ─────────────────────────────────────────────
// Native textarea insertion
// ─────────────────────────────────────────────
logSection("Native textarea insertion - BEGIN");

const textarea = GM_addElement('textarea', {
native: true,
value: "myText",
});

logStep("Textarea value", textarea.value);
logSection("Native textarea insertion - END");


// ─────────────────────────────────────────────
// Div insertion
// ─────────────────────────────────────────────
logSection("Div insertion - BEGIN");

GM_addElement('div', {
innerHTML: '<div id="test777"></div>',
});

logSection("Div insertion - END");


// ─────────────────────────────────────────────
// Span insertion
// ─────────────────────────────────────────────
logSection("Span insertion - BEGIN");

GM_addElement(document.getElementById("test777"), 'span', {
className: "test777-span",
textContent: 'Hello World!',
});

logStep(
"Span content",
document.querySelector("span.test777-span").textContent
);

logSection("Span insertion - END");


// ─────────────────────────────────────────────
// Image insertion
// ─────────────────────────────────────────────
logSection("Image insertion - BEGIN");

let img;
await new Promise((resolve, reject) => {
img = GM_addElement(document.body, 'img', {
src: 'https://www.tampermonkey.net/favicon.ico',
onload: resolve,
onerror: reject
});

logStep("Image element inserted");
});

logStep("Image loaded");
logSection("Image insertion - END");


// ─────────────────────────────────────────────
// Script insertion
// ─────────────────────────────────────────────
logSection("Script insertion - BEGIN");

GM_addElement(document.body, 'script', {
textContent: "window.myCustomFlag = true; console.log('script run ok');",
}, img);

logStep(
"Script inserted before image",
img.previousSibling?.nodeName === "SCRIPT"
);

logSection("Script insertion - END");
103 changes: 103 additions & 0 deletions example/tests/gm_add_element_TM.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// ==UserScript==
// @name GM_addElement test
// @match *://*/*?test_GM_addElement
// @grant GM_addElement
// @version 0
// ==/UserScript==

/*
### Example Sites
* https://content-security-policy.com/?test_GM_addElement (CSP)
* https://github.com/scriptscat/scriptcat/?test_GM_addElement (CSP)
* https://www.youtube.com/account_playback/?test_GM_addElement (TTP)
*/

const logSection = (title) => {
console.log(`\n=== ${title} ===`);
};

const logStep = (message, data) => {
if (data !== undefined) {
console.log(`→ ${message}:`, data);
} else {
console.log(`→ ${message}`);
}
};


// ─────────────────────────────────────────────
// Native textarea insertion
// ─────────────────────────────────────────────
logSection("Native textarea insertion - BEGIN");

const textarea = GM_addElement('textarea', {
value: "myText",
});

logStep("Textarea value", textarea.value);
logSection("Native textarea insertion - END");


// ─────────────────────────────────────────────
// Div insertion
// ─────────────────────────────────────────────
logSection("Div insertion - BEGIN");

GM_addElement('div', {
textContent: 'DIV TEXT',
});

logSection("Div insertion - END");


// ─────────────────────────────────────────────
// Span insertion
// ─────────────────────────────────────────────
logSection("Span insertion - BEGIN");

GM_addElement(document.getElementById("test777"), 'span', {
textContent: 'Hello World!',
});

logStep(
"Span content",
document.querySelector("span.test777-span").textContent
);

logSection("Span insertion - END");


// ─────────────────────────────────────────────
// Image insertion
// ─────────────────────────────────────────────
logSection("Image insertion - BEGIN");

let img;
await new Promise((resolve, reject) => {
img = GM_addElement(document.body, 'img', {
src: 'https://www.tampermonkey.net/favicon.ico',
onload: resolve,
onerror: reject
});

logStep("Image element inserted");
});

logStep("Image loaded");
logSection("Image insertion - END");


// ─────────────────────────────────────────────
// Script insertion
// ─────────────────────────────────────────────
logSection("Script insertion - BEGIN");

GM_addElement(document.body, 'script', {
textContent: "window.myCustomFlag = true; console.log('script run ok');",
});

logStep(
"Script inserted before image"
);

logSection("Script insertion - END");
Loading
Loading