Preliminary support for Greasemonkey 4.
This commit is contained in:
parent
75ed8fe248
commit
4226a18a6d
@ -56,7 +56,12 @@
|
||||
"GM_listValues",
|
||||
"GM_addValueChangeListener",
|
||||
"GM_openInTab",
|
||||
"GM_xmlhttpRequest"
|
||||
"GM_xmlhttpRequest",
|
||||
"GM.getValue",
|
||||
"GM.setValue",
|
||||
"GM.deleteValue",
|
||||
"GM.listValues",
|
||||
"GM.xmlHttpRequest"
|
||||
],
|
||||
"min": {
|
||||
"chrome": "33",
|
||||
|
||||
@ -16,11 +16,14 @@
|
||||
"globals": {
|
||||
"MediaError": false,
|
||||
"Set": false,
|
||||
"Promise": false,
|
||||
"BroadcastChannel": false,
|
||||
"GM_info": false,
|
||||
"cloneInto": false,
|
||||
"unsafeWindow": false,
|
||||
"chrome": false<%=
|
||||
meta.grants.map(x => `,\n "${x}": false`).join('')
|
||||
"chrome": false,
|
||||
"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('')
|
||||
%><%=
|
||||
|
||||
@ -492,125 +492,166 @@ do ->
|
||||
# http://wiki.greasespot.net/Main_Page
|
||||
# https://tampermonkey.net/documentation.php
|
||||
|
||||
# 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
|
||||
if GM?.deleteValue?
|
||||
|
||||
unless GM_deleteValue?
|
||||
$.perProtocolSettings = true
|
||||
$.syncChannel = new BroadcastChannel(g.NAMESPACE + 'sync')
|
||||
|
||||
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 = -> []
|
||||
$.on $.syncChannel, 'message', (e) ->
|
||||
for key, val of e.data when (cb = $.syncing[key])
|
||||
cb val, key
|
||||
|
||||
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
|
||||
$.delete = (keys, cb) ->
|
||||
unless keys instanceof Array
|
||||
keys = [keys]
|
||||
Promise.all(GM.deleteValue(g.NAMESPACE + key) for key in keys).then ->
|
||||
items = {}
|
||||
items[key] = undefined for key in keys
|
||||
$.syncChannel.postMessage items
|
||||
cb?()
|
||||
|
||||
$.get = $.oneItemSugar (items, cb) ->
|
||||
$.queueTask $.getSync, items, cb
|
||||
$.get = $.oneItemSugar (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) ->
|
||||
for key of items when (val2 = $.getValue g.NAMESPACE + key)
|
||||
items[key] = JSON.parse val2
|
||||
cb items
|
||||
$.set = $.oneItemSugar (items, cb) ->
|
||||
Promise.all(GM.setValue(g.NAMESPACE + key, JSON.stringify(val)) for key, val of items).then ->
|
||||
$.syncChannel.postMessage items
|
||||
cb?()
|
||||
|
||||
$.set = $.oneItemSugar (items, cb) ->
|
||||
for key, value of items
|
||||
$.setValue(g.NAMESPACE + key, JSON.stringify value)
|
||||
cb?()
|
||||
$.clear = (cb) ->
|
||||
GM.listValues.then (keys) ->
|
||||
$.delete keys.map((key) -> key.replace g.NAMESPACE, ''), 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'
|
||||
else
|
||||
options.responseType = 'arraybuffer'
|
||||
GM_xmlhttpRequest options
|
||||
(GM?.xmlHttpRequest or GM_xmlhttpRequest) options
|
||||
<% } %>
|
||||
|
||||
file: (url, cb) ->
|
||||
@ -99,7 +99,7 @@ CrossOrigin =
|
||||
return
|
||||
callbacks[url] = [cb]
|
||||
<% if (type === 'userscript') { %>
|
||||
GM_xmlhttpRequest
|
||||
(GM?.xmlHttpRequest or GM_xmlhttpRequest)
|
||||
method: "GET"
|
||||
url: url+''
|
||||
onload: (xhr) ->
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user