Greasemonkey 4 μ
λ°μ΄νΈλ‘ jQueryλ₯Ό μ¬μ©νλ λ§μ μ¬μ©μ μ€ν¬λ¦½νΈκ° μμλ κ² κ°μ΅λλ€. μ΄μ λ²μ μμ λ€μ μ½λλ <script>
νκ·Έμμ jQueryλ₯Ό μ¬μ©νλ νμ΄μ§μμ μλνμ΅λλ€.
// ==UserScript==
// <strong i="7">@name</strong> Variable access test
// <strong i="8">@namespace</strong> example.com
// ==/UserScript==
$.ready(document, function() {
console.log("Accessed jQuery successfully.")
});
κ·Έλ¬λ λ μ΄μ μλνμ§ μμ΅λλ€. λμ ν΄λμ $ is not defined
λ§ μ»μ μ μμ΅λλ€. μ΄λ <script>
νκ·Έκ° λ‘λ λκΈ° μ μ Greasemonkeyκ° μ¬μ©μ μ€ν¬λ¦½νΈ document.readyState
κ° interactive
λ μ€ν¬λ¦½νΈκ° κ³μ μ€νλλ κ²μ 보면 μ΄μν©λλ€!
νμ§λ§ νμ€ν νκΈ° μν΄ window.addEventListener('load', ...)
λ€μμ jQueryμ μ‘μΈμ€νλ €κ³ νμ΅λλ€. 보λΌ, λ€μμ λ€λ₯Έ μ€λ₯λ₯Ό λνλΈλ€.
// ==UserScript==
// <strong i="19">@name</strong> Variable access test
// <strong i="20">@namespace</strong> example.com
// ==/UserScript==
window.addEventListener('load', function() {
console.log("Before accessing jQuery")
$;
console.log("Accessed jQuery successfully!")
});
μ€νλμ§λ μκ³ μ€λ₯κ° λ°μνμ§λ μμ΅λλ€. λμ $
μ μ‘μΈμ€νλ €κ³ ν λ λ©μΆ₯λλ€ . μ€ν¬λ¦½νΈλ ν΄λΉ μ€κΉμ§λ§ μ€νλκ³ λ μ΄μ μ€νλμ§ μμ΅λλ€.
jQueryλ₯Ό μ¬μ©νλ λͺ¨λ νμ΄μ§μμ μλνλ©΄ λμΌν κ²°κ³Όλ₯Ό μ»μ μ μμ΅λλ€. @require
κ²μ μ΄ λ¬Έμ μ λν ν΄κ²°μ±
μ΄ μλλλ€. μΌλΆ μ ν리μΌμ΄μ
μ κ²½μ° νμ΄μ§μ λμΌν jQuery μΈμ€ν΄μ€μ μ‘μΈμ€ν΄μΌ ν©λλ€. μ΄κ²μ jQuery μ΄μΈμ μ€ν¬λ¦½νΈμλ μν₯μ λ―ΈμΉ κ°λ₯μ±μ΄ λμ΅λλ€.
μ€μ λ‘ Greasemonkey λ¬Έμ κ° μλλΌ Firefox μ½ν
μΈ μ€ν¬λ¦½νΈ λ¬Έμ μ κ°κΉμ΅λλ€.
https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Content_scripts#Accessing_page_script_objects_from_content_scripts
μμ μ window.wrappedJSObject
ν λΉνκ±°λ Greasemonkeyκ° μ΄λ―Έ λνλ κ°μ²΄λ₯Ό ν λΉν unsafeWindow
λ₯Ό μ¬μ©νμμμ€.
@Sxderp "Greasemonkey λ¬Έμ κ° μλ"μ λν΄μλ μ λͺ¨λ₯΄κ² μ΅λλ€. Tampermonkeyμ Violentmonkey λͺ¨λ λ¬Έμ μμ΄ λ°λ‘ μ΄ κ²½μ°λ₯Ό μ²λ¦¬ν©λλ€. λΏλ§ μλλΌ μ΄κ²μ λΈλ‘κ·Έ κ²μλ¬Όμ μΈκΈλμ§ μμ μ£Όμ λ³κ²½ μ¬νμ λλ€.
κΈ°μ‘΄ μ¬μ©μ μ€ν¬λ¦½νΈμμ μμλλ‘ μλνκ³ λ€λ₯Έ μΈκΈ° μλ μ¬μ©μ μ€ν¬λ¦½νΈ κ΄λ¦¬μμ μνΈ νΈνλλλ‘ νλ €λ©΄ μ΄ λ¬Έμ λ₯Ό μμ ν΄μΌ νμ§ μμ΅λκΉ?
λν ... μ΄κ²μ΄ μ€μ λ‘ λ¬Έμ λ₯Ό μ€λͺ ν©λκΉ? μ μ€ν¬λ¦½νΈκ° μ μ§λκ³ μ€ν¨ν μ‘°νλ§ λ°μνμ§ μμ΅λκΉ?
λκ²°μ λν΄μλ μ λͺ¨λ₯΄κ² μ΅λλ€. κ·νμ μ½λλ₯Ό 볡μ¬νλλ° μ λ₯Ό μν΄ κ³ μ λμ§ μμ΅λλ€.
νΈμ§: μ£μ‘ν©λλ€. 'λκ²°' λκΈμ μ€ν΄νμ΅λλ€. λλ Greasemonkeyκ° λ μ΄μ μλνμ§ μλλ€λ κ²μ μλ―Ένλ€κ³ μκ°νμ΅λλ€. Javascriptκ° μ μΈ μ€λ₯ μ μ μ¬μ©μ λλ¬νκΈ° λλ¬Έμ ν΄λΉ νμμ 'μ μ§'(μ€ν μ€μ§)ν©λλ€. κ·Έκ²μ 'μΉλͺ μ μΈ' κ²μΌλ‘ κ°μ£Όλλ κ²μ΄ νμ€ν©λλ€. μμμ κ°μ΄ μ½λ μ€νμ κ³μνμ§ μμ΅λλ€.
Violentmonkey μ½λλ₯Ό κ°λ΅ν μ΄ν΄λ³΄λ©΄ <script>
μμ λ₯Ό μμ±νμ¬ μ€ν¬λ¦½νΈλ₯Ό μ½μ
νλ κ²μ²λΌ 보μ
λλ€. tabs.executeScripts()
API λ©μλλ₯Ό μ¬μ©νλ λμ .
λ¬Όλ‘ κ·Έκ²μ μ¬μ©νλ κ² μ체μ λ¨μ λ μμ΅λλ€.
κ·Έλμ... Firefoxκ° ν΄λΉ λΌμΈμ λ€μ΄κ°λ©΄ μλμΌλ‘ μ€νμ λ©μΆ₯λλ€? μ€λ₯ λ©μμ§ μμ΄? μμ²λκ² μ΄μν μΌμ λλ€.
μ΄μ¨λ κΈ°μ‘΄ μ¬μ©μ μ€ν¬λ¦½νΈμμ νΈνμ±μ μ μ§νλ κ²μ΄ λͺ©νκ° μλκ°μ? μ΄κ²μ νμ κΈ°λ₯μ΄ μλλλ€. κ²°κ΅ νμ΄μ§μ μ체 JavaScriptμ μΈν°νμ΄μ€νλ κ²μ λ§€μ° μΌλ°μ μΈ μΌμ λλ€.
μ΄μ¨λ κΈ°μ‘΄ μ¬μ©μ μ€ν¬λ¦½νΈμμ νΈνμ±μ μ μ§νλ κ²μ΄ λͺ©νκ° μλκ°μ?
λΉμ°νμ§. μ°λ¦¬λ μλ²½νμ§ μμ΅λλ€. μ΄κ²μ μμ μκ°μ΄ λ무 λ§μ μμ λ΄μ¬μλ€μ΄ λ§λ λ¬΄λ£ μ€ν μμ€ νλ‘μ νΈμ λλ€.
μ΄ μμ μμ μ λ μ΄κ²μ κ°μ νλ λ°©λ²μ λν κ³νμ κ°μ§κ³ μμ§λ§ Mozillaκ° μμ νκ² μνν μ μλ κΈ°λ₯μ ꡬννκΈ°λ₯Ό κΈ°λ€λ¦¬κ³ μμ΅λλ€. #2549
@arantius μ κ° κΊΌλμ κ² κ°μλ°... μ£μ‘ν©λλ€.
μ¬κΈ°μ μ μ©μ±λ³΄λ€ 보μμ μ°μ μνλ κ²μ μ μ€ν κ²°μ μ΄λΌκ³ μκ°ν©λλ€. μν©μ΄ ν΄κ²°λ λκΉμ§ μ€ν¬λ¦½νΈ μμ±μ μΈ‘μμ ν΄κ²° λ°©λ²μΌλ‘ 무μμ ν μ μμ΅λκΉ? λ΄ κ²½μ°μλ μ€ν¬λ¦½νΈ μλ¨μμ var $ = window.wrappedJSObject.$;
λ° var $= unsafeWindow.$;
λ₯Ό λͺ¨λ μλνμ§λ§ $(document).ready(...)
λ₯Ό μ¬μ©νλ €κ³ ν λ λ λ€λ₯Έ μ€λ₯κ° λ°μνμ΅λλ€. Error: Permission denied to access property Symbol.toStringTag
.
μ€λ₯: Symbol.toStringTag μμ±μ λν μ‘μΈμ€ κΆνμ΄ κ±°λΆλμμ΅λλ€.
λλ κ·Έκ²μ΄ window.wrappedJSObject.$
μ λ¬Έμ λΌκ³ μκ°νμ§ μμ§λ§ μ€νλ € μ¬μ©μ μ€ν¬λ¦½νΈμμ κ°μ²΄ 리ν°λ΄ λλ new
μμ±μλ‘ λ§λ λ€λ₯Έ κ°μ²΄κ° μ λλ‘ κ°μ Έμ€μ§ μμμ΅λλ€. μ‘μΈμ€νλ €λ λ²μ(μλ§λ νμ΄μ§μ μ°½ λ²μ).
μμ λ§ν¬λ νμν cloneInto
μ λν μΈλΆ μ 보λ₯Ό μ 곡ν©λλ€.
μλμ, λ¬Έμ κ° window.wrappedJSObject.$
μλ€κ³ νμ ν©λλ€. λ€μμ λμΌν μ€λ₯λ‘ μ€ν¨ν©λλ€.
// ==UserScript==
// <strong i="7">@name</strong> Variable access test
// <strong i="8">@namespace</strong> example.com
// ==/UserScript==
var $ = window.wrappedJSObject.$;
$(document).ready(function() {});
κ·Έλ¬λ μ΄κ²μ μλμΌλ‘ μ€ν¨ν©λλ€.
// ==UserScript==
// <strong i="12">@name</strong> Variable access test
// <strong i="13">@namespace</strong> example.com
// ==/UserScript==
var $ = window.wrappedJSObject.$;
$.ready(function() {});
cloneInto
μ¬μ©ν΄ 보μμ§λ§ λμμ΄ λμ§ μμ΅λλ€. νμ΄μ§μ $
μΈμ€ν΄μ€λ₯Ό μ¬μ©νλ 짧μ μμ μ¬μ©μ μ€ν¬λ¦½νΈλ₯Ό μ 곡ν μ μλ€κ³ μκ°νμλκΉ?
μ, κ·Έλ λ€λ©΄ ν΄λΉ κΈ°λ₯μ μ‘μΈμ€ν μ μλ κΆνμ΄ μμ΅λλ€. κ·Έλ° λ€μ exportFunction
λ₯Ό μ¬μ©ν΄μΌ ν©λλ€.
// ==UserScript==
// <strong i="7">@name</strong> ExampleJQuery
// <strong i="8">@version</strong> 1
// <strong i="9">@include</strong> *
// <strong i="10">@grant</strong> none
// ==/UserScript==
var unsafeWindow = window.wrappedJSObject;
var $;
// For sanity just return if we don't have the object
if (typeof unsafeWindow.$ === 'undefined') {
console.log('No jQuery object, returning');
return;
} else {
$ = unsafeWindow.$;
}
// Create the function we want to export
function onReady() {
console.log("I'm ready!");
}
// Export it. Some details on this.
// Argument 1. The function to export
// Argument 2. The scope to export it to. In general this will be window,
// or some object in the scope. While it is valid to use
// "window", I prefer to use "unsafeWindow" if I'm exporting
// into that scope. I find it less confusing.
// Return This is a reference to exported function. In general you'll
// assign this to some property of the scope you're exporting
// into. However, it's not always neccessary. For example, if
// you're going to use it as a callback (like for .ready())
// then you don't need to assign it into the exported scope.
// But if you want it globally (or scopally) accessable then
// you need to assign it.
let exported_onReady = exportFunction(onReady, unsafeWindow);
// OR
// unsafeWindow.onReady = exportFunction(onReady, unsafeWindow);
$(document).ready(exported_onReady);
// OR
// $(document).ready(unsafeWindow.onReady);
λλ μ§κΈ (λ€λ₯Έ ꡬμ±μμ) κ·Έ μ κ·Ό λ°©μμ μλνκ³ , 무μμ νλ κ³μ κΆν μ€λ₯κ° λ°μν©λλ€. μ΄ μμ μμ λ²κ±°λ‘κ² ν κ°μΉκ° μμ΅λλ€.
κ°νΉνκ² λ€λ¦¬μ§λ§ μ΄κ²μ΄ λ°©ν΄κ° λ λκΉμ§ μ¬λλ€μκ² Tampermonkeyλ₯Ό μ¬μ©νλλ‘ κΆμ₯ν΄μΌ νλ€κ³ μκ°ν©λλ€. νμ¬ κ΅¬νλ μ½ν μΈ μ€ν¬λ¦½νΈλ μ€μ λ‘ μ¬μ©μ μ€ν¬λ¦½νΈ μ¬μ© μ¬λ‘μ μ ν μ ν©νμ§ μμ΅λλ€.
@obskyrμ λμν©λλ€. μ¬λλ€μκ² tampermonkeyλ₯Ό μ¬μ©νλλ‘ κΆμ₯νμμμ€.
+1, Tampermonkey(https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/)λ‘ μ΄λνμΌλ©° λͺ¨λ μ€ν¬λ¦½νΈκ° κ±°κΈ°μμ μλνλ κ² κ°μ΅λλ€.
+1, Tampermonkey(https://addons.mozilla.org/en-US/firefox/addon/tampermonkey/)λ‘ μ΄λνμΌλ©° λͺ¨λ μ€ν¬λ¦½νΈκ° κ±°κΈ°μμ μλνλ κ² κ°μ΅λλ€.
μ΄κ²μ λ¨κΈ°μ μΌλ‘λ ν¨κ³Όκ° μμ μ μκ³ μ€ν¬λ¦½νΈλ₯Ό κ³μ μ€ννλ λ°μλ λ¬Έμ κ° μμ§λ§ μ₯κΈ°μ μΌλ‘λ μμ ν λ체μ μμ‘΄νλ κ²μ μλͺ»λ κ²°μ μΌ μ μμ΅λλ€. λ¨κΈ°μ μ±κ³΅μ κ·Όμμμ μΌ μ μμ΅λλ€... ;-)
λλ TMμ λμ©μΌλ‘ μ¬μ©νμ§λ§, κ±°κΈ°μλ λͺ κ°μ§ λ¬Έμ κ° μμ΅λλ€. λΆμ ν μ μμ΅λλ€. λν FF Quantumμλ λͺ κ°μ§ 보μ λ¬Έμ κ° μμ μ μμΌλ―λ‘ μλνμ§λ§ λ¨μΌ μ루μ μλ§ μμ‘΄ν΄μλ μλ©λλ€...
κΈμ, λͺ¨λ μ¬λμ΄ Firefoxλ₯Ό μ¬μ©νλ κ²μ μλκΈ° λλ¬Έμ μ΄μ¨λ λ΄ μ€ν¬λ¦½νΈμμ TMμ μ§μν΄μΌ ν©λλ€. κ·Έλμ μ κ° GMκ³Ό TMμ μ§μνκΈ° μ μλ μ§κΈμ TMμΌ λΏμ λλ€. μ§κΈκΉμ§ λ¬Έμ λ₯Ό λ°κ²¬νμ§ λͺ»νμ΅λλ€.
κ°μ₯ μ μ©ν λκΈ
λλ μ§κΈ (λ€λ₯Έ ꡬμ±μμ) κ·Έ μ κ·Ό λ°©μμ μλνκ³ , 무μμ νλ κ³μ κΆν μ€λ₯κ° λ°μν©λλ€. μ΄ μμ μμ λ²κ±°λ‘κ² ν κ°μΉκ° μμ΅λλ€.
κ°νΉνκ² λ€λ¦¬μ§λ§ μ΄κ²μ΄ λ°©ν΄κ° λ λκΉμ§ μ¬λλ€μκ² Tampermonkeyλ₯Ό μ¬μ©νλλ‘ κΆμ₯ν΄μΌ νλ€κ³ μκ°ν©λλ€. νμ¬ κ΅¬νλ μ½ν μΈ μ€ν¬λ¦½νΈλ μ€μ λ‘ μ¬μ©μ μ€ν¬λ¦½νΈ μ¬μ© μ¬λ‘μ μ ν μ ν©νμ§ μμ΅λλ€.