Greasemonkey: 에 μ •μ˜λœ λ³€μˆ˜μ— μ•‘μ„ΈμŠ€ν•  수 μ—†μŠ΅λ‹ˆλ‹€.<script>tags on the actual page.</script>

에 λ§Œλ“  2017λ…„ 11μ›” 18일  Β·  14μ½”λ©˜νŠΈ  Β·  좜처: greasemonkey/greasemonkey

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 μ΄μ™Έμ˜ μŠ€ν¬λ¦½νŠΈμ—λ„ 영ν–₯을 λ―ΈμΉ  κ°€λŠ₯성이 λ†’μŠ΅λ‹ˆλ‹€.

duplicate

κ°€μž₯ μœ μš©ν•œ λŒ“κΈ€

λ‚˜λŠ” μ§€κΈˆ (λ‹€λ₯Έ κ΅¬μ„±μ—μ„œ) κ·Έ μ ‘κ·Ό 방식을 μ‹œλ„ν–ˆκ³ , 무엇을 ν•˜λ“  계속 κΆŒν•œ 였λ₯˜κ°€ λ°œμƒν•©λ‹ˆλ‹€. 이 μ‹œμ μ—μ„œ 번거둭게 ν•  κ°€μΉ˜κ°€ μ—†μŠ΅λ‹ˆλ‹€.

κ°€ν˜Ήν•˜κ²Œ λ“€λ¦¬μ§€λ§Œ 이것이 λ°©ν•΄κ°€ 될 λ•ŒκΉŒμ§€ μ‚¬λžŒλ“€μ—κ²Œ Tampermonkeyλ₯Ό μ‚¬μš©ν•˜λ„λ‘ ꢌμž₯ν•΄μ•Ό ν•œλ‹€κ³  μƒκ°ν•©λ‹ˆλ‹€. ν˜„μž¬ κ΅¬ν˜„λœ μ½˜ν…μΈ  μŠ€ν¬λ¦½νŠΈλŠ” μ‹€μ œλ‘œ μ‚¬μš©μž 슀크립트 μ‚¬μš© 사둀에 μ „ν˜€ μ ν•©ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

λͺ¨λ“  14 λŒ“κΈ€

μ‹€μ œλ‘œ 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일 λΏμž…λ‹ˆλ‹€. μ§€κΈˆκΉŒμ§€ 문제λ₯Ό λ°œκ²¬ν•˜μ§€ λͺ»ν–ˆμŠ΅λ‹ˆλ‹€.

이 νŽ˜μ΄μ§€κ°€ 도움이 λ˜μ—ˆλ‚˜μš”?
0 / 5 - 0 λ“±κΈ‰