您需要先安装一个扩展,例如 篡改猴、Greasemonkey 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 暴力猴,之后才能安装此脚本。
您需要先安装一个扩展,例如 篡改猴 或 Userscripts ,之后才能安装此脚本。
您需要先安装一款用户脚本管理器扩展,例如 Tampermonkey,才能安装此脚本。
您需要先安装用户脚本管理器扩展后才能安装此脚本。
utils for DOM manipulation and fetching info of a webpage
当前为
此脚本不应直接安装。它是供其他脚本使用的外部库,要使用该库请加入元指令 // @require https://update.gf.qytechs.cn/scripts/20131/128690/html-utils.js
// extend HtmlFactory var HtmlFactoryExtension = (function() { /** * Creates a 'button' Html Element. * The initial class attribute is <code>class='smallbutton'</code>. * @param {function} [callback] - The callback function for the <code>onClick<code> event * @param {string} [text] - The content text of the element (text shown on the button) * @param {string} [id] - The value for the <code>id</code> attribute * @returns {ElType} The 'button' HTML element */ var createButtonSmall = function(callback, text, id) { return HtmlFactory.newButton('smallbutton', callback, text, id); }; /** * Creates a 'button' Html Element. * The initial class attribute is <code>class='tinybutton'</code>. * @param {function} [callback] - The callback function for the <code>onClick<code> event * @param {string} [text] - The content text of the element (text shown on the button) * @param {string} [id] - The value for the <code>id</code> attribute * @returns {ElType} The 'button' HTML element */ var createButtonTiny = function ButtonTiny(callback, text, id) { var elBtn = HtmlFactory.newButton('tinybutton', callback, text, id); elBtn.style = 'margin:0;padding:0;width:auto;'; return elBtn; }; /** * Creates a 'Select' HTML element for selecting camamba users. * The options will be generated by the list of users. * The initial class attribute is <code>class='smallselect'</code>. * @param {Object<string, User>[]} users - The list of users shown as options * @param {string} [id] - The value for the <code>id</code> attribute * @returns {ElType} The 'select' HTML element */ var createSelectUsers = function(users, id) { var elSelect = HtmlFactory.newSelect('smallselect', id); var _onchangeCallback; /** * Returns the user of the selected option * @returns {User} The current selected user */ elSelect.getSelectedUser = function() { return elSelect.options[elSelect.selectedIndex].user; }; /** * Sets a callback function triggered by the events <code>OnChange</code>, <code>OnKeyUp</code> and <code>OnFocus</code>. * Removes any former callback function registered to these events. * @param {function} callback */ elSelect.setOnChangeKeyUpFocus = function(callback) { if (_onchangeCallback) { elSelect.removeEventListener("focus", _onchangeCallback); elSelect.removeEventListener("change", _onchangeCallback); elSelect.removeEventListener("keyup", _onchangeCallback); } if (typeof callback === 'function') { _onchangeCallback = callback; elSelect.addEventListener("focus", callback); elSelect.addEventListener("change", callback); elSelect.addEventListener("keyup", callback); } }; /** * The options will be regenerated by the list of users. * @param {Object<string, User>[]} users - The list of users shown as options */ elSelect.updateUsers = function(users) { var sortUsers = []; var remainingUsers = {}; for (var i = 0; i <= elSelect.length - 1; i++) { var userInSelect = elSelect[i].user; if (!users[userInSelect.uid]) { // deleted users elSelect.remove(i); } else { // remaining users remainingUsers[userInSelect.uid] = true; sortUsers.push({ user:userInSelect, selected:elSelect[i].selected }); } } Object.keys(users).forEach(function(uid){ if (!remainingUsers[uid]) { // additional users var user = users[uid]; sortUsers.push({ user:user, selected:false }); /** * Html 'Option' Child of a Html 'Select' Element that holds a User * @type {HTMLOptionElement} * @property {User} user - The User related to the option */ elSelect.add(document.createElement('OPTION')); } }); elSelect.length = sortUsers.length; sortUsers.sort(function (a, b) { if (a.user.uname < b.user.uname) { return -1; } if (a.user.uname > b.user.uname) { return 1; } return 0; }); sortUsers.forEach(function (opt, i) { elSelect[i].text = opt.user.uname; elSelect[i].value = opt.user.uid; elSelect[i].user = opt.user; elSelect[i].selected = opt.selected; }); }; elSelect.updateUsers(users); return elSelect; }; return { newButtonSmall : createButtonSmall, newButtonTiny : createButtonTiny, newSelectUsers : createSelectUsers } })(); Object.keys(HtmlFactoryExtension).forEach(function (propName) { HtmlFactory[propName] = HtmlFactoryExtension[propName]; }); //extend Page var PageExtension = (function() { var isGerman = window.location.hostname.indexOf("de.camamba.com") >= 0; var uriRoute = /^\/(.+?)(?:_de)?\.php.*/g.exec(location.pathname)[1]; /** * Verifies an uri, if it loads the German version of camamba. * @param {string} uri The uri for a camamba Page. * @returns {boolean} <code>true</code> if the uri will request a camamba Page in German. */ var uriIsGerman = function(uri) { return (uri.indexOf('www.de.camamba.com') >= 0); }; /** * Transforms the uri of a camamba Page wether to request that Page in English or German, depending the language of the current Page. * @param {string} uri - The uri for a cammaba Page. * @param {Object.<string,string>[]} [queryParamsObj] - A key-value Object for additional query parameter to be attached to the uri. * @returns {string} The localized uri */ var uriLocalized = function(uri, queryParamsObj) { var localizedUri = uri; if (isGerman && !uriIsGerman(uri)) { localizedUri = uri .replace("www.camamba.com", "www.de.camamba.com") .replace(".php", "_de.php"); } else if (!isGerman && uriIsGerman(uri)) { localizedUri = uri .replace("www.de.camamba.com", "www.camamba.com") .replace("_de.php", "php"); } var queryParams = ''; if (queryParamsObj) { var hasParams = uri.indexOf('.php?') >= 1; Object.keys(queryParamsObj).forEach(function (key) { var sep = (hasParams ? '&' : '?'); var value = queryParamsObj[key]; queryParams += sep + key + '=' + value; hasParams = true; }); } return localizedUri + queryParams; }; return { /** * Indicates the localization of the current camamba Page. * @returns {boolean} <code>true</code> if the current Page is in German * <code>false</code> the current Page is in English */ isGerman : isGerman, /** * The current path in camamba according to the uri. * @returns {string} The current path. */ route : uriRoute, localizeUri : uriLocalized }; })(); Object.keys(PageExtension).forEach(function (propName) { Page[propName] = PageExtension[propName]; }); /** * @name uidType * @type string|number */ /** * Represents a camamba user. * Intitially tries to load the User from the database that has the given uid. * @constructor * @param {uidType} uid Identifies the User with its camaba uid. */ function User(uid) { var _uid = parseInt(uid, 10); // camamba user ID (readonly) var _key = 'uid' + _uid, // key for storing (readonly) _uname = "", // camamba username _name = "", // custom username _note = "", // custom annotation _hasChanged = true; // is any value is unsaved (readonly) /** * @name User#uid * @type number * @readonly */ /** * @name User#key * @type String * @readonly */ /** * @name User#hasChanged * @type Boolean * @readonly */ /** * @name User#note * @type String */ Object.defineProperties(this, { uid : { value : _uid, writable : false }, key : { value : _key, writable : false }, hasChanged : { get : function() { return _hasChanged; } }, uname : { get : function() { return _uname; }, set : function(val) { if (_uname != val) { _uname = val; _hasChanged = true; } } }, name : { get : function() { return _name || _uname || _uid.toString(); }, set : function(val) { if (_name != val) { _name = val; _hasChanged = true; } } }, note : { get : function() { return _note; }, set : function(val) { if (_note != val) { _note = val; _hasChanged = true; } } } }); /** * Saves or updates the user in the database of this script. * Overwrites an existing entry or creates a new entry if it doesn't alread exist. */ this.save = function() { User.prototype.save.call(this); _hasChanged = false; }; /** * Loads the User from the database of this script. * @returns {Boolean} <code>true</code> if the user was found and could be sucessfully loaded from db */ this.load = function() { var isSuccess = User.prototype.load.call(this); if (isSuccess) {_hasChanged = false; } return isSuccess; }; /** * Removes the User from the database of this script. */ this.remove = function () { User.prototype.remove.call(this); _hasChanged = true; }; this.load(); } User.prototype = { constructor : User, save : function() { if (this.hasChanged) { GM_setValue("uid" + this.uid, JSON.stringify({ uname : this.uname, name : this.name, note : this.note })); } }, load : function() { var isScuccess = false; var loadedString = GM_getValue("uid" + this.uid); if (loadedString) { var loadedObj = JSON.parse(loadedString); var uname = loadedObj.uname; var name = loadedObj.name; var note = loadedObj.note; if (uname !== undefined && name !== undefined && note !== undefined){ this.uname = uname; this.name = name; this.note = note; isScuccess = true; } } return isScuccess; }, remove : function() { GM_deleteValue("uid" + this.uid); }, /** * Gets all users stored from the database determined for this Script. * @returns {{}<uidType,User>[]} List with all Stored Users */ loadAllUsers : function() { var users = {}; var storedKeys = GM_listValues(); for (var i = 0; i <= storedKeys.length - 1; i++) { var key = storedKeys[i].toString(); if (key.indexOf('uid') === 0) { var uid = key.substr(3); users[uid] = new User(uid); } } return users; }, /** * Has the browser open the profile Page of this user. * @param {boolean} [asNewTab=false] * <code>true</code>, Page is opened in a new tab. * <code>false</code>, replaces the current Page. */ openProfilePage : function (asNewTab) { var profPageLocPath = location.protocol + '//www.camamba.com/profile_view.php'; var queryParamsObj = { uid : this.uid, m : 'start' }; var uri = Page.localizeUri(profPageLocPath, queryParamsObj); var target = asNewTab ? '_blank' : '_self'; window.open(uri, target); } };
QingJ © 2025
镜像随时可能失效,请加Q群300939539或关注我们的公众号极客氢云获取最新地址