Skip to content

Instantly share code, notes, and snippets.

@neetsdkasu
Last active September 1, 2018 10:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save neetsdkasu/92f0039bd87036fc859ec171f4dd9cc4 to your computer and use it in GitHub Desktop.
Save neetsdkasu/92f0039bd87036fc859ec171f4dd9cc4 to your computer and use it in GitHub Desktop.
AtCoder ProblemsのRankingsのLanguage Ownersの名前出現数順の表を挿入するブラウザ拡張(雑)
ブラウザ拡張機能(アドオン)
AtCoder ProblemsのRankingsのLanguage Owners( kenkoooo.com/atcoder/?kind=lang )の名前出現数順の表を挿入するブラウザ拡張
ブラウザにmanifest.jsonを読み込ませる
FireFox: about:debugging#addons -> 一時的なアドオンを読み込む
vivalid: vivaldi://extensions -> パッケージ化されていない拡張機能を読み込む
manifest.jsonとscript.jsがあれば動く
※なんとなくtypescriptで書いたためscript.tsとtsconfig.jsonもあるが特に意味は無い
{
"manifest_version": 2,
"name": "AtCoder Problems Language Owners Rank",
"version": "1.1",
"author": "Leonardone",
"description": "AtCoder Problems Language Owners Rank",
"content_scripts": [
{
"matches": ["*://kenkoooo.com/atcoder/?*kind=lang*"],
"js": ["script.js"]
}
]
}
"use strict";
// script.js
// FireFox WebExtention
// AtCoder Problems Language Owners Rank
// author: Leonardone
var neetsdkasu;
(function (neetsdkasu) {
var MY_BUTTON_ID = 'neetsdkasu_button';
var MY_TABLE_ID = 'neetsdkasu_table';
var Status = /** @class */ (function () {
function Status(lang, rank, ac) {
this.lang = lang;
this.rank = rank;
this.ac = ac;
}
Status.prototype.compare = function (o) {
var c = this.rank - o.rank;
if (c !== 0) {
return c;
}
c = o.ac - this.ac;
if (c !== 0) {
return c;
}
if (this.lang < o.lang) {
return -1;
}
return this.lang > o.lang ? 1 : 0;
};
return Status;
}());
var Owner = /** @class */ (function () {
function Owner(name) {
this.name = name;
this.list = [];
this.rankSum = 0;
this.acSum = 0;
}
Owner.prototype.add = function (lang, rank, ac) {
this.rankSum += rank * rank * rank;
this.acSum += ac; //(4 - rank) * (4 - rank) * ac;
this.list.push(new Status(lang, rank, ac));
};
Owner.prototype.count = function () {
return this.list.length;
};
Owner.prototype.value = function () {
this.list.sort(function (a, b) { return a.compare(b); });
var s = '';
for (var _i = 0, _a = this.list; _i < _a.length; _i++) {
var v = _a[_i];
s += "( " + v.lang + ", " + v.rank + ", " + v.ac + " ), ";
}
return s;
};
Owner.prototype.compare = function (o) {
var c = o.list.length - this.list.length;
if (c !== 0) {
return c;
}
c = o.acSum - this.acSum;
if (c !== 0) {
return c;
}
c = this.rankSum - o.rankSum;
return c;
};
return Owner;
}());
function getRow() {
return document.getElementsByClassName('row').item(0);
}
function countOwners() {
var row = getRow();
if (row == null) {
return [];
}
var elements = row.children;
var m = {};
for (var i = 0; i < elements.length; i++) {
var e = elements.item(i);
var lang = e.getElementsByTagName('h1').item(0).innerHTML;
var ds = e.getElementsByTagName('div');
for (var j = 0; j < ds.length; j++) {
var d = ds.item(j);
if (d.className == 'page-header') {
continue;
}
var rank = parseInt(d.getElementsByTagName('h4').item(0).innerHTML[0]);
var name_1 = d.getElementsByTagName('h3').item(0).innerHTML;
var ac = parseInt(d.getElementsByTagName('span').item(0).innerHTML);
var owner = m[name_1];
if (owner == null) {
owner = new Owner(name_1);
m[name_1] = owner;
}
owner.add(lang, rank, ac);
}
}
var arr = [];
for (var k in m) {
arr.push(m[k]);
}
arr.sort(function (a, b) { return a.compare(b); });
return arr;
}
function makeRankTable() {
var tb = document.createElement('table');
tb.id = MY_TABLE_ID;
tb.style.display = 'none';
tb.border = '1';
var makeHead = (function (hd) {
return function (c) {
var th = hd.appendChild(document.createElement('th'));
th.appendChild(document.createTextNode(c));
};
})(tb.appendChild(document.createElement('tr')));
makeHead('rank');
makeHead('count');
makeHead('name');
makeHead('languages');
var owners = countOwners();
var rank = 1;
for (var i = 0; i < owners.length; i++) {
var tr = tb.appendChild(document.createElement('tr'));
var addCol = (function (tr) {
return function (c, right) {
var td = tr.appendChild(document.createElement('td'));
if (right) {
td.align = 'right';
}
td.appendChild(document.createTextNode(c));
};
})(tr);
var o = owners[i];
if (i > 0 && o.compare(owners[i - 1]) !== 0) {
rank = i + 1;
}
addCol(rank.toString(), true);
addCol(o.count().toString(), true);
addCol(o.name, false);
addCol(o.value(), false);
}
var target = document.getElementById(MY_BUTTON_ID);
if (target && (target = target.nextSibling)) {
var parent_1 = target.parentNode;
if (parent_1) {
parent_1.insertBefore(tb, target);
}
}
return tb;
}
function clickMyButton() {
var table = document.getElementById(MY_TABLE_ID) || makeRankTable();
if (table.style.display == '') {
table.style.display = 'none';
}
else {
table.style.display = '';
}
}
function createMyButton() {
var row = getRow();
if (row == null) {
return;
}
var button = document.createElement('button');
var label = document.createTextNode('show');
button.id = MY_BUTTON_ID;
button.appendChild(label);
button.onclick = clickMyButton;
var parent = row.parentNode;
if (parent) {
parent.insertBefore(button, row);
}
}
createMyButton();
})(neetsdkasu || (neetsdkasu = {})); // namespace neetsdkasu
// script.js
// FireFox WebExtention
// AtCoder Problems Language Owners Rank
// author: Leonardone
namespace neetsdkasu {
type Map<T> = { [key: string]: T };
const MY_BUTTON_ID = 'neetsdkasu_button';
const MY_TABLE_ID = 'neetsdkasu_table';
class Status {
lang: string;
rank: number;
ac: number;
constructor(lang: string, rank: number, ac: number) {
this.lang = lang;
this.rank = rank;
this.ac = ac;
}
compare(o: Status): number {
let c = this.rank - o.rank;
if (c !== 0) { return c; }
c = o.ac - this.ac;
if (c !== 0) { return c; }
if (this.lang < o.lang) { return -1; }
return this.lang > o.lang ? 1 : 0;
}
}
class Owner {
name: string;
list: Array<Status>;
rankSum: number;
acSum: number;
constructor(name: string) {
this.name = name;
this.list = [];
this.rankSum = 0;
this.acSum = 0;
}
add(lang: string, rank: number, ac: number): void {
this.rankSum += rank * rank * rank;
this.acSum += ac; //(4 - rank) * (4 - rank) * ac;
this.list.push(new Status(lang, rank, ac));
}
count(): number {
return this.list.length;
}
value(): string {
this.list.sort( (a, b) => a.compare(b) );
let s = '';
for (const v of this.list) {
s += `( ${v.lang}, ${v.rank}, ${v.ac} ), `;
}
return s;
}
compare(o: Owner): number {
let c = o.list.length - this.list.length;
if (c !== 0) { return c; }
c = o.acSum - this.acSum;
if (c !== 0) { return c; }
c = this.rankSum - o.rankSum;
return c;
}
}
function getRow(): HTMLElement | null {
return <HTMLElement>document.getElementsByClassName('row').item(0);
}
function countOwners(): Array<Owner> {
const row = getRow();
if (row == null) { return []; }
const elements = row.children;
const m: Map<Owner> = {};
for (let i = 0; i < elements.length; i++) {
const e = elements.item(i);
const lang = e.getElementsByTagName('h1').item(0).innerHTML;
const ds = e.getElementsByTagName('div');
for (let j = 0; j < ds.length; j++) {
const d = ds.item(j);
if (d.className == 'page-header') { continue; }
const rank = parseInt(d.getElementsByTagName('h4').item(0).innerHTML[0]);
const name = d.getElementsByTagName('h3').item(0).innerHTML;
const ac = parseInt(d.getElementsByTagName('span').item(0).innerHTML);
let owner = m[name];
if (owner == null) {
owner = new Owner(name);
m[name] = owner;
}
owner.add(lang, rank, ac);
}
}
const arr: Array<Owner> = [];
for (const k in m) {
arr.push(m[k]);
}
arr.sort( (a, b) => a.compare(b) );
return arr;
}
function makeRankTable(): HTMLElement {
const tb = document.createElement('table');
tb.id = MY_TABLE_ID;
tb.style.display = 'none';
tb.border = '1';
const makeHead = (function(hd) {
return function(c: string): void {
const th = hd.appendChild(document.createElement('th'));
th.appendChild(document.createTextNode(c));
};
})(tb.appendChild(document.createElement('tr')));
makeHead('rank');
makeHead('count');
makeHead('name');
makeHead('languages');
const owners = countOwners();
let rank = 1;
for (let i = 0; i < owners.length; i++) {
const tr = tb.appendChild(document.createElement('tr'));
const addCol = (function(tr) {
return function(c: string, right: boolean): void {
let td = tr.appendChild(document.createElement('td'));
if (right) { td.align = 'right'; }
td.appendChild(document.createTextNode(c));
};
})(tr);
const o = owners[i];
if (i > 0 && o.compare(owners[i - 1]) !== 0) {
rank = i + 1;
}
addCol(rank.toString(), true);
addCol(o.count().toString(), true);
addCol(o.name, false);
addCol(o.value(), false);
}
let target: Node | null = document.getElementById(MY_BUTTON_ID);
if (target && (target = target.nextSibling)) {
const parent = target.parentNode;
if (parent) { parent.insertBefore(tb, target); }
}
return tb;
}
function clickMyButton(): void {
const table = document.getElementById(MY_TABLE_ID) || makeRankTable();
if (table.style.display == '') {
table.style.display = 'none';
} else {
table.style.display = '';
}
}
function createMyButton(): void {
const row = getRow();
if (row == null) { return; }
const button = document.createElement('button');
const label = document.createTextNode('show');
button.id = MY_BUTTON_ID;
button.appendChild(label);
button.onclick = clickMyButton;
const parent = row.parentNode;
if (parent) { parent.insertBefore(button, row); }
}
createMyButton();
} // namespace neetsdkasu
{
"compilerOptions": {
/* Basic Options */
"target": "es5", /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017','ES2018' or 'ESNEXT'. */
"module": "commonjs", /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
// "lib": [], /* Specify library files to be included in the compilation. */
// "allowJs": true, /* Allow javascript files to be compiled. */
// "checkJs": true, /* Report errors in .js files. */
// "jsx": "preserve", /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
// "declaration": true, /* Generates corresponding '.d.ts' file. */
// "declarationMap": true, /* Generates a sourcemap for each corresponding '.d.ts' file. */
// "sourceMap": true, /* Generates corresponding '.map' file. */
// "outFile": "./", /* Concatenate and emit output to single file. */
// "outDir": "./", /* Redirect output structure to the directory. */
// "rootDir": "./", /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
// "composite": true, /* Enable project compilation */
// "removeComments": true, /* Do not emit comments to output. */
// "noEmit": true, /* Do not emit outputs. */
// "importHelpers": true, /* Import emit helpers from 'tslib'. */
// "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
// "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */
/* Strict Type-Checking Options */
"strict": true, /* Enable all strict type-checking options. */
"noImplicitAny": true, /* Raise error on expressions and declarations with an implied 'any' type. */
"strictNullChecks": true, /* Enable strict null checks. */
"strictFunctionTypes": true, /* Enable strict checking of function types. */
"strictPropertyInitialization": true, /* Enable strict checking of property initialization in classes. */
"noImplicitThis": true, /* Raise error on 'this' expressions with an implied 'any' type. */
"alwaysStrict": true, /* Parse in strict mode and emit "use strict" for each source file. */
/* Additional Checks */
"noUnusedLocals": true, /* Report errors on unused locals. */
"noUnusedParameters": true, /* Report errors on unused parameters. */
"noImplicitReturns": true, /* Report error when not all code paths in function return a value. */
"noFallthroughCasesInSwitch": true, /* Report errors for fallthrough cases in switch statement. */
/* Module Resolution Options */
// "moduleResolution": "node", /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
// "baseUrl": "./", /* Base directory to resolve non-absolute module names. */
// "paths": {}, /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
// "rootDirs": [], /* List of root folders whose combined content represents the structure of the project at runtime. */
// "typeRoots": [], /* List of folders to include type definitions from. */
// "types": [], /* Type declaration files to be included in compilation. */
// "allowSyntheticDefaultImports": true, /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
"esModuleInterop": true /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
// "preserveSymlinks": true, /* Do not resolve the real path of symlinks. */
/* Source Map Options */
// "sourceRoot": "./", /* Specify the location where debugger should locate TypeScript files instead of source locations. */
// "mapRoot": "./", /* Specify the location where debugger should locate map files instead of generated locations. */
// "inlineSourceMap": true, /* Emit a single file with source maps instead of having a separate file. */
// "inlineSources": true, /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */
/* Experimental Options */
// "experimentalDecorators": true, /* Enables experimental support for ES7 decorators. */
// "emitDecoratorMetadata": true, /* Enables experimental support for emitting type metadata for decorators. */
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment