// ==UserScript==
// @name OKX_exchange
// @namespace [email protected]
// @version 1.0
// @description the OKX_exchange
// @author [email protected]
// @match *://www.okx.com
// @match *://*.okx.com
// @match *://www.okx.com/*
// @match *://*.okx.com/*
// @exclude *://www.12gm.com/*
// @exclude *://*.12gm.com/*
// @license AGPL License
// @grant GM_download
// @grant GM_openInTab
// @grant GM_setValue
// @grant GM_getValue
// @grant GM_deleteValue
// @grant GM_xmlhttpRequest
// @grant GM_addStyle
// @grant unsafeWindow
// @grant GM_setClipboard
// @grant GM_getResourceURL
// @grant GM_getResourceText
// @grant GM_info
// @grant GM_registerMenuCommand
// @grant GM_cookie
// ==/UserScript==
(function () {
'use strict';
class PublicFunc {
base_url = `https://local.12gm.com`
#stop_wait_value = false //是否停止等待查找元素
#stop_wait_ele = false
#_get(URL, queryJSON, callback) {
if (typeof queryJSON == 'function') {
callback = queryJSON;
queryJSON = {}
}
let xhr;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest()
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP")
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
let data = null;
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
data = xhr.responseText
} else {
console.log(new Error("AJAX GET did not find the requested file"))
}
callback(data)
}
};
let querystring = this.#_json_query(queryJSON);
let joiner;
if (!URL.includes('?')) {
joiner = "?"
} else {
joiner = "&"
}
if (querystring) {
querystring = joiner + querystring
}
URL = URL + querystring;
xhr.open("get", URL, true);
xhr.send(null)
}
#_post(URL, queryJSON, callback) {
let xhr;
if (window.XMLHttpRequest) {
xhr = new window.XMLHttpRequest()
} else {
xhr = new ActiveXObject("Microsoft.XMLHTTP")
}
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
let data = null;
if (xhr.status >= 200 && xhr.status < 300 || xhr.status == 304) {
data = xhr.responseText
} else {
console.log(new Error("AJAX POST did not find the requested file"))
}
callback(data)
}
};
let querystring = this.#_json_query(queryJSON);
xhr.open("post", URL, true);
xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhr.send(querystring)
}
#check_url(url) {
let url_check = /^((https|http)\:|\/\/)/;
if (url_check.test(url)) {
return url
}
return this.remote_url(url)
}
#_json_query(json) {
var arr = [];
for (var k in json) {
arr.push(k + "=" + encodeURIComponent(json[k]))
}
if (arr.length == 0) {
return ""
}
return arr.join("&")
}
get(url_method, request_data) {
url_method = this.#check_url(url_method);
return new Promise((resolve, reject) => {
console.log(url_method)
this.#_get(url_method, request_data, (data) => {
if (data) {
data = this.to_json(data)
}
resolve(data)
})
})
}
post(url_method, data) {
url_method = this.#check_url(url_method);
return new Promise((resolve, reject) => {
this.#_post(url_method, data, (data) => {
if (data) {
data = this.to_json(data)
}
resolve(data)
})
})
}
class_toggle(selector, class_toggle) {
class_toggle = class_toggle.trim()
let ele = document.querySelector(selector)
let classes = ele.getAttribute('class')
classes = classes.split(/\s+/)
let index = classes.indexOf(class_toggle)
if (index != -1) {
classes[index] = ""
} else {
classes.push(class_toggle)
}
classes = classes.join(' ')
ele.setAttribute('class', classes)
}
numeric(n) {
let numbric = /^\d+$/
if (numbric.test(n)) {
return true
}
return false
}
get_base_url(suffix = '') {
let base_remote_url = `${this.base_url}/${suffix}`
return base_remote_url
}
get_file(file) {
let this_point = this
return new Promise((resolve, reject) => {
this_point.get('api:get_static_files', { file }).then((data) => {
resolve(data)
})
});
}
to_json(value) {
try {
value = JSON.parse(value)
} catch (e) {
console.log(`value ${value}`)
console.log(`to_json ${e}`)
}
return value
}
info(message) {
let id = "#WordToNoteBookButton"
let note = document.querySelector(id)
if (note) {
note.querySelector('span').innerHTML = message
note.style.display = 'block'
setTimeout(() => {
note.style.display = 'none'
}, 1500)
}
}
is_mobile_browser() {
let mobile_match = navigator.userAgent.match(
/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i
)
if (mobile_match) {
this.get_trans_word_index = 2
this.mobile_browser = 1
} else {
this.get_trans_word_index = 3
this.mobile_browser = 0
}
}
exclude() {
let is_frame = (window.self === window.top) == false
let is_exclude = false
if (is_frame) {
return true
}
let exclude_hosts = [
// "12gm.com",
`127.0.0.1`,
`localhost`
]
let hostname = window.location.hostname
exclude_hosts.forEach(exclude_host => {
if (hostname.endsWith(exclude_host)) {
is_exclude = true
return
}
})
return is_exclude
}
date_totimestamp(time) {
if (!time) {
time = new Date()
} else if (typeof time == 'string' || typeof time == 'number') {
time = new Date(time)
}
let timesdamp = Date.parse(time)
return timesdamp
}
timestamp_todate(time, format = 'Y-M-D h:m:s') {
let date
if (typeof time == 'object') {
date = time
} else {
if (this.numeric(time)) {
time = parseInt(time)
}
date = new Date(time)
}
let Y = date.getFullYear();
let M = this.fill_alphabet(date.getMonth() + 1, 2, '0');
let D = this.fill_alphabet(date.getDate(), 2, '0');
let h = this.fill_alphabet(date.getHours(), 2, '0');
let m = this.fill_alphabet(date.getMinutes(), 2, '0');
let s = this.fill_alphabet(date.getSeconds(), 2, '0');
format = format.replace('Y', Y)
format = format.replace('M', M)
format = format.replace('D', D)
format = format.replace('h', h)
format = format.replace('m', m)
format = format.replace('s', s)
return format
}
rate(price, comparison_price) {
return (price - comparison_price) / comparison_price
}
keep_pointtostring(n, keep_point = 2) {
n = (n + '').split('.')
if (n.length > 1) {
n[1] = n[1].substr(0, keep_point)
}
n = n.join('.')
return n
}
create_time(format = 'Y-M-D h:m:s') {
let time = this.timestamp_todate(new Date(), format)
return time
}
fill_alphabet(s, l, fill_s = "0") {
s = s + ""
s = s.padStart(l, fill_s)
return s
}
remove(selector) {
let ele = document.querySelector(selector)
if (ele) {
ele.remove()
}
}
split_html(html) {
html = html.replaceAll(/<.+?>/g, '')
return html
}
local_storage(key, value) {
if (value) {
localStorage.setItem(key, value)
} else {
return localStorage.getItem(key)
}
}
remote_url(module_method) {
module_method = module_method.split(":")
if (module_method.length == 0) {
module_method.unshift('translate')
}
let method = module_method[module_method.length - 1]
let module_name = module_method[0]
if (module_name != 'control') {
module_name = `com_${module_name}`
}
let key = `9LrQN0~14,dSmoO^`
let url = this.get_base_url(`api?method=${method}&key=${key}&module=${module_name}`)
return url
}
//给添加的元素添加监听事件
listen(ele_selector, event, callback) {
if (typeof ele_selector == 'string') {
ele_selector = document.querySelector(ele_selector)
}
if (ele_selector) {
ele_selector.addEventListener(event, () => {
callback()
})
}
}
toggle_action(ele) {
ele = this.get_elements(ele)
let toggle = ele.dataset.toggle
if (toggle) {
let key_default = ['textContent', `value`, `className`]
let toggles = toggle.split('|')
let toggle_object = {}
toggles.forEach((val, index) => {
let key
if (val.indexOf('=') != -1) {
let vals = val.split(`=`)
val = vals.pop()
key = vals[0]
} else {
if (index >= key_default.length) {
return true
}
key = key_default[index]
}
key = key.trim()
if (key == 'class') {
key = 'className'
}
if (key == 'text' || key == 'html') {
key = 'textContent'
}
val = val.trim()
toggle_object[key] = val
})
let keys = Object.keys(toggle_object)
let backup_origin = {}
keys.forEach((key) => {
backup_origin[key] = ele[key]
})
let toggle_value = toggle_object.value
if (typeof toggle_value == 'string') {
toggle_value = ['false', '', 'null'].indexOf(toggle_value.toLowerCase()) != -1 ? false : true;
}
toggle_value = !toggle_value
backup_origin.value = toggle_value.toString()
let backup_origintext = []
for (let key in backup_origin) {
let val = backup_origin[key]
backup_origintext.push(`${key}=${val}`)
}
for (let key in toggle_object) {
let val = toggle_object[key]
if (key != 'value') {
ele[key] = val
}
}
backup_origintext = backup_origintext.join("|")
ele.setAttribute('data-toggle', backup_origintext)
return toggle_value
}
return true
}
bind(Okx, parent_selectro = "", ...additional) {
let panelasid = this.get_elements(`${parent_selectro} [id]`)
panelasid.forEach((ele) => {
let id = ele.getAttribute('id')
if (id.startsWith('on-')) {
let id_information = id.split('-')
let event_name = id_information.pop()
let event_entity = Okx[event_name]
if (event_entity) {
console.log(`bind of Okx of ${id}`, Okx)
$$.listen(ele, 'click', () => {
let toggle_object = this.toggle_action(ele)
Okx[event_name](toggle_object)
})
} else {
console.log(`additional`, additional, event_name)
additional.forEach((another) => {
if (another[event_name]) {
console.log(`bind at another of ${id}`, another)
$$.listen(ele, 'click', () => {
let toggle_object = this.toggle_action(ele)
// console.log(`toggle_object ${toggle_object}`)
another[event_name](toggle_object)
})
}
})
}
}
})
}
wait_ele(ele_selector, callback, wait = 1000) {
if (this.#stop_wait_ele == true) {
this.#stop_wait_ele == false
console.log(`wait_ele has stoped from ${ele_selector}`)
return
}
let ele = document.querySelector(ele_selector)
if (!ele) {
console.log(`wait_ele ${ele_selector} loading ${wait / 1000}s`)
setTimeout(() => {
this.wait_ele(ele_selector, callback, wait)
}, wait)
} else {
callback()
}
}
wait_value(ele_selector, valuetype = 'innerHTML', expect = 'text', callback, wait = 1000) {
if (this.#stop_wait_value == true) {
this.#stop_wait_value == false
console.log(`wait_value has stoped from ${ele_selector}`)
return
}
let ele = document.querySelector(ele_selector)
let reg = /.{1,}/
switch (expect) {
case 'number':
reg = /^\d+$/
break
case 'float':
reg = /^[\d\.]+$/
break
}
if (!ele || !reg.test(ele[valuetype])) {
console.log(`wait_value ${ele_selector} loading ${wait / 1000}s`)
setTimeout(() => {
this.wait_value(ele_selector, valuetype, expect, callback, wait)
}, wait)
} else {
callback()
}
}
set_stop_wait_ele(val = false) {
this.#stop_wait_ele = val
}
set_stop_wait_value(val = false) {
this.#stop_wait_value = val
}
get_ele(ele_selector) {
if (typeof ele_selector == 'string') {
ele_selector = document.querySelector(ele_selector)
}
return ele_selector
}
get_elements(ele_selector) {
if (typeof ele_selector == 'string') {
ele_selector = document.querySelectorAll(ele_selector)
}
return ele_selector
}
create_ele(tag, types) {
let ele = document.createElement(tag)
for (let key in types) {
let val = types[key]
ele[key] = val
}
document.querySelector(`body`).insertAdjacentElement('beforeEnd', ele)
}
load_module(module_names) {
let import_js = ``
for (let key in module_names) {
let val = module_names[key]
import_js += `\nimport {${key}} from '${this.base_url}/static/core_js/${val}'\n`
}
// import_js += `
// okx_tampermonkey.initial()
// `
let ele = document.createElement('script')
ele.type = 'module'
ele.innerHTML = import_js
ele.textContent = import_js
document.querySelector(`body`).insertAdjacentElement('afterEnd', ele)
}
initial() {
if (this.exclude()) {
return
}
//页面执行标记
document.$$executeToken = true
let okx_jsurl = `static/core_js/okx.js`
this.get_file(okx_jsurl).then((data) => {
if (!data || !data.data || data.data.length == 0) {
console.log(data)
alert('okx_main 主文件请求不成功,请检查网络.')
return
} else {
// console.log(`okx load success, url${okx_jsurl}, code length ${data.data.length}`, data)
}
let script = data.data[0]
script = script.replaceAll("{{base_url}}", this.base_url)
// console.log("script",script)
this.create_ele('script', {
type: 'module',
innerHTML: script,
// textContent: script
})
})
}
}
const $$ = new PublicFunc()
document.$$ = $$
$$.initial()
})();