Preliminary support for Greasemonkey 4.
This commit is contained in:
parent
75ed8fe248
commit
4226a18a6d
@ -56,7 +56,12 @@
|
|||||||
"GM_listValues",
|
"GM_listValues",
|
||||||
"GM_addValueChangeListener",
|
"GM_addValueChangeListener",
|
||||||
"GM_openInTab",
|
"GM_openInTab",
|
||||||
"GM_xmlhttpRequest"
|
"GM_xmlhttpRequest",
|
||||||
|
"GM.getValue",
|
||||||
|
"GM.setValue",
|
||||||
|
"GM.deleteValue",
|
||||||
|
"GM.listValues",
|
||||||
|
"GM.xmlHttpRequest"
|
||||||
],
|
],
|
||||||
"min": {
|
"min": {
|
||||||
"chrome": "33",
|
"chrome": "33",
|
||||||
|
|||||||
@ -16,11 +16,14 @@
|
|||||||
"globals": {
|
"globals": {
|
||||||
"MediaError": false,
|
"MediaError": false,
|
||||||
"Set": false,
|
"Set": false,
|
||||||
|
"Promise": false,
|
||||||
|
"BroadcastChannel": false,
|
||||||
"GM_info": false,
|
"GM_info": false,
|
||||||
"cloneInto": false,
|
"cloneInto": false,
|
||||||
"unsafeWindow": false,
|
"unsafeWindow": false,
|
||||||
"chrome": false<%=
|
"chrome": false,
|
||||||
meta.grants.map(x => `,\n "${x}": false`).join('')
|
"GM": false<%=
|
||||||
|
meta.grants.filter(x => !/\./.test(x)).map(x => `,\n "${x}": false`).join('')
|
||||||
%><%=
|
%><%=
|
||||||
read('/tmp/declaration.js').match(/^var (.*);/)[1].split(', ').map(x => `,\n "${x}": true`).join('')
|
read('/tmp/declaration.js').match(/^var (.*);/)[1].split(', ').map(x => `,\n "${x}": true`).join('')
|
||||||
%><%=
|
%><%=
|
||||||
|
|||||||
@ -492,125 +492,166 @@ do ->
|
|||||||
# http://wiki.greasespot.net/Main_Page
|
# http://wiki.greasespot.net/Main_Page
|
||||||
# https://tampermonkey.net/documentation.php
|
# https://tampermonkey.net/documentation.php
|
||||||
|
|
||||||
# workaround for Firefox 53 issue
|
if GM?.deleteValue?
|
||||||
$.currentValue = {}
|
|
||||||
$.GM_getValue = (key) ->
|
|
||||||
try
|
|
||||||
$.currentValue[key] = GM_getValue key
|
|
||||||
catch err
|
|
||||||
$.currentValue[key]
|
|
||||||
$.GM_setValue = (key, val) ->
|
|
||||||
$.currentValue[key] = val
|
|
||||||
GM_setValue key, val
|
|
||||||
$.GM_deleteValue = (key) ->
|
|
||||||
delete $.currentValue[key]
|
|
||||||
GM_deleteValue key
|
|
||||||
|
|
||||||
unless GM_deleteValue?
|
$.syncChannel = new BroadcastChannel(g.NAMESPACE + 'sync')
|
||||||
$.perProtocolSettings = true
|
|
||||||
|
|
||||||
if GM_deleteValue?
|
$.on $.syncChannel, 'message', (e) ->
|
||||||
$.getValue = $.GM_getValue
|
for key, val of e.data when (cb = $.syncing[key])
|
||||||
$.listValues = -> GM_listValues() # error when called if missing
|
cb val, key
|
||||||
else if $.hasStorage
|
|
||||||
$.getValue = (key) -> localStorage[key]
|
|
||||||
$.listValues = ->
|
|
||||||
key for key of localStorage when key[...g.NAMESPACE.length] is g.NAMESPACE
|
|
||||||
else
|
|
||||||
$.getValue = ->
|
|
||||||
$.listValues = -> []
|
|
||||||
|
|
||||||
if GM_addValueChangeListener?
|
|
||||||
$.setValue = $.GM_setValue
|
|
||||||
$.deleteValue = $.GM_deleteValue
|
|
||||||
else if GM_deleteValue?
|
|
||||||
$.oldValue = {}
|
|
||||||
$.setValue = (key, val) ->
|
|
||||||
$.GM_setValue key, val
|
|
||||||
if key of $.syncing
|
|
||||||
$.oldValue[key] = val
|
|
||||||
localStorage[key] = val if $.hasStorage # for `storage` events
|
|
||||||
$.deleteValue = (key) ->
|
|
||||||
$.GM_deleteValue key
|
|
||||||
if key of $.syncing
|
|
||||||
delete $.oldValue[key]
|
|
||||||
localStorage.removeItem key if $.hasStorage # for `storage` events
|
|
||||||
$.cantSync = true if !$.hasStorage
|
|
||||||
else if $.hasStorage
|
|
||||||
$.oldValue = {}
|
|
||||||
$.setValue = (key, val) ->
|
|
||||||
$.oldValue[key] = val if key of $.syncing
|
|
||||||
localStorage[key] = val
|
|
||||||
$.deleteValue = (key) ->
|
|
||||||
delete $.oldValue[key] if key of $.syncing
|
|
||||||
localStorage.removeItem key
|
|
||||||
else
|
|
||||||
$.setValue = ->
|
|
||||||
$.deleteValue = ->
|
|
||||||
$.cantSync = $.cantSet = true
|
|
||||||
|
|
||||||
if GM_addValueChangeListener?
|
|
||||||
$.sync = (key, cb) ->
|
$.sync = (key, cb) ->
|
||||||
$.syncing[key] = GM_addValueChangeListener g.NAMESPACE + key, (key2, oldValue, newValue, remote) ->
|
|
||||||
if remote
|
|
||||||
newValue = JSON.parse newValue unless newValue is undefined
|
|
||||||
cb newValue, key
|
|
||||||
$.forceSync = ->
|
|
||||||
else if GM_deleteValue? or $.hasStorage
|
|
||||||
$.sync = (key, cb) ->
|
|
||||||
key = g.NAMESPACE + key
|
|
||||||
$.syncing[key] = cb
|
$.syncing[key] = cb
|
||||||
$.oldValue[key] = $.getValue key
|
|
||||||
|
|
||||||
do ->
|
|
||||||
onChange = ({key, newValue}) ->
|
|
||||||
return if not (cb = $.syncing[key])
|
|
||||||
if newValue?
|
|
||||||
return if newValue is $.oldValue[key]
|
|
||||||
$.oldValue[key] = newValue
|
|
||||||
cb JSON.parse(newValue), key[g.NAMESPACE.length..]
|
|
||||||
else
|
|
||||||
return unless $.oldValue[key]?
|
|
||||||
delete $.oldValue[key]
|
|
||||||
cb undefined, key[g.NAMESPACE.length..]
|
|
||||||
$.on window, 'storage', onChange
|
|
||||||
|
|
||||||
$.forceSync = (key) ->
|
|
||||||
# Storage events don't work across origins
|
|
||||||
# e.g. http://boards.4chan.org and https://boards.4chan.org
|
|
||||||
# so force a check for changes to avoid lost data.
|
|
||||||
key = g.NAMESPACE + key
|
|
||||||
onChange {key, newValue: $.getValue key}
|
|
||||||
else
|
|
||||||
$.sync = ->
|
|
||||||
$.forceSync = ->
|
$.forceSync = ->
|
||||||
|
|
||||||
$.delete = (keys) ->
|
$.delete = (keys, cb) ->
|
||||||
unless keys instanceof Array
|
unless keys instanceof Array
|
||||||
keys = [keys]
|
keys = [keys]
|
||||||
for key in keys
|
Promise.all(GM.deleteValue(g.NAMESPACE + key) for key in keys).then ->
|
||||||
$.deleteValue g.NAMESPACE + key
|
items = {}
|
||||||
return
|
items[key] = undefined for key in keys
|
||||||
|
$.syncChannel.postMessage items
|
||||||
|
cb?()
|
||||||
|
|
||||||
$.get = $.oneItemSugar (items, cb) ->
|
$.get = $.oneItemSugar (items, cb) ->
|
||||||
$.queueTask $.getSync, items, cb
|
keys = Object.keys items
|
||||||
|
Promise.all(GM.getValue(g.NAMESPACE + key) for key in keys).then (values) ->
|
||||||
|
for val, i in values when val
|
||||||
|
items[keys[i]] = JSON.parse val
|
||||||
|
cb items
|
||||||
|
|
||||||
$.getSync = (items, cb) ->
|
$.set = $.oneItemSugar (items, cb) ->
|
||||||
for key of items when (val2 = $.getValue g.NAMESPACE + key)
|
Promise.all(GM.setValue(g.NAMESPACE + key, JSON.stringify(val)) for key, val of items).then ->
|
||||||
items[key] = JSON.parse val2
|
$.syncChannel.postMessage items
|
||||||
cb items
|
cb?()
|
||||||
|
|
||||||
$.set = $.oneItemSugar (items, cb) ->
|
$.clear = (cb) ->
|
||||||
for key, value of items
|
GM.listValues.then (keys) ->
|
||||||
$.setValue(g.NAMESPACE + key, JSON.stringify value)
|
$.delete keys.map((key) -> key.replace g.NAMESPACE, ''), cb
|
||||||
cb?()
|
|
||||||
|
else
|
||||||
|
|
||||||
|
# workaround for Firefox 53 issue
|
||||||
|
$.currentValue = {}
|
||||||
|
$.GM_getValue = (key) ->
|
||||||
|
try
|
||||||
|
$.currentValue[key] = GM_getValue key
|
||||||
|
catch err
|
||||||
|
$.currentValue[key]
|
||||||
|
$.GM_setValue = (key, val) ->
|
||||||
|
$.currentValue[key] = val
|
||||||
|
GM_setValue key, val
|
||||||
|
$.GM_deleteValue = (key) ->
|
||||||
|
delete $.currentValue[key]
|
||||||
|
GM_deleteValue key
|
||||||
|
|
||||||
|
unless GM_deleteValue?
|
||||||
|
$.perProtocolSettings = true
|
||||||
|
|
||||||
|
if GM_deleteValue?
|
||||||
|
$.getValue = $.GM_getValue
|
||||||
|
$.listValues = -> GM_listValues() # error when called if missing
|
||||||
|
else if $.hasStorage
|
||||||
|
$.getValue = (key) -> localStorage[key]
|
||||||
|
$.listValues = ->
|
||||||
|
key for key of localStorage when key[...g.NAMESPACE.length] is g.NAMESPACE
|
||||||
|
else
|
||||||
|
$.getValue = ->
|
||||||
|
$.listValues = -> []
|
||||||
|
|
||||||
|
if GM_addValueChangeListener?
|
||||||
|
$.setValue = $.GM_setValue
|
||||||
|
$.deleteValue = $.GM_deleteValue
|
||||||
|
else if GM_deleteValue?
|
||||||
|
$.oldValue = {}
|
||||||
|
$.setValue = (key, val) ->
|
||||||
|
$.GM_setValue key, val
|
||||||
|
if key of $.syncing
|
||||||
|
$.oldValue[key] = val
|
||||||
|
localStorage[key] = val if $.hasStorage # for `storage` events
|
||||||
|
$.deleteValue = (key) ->
|
||||||
|
$.GM_deleteValue key
|
||||||
|
if key of $.syncing
|
||||||
|
delete $.oldValue[key]
|
||||||
|
localStorage.removeItem key if $.hasStorage # for `storage` events
|
||||||
|
$.cantSync = true if !$.hasStorage
|
||||||
|
else if $.hasStorage
|
||||||
|
$.oldValue = {}
|
||||||
|
$.setValue = (key, val) ->
|
||||||
|
$.oldValue[key] = val if key of $.syncing
|
||||||
|
localStorage[key] = val
|
||||||
|
$.deleteValue = (key) ->
|
||||||
|
delete $.oldValue[key] if key of $.syncing
|
||||||
|
localStorage.removeItem key
|
||||||
|
else
|
||||||
|
$.setValue = ->
|
||||||
|
$.deleteValue = ->
|
||||||
|
$.cantSync = $.cantSet = true
|
||||||
|
|
||||||
|
if GM_addValueChangeListener?
|
||||||
|
$.sync = (key, cb) ->
|
||||||
|
$.syncing[key] = GM_addValueChangeListener g.NAMESPACE + key, (key2, oldValue, newValue, remote) ->
|
||||||
|
if remote
|
||||||
|
newValue = JSON.parse newValue unless newValue is undefined
|
||||||
|
cb newValue, key
|
||||||
|
$.forceSync = ->
|
||||||
|
else if GM_deleteValue? or $.hasStorage
|
||||||
|
$.sync = (key, cb) ->
|
||||||
|
key = g.NAMESPACE + key
|
||||||
|
$.syncing[key] = cb
|
||||||
|
$.oldValue[key] = $.getValue key
|
||||||
|
|
||||||
|
do ->
|
||||||
|
onChange = ({key, newValue}) ->
|
||||||
|
return if not (cb = $.syncing[key])
|
||||||
|
if newValue?
|
||||||
|
return if newValue is $.oldValue[key]
|
||||||
|
$.oldValue[key] = newValue
|
||||||
|
cb JSON.parse(newValue), key[g.NAMESPACE.length..]
|
||||||
|
else
|
||||||
|
return unless $.oldValue[key]?
|
||||||
|
delete $.oldValue[key]
|
||||||
|
cb undefined, key[g.NAMESPACE.length..]
|
||||||
|
$.on window, 'storage', onChange
|
||||||
|
|
||||||
|
$.forceSync = (key) ->
|
||||||
|
# Storage events don't work across origins
|
||||||
|
# e.g. http://boards.4chan.org and https://boards.4chan.org
|
||||||
|
# so force a check for changes to avoid lost data.
|
||||||
|
key = g.NAMESPACE + key
|
||||||
|
onChange {key, newValue: $.getValue key}
|
||||||
|
else
|
||||||
|
$.sync = ->
|
||||||
|
$.forceSync = ->
|
||||||
|
|
||||||
|
$.delete = (keys) ->
|
||||||
|
unless keys instanceof Array
|
||||||
|
keys = [keys]
|
||||||
|
for key in keys
|
||||||
|
$.deleteValue g.NAMESPACE + key
|
||||||
|
return
|
||||||
|
|
||||||
|
$.get = $.oneItemSugar (items, cb) ->
|
||||||
|
$.queueTask $.getSync, items, cb
|
||||||
|
|
||||||
|
$.getSync = (items, cb) ->
|
||||||
|
for key of items when (val2 = $.getValue g.NAMESPACE + key)
|
||||||
|
items[key] = JSON.parse val2
|
||||||
|
cb items
|
||||||
|
|
||||||
|
$.set = $.oneItemSugar (items, cb) ->
|
||||||
|
for key, value of items
|
||||||
|
$.setValue(g.NAMESPACE + key, JSON.stringify value)
|
||||||
|
cb?()
|
||||||
|
|
||||||
|
$.clear = (cb) ->
|
||||||
|
# XXX https://github.com/greasemonkey/greasemonkey/issues/2033
|
||||||
|
# Also support case where GM_listValues is not defined.
|
||||||
|
$.delete Object.keys(Conf)
|
||||||
|
$.delete ['previousversion', 'QR Size', 'captchas', 'QR.persona', 'hiddenPSA']
|
||||||
|
try
|
||||||
|
$.delete $.listValues().map (key) -> key.replace g.NAMESPACE, ''
|
||||||
|
cb?()
|
||||||
|
|
||||||
$.clear = (cb) ->
|
|
||||||
# XXX https://github.com/greasemonkey/greasemonkey/issues/2033
|
|
||||||
# Also support case where GM_listValues is not defined.
|
|
||||||
$.delete Object.keys(Conf)
|
|
||||||
$.delete ['previousversion', 'QR Size', 'captchas', 'QR.persona', 'hiddenPSA']
|
|
||||||
try
|
|
||||||
$.delete $.listValues().map (key) -> key.replace g.NAMESPACE, ''
|
|
||||||
cb?()
|
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|||||||
@ -63,7 +63,7 @@ CrossOrigin =
|
|||||||
options.overrideMimeType = 'text/plain; charset=x-user-defined'
|
options.overrideMimeType = 'text/plain; charset=x-user-defined'
|
||||||
else
|
else
|
||||||
options.responseType = 'arraybuffer'
|
options.responseType = 'arraybuffer'
|
||||||
GM_xmlhttpRequest options
|
(GM?.xmlHttpRequest or GM_xmlhttpRequest) options
|
||||||
<% } %>
|
<% } %>
|
||||||
|
|
||||||
file: (url, cb) ->
|
file: (url, cb) ->
|
||||||
@ -99,7 +99,7 @@ CrossOrigin =
|
|||||||
return
|
return
|
||||||
callbacks[url] = [cb]
|
callbacks[url] = [cb]
|
||||||
<% if (type === 'userscript') { %>
|
<% if (type === 'userscript') { %>
|
||||||
GM_xmlhttpRequest
|
(GM?.xmlHttpRequest or GM_xmlhttpRequest)
|
||||||
method: "GET"
|
method: "GET"
|
||||||
url: url+''
|
url: url+''
|
||||||
onload: (xhr) ->
|
onload: (xhr) ->
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user