//(c) Твоя Библия www.bible.com.ua (идея некоторой реализации частично Бегун) // // При использовании в любом виде обязательно размещение "кнопки" сайта: // // // // var DYNLINK; /////////////////////// ПАРСЕР function DYNLINK( container ) { this.container = container; this.fragments = new Array(); this.banners = new Array(); this.phrases = new Array(); this.foundWords = new Array(); this.viewType = 1; this.words = new Array(); this.VerseDivider = ":"; this.parameters = { 'phraseLimit' : 3, 'showTimeout' : 100, 'hideTimeout' : 500, 'openNewWin' : false, 'bannersURL' : 'http://www.bible.com.ua/exp/result.js' } //стили баннеров и ссылок this.design = { 'banner' : { 'width' : 350, 'bgColor' : '#D5ECFC', 'headColor' : '#7698AF', 'linkColor' : '#016AB4', 'textColor' : '#000000', 'domainColor' : '#7698AF' }, 'phrase' : { 'style' : { 'fontWeight' : 'normal', 'color' : '#0000FF', 'textDecoration' : 'none', 'borderBottomWidth' : '1px', 'borderBottomStyle' : 'solid', 'borderBottomColor' : '#0000FF', 'cursor' : 'pointer' } } } //добавление баннера this.addBanner = function(title, text, url, domain, word) { var banner = new DYNLINK_Banner(title, text, url, domain, word); banner.id = this.banners.length; this.banners[banner.id] = banner; } //добавление баннера this.addWords = function(words) { for(var i=0;i"); } //в этот нод можно вставлять ссылку? this.isLegalNode = function( node ) { var regexp = new RegExp( '^(a|h1|h2|h3|h4|h5|h6|big)$', 'i' ); if ( node.tagName && node.tagName.search( regexp ) != -1 ) { return false; } return true; } //парсим this.findPhrases = function findPhrases( parent, offset ) { if ( parent.hasChildNodes() ) { for ( var i = 0; i < parent.childNodes.length; i++ ) { if ( parent.childNodes[ i ].nodeType == 3 ) { var fragment = new DYNLINK_Fragment( parent.childNodes[ i ], offset ); this.fragments[ this.fragments.length ] = fragment; for ( var j in this.banners ) { this.banners[ j ].regexp.lastIndex = 0; while ( ( phrase = this.banners[ j ].findPhrases( fragment ) ) != false ) { this.phrases[ this.phrases.length ] = phrase; } } offset = offset + fragment.text.length; } else { if ( this.isLegalNode( parent.childNodes[ i ] ) ) { offset = this.findPhrases( parent.childNodes[ i ], offset ); } } } } return offset; } //ищем слова, генерируем баннеры this.findWords = function findWords( parent, offset ) { if ( parent.hasChildNodes() ) { for ( var i = 0; i < parent.childNodes.length; i++ ) { if ( parent.childNodes[ i ].nodeType == 3 ) { var fragment = new DYNLINK_Fragment( parent.childNodes[ i ], offset ); for ( var j in this.words ) { var regexpPattern = "(("+this.words[j]+")(\\?| |.|. |.\\r\\n|\\r\\n)([0-9]{1,5})"+this.VerseDivider+"([0-9]{1,10})(\\?|\\-[0-9]{1,3}|,[0-9]{1,3}|,[0-9]{1,3}|\\b)|("+this.words[j]+")(\\?| |.|. |.\\r\\n|\\r\\n)([0-9]{1,6}))"; var regexp = new RegExp( regexpPattern, 'ig' ); regexp.lastIndex = 0; while ( ( phrase = this.findWord( fragment , regexp) ) != false ) { var head = (RegExp.$9==""?RegExp.$4:RegExp.$9); var verse = RegExp.$5; var key = ""+j+":"+(head==""?"1":head)+":"+(verse==""?"1":verse); this.foundWords[this.foundWords.length] = key; this.addBanner("", "", "", "", phrase.getText()); } } offset = offset + fragment.text.length; } else { if ( this.isLegalNode( parent.childNodes[ i ] ) ) { offset = this.findWords( parent.childNodes[ i ], offset ); } } } } return offset; } this.findWord = function( fragment , regexp) { var result = regexp.exec( fragment.text ); if ( result != null ) { //regexp.lastIndex -= result[ result.length - 1 ].length; return new DYNLINK_Phrase( this, fragment, result.index, RegExp.$1.length, RegExp.$3, RegExp.$4 ); } return false; } //вставка линков в текст this.highlight = function() { for ( var i in this.phrases ) { var phrase = this.phrases[ i ]; var phrases = phrase.fragment.phrases; phrases[ phrases.length ] = phrase; } for ( var i in this.fragments ) { var index = 0; var nodes = new Array(); var fragment = this.fragments[ i ]; var text = fragment.node.nodeValue; var parent = fragment.node.parentNode; for ( var j in fragment.phrases ) { var phrase = fragment.phrases[ j ]; var textNode = document.createTextNode( text.substr( index, phrase.index - index ) ); nodes[ nodes.length ] = textNode; nodes[ nodes.length ] = this.createHTMLPhrase( phrase ); index = phrase.index + phrase.length; } if ( text.length > index ) { nodes[ nodes.length ] = document.createTextNode( text.substr( index ) ); } var prevNode = fragment.node; while ( nodes.length > 0 ) { prevNode = parent.insertBefore( nodes.pop(), prevNode ); } parent.removeChild( fragment.node ); } } //создание ссылки this.createHTMLPhrase = function( phrase ) { var result = document.createElement( 'A' ); result.target = '_blank'; result.appendChild( document.createTextNode( phrase.getText() ) ); result.href = phrase.banner.url; for ( var property in this.design.phrase.style ) { result.style[ property ] = this.design.phrase.style[ property ]; } phrase.element = new HTMLNodeWrapper( result ); return phrase.element.node; } //создание HTML баннера this.createHTMLBanner = function( banner ) { var DYNLINK_header = ''; DYNLINK_header += ''; DYNLINK_header += ' '; DYNLINK_header += ' '; DYNLINK_header += ' '; DYNLINK_header += ' '; DYNLINK_header += ' '; DYNLINK_header += '
bible.com.uaТвоя Библия
'; var DYNLINK_content = ''; DYNLINK_content += ''; DYNLINK_content += ' '; DYNLINK_content += ' '; DYNLINK_content += ' '; DYNLINK_content += ' '; DYNLINK_content += '
'; DYNLINK_content += ' '; DYNLINK_content += '
' + banner.text + '
'; DYNLINK_content += '
' + banner.domain + '
'; DYNLINK_content += '
'; var result = document.createElement( 'DIV' ); result.style.backgroundColor = this.design.banner.bgColor; result.style.position = 'absolute'; result.style.border = 'solid 1px #000000'; result.style.visibility = 'hidden'; result.style.width = parseInt( this.design.banner.width ) + 'px'; result.style.top = '0px'; result.style.left = '0px'; result.style.padding = '5px'; result.style.zIndex = 99999; result.className = 'DYNLINK'; result.innerHTML = DYNLINK_header + DYNLINK_content; banner.element = new HTMLNodeWrapper( result ); return result; } //стили this.css = function() { var result = ''; result += ''; return result; } //обработчики событий .... this.bannerClick = function(elem) { var a = elem.getElementsByTagName( 'A' )[ 0 ]; if ( a.target == '_blank' ) { window.open().location.href = a.href; } else { window.location.href = a.href; } } this.Event_PhraseOnMouseOver = function( phraseIndex ) { var phrase = DYNLINK.phrases[ phraseIndex ]; phrase.element.node.style.borderBottomWidth = '2px'; if ( DYNLINK.hideTimer ) { clearTimeout( DYNLINK.hideTimer ); DYNLINK.hideTimer = false; } DYNLINK.hideAllBanners(); DYNLINK.showTimer = setTimeout( 'DYNLINK.showBanner( ' + phraseIndex + ' )', DYNLINK.parameters.showTimeout ); } this.Event_PhraseOnMouseOut = function( phraseIndex ) { var phrase = DYNLINK.phrases[ phraseIndex ]; var banner = phrase.banner; phrase.element.node.style.borderBottomWidth = '1px'; DYNLINK.hideTimer = setTimeout( 'DYNLINK.hideBanner( ' + banner.id + ' )', DYNLINK.parameters.hideTimeout ); } this.Event_BannerOnMouseOver = function() { if ( DYNLINK.hideTimer ) { clearTimeout( DYNLINK.hideTimer ); DYNLINK.hideTimer = false; } } this.Event_BannerOnMouseOut = function( bannerIndex ) { DYNLINK.hideTimer = setTimeout( 'DYNLINK.hideBanner( ' + bannerIndex + ' )', DYNLINK.parameters.hideTimeout ); } this.showBanner = function( phraseIndex ) { var left, top; var phrase = DYNLINK.phrases[ phraseIndex ]; var banner = phrase.banner; var winW = phrase.element.windowWidth(); var winH = phrase.element.windowHeight(); var winS = phrase.element.windowScrollTop(); var phraseX = phrase.element.left(); var phraseY = phrase.element.top(); var phraseW = phrase.element.width(); var phraseH = phrase.element.height(); var bannerW = banner.element.width(); var bannerH = banner.element.height(); if ( 2 * phraseX > winW - phraseW ) { left = phraseX -bannerW - 3; } else{ left = phraseX + phraseW + 3; } if ( 2 * phraseY > winH - phraseH + 2 * winS ) { top = phraseY - bannerH; } else { top = phraseY + phraseH + 3; } if ( banner.element.node.parentNode.tagName != 'BODY' ) { var body = document.getElementsByTagName( 'BODY' )[ 0 ]; if ( body ) { body.appendChild( banner.element.node ); } } banner.element.move( top, left ); banner.element.show(); } this.hideBanner = function( bannerIndex ) { var banner = DYNLINK.banners[ bannerIndex ]; banner.element.hide(); } this.hideAllBanners = function() { for ( var i in DYNLINK.banners ) if(DYNLINK.banners[ i ].element) { DYNLINK.banners[ i ].element.hide(); } } //вспомогательные функции ........... this.deletePhrase = function( i ) { i = parseInt( i ); this.phrases[ i ].banner.phrasesCount--; this.phrases.splice( i, 1 ); this.calculatePhrasesDensity( i ); this.calculatePhrasesDensity( i - 1 ); } this.calculatePhrasesDensity = function( i ) { i = parseInt( i ); if ( 0 <= i && i < this.phrases.length ) { var count = 0; this.phrases[ i ].density = 0; if ( i > 0 ) { this.phrases[ i ].density += this.phrases[ i ].space - this.phrases[ i - 1 ].space; count++; } if ( i < this.phrases.length - 1 ) { this.phrases[ i ].density += this.phrases[ i + 1 ].space - this.phrases[ i ].space; count++; } if ( count > 1 ) { this.phrases[ i ].density /= count; } } } this.deleteCrossing = function() { var i = 1; while ( i < this.phrases.length ) { curr = this.phrases[ i ]; prev = this.phrases[ i - 1 ]; if ( prev.space + prev.length > curr.space ) { if ( curr.banner.phrasesCount > prev.banner.phrasesCount ) { this.deletePhrase( i ); } else { this.deletePhrase( i - 1 ); } } else { i++; } } } this.combineRelatives = function() { var i = 1; var regexp = new RegExp( '^(\\s|-|\\+|/|–| |&|[0-9a-zа-я]){1,14}$', 'i' ); while ( i < this.phrases.length ) { curr = this.phrases[ i ]; prev = this.phrases[ i - 1 ]; if ( curr.banner == prev.banner && curr.fragment == prev.fragment ) { var lining = curr.fragment.text.substr( prev.index + prev.length, curr.index - prev.index - prev.length ); if ( regexp.test( lining ) ) { prev.length = prev.length + lining.length + curr.length; this.deletePhrase( i ); continue; } } i++; } } this.deleteMoreThanOne = function() { for ( var i in this.phrases ) { var phrase = this.phrases[ i ]; phrase.banner.phrases[ phrase.banner.phrases.length ] = phrase; } for ( var i in this.banners ) { if ( this.banners[ i ].phrases.length > 0 ) { var maxDensity = 0; var maxLength = 0; var maxRating = 0; var maxSpace = 0; var minSpace = Number.POSITIVE_INFINITY; var bestPhrase = this.banners[ i ].phrases[ 0 ]; for ( var j in this.banners[ i ].phrases ) { var phrase = this.banners[ i ].phrases[ j ]; if ( phrase.space < minSpace ) minSpace = phrase.space; if ( phrase.space > maxSpace ) maxSpace = phrase.space; if ( phrase.length > maxLength ) maxLength = phrase.length; if ( phrase.density > maxDensity ) maxDensity = phrase.density; } for ( var j in this.banners[ i ].phrases ) { var phrase = this.banners[ i ].phrases[ j ]; var kD = phrase.density / maxDensity; var kL = phrase.length / maxLength; var kS = ( maxSpace + minSpace - phrase.space ) / maxSpace; var kR = kL * 100 + kD * 10 + kS; if ( kR > maxRating ) { maxRating = kR; bestPhrase = phrase; } } bestPhrase.rating = 1; } } var cmpRating = function( a, b ) { return b.rating - a.rating }; this.phrases = this.phrases.sort( cmpRating ); while ( this.phrases.length > this.banners.length ) { this.deletePhrase( this.phrases.length - 1 ); } var cmpSpace = function( a, b ) { return a.space - b.space }; this.phrases = this.phrases.sort( cmpSpace ); } this.cleanForBestView = function( limit ) { while ( this.phrases.length > limit ) { var index = null; var minDensity = Number.POSITIVE_INFINITY; for ( var i in this.phrases ) { if ( this.phrases[ i ].banner.phrasesCount > 1 ) { if ( minDensity > this.phrases[ i ].density ) { index = i; minDensity = this.phrases[ i ].density; } } } if ( index == null ) { break; } this.deletePhrase( index ); } } } //////////////////// ФРАГМЕНТ HTML function DYNLINK_Fragment( node, offset ) { this.node = node; this.text = node.nodeValue; this.offset = offset; this.phrases = new Array(); } //////////////////// БАННЕР function DYNLINK_Banner( title, text, url, domain, word ) { this.phrasesCount = 0; this.title = title; this.text = text; this.url = url; this.domain = domain; this.element = null; this.phrases = new Array() var regexpWordBorder = '(^|$|[^0-9a-zA-Zа-яА-Я_])'; var regexpPattern = regexpWordBorder + '(' + word + ')' + regexpWordBorder; this.regexp = new RegExp( regexpPattern, 'ig' ); this.findPhrases = function( fragment ) { var result = this.regexp.exec( fragment.text ); if ( result != null ) { this.regexp.lastIndex -= result[ result.length - 1 ].length; return new DYNLINK_Phrase( this, fragment, result.index + result[ 1 ].length, result[ 2 ].length ); } return false; } } ////////////////////////КОНКРЕТНАЯ РЕАЛИЗАЦИЯ БАННЕРА function DYNLINK_Phrase( banner, fragment, index, length ) { this.banner = banner; this.fragment = fragment; this.index = index; this.length = length; this.density = null; this.element = null; this.rating = 0; this.space = fragment.offset + index; this.banner.phrasesCount++; this.getText = function() { return this.fragment.text.substr( this.index, this.length ); } } //кроссбраузерная обертка над элементами HTML function HTMLNodeWrapper( node ) { this.node = node; if ( document.all ) { this.browser = 'ie'; } else { if ( navigator.userAgent.indexOf( 'Opera' ) > -1 ) { this.browser = 'opera'; } else { this.browser = 'mozilla'; } } this.top = function() { return _sumProperty( this.node, 'offsetTop' ); } this.left = function() { return _sumProperty( this.node, 'offsetLeft' ); } this.width = function() { return this.node.offsetWidth; } this.height = function() { return this.node.offsetHeight; } this.show = function() { this.node.style.visibility = 'visible'; } this.hide = function() { this.node.style.visibility = 'hidden'; } this.move = function( top, left ) { this.node.style.top = parseInt( top ) + 'px'; this.node.style.left = parseInt( left ) + 'px'; } this.windowWidth = function() { if ( this.browser == 'ie' ) { return window.document.body.clientWidth; } return window.innerWidth; } this.windowHeight = function() { if ( this.browser == 'ie' ) { return window.document.body.clientHeight; } return window.innerHeight; } this.windowScrollTop = function() { return document.body.scrollTop; } function _sumProperty( node, propertyName ) { var result = 0; while( node.offsetParent ) { result += node[ propertyName ]; node = node.offsetParent; } return result; } } DYNLINK = new DYNLINK(document.body); //задаем слова DYNLINK.words = new Array( 'nobiblecomualink', 'Быт|Бытие|Книга Бытие|Бт', 'Книга Исход|Исход|Исх', 'Книга Левит|Лев|Левит', 'Чс|Чис|Книга Чисел|Числа', 'Второзаконие|Книга Второзаконие|Вт|Втор', 'Книга Иисуса Навина|Иисус Навин|Ис Нав', 'Суд|Книга Судей', 'Книга Руфь|Руф|Руфь', '1Цар|Первая книга Царств|1 Цар|1 Царств', 'Вторая книга Царств|2Цар|2 Цар|2 Царств', 'Третья книга Царств|3Цар|3 Цар|3 Царств', 'Четвертая книга Царств|4Цар|4 Цар', 'Первая книга Паралипоменон|Первый Паралипоменон|1 Пар|1Пар|1 Паралипоменон', 'Вторая книга Паралипоменон|Второй Паралипоменон|2Пар|2 Пар|2 Паралипоменон', 'Ез|Ездр|Езд|Книга Ездры|Ездра', 'Книга Неемии|Неем|Неемия', 'Ес|Есф|Книга Есфирь|Есфирь', 'Книга Иова|Иов|Ив', 'Псалом|Книга Псалтырь|Псалтырь|Псал|Пс', 'Книга Притчей Соломона|Книга Притч|Пр|Притчи|Прит', 'Екл|Ек|Еккл|Екк|Екклесиаст|Книга Екклесиаста', 'Пес|Песн|Книга Песнь Песней|Пес Пес|Песнь Песней', 'Книга пророка Исайя|Книга Исайя|Исайя|Ис|Исаия', 'Книга Иеремии|Иерем|Книга пророка Иеремии|Иеремии|Иер|Ир|Иеремия', 'Книга Плач Иеремии|Плач Иеремии|Пл|Плач', 'Иезекииля|Книга пророка Иезекииля|Книга Иезекииля|Иезекииль|Из|Иез', 'Книга пророка Даниила|Даниила|Книга Даниила|Дн|Дан', 'Книга пророка Осии|Книга Осии|Осия|Осии|Ос', 'Книга Иоиля|Книга пророка Иоиль|Книга Иоиль|Иоиль', 'Книга Амоса|Книга пророка Амоса|Амос|Амоса|Ам', 'Авд|Книга пророка Авдия|Книга Авдия|Адвий', 'Книга пророка Ионы|Книга Ионы|Ион|Ионы|Иона', 'Книга Михея|Книга пророка Михея|Михея|Мх|Михей|Мих', 'Книга Наума|Наума|Книга пророка Наума|Наум', 'Книга Аввакума|Книга пророка Аввакума|Аввакума|Аввакум|Авв', 'Книга пророка Софонии|Сф|Софония|Соф|Книга Софонии', 'Книга Аггея|Книга пророка Аггея|Аггея|Аггей|Агг|Аг', 'Книга пророка Захарии|Захария|Книга Захарии|Захарии|Захар|Зах', 'Книга Малахии|Книга пророка Малахии|Малахии|Малахия|Мал|Мл', 'Евангелие по Матфею|Матфея|Евангелие от Матфея|Матф|Мф|Мат|Матфей', 'Евангелие по Марку|Евангелия от Марка|Мар|Мк|Марка|Марк', 'Евангелие от Луки|Евангелие по Луке|Лк|Луки|Лук|Лука', 'Евангелие от Иоанна|Евангелие по Иоанну|Ин|Иоанн|Иоанна', 'Деяния апостолов|Книга Деяния|Деян|Деяния', 'Рим|Послание к римлянам|Римлянам', 'Первое послание к коринфянам|1Кор|1 Кор', '2 Кор|2Кор|Второе послание к коринфянам', 'Послание к галатам|Гал|Галатам', 'Ефес|Эф|Еф|Эфес|Послание к эфесянам', 'Фил|Послание к филиппийцам|Флп', 'Послание к колоссянам|Кол|Кл', '1Фес|1 Фес|Первое послание к фессалоникийцам', 'Второе послание к фессалоникийцам|2Фес|2 Фес', '1 Тим|1Тим|Первое послание к Тимофею', '2 Тим|Второе послание к Тимофею', 'Послание к Титу|Титу|Тит', 'Флм|Филимону|Послание к Филимону', 'Евр|Евреям|Послание к Евреям', 'Послание Иакова|Ик|Иакова|Иак', 'Первое послание Петра|1 Пет|1Пет', 'Второе послание Петра|2Пет|2 Пет', 'Первое Послание Иоанна|1Ин|1 Ин', '2Ин|Второе Послание Иоанна|2 Ин', '3Ин|3 Ин|Третье Послание Иоанна', 'Иуд|Иуды|Послание Иуды|Ид', 'Откровение|Откр|Отк|Откровение Иоанна Богослова'); DYNLINK.prepare();