User:V111P/js/webRefSetup.js
Appearance
< User:V111P | js
Code that you insert on this page could contain malicious content capable of compromising your account. If you import a script from another page with "importScript", "mw.loader.load", "iusc", or "lusc", take note that this causes you to dynamically load a remote script, which could be changed by others. Editors are responsible for all edits and actions they perform, including by scripts. User scripts are not centrally supported and may malfunction or become inoperable due to software changes. A guide to help you find broken scripts is available. If you are unsure whether code you are adding to this page is safe, you can ask at the appropriate village pump. This code will be executed when previewing this page. |
Documentation for this user script can be added at User:V111P/js/webRefSetup. |
// This script is used in combination with the WebRef script, which is not yet uploaded for use for the English Wikipedia.
// v. 2013-04-23 / 0.01.2
if (!window.webRef || !window.webRef.getRef) alert('WebRef Setup error: Please, load WebRef first!');
else webRef.webRefSetup = (function () {
'use strict';
function prt(txt) {
if (window.console && console.log)
console.log(txt);
}
window.webRef.webRefSetupVer = 1;
// Shortcuts
var refDocData = window.webRef.refDocData;
var domain = window.webRef.domain;
var dom = window.webRef.dom;
var newEl = dom.newEl;
var aux = window.webRef.aux;
var idToText = webRef.idToText;
var maxStrLengthInOption = 100;
var showCharsFromEnd = 20;
var frameBodyStyleObj = {
margin: '0 auto',
color: '#ffffff', backgroundColor: '#000077',
border: '5px solid gray', borderWidth: '5px 0',
padding: '1px', font: 'normal normal normal medium serif',
textAlign: 'left'
};
var refFrame = {
frame: null,
win: null,
doc: null,
body: null
};
// a collection of references to the form controls
var ctrls = {}; // site, title, date, author, publisher, visited, url, code, etc.
refDocData.searchSection = {
things: ['title', 'date', 'author'],
fieldIdEndings: ['Search'], //['SeparatorBefore', 'Search', 'SeparatorAfter']
fieldSizes: [70] //[5, 70, 5]
};
refDocData.aboutSiteFields = [
'siteName',
'lang',
'publisher',
'authorName',
'authorWikiArticle',
'notAnAuthor'
];
refDocData.buttonSectionButtons = [
{id: 'toCode', onclick: toCode},
{id: 'saveToStorage', onclick: saveToStorage},
{id: 'loadFromVar', onclick: loadFromVar},
{id: 'loadFromStorage', onclick: loadFromStorage},
{id: 'deleteFromStorage', onclick: deleteFromStorage},
{id: 'resetForm', onclick: resetForm},
{id: 'useOnceFromTA', onclick: useOnceFromTA},
{id: 'closeSetup', onclick: closeSetup}
];
function loadFromStorage() {
var code = localStorage && localStorage.getItem('webRef-1') || '';
ctrls.code.value = (code && '"' + domain + '": ' + code) || '';
}
function deleteFromStorage() {
if (localStorage && localStorage.getItem('webRef-1') && confirm(idToText['delStorageConfirm']))
localStorage.removeItem('webRef-1');
}
function saveToStorage() {
var code, obj;
if (!window.localStorage || !window.JSON)
alert(idToText['noStorage']);
else {
code = ctrls.code.value.replace(/^[^{]*/, '');
try { obj = JSON.parse(code); }
catch (e) {
alert(idToText['invalidCode']);
return;
}
if ( !localStorage.getItem('webRef-1') || confirm(idToText['overwriteStorageConfirm']) )
localStorage.setItem('webRef-1', JSON.stringify(obj, null, '\t'));
}
}
function useOnceFromTA() {
var code, obj;
code = ctrls.code.value.replace(/^[^{]*/, '');
try { obj = JSON.parse(code); }
catch (e) {
alert(idToText['invalidCode']);
return;
}
if (!window.webRefSiteData)
window.webRefSiteData = {};
webRefSiteData[domain] = obj;
closeSetup();
webRef.getRef();
}
function closeSetup() {
dom.byId('ref01ref').style.display = 'none';
dom.byId('ref01refDiv').style.display = 'none';
webRef.displayWebRefFrame(true);
document.body.scrollTop = document.documentElement.scrollTop = 0;
}
function resetForm() {
if (confirm(idToText['resetFormConfirm']))
autoFillInfo();
}
aux.shorten = function (longStr) { // shorten a string for display
var str = longStr;
if (str.length > maxStrLengthInOption)
str = str.substr(0, maxStrLengthInOption - 5 - showCharsFromEnd)
+ ' ... ' + str.substr(str.length - showCharsFromEnd, showCharsFromEnd);
return str;
};
function autoFillInfo() {
// Auto fill fields in the Search Results section
var i, str, o, autoIn, things = refDocData.searchSection.things;
for (o in things) {
if (!things.hasOwnProperty(o))
continue;
autoIn = refDocData.things[things[o]] && refDocData.things[things[o]].autoSearchIn;
if (!autoIn)
continue;
var selEl = ctrls[things[o] + 'Results'];
selEl.innerHTML = '';
var n = 0;
for (i = 0; i < autoIn.length; i++) {
str = window.webRef.textFromAddr(autoIn[i], false);
if (str) {
var txt = aux.shorten(autoIn[i]) + ' (' + aux.shorten(str) + ')';
if (n == 0)
selEl.appendChild(newEl('option', {
value: '',
text: idToText['default'] + ': ' + txt
}));
n++;
selEl.appendChild(newEl('option', {
value: autoIn[i],
text: txt
}));
}
}
}
// Auto fill fields in the About the Site section
var searchInArr, thing, formatter;
var abtFields = refDocData.aboutSiteFields;
var things = refDocData.things;
for (var i = 0; i < abtFields.length; i++) {
thing = abtFields[i];
searchInArr = (things[thing] && things[thing].autoSearchIn) || [];
for (var j = 0; j < searchInArr.length; j++) {
str = window.webRef.metaContent[searchInArr[j]];
if (str) {
formatter = things[thing].formatter;
if (formatter)
str = formatter(str);
dom.byId(thing + 'DefaultSpan', refFrame.doc)
.innerHTML = idToText['default'] + ': ' + str;
break;
}
}
}
} // autoFillInfo
function createUI() {
if (!document.body || !document.body.firstChild) {
aux.fatalError('Web page is empty!');
}
var i, id, docFrag = document.createDocumentFragment();
var subDiv;
function br() {
docFrag.appendChild(newEl('br'));
}
docFrag.appendChild(newEl('strong', {text: idToText['searchSectionH']})); br();
dom.text(idToText['searchSectionIntro'], docFrag); br(); br();
var searchThings = refDocData.searchSection.things;
var fieldIdEndings = refDocData.searchSection.fieldIdEndings;
var fieldSizes = refDocData.searchSection.fieldSizes;
for (i = 0; i < searchThings.length; i++) {
dom.text(idToText[searchThings[i] + 'Results'], docFrag);
br(docFrag);
for (var j = 0; j < fieldIdEndings.length; j++) { //'
id = searchThings[i] + fieldIdEndings[j];
ctrls[id] = newEl('input', {
id: id,
size: fieldSizes[j],
css: {backgroundColor: (fieldSizes[j] == 5 ? 'gray' : 'white')}
});
docFrag.appendChild(ctrls[id]);
}
br();
}
var goButton = newEl('input', {
type: 'button',
value: idToText['searchButton'],
onclick: findContainingEls // doesn't work
});
goButton.onclick = findContainingEls;
docFrag.appendChild(goButton);
br(); br();
docFrag.appendChild(newEl('strong', {text: idToText['resultsH']})); br();
dom.text(idToText['resultsSectionIntro'], docFrag); br(); br();
for (i = 0; i < searchThings.length; i++) {
id = searchThings[i] + 'Results';
dom.text(idToText[id], docFrag); br();
ctrls[id] = newEl('select', {id: id});
docFrag.appendChild(ctrls[id]);
br();
}
br();
docFrag.appendChild(newEl('strong', {text: idToText['aboutSiteH']})); br();
dom.text(idToText['aboutSiteSectionIntro'], docFrag); br(); br();
for (var i = 0, fieldId; i < refDocData.aboutSiteFields.length; i++) {
fieldId = refDocData.aboutSiteFields[i];
dom.text(idToText[fieldId + '_L'], docFrag); br();
ctrls[fieldId] = newEl('input', {id: fieldId});
docFrag.appendChild(ctrls[fieldId]);
dom.text(' ', docFrag);
docFrag.appendChild(newEl('span', {
id: fieldId + 'DefaultSpan',
css: {color: '#bbbbbb'}
}));
br();
}
br();
dom.text(idToText['buttonsIntro'], docFrag); br();
for (var i = 0, buttonData, button; i < refDocData.buttonSectionButtons.length; i++) {
buttonData = refDocData.buttonSectionButtons[i];
button = newEl('input', {
type: 'button',
value: idToText[buttonData.id],
onclick: buttonData.onclick //' doesn't work
});
button.onclick = buttonData.onclick;
docFrag.appendChild(button);
}
br(); br();
docFrag.appendChild(newEl('strong', {text: idToText['codeTaH']}));
br();
ctrls.code = newEl('textarea', {
id: 'codeTA',
cols: 100,
rows: 8
});
docFrag.appendChild(ctrls.code);
refFrame.frame = dom.byId('ref00ref');
if (refFrame.frame)
refFrame.frame.style.display = 'none';
refFrame.frame = newEl('iframe', {
id: 'ref01ref',
resizable: 'resizable',
css: {width: '100%', position: 'absolute', zIndex: '2147483647', top: 0, left: 0}
});
document.body.insertBefore(refFrame.frame, document.body.firstChild);
refFrame.win = (refFrame.frame.contentWindow
|| refFrame.frame.contentDocument);
refFrame.doc = refFrame.win.document;
refFrame.doc.open();
refFrame.doc.write('<!DOCTYPE html>\n<html>\n<head>\n<title>Ref</title>\n</head>'
+ '<body>\n</body>\n</html>');
refFrame.doc.close();
refFrame.body = refFrame.doc.body;
dom.setStyle(refFrame.body, frameBodyStyleObj);
refFrame.body.appendChild(docFrag);
var frameHeight = getDocHeight(refFrame.body, refFrame.doc) + 'px';
refFrame.frame.style.height = frameHeight;
subDiv = dom.newEl('div', {
id: 'ref01refDiv',
css: {height: frameHeight}
});
document.body.insertBefore(subDiv, document.body.firstChild);
function getDocHeight(b,D) {
return Math.max(
Math.max(b.scrollHeight, D.documentElement.scrollHeight),
Math.max(b.offsetHeight, D.documentElement.offsetHeight)//,
//Math.max(b.clientHeight, D.documentElement.clientHeight)
);
}
} // createUI
function findContainingEls() { // getElAddr
var i, o;
var all = dom.byTagName("*");
var patternsToSearchFor = {};
var things = refDocData.searchSection.things;
var idEndings = refDocData.searchSection.fieldIdEndings;
for (i = 0; i < things.length; i++) {
var pattern = '';
for (var j = 0; j < idEndings.length; j++) {
var id = things[i] + idEndings[j];
if (!refFrame.doc.getElementById(id)) {
aux.fatalError("findContainingEls: No element with id " + id);
}
var val = aux.trimStr(refFrame.doc.getElementById(id).value);
if (val) {
val = val
.replace(/[-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') // escape
.replace(/\s+/g, '\\s+');
pattern += val + '\\s*';
}
}
if (pattern) {
pattern = pattern.slice(0, -3); // removing the final \s*
patternsToSearchFor[things[i]] = pattern;
}
}
var matchedEls = {};
for (o in patternsToSearchFor) {
if (!patternsToSearchFor.hasOwnProperty(o))
continue;
matchedEls[o] = [];
}
// loop through all elements in the document and add to matchedEls[o]
// all elements within which the text string patternsToSearchFor[o] is found,
// but only if it's not also found in a child node of the element
// ("o" is one of 'title', 'date' and 'authors').
for (i = 0; i < all.length; i++) {
var el = all[i];
var str = dom.getText(el);
var tagName = el.tagName.toLowerCase();
// replace el's parent node with el in the list of elements (matchedEls[o])
// containing the string str.
for (o in patternsToSearchFor) {
if (!patternsToSearchFor.hasOwnProperty(o))
continue;
if (str && str.search(patternsToSearchFor[o]) > -1) {
if (el.parentNode) {
var n = -1; // matchedEls[o].indexOf(el.parentNode);
for (var ii = 0; ii < matchedEls[o].length; ii++) {
if (matchedEls[o][ii] == el.parentNode) {
n = ii;
break;
}
}
if (n > -1)
matchedEls[o].splice(n, 1); // remove parent if child has the string
}
if (tagName != 'script' && tagName != 'style' && el != 'refFrame')
matchedEls[o].push(el);
}
}
}
var rules = {};
var content;
// Add meta info: title, author/authors, date, og:title, og:site_name,
var metaC = window.webRef.metaContent;
for (o in patternsToSearchFor) {
if (!patternsToSearchFor.hasOwnProperty(o))
continue;
for (var address in metaC) {
if (!metaC.hasOwnProperty(address))
continue;
content = metaC[address];
if (content.search(patternsToSearchFor[o]) > -1) {
rules[o] = rules[o] || [];
rules[o].push({
addr: address,
textContent: content
});
}
}
}
// from the element references of the elements found above,
// find their text "addresses" (similar to CSS selectors)
for (o in matchedEls) {
if (matchedEls[o].length == 0)
continue;
rules[o] = rules[o] || [];
for (var i = 0, k = rules[o].length, el, address; i < matchedEls[o].length; i++) {
el = matchedEls[o][i];
address = getElAddr(el, 50); // second arg is maximum element depth
if (address)
rules[o][k+i] = {
addr: address,
textContent: dom.getText(el)
};
}
}
// add results to the drop-down menus in the Results section
for (o in rules) {
var ctrl = ctrls[o + 'Results'];
ctrl.innerHTML = ''; // remove all option's from the drop down menu
for (var i = 0, rule, option; i < rules[o].length; i++) {
rule = rules[o][i];
option = newEl('option', {
value: rule.addr,
text: aux.shorten(rule.addr) + ' (' + aux.shorten(rule.textContent) + ')'
});
ctrl.appendChild(option);
}
}
} // findContainingEls()
// returns null if maxRecursion is reached and in the case of other errors
function getElAddr(el, maxRecursion) {
if (el.id)
return '#' + el.id;
//window.docSelAll = document.querySelectorAll || docSelAll; document.querySelectorAll=null;
var compact = true;//false;
// example from novatv.bg :
// compact : span.medium.black
// not comp: #main_column div div div.news_sidebar.right div span
// compact ,querySelectorAll=null; = #main_column div div 4div div
// not comp,querySelectorAll=null; = #main_column div div 4div div span
// bbc compact = span.date
// bbc-noncomp = #main-content div.layout-block-a div span span
var parent = el.parentNode;
if (maxRecursion < 0) {
prt('WebRef debug info: Element is too deep in document structure? (error code: getElAddr(): '
+ 'maxRecursion)');
return null;
}
maxRecursion--;
var tagName = el.tagName.toLowerCase();
var classes = aux.collapseWhitespace(el.getAttribute('class') || '').replace(/ /g, '.');
var nodePlusClasses = tagName + (classes ? '.' + classes : '');
if (parent == document.body || parent == document)
return numInParent(el) + tagName;
if (compact) {
if (el == dom.byTagName('title')[0])
return 'title';
// if only one h1 tag in document, accept this as a unique id
if (tagName == 'h1' && dom.byTagName('h1').length == 1)
return 'h1';
// if in the whole document there is only one element of this type with these classes,
// accept that as a unique id for this tag
// only for browsers supporting document.querySelectorAll (IE8+)
if (document.querySelectorAll) {
var selEls;
try {
selEls = document.querySelectorAll(nodePlusClasses);
} catch (e) {
aux.error('getElAddr(): invalid selector: ' + nodePlusClasses);
return null;
}
if (classes && selEls.length == 1)
return nodePlusClasses;
}
}
var thisElAddr = ''; // do not record this tag if parent has the same text content
if (!compact || dom.getText(parent) != dom.getText(el)) {
var n = numInParent(el);
if (n && classes // use classes only if there are siblings w/ same tag name
&& document.querySelectorAll // and no siblings w/ same tag name & same classes
&& parent.querySelectorAll(nodePlusClasses).length == 1
)
thisElAddr = nodePlusClasses;
else
thisElAddr = n + tagName; // n is '' for 0
}
return getElAddr(parent) + (thisElAddr ? ' ' + thisElAddr : '');
} // getElAddr()
function numInParent(el) {
var tagName = el.tagName.toLowerCase();
if (!el.parentNode)
aux.fatalError('NO PARENT! ' + tagName);
var elsOfThisType = el.parentNode.getElementsByTagName(tagName);
var foundNum = -1;
for (var i = 0; i < elsOfThisType.length; i++) {
if (elsOfThisType[i] == el) {
foundNum = i;
break;
}
}
if (foundNum == -1)
aux.fatalError('CHILD NOT FOUND IN PARENT!'
+ tagName + ' Total children of this type found = ' + i
);
return (foundNum ? foundNum : '');
} // numInParent()
function toCode() {
var str = '"' + domain + '": {\n';
var arr = refDocData.searchSection.things;
for (var i = 0, val, name; i < arr.length; i++) {
name = arr[i];
val = ctrls[name + 'Results'].value;
if (val)
str += '\t"' + name + '": "' + val + '",\n';
}
arr = refDocData.aboutSiteFields;
for (var i = 0, val, name; i < arr.length; i++) {
name = arr[i];
val = ctrls[name].value;
if (val)
str += '\t"' + name + '": "' + val + '",\n';
}
if (str.charAt(str.length - 2) == ',')
str = str.slice(0, -2); // remove last comma
str += "\n}";
ctrls.code.value = str;
} // toCode
// shows in the textarea the currently used settings for this site
// (by reading the variable siteRefs[domain] or reading from local storage)
function loadFromVar() {
var str = '';
if (!window.webRefSiteData || !webRefSiteData[domain]) {
loadFromStorage();
return;
}
str = '"' + domain + '": {\n';
for (var thing in refDocData.things)
if (typeof webRefSiteData[domain][thing] != 'undefined')
str += '\t"' + thing + '": "' + webRefSiteData[domain][thing] + '",\n';
str = str.slice(0, -2) + '\n}';
ctrls.code.value = str;
}
return function () {
var setupFrame = dom.byId('ref01ref');
webRef.displayWebRefFrame(false);
if (setupFrame) {
setupFrame.style.display = 'block';
dom.byId('ref01refDiv').style.display = 'block';
}
else {
createUI();
autoFillInfo();
}
};
})();
if (window.webRef && webRef.webRefSetupStartOnLoad) {
webRef.webRefSetupStartOnLoad = false;
webRef.webRefSetup();
}