User:V111P/js/webRefSetup.js

// 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();
}

Content Disclaimer

Informasi ini disarikan dari Wikipedia dan disajikan kembali untuk tujuan edukasi. Konten tersedia di bawah lisensi CC BY-SA 3.0. Kami tidak bertanggung jawab atas ketidakakuratan data yang bersumber dari kontribusi publik tersebut.

  1. The information displayed on this website is sourced in part or in whole from Wikipedia and has been adapted for the purpose of restating it. We strive to provide accurate and relevant information, however:
  2. There is no guarantee of absolute accuracy. Wikipedia is an open, collaborative project that can be edited by anyone, so information is subject to change.
  3. It is not intended to constitute professional advice. The content displayed is for informational and educational purposes only. For important decisions (e.g., medical, legal, or financial), please consult a professional.
  4. Content copyright. Wikipedia is licensed under the Creative Commons Attribution-ShareAlike License (CC BY-SA). This means that content may be reused with appropriate attribution and shared under a similar license.
  5. Responsible use. Any risk arising from the use of information from this website is entirely the responsibility of the user.