/* * Checks if property is derived from prototype, applies method if it is not exists * * @param string property name * @return bool true if prototyped * @access public */ if ('undefined' == typeof Object.hasOwnProperty) { Object.prototype.hasOwnProperty = function (prop) { return !(this.constructor && this.constructor.prototype[prop] && this[prop] === this.constructor.prototype[prop]); } } /************************************************ ******** DOM related stuff ************************************************/ /* * Performs parent lookup by * - node object: actually it's "is child of" check * - tagname: getParent(el, 'li') == getParent(el, 'tagName', 'LI') * - any node attribute * * @param DOMnode source element * @param mixed DOMNode or string tagname or string attribute name * @param string optional attribute value * @return mixed DOMNode or null */ function getParent (el, cp, vl) { if (el == null) return null; else if (el.nodeType == 1 && ((!isUndefined(vl) && el[cp] == vl) || ('string' == typeof cp && el.tagName.toLowerCase() == cp.toLowerCase()) || el == cp)) return el; else return getParent(el.parentNode, cp, vl); }; /* * Creates element all-at-once * * @param string tag name * @param hash tag element properties { 'class' : 'className', * 'style' : { 'property' : value, ... }, * 'event' : { 'eventType' : handler, ... }, * 'child' : [ child1, child2, ...], * 'param' : { 'property' : value, ... }, * @return DOMObject created element or false * @access public */ document.createElementExt = function (tag,p) { var L, i, k, el = document.createElement(tag); if (!el) return false; for (i in p) { if (!p.hasOwnProperty(i)) continue; switch (i) { case "class" : el.setAttribute('className',p[i]); el.setAttribute('class',p[i]); break; case "style" : for (k in p[i]) { if (!p[i].hasOwnProperty(k)) continue; el.style[k] = p[i][k]; } break; case "event" : for (k in p[i]) { if (!p[i].hasOwnProperty(k)) continue; el.attachEvent(k,p[i][k]); } break; case "child" : L = p[i].length; for (k = 0; k0) { top -= el.scrollTop; } if (el.scrollLeft && el.scrollLeft>0) { left -= el.scrollLeft; } } } // If this node is also the offsetParent, add on the offsets and reset to the new offsetParent if (el == offsetParent) { left += o.offsetLeft; if (el.clientLeft && el.nodeName!="TABLE") { left += el.clientLeft; } top += o.offsetTop; if (el.clientTop && el.nodeName!="TABLE") { top += el.clientTop; } o = el; if (o.offsetParent==null) { if (o.offsetLeft) { left += o.offsetLeft; } if (o.offsetTop) { top += o.offsetTop; } } offsetParent = o.offsetParent; } } if (originalObject.offsetWidth) { width = originalObject.offsetWidth; } if (originalObject.offsetHeight) { height = originalObject.offsetHeight; } return {'left':left, 'top':top, 'width':width, 'height':height }; }; /* * Update toolip contents * * @param {String} tooltip id * @param {String} new content * @access private */ var tooltipShow = function (id, content) { domTT_update(tooltips[id], content); }; /* * Retrieve object's position from the server * * @param {String} document URI * @access private */ var tooltipFetch = function (href) { if (!RemoteScript) { tooltipShow(href,'RemoteScript plugin is not available'); } else { tooltipShow(href,'Please wait, loading...'); }; var req = new RemoteScript; req.onreadystatechange = function() { if (req.readyState == 4) { if (req.responseJS) { tooltipShow(href, req.responseJS); } else { tooltipShow(href, '
'+req.responseText); } } }; req.loader = 'script'; req.cache = false; req.open ("GET",['livepreview','getpreview']); req.send ({'src' : href}); }; /* * Tries to find the anchor to the local page * * @param {MouseEvent} mousemove event * @access protected */ this.anchorCatcher = function (e) { if (!dotQuestion.offsetParent) document.body.appendChild(dotQuestion); var el = getParent(e.srcElement || e.target, 'a'); /* * get the controller */ var ctrl = getParent(e.srcElement || e.target, 'className', 'livePreviewIcon'); /* * if we are on the livepreview controller, show the tip */ if (ctrl && curA && (!tooltips[String(curA)] || !domTT_isActive(tooltips[String(curA)]))) { var ts1 = 'undefined' == typeof tooltips[curA.href]; var i = 'livePreviewTip'+Math.round(Math.random()*10000); tooltips[String(curA)] = domTT_activate(curA, e, 'content', '...', 'type', 'velcro', 'delay', 1, 'width', 400, 'id', i, 'styleClass', 'livePreviewTooltip', 'maxWidth', document.body.offsetWidth*0.8); if (ts1) { tooltipFetch(String(curA)); } } /* * no need to update current target */ if (el == curA || (ctrl && curA)) return; /* * if something was before... */ if (ctrl != null || (el != null // element exists && el.className.indexOf('urlextern')<0 // is not an external link && el.className.indexOf('toc')<0 // is not a toc item && !String(el).match(/\.php$/) // is not a script && String(el).indexOf(document.location.protocol+"//" +document.location.host)==0 // host is the same as current && (document.location.pathname == DOKU_BASE // site's root || String(el).indexOf(document.location.protocol+"//" +document.location.host+document.location.pathname)<0 // is not a cyclic url ) && !String(el).match(/[?&]do=/) // is not the action url ) ) { var c = getPos(ctrl?curA:el); dotQuestion.style.left = c.left+(ctrl?curA:el).offsetWidth+'px'; dotQuestion.style.top = c.top+3+'px'; dotQuestion.style.display = ''; } else { dotQuestion.style.display = 'none'; } if (el != curA && curA) domTT_deactivate(tooltips[curA.href]); /* * save current handler, if we are on the anchor */ if (!ctrl) curA = el; } }; if (document.addEventListener) { document.addEventListener('mousemove',LivePreview.anchorCatcher,false); } else if (document.attachEvent) { document.attachEvent('onmousemove',LivePreview.anchorCatcher) }