NOTICE: By continued use of this site you understand and agree to the binding Terms of Service and Privacy Policy.
// ==UserScript== // @name FaceCards // @namespace https://openuserjs.org/scripts/hklene/FaceCards // @description Gesichter lernen mit Karteikarten // @copyright 2018, hklene (https://openuserjs.org/users/hklene) // @license GPL-3.0-or-later; http://www.gnu.org/licenses/gpl-3.0.txt // @version 2020-05-18 // @include https://*/browsepeople.action* // @include https://*/dopeopledirectorysearch.action* // @icon data:image/png;base64,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 // @grant none // ==/UserScript== // ==OpenUserJS== // @author hklene // ==OpenUserJS== // Der Inhalt dieser umschließenden Funktion wird komplett in die Seite injiziert (benötigt keinen Zugriff auf besondere GreaseMonkey-API). function injectContent() { // BEGIN injectContent() function debug(message) { if (false) { alert(message); } } // http://de.selfhtml.org/xml/darstellung/xpathsyntax.htm function viaXpath(path, node, ordered) { return document.evaluate(path, node ? node : document, null, ordered ? XPathResult.ORDERED_NODE_SNAPSHOT_TYPE : XPathResult.UNORDERED_NODE_SNAPSHOT_TYPE, null); } // https://developer.mozilla.org/en-US/docs/Introduction_to_using_XPath_in_JavaScript#First_Node function viaXpath0(path, node, ordered) { return document.evaluate(path, node ? node : document, null, ordered ? XPathResult.FIRST_ORDERED_NODE_TYPE : XPathResult.ANY_UNORDERED_NODE_TYPE, null).singleNodeValue; } // Lightbox nach Denis Potschien: http://www.drweb.de/magazin/css3-lightbox-komplett-ohne-javascript function lightboxStyle() { /* DIV.lightbox { overflow: hidden; position: fixed; width: 0; height: 0; left: 0; top: 0; opacity: 0; background: rgba(127,127,127, 0.95); -moz-transition: opacity 0.5s; -o-transition: opacity 0.5s; -webkit-transition: opacity 0.5s; } DIV.lightbox:target { width: 100%; height: 100%; opacity: 1; z-index: 100; } */} function lightboxContent() { /* <TABLE width="100%" height="100%" border="0" style="padding:10px;"><TR> <TD><A id="auswertung" style="visibility:hidden" href="javascript:auswertung();" title="Auswertung"><H1>A</H1></A></TD> <TD><CENTER id="FaceCardsNumber"></CENTER></TD> <TD><A href="#" title="Schließen"><H1 style="text-align:right;">X</H1></A> </TD></TR><TR><TD colspan=3 align="center" height="100%"> <IMG id="FaceCardsImg" style="height:100%; max-height:512px;"> </TD></TR><TR><TD colspan=3 align="center"> <DIV id="FaceCardsQuestion"> <H1>Wer ist das?</H1> <BUTTON style="width:15%;" onclick="solve();">Lösung</BUTTON> </DIV> <DIV id="FaceCardsResult"><H1 style="font-weight:bold;"></H1><H2></H2><BR> <H2>Bewerte, wie gut Du Dich an dieses Gesicht erinnern konntest:</H2><BR> <BUTTON style="width:15%; background:#F77;" onclick="showRandomEntry(1);">Keine Ahnung</BUTTON> <BUTTON style="width:15%; background:#FB7;" onclick="showRandomEntry(2);">Lange überlegt</BUTTON> <BUTTON style="width:15%; background:#FF7;" onclick="showRandomEntry(3);">Beinahe</BUTTON> <BUTTON style="width:15%; background:#BF7;" onclick="showRandomEntry(6);">Zuversichtlich</BUTTON> <BUTTON style="width:15%; background:#7F7;" onclick="showRandomEntry(9);">Sicher erkannt</BUTTON> </DIV> </TD></TR> </TABLE> */} // https://developer.mozilla.org/en-US/docs/Web/API/Web_Storage_API/Using_the_Web_Storage_API var storage, prefix = "FaceCards_"; try { // detect availability and ensure functionality storage = window.localStorage; storage.setItem(prefix, prefix); storage.removeItem(prefix); } catch(e) { storage = null; } var FaceCardsNumber, FaceCardsImg, FaceCardsQuestion, FaceCardsResult; function solve() { FaceCardsQuestion.style.visibility = "hidden"; FaceCardsQuestion.style.height = "0px"; FaceCardsResult .style.visibility = "visible"; FaceCardsResult .style.height = null; viaXpath0("BUTTON[3]", FaceCardsResult).focus(); } function Entry(src) { this.src = src; this.name = ""; this.email = ""; this.confidence = 0; this.hash = null; this.load = function() { // Falls lokaler Web Speicher verfügbar, versuche alten Lernfortschritt zu lesen if (storage) { this.hash = prefix + MD5_hexhash(src); this.confidence = parseInt(storage.getItem(this.hash)); if (!this.confidence) { this.confidence = 0; } } } this.store = function() { if (storage && this.confidence > 0) { storage.setItem(this.hash, this.confidence); } } this.toString = function() { return this.name + "\n" + this.confidence + "\n" + this.email + "\n" + this.src; } } var entries = null, lesson = null, showing = false, rawCount = 0, enoughForToday = 0, enoughTotal = 0, hotspot = new Array(), hotspotSize = 20, confidenceThreshold = 9, confidenceModulo = 3; // in zufälliger Reihenfolge in Hotspot einfügen function addToHotspot(index) { if (hotspot.length < hotspotSize && hotspot.indexOf(index) < 0) { if (0 == hotspot.length) { hotspot.push(index); } else { var i = (Math.random() * hotspot.length) | 0; hotspot.push(hotspot[i]); hotspot[i] = index; } // debug("inserted i:" + index + " in h:" + hotspot.join()); } } function countSaved(location) { var saved = 0, expected = 0; if (storage) { for(var propertyName in storage) { if (propertyName.substr(0,prefix.length) == prefix) { saved++; } } for (var i = 0; i < entries.length; i++) { if (0 < entries[i].confidence) { expected++; } } if (saved != expected) { debug("Abweichung: " + saved + " != " + expected + "\nin: " + location); } } return saved; } function cleanup() { if (waitOnNavigation) { return; } var before = countSaved("clean before"); // normalisiere auf das Minimum var min = confidenceThreshold; for (var i = 0; i < entries.length; i++) { if (0 == entries[i].confidence) { continue; } min = Math.min(min, entries[i].confidence); if (min < confidenceModulo) { break; } } if (storage) { // Alle Werte aus dem Speicher löschen, auch die, zu denen es keinen Eintrag mehr gibt. for(var propertyName in storage) { if (propertyName.substr(0,prefix.length) == prefix) { storage.removeItem(propertyName); } } } if (confidenceModulo < min) { min--; min = min - min % confidenceModulo; } else { min = 0; } var foundNew = 0; for (var i = 0; i < entries.length; i++) { if (0 == entries[i].confidence) { foundNew++; continue; } if (entries[i].confidence == min){ debug("Killing " + entries[i]); } entries[i].confidence -= min; entries[i].store(); if (entries[i].confidence < confidenceThreshold) { // bevorzuge "alte" unbekannte vor neuen Gesichtern addToHotspot(i); } } if (foundNew && hotspot.length < hotspotSize) { // fülle den Hotspot am Ende mit unbekannten Gesichtern auf // wer schon die meisten kennt, kommt so schneller an die wenigen neuen Kollegen foundNew = hotspot.length; for (var i = 0; i < entries.length; i++) { if (0 == entries[i].confidence) { addToHotspot(i); if (hotspot.length == hotspotSize) { break; } } } debug("Hotspot aufgefüllt mit " + (hotspot.length - foundNew) + " neuen Kollegen!"); } var after = countSaved("clean after"); if (before != after) { debug("Anzahl " + before + " -> " + after); } } function padding(zahl, length) { var string = "" + zahl; if (!length) { length = 2; } while (string.length < length) { // 2 Leerzeichen sind so breit wie eine Ziffer string = " " + string; } return string; } function auswertung() { cleanup(); // Liste alle Werte auf var min = entries[0].confidence, max = min; var w = "Werte: " + entries.length + "\n", map = new Object(); for (var i = 0; i < entries.length; i++) { min = Math.min(min, entries[i].confidence); max = Math.max(max, entries[i].confidence); w += padding(entries[i].confidence ? entries[i].confidence : '_') + (i % 10 == 9 ? ",\n" : ", "); map[entries[i].confidence] = (map[entries[i].confidence] ? map[entries[i].confidence] + 1 : 1); } // Verteilung zwischen min und max var v = "", c = 0, d = 0; for (var k in map) { v += padding(k) + "=" + padding(map[k]) + (++c % 5 == 0 ? ",\n" : ", "); d += map[k]; } v = "\nVerteilung: " + c + " Gruppen " + d + " Werte\n" + v; var h = "\nHotspot: " + hotspot.length + "\n"; for (var i = 0; i < hotspot.length; i++) { h += padding(hotspot[i]) + (i % 10 == 9 ? ",\n" : ", "); } alert("Auswertung\nAngemeldet: " + rawCount + "\nmit Foto: " + entries.length + "\ngespeichert: " + countSaved("auswertung") + "\nmin:" + min + " max:" + max + v.replace(/,\s$/, "\n") + w + h); } function showRandomEntry(lessonLearned) { // summiere den aktuellen Lernfortschritt lesson.confidence += lessonLearned; if (confidenceThreshold < lesson.confidence && lesson.confidence % confidenceModulo != 0) { lesson.confidence = lesson.confidence - lesson.confidence % confidenceModulo; } lesson.store(); // einer der linken beiden Buttons // oder der mittlere Button und Gesamtsicherheit ist noch zu gering // -> versuche es im Hotspot unterzubringen var old = entries.indexOf(lesson); if (0 < lessonLearned) { if (lessonLearned < confidenceModulo || lessonLearned == confidenceModulo && lesson.confidence <= confidenceThreshold) { addToHotspot(old); enoughForToday--; } else { // aus Hotspot entfernen var hi = hotspot.indexOf(old); if (0 <= hi) { hotspot.splice(hi, 1); } enoughForToday++; } enoughTotal++; if (hotspotSize < Math.abs(enoughForToday) || 3 * hotspotSize < enoughTotal) { cleanup(); if (confirm("Genug für heute?")) { window.location.hash = "#"; } else { enoughForToday = enoughTotal = 0; } } } var j, category = '', hr = hotspot.length; if (0 < hr // 20% für letzten Eintrag bis 80% wenn hotspot voll && (hr - 1) / (hotspotSize - 1) * 3 > 5 * Math.random() - 1 && hotspot[hr = hr * Math.random() | 0] != old) { j = hotspot[hr]; lesson = entries[j]; category = 'Hotspot'; } else { // wähle zufällig die nächste Herausforderung, möglichst mit geringerem Lernfortschritt for (var i = 0; ; i++) { j = (Math.random() * entries.length) | 0; var candidate = entries[j]; if (candidate.confidence < lesson.confidence || i == confidenceThreshold) { // wähle geringeren Lernfortschritt oder akzeptiere den letzten Versuch lesson = candidate; category = 0 <= hotspot.indexOf(j) ? 'hotspot' : 'random'; break; } } } FaceCardsNumber.innerHTML = "Punkte: " + lesson.confidence + ", Foto: " + j + " von " + entries.length + ", Auswahl: " + category + " bei " + hotspot.length + " " + enoughForToday + " " + enoughTotal; FaceCardsImg.src = lesson.src; FaceCardsResult.style.visibility = "hidden"; FaceCardsResult.style.height = "0px"; FaceCardsResult.firstChild.innerHTML = lesson.name; viaXpath0("H2", FaceCardsResult).innerHTML = lesson.email ? lesson.email : ""; FaceCardsQuestion.style.visibility = "visible"; FaceCardsQuestion.style.height = null; viaXpath0("BUTTON", FaceCardsQuestion).focus(); showing = true; } function collectData(myBody) { var img = viaXpath("//DIV[@class='profile-macro']", myBody); rawCount += img.snapshotLength; for (var i = 0; i < img.snapshotLength; i++) { var parent = img.snapshotItem(i); var current = viaXpath0(".//A/IMG[@class='userLogo logo']", parent); if (current.src.indexOf('/default.svg') >= 0 || current.src.indexOf('/default.png') >= 0) { continue; } // parent.style.border = "5px solid red"; var entry = new Entry(current.src); entry.load(); current.setAttribute("test", i); current = viaXpath0(".//DIV[@class='values']/H4/A[contains(@class, 'confluence-userlink')]", parent); entry.name = current.firstChild.data; current = viaXpath0(".//DIV[@class='values']/A[@class='email']", parent); if (current && current.firstChild) { entry.email = current.firstChild.data; } entries.push(entry); if (0 < entry.confidence && entry.confidence < confidenceThreshold) { addToHotspot(entries.length - 1); } } // debug("collectData " + img.snapshotLength + " " + entries.length + " " + lesson); } function loadNextPage(link, direction) { // debug("loadNextPage " + link + " " + direction); var childDoc = new XMLHttpRequest(); childDoc.open("GET", link, false); childDoc.send(); childDoc = childDoc.responseText; childDoc = childDoc.substring(childDoc.indexOf("<body"), childDoc.lastIndexOf("</body>")).replace(/^.*>/, ""); // weil eine HTML-Seite und kein XML abgefragt wird, weise den Inhalt einem dummy-Knoten zu var childBody = document.createElement("DIV"); childBody.innerHTML = childDoc; collectData(childBody); navigateRecursive(childBody, direction); } var waitOnNavigation = 0; function navigateRecursive(myBody, direction) { var link = viaXpath0("//OL[@class]/LI[@class='" + direction + "']/A[@href]", myBody); if (!link) { waitOnNavigation--; if (!waitOnNavigation) { document.getElementById("auswertung").removeAttribute("style"); cleanup(); } return; } if (showing || entries.length == 0) { // erstes Foto wird bereits angezeigt oder noch keines gefunden -> suche synchron auf der nächsten Seite loadNextPage(link.href, direction); } else { // es wurde bereits ein Foto gefunden -> breche hier ab um es sofort anzuzeigen und lade die weiteren Seiten erst im Anschluss window.setTimeout("loadNextPage('" + link.href + "', '" + direction + "');", 0); } } function initialize() { // definiere CSS für die Lightbox var lightbox = document.createElement("STYLE"); lightbox.type = "text/css"; lightboxStyle = lightboxStyle.toString(); lightboxStyle = lightboxStyle.substring(lightboxStyle.indexOf("/*") + 2, lightboxStyle.lastIndexOf("*/") - 1); lightbox.innerHTML = lightboxStyle; document.head.appendChild(lightbox); // füge die Lightbox selbst unten an das Dokument an (wird dank CSS später die anderen Inhalte überdecken) lightbox = document.createElement("DIV"); lightbox.id = "FaceCards"; lightbox.setAttribute("class", "lightbox"); lightboxContent = lightboxContent.toString(); lightboxContent = lightboxContent.substring(lightboxContent.indexOf("/*") + 2, lightboxContent.lastIndexOf("*/") - 1); lightbox.innerHTML = lightboxContent; document.body.appendChild(lightbox); // Esc key action $(lightbox).keyup(function(e) { if (e.keyCode == 27) { window.location.hash = "#"; } }); FaceCardsNumber = document.getElementById("FaceCardsNumber"); FaceCardsImg = document.getElementById("FaceCardsImg"); FaceCardsQuestion = document.getElementById("FaceCardsQuestion"); FaceCardsResult = document.getElementById("FaceCardsResult"); // durchsuche die Original-Seite nach Fotos und sammle die Informationen collectData(document.body); waitOnNavigation = 2; navigateRecursive(document.body, "aui-nav-previous"); navigateRecursive(document.body, "aui-nav-next"); } function show() { enoughForToday = enoughTotal = 0; // faule Initialisierung der Lightbox if (!entries) { entries = new Array(); initialize(); } if (entries.length == 0) { alert("Es wurden keine Fotos auf dieser Seite gefunden! " + rawCount); return; } // rufe die Lightbox auf window.location.hash = "#FaceCards"; lesson = entries[0]; showRandomEntry(0); } // Füge einen Link zum Aufruf der Initialisierung hinzu var nav = viaXpath0("//DIV[@class='aui-navgroup-inner']/UL[@class='aui-nav']"); var link = document.createElement("li"); link.innerHTML = "<A href='javascript:show();' title='Zeige Karteikarten der Fotos'>Namen lernen</A>"; nav.appendChild(link); // TODO Debug: rufe die Lightbox sofort auf und warte nicht auf den Klick // initialize(); // show(); // END injectContent() } // -------------------------------------------------------------------------------------------------------------------- // Message Digest MD5 - Hash Funktion zur Verschlüsselung personenbezogener Daten vor der Speicherung lokal im Browser // http://www.onicos.com/staff/iz/amuse/javascript/expert/md5.txt function injectMD5() { // BEGIN injectMD5() /* md5.js - MD5 Message-Digest * Copyright (C) 1999,2002 Masanao Izumo <iz@onicos.co.jp> * Version: 2.0.0 * LastModified: May 13 2002 * * This program is free software. You can redistribute it and/or modify * it without any warranty. This library calculates the MD5 based on RFC1321. * See RFC1321 for more information and algorism. */ /* Interface: * md5_128bits = MD5_hash(data); * md5_hexstr = MD5_hexhash(data); */ /* ChangeLog * 2002/05/13: Version 2.0.0 released * NOTICE: API is changed. * 2002/04/15: Bug fix about MD5 length. */ // md5_T[i] = parseInt(Math.abs(Math.sin(i)) * 4294967296.0); var MD5_T = new Array(0x00000000, 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee, 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501, 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be, 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821, 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa, 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8, 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed, 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a, 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c, 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70, 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05, 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665, 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039, 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1, 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1, 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391); var MD5_round1 = new Array(new Array( 0, 7, 1), new Array( 1,12, 2), new Array( 2,17, 3), new Array( 3,22, 4), new Array( 4, 7, 5), new Array( 5,12, 6), new Array( 6,17, 7), new Array( 7,22, 8), new Array( 8, 7, 9), new Array( 9,12,10), new Array(10,17,11), new Array(11,22,12), new Array(12, 7,13), new Array(13,12,14), new Array(14,17,15), new Array(15,22,16)); var MD5_round2 = new Array(new Array( 1, 5,17), new Array( 6, 9,18), new Array(11,14,19), new Array( 0,20,20), new Array( 5, 5,21), new Array(10, 9,22), new Array(15,14,23), new Array( 4,20,24), new Array( 9, 5,25), new Array(14, 9,26), new Array( 3,14,27), new Array( 8,20,28), new Array(13, 5,29), new Array( 2, 9,30), new Array( 7,14,31), new Array(12,20,32)); var MD5_round3 = new Array(new Array( 5, 4,33), new Array( 8,11,34), new Array(11,16,35), new Array(14,23,36), new Array( 1, 4,37), new Array( 4,11,38), new Array( 7,16,39), new Array(10,23,40), new Array(13, 4,41), new Array( 0,11,42), new Array( 3,16,43), new Array( 6,23,44), new Array( 9, 4,45), new Array(12,11,46), new Array(15,16,47), new Array( 2,23,48)); var MD5_round4 = new Array(new Array( 0, 6,49), new Array( 7,10,50), new Array(14,15,51), new Array( 5,21,52), new Array(12, 6,53), new Array( 3,10,54), new Array(10,15,55), new Array( 1,21,56), new Array( 8, 6,57), new Array(15,10,58), new Array( 6,15,59), new Array(13,21,60), new Array( 4, 6,61), new Array(11,10,62), new Array( 2,15,63), new Array( 9,21,64)); function MD5_F(x, y, z) { return (x & y) | (~x & z); } function MD5_G(x, y, z) { return (x & z) | (y & ~z); } function MD5_H(x, y, z) { return x ^ y ^ z; } function MD5_I(x, y, z) { return y ^ (x | ~z); } var MD5_round = new Array(new Array(MD5_F, MD5_round1), new Array(MD5_G, MD5_round2), new Array(MD5_H, MD5_round3), new Array(MD5_I, MD5_round4)); function MD5_pack(n32) { return String.fromCharCode(n32 & 0xff) + String.fromCharCode((n32 >>> 8) & 0xff) + String.fromCharCode((n32 >>> 16) & 0xff) + String.fromCharCode((n32 >>> 24) & 0xff); } function MD5_unpack(s4) { return s4.charCodeAt(0) | (s4.charCodeAt(1) << 8) | (s4.charCodeAt(2) << 16) | (s4.charCodeAt(3) << 24); } function MD5_number(n) { while (n < 0) n += 4294967296; while (n > 4294967295) n -= 4294967296; return n; } function MD5_apply_round(x, s, f, abcd, r) { var a, b, c, d; var kk, ss, ii; var t, u; a = abcd[0]; b = abcd[1]; c = abcd[2]; d = abcd[3]; kk = r[0]; ss = r[1]; ii = r[2]; u = f(s[b], s[c], s[d]); t = s[a] + u + x[kk] + MD5_T[ii]; t = MD5_number(t); t = ((t<<ss) | (t>>>(32-ss))); t += s[b]; s[a] = MD5_number(t); } function MD5_hash(data) { var abcd, x, state, s; var len, index, padLen, f, r; var i, j, k; var tmp; state = new Array(0x67452301, 0xefcdab89, 0x98badcfe, 0x10325476); len = data.length; index = len & 0x3f; padLen = (index < 56) ? (56 - index) : (120 - index); if(padLen > 0) { data += "\x80"; for(i = 0; i < padLen - 1; i++) data += "\x00"; } data += MD5_pack(len * 8); data += MD5_pack(0); len += padLen + 8; abcd = new Array(0, 1, 2, 3); x = new Array(16); s = new Array(4); for(k = 0; k < len; k += 64) { for(i = 0, j = k; i < 16; i++, j += 4) { x[i] = data.charCodeAt(j) | (data.charCodeAt(j + 1) << 8) | (data.charCodeAt(j + 2) << 16) | (data.charCodeAt(j + 3) << 24); } for(i = 0; i < 4; i++) s[i] = state[i]; for(i = 0; i < 4; i++) { f = MD5_round[i][0]; r = MD5_round[i][1]; for(j = 0; j < 16; j++) { MD5_apply_round(x, s, f, abcd, r[j]); tmp = abcd[0]; abcd[0] = abcd[3]; abcd[3] = abcd[2]; abcd[2] = abcd[1]; abcd[1] = tmp; } } for(i = 0; i < 4; i++) { state[i] += s[i]; state[i] = MD5_number(state[i]); } } return MD5_pack(state[0]) + MD5_pack(state[1]) + MD5_pack(state[2]) + MD5_pack(state[3]); } function MD5_hexhash(data) { var i, out, c; var bit128; bit128 = MD5_hash(data); out = ""; for(i = 0; i < 16; i++) { c = bit128.charCodeAt(i); out += "0123456789abcdef".charAt((c>>4) & 0xf); out += "0123456789abcdef".charAt(c & 0xf); } return out; } // END injectMD5() } // -------------------------------------------------------------------------------------------------------------------- // Wandle die Funktion in eine Zeichenkette und hänge sie an den Dokumenten-Kopf injectMD5 = injectMD5.toString(); injectMD5 = injectMD5.substring(injectMD5.indexOf("{") + 1, injectMD5.lastIndexOf("}") - 1); injectContent = injectContent.toString(); injectContent = injectContent.substring(injectContent.indexOf("{") + 1, injectContent.lastIndexOf("}") - 1); var inPageScript = document.createElement("SCRIPT"); inPageScript.type = "text/javascript"; inPageScript.innerHTML = injectMD5 + "\n" + injectContent; document.head.appendChild(inPageScript);