mirror of
https://github.com/php/doc-base.git
synced 2026-03-24 23:32:15 +01:00
git-svn-id: https://svn.php.net/repository/phpdoc/doc-base/trunk@283875 c90b9560-bf6c-de11-be94-00142212c4b1
538 lines
19 KiB
JavaScript
538 lines
19 KiB
JavaScript
// $Id$
|
|
// =============================================================================
|
|
// Preference handling
|
|
|
|
// Handle all the preferences, including online functions custom
|
|
// context menus, and skins [this is called from php_manual_prefs.js]
|
|
function prefHandler()
|
|
{
|
|
// Find out what file stores the skin JS code
|
|
switch (prefs_skin) {
|
|
|
|
// Internal low skin
|
|
case "Low":
|
|
skin_js_file = '_skin_lo.js';
|
|
break;
|
|
|
|
// Internal high skin
|
|
case "High":
|
|
skin_js_file = '_skin_hi.js';
|
|
break;
|
|
|
|
// An external skin with full path (escape it just
|
|
// to make sure that paths with spaces and other
|
|
// unusual chars will work - and turn back : to
|
|
// it's original form)
|
|
default:
|
|
//escaped_skin = escape(prefs_skin);
|
|
//escaped_skin = escaped_skin.replace(/%3A/, ':')
|
|
skin_js_file = "file:///" + prefs_skin;
|
|
break;
|
|
}
|
|
|
|
// Load in the skin JS code
|
|
document.write('<script src="' + skin_js_file + '"><'+ '/script>');
|
|
|
|
// OnContextMenu is only supported in IE5+ so do
|
|
// not try to support the context menu otherwise
|
|
if (ie_version_major >= 5) {
|
|
|
|
// Write out context menu for the first time into it's div
|
|
document.write('<div id="contextMenu">');
|
|
contextMenuRewrite(true);
|
|
document.write('</div>');
|
|
|
|
// Assign our own event handlers to document events [5+]
|
|
document.oncontextmenu = contextMenu;
|
|
document.onclick = contextMenuCloseTimeout;
|
|
window.onblur = contextMenuCloseTimeout;
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// CHM path detection - Thanks to Pete Lees and Jeff Hall for this code
|
|
|
|
// Get the path and name of the CHM file and assign values
|
|
function getCHMFile()
|
|
{
|
|
var a, X, Y, Z;
|
|
a = location.href.search(/:/);
|
|
Y = location.href.lastIndexOf("::");
|
|
if (a == 4) { // file: or http:
|
|
Y = location.href.lastIndexOf("/");
|
|
chmfile_page = unescape(location.href.substring(Y+1));
|
|
if (location.href.substring(0,4) == "file") {
|
|
chmfile_path = unescape(location.href.substring(8, Y+1));
|
|
}
|
|
}
|
|
else {
|
|
if (a == 2) X = 14; // mk:@MSITStore:
|
|
if (a == 7) X = 7; // ms-its:
|
|
chmfile_fullname = unescape(location.href.substring(X, Y));
|
|
Z = chmfile_fullname.lastIndexOf("\\");
|
|
chmfile_path = unescape(chmfile_fullname.substring(0, Z+1));
|
|
chmfile_name = unescape(chmfile_fullname.substring(Z+1));
|
|
chmfile_page = unescape(location.href.substring(Y+3));
|
|
}
|
|
|
|
// RAQ : Wednesday, 16 March 2005 01:56 pm : If this page has been loaded because
|
|
// the notes were selected from the search results, then remove the hash.
|
|
if (location.hash == '#userNotes')
|
|
chmfile_page = chmfile_page.substring(0, chmfile_page.lastIndexOf('#'));
|
|
|
|
//alert(
|
|
// "_script\n\n" +
|
|
// "location\n"+
|
|
// "location.hash = '" + location.hash + "'\n" +
|
|
// "location.host = '" + location.host + "'\n" +
|
|
// "location.hostname = '" + location.hostname + "'\n" +
|
|
// "location.href = '" + location.href + "'\n" +
|
|
// "location.pathname = '" + location.pathname + "'\n" +
|
|
// "location.port = '" + location.port + "'\n" +
|
|
// "location.protocol = '" + location.protocol + "'\n" +
|
|
// "location.search = '" + location.search + "'\n\n" +
|
|
// "chmfile\n"+
|
|
// "chmfile_name = '" + chmfile_name + "'\n" +
|
|
// "chmfile_path = '" + chmfile_path + "'\n" +
|
|
// "chmfile_page = '" + chmfile_page + "'\n"
|
|
// );
|
|
|
|
}
|
|
|
|
// =============================================================================
|
|
// Page display and online functions code
|
|
|
|
// Go online to see this page in an external window [called when a user
|
|
// clicks on the "this page oline" link]
|
|
function thisPageOnline()
|
|
{
|
|
if (!prefs_online) {
|
|
alert("You are in offline mode.\nThis functionality is not available");
|
|
} else {
|
|
window.open(prefs_mirror + 'manual/' + this_lang + '/' + this_page_php);
|
|
}
|
|
}
|
|
|
|
// Report bug on this manual page, using GET method URL tricks
|
|
// [called when a user clicks on the "report bug on this page" link]
|
|
function bugOnPage()
|
|
{
|
|
if (!prefs_online) {
|
|
alert("You are in offline mode.\nThis functionality is not available");
|
|
} else {
|
|
window.open(
|
|
"http://bugs.php.net/report.php?" +
|
|
escape("in[php_version]") + "=earlier&" +
|
|
escape("in[bug_type]") + "=Documentation%20problem&" +
|
|
escape("in[php_os]") + "=windows&" +
|
|
escape("in[sdesc]") + "=" + escape("[chm] bug on " + this_page) + "&" +
|
|
escape("in[ldesc]") + "=" + escape("I have found a bug on page " +
|
|
this_page + "\n[chm date: " + this_date + "]...\n")
|
|
);
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Handle user notes from an external CHM file
|
|
|
|
// Copy user notes text from aan invisible IFRAME to a visible
|
|
// DIV tag's content area [this is called from displayNotes()
|
|
// which is defined in every HTML page to fix an old IE bug]
|
|
function _displayNotes()
|
|
{
|
|
// Get the element from the "all" collection
|
|
element = document.all['pageNotes'];
|
|
|
|
// If we have that element, copy notes here [4+]
|
|
if (element) {
|
|
element.innerHTML = parent.nbuff.document.body.innerHTML;
|
|
// RAQ : Wednesday, 16 March 2005 01:58 pm : Bring the notes into view
|
|
// if the hash has been supplied
|
|
if (location.hash == '#userNotes')
|
|
{
|
|
setTimeout('element.scrollIntoView(true);',200);
|
|
}
|
|
} else {
|
|
alert("Error in user note inclusion");
|
|
}
|
|
}
|
|
|
|
// Load the user notes HTML file indirectly via a list
|
|
// of available user note files [a workaround for a bug
|
|
// affecting several IE 5.5 and IE 6 installations]
|
|
function loadNotes()
|
|
{
|
|
document.write('<script src="ms-its:' +
|
|
chmfile_path + 'php_manual_notes.chm::/_filelist.js"></script>');
|
|
}
|
|
|
|
// Prints out the inline frame for the notes HTML file
|
|
function notesIframe()
|
|
{
|
|
// Notes buffer for user notes to display on this page
|
|
document.write(
|
|
'<iframe name="nbuff" style="display:none" src="ms-its:' +
|
|
chmfile_path + 'php_manual_notes.chm::/' + chmfile_page +
|
|
'"></iframe>'
|
|
);
|
|
}
|
|
|
|
// =============================================================================
|
|
// Context menu code
|
|
|
|
// Rewrite context menu according to the current environment. The only parameter
|
|
// indicates that this is the first display or not. [called once from
|
|
// prefHandler() and then every time before a context menu needs to be displayed]
|
|
function contextMenuRewrite(first)
|
|
{
|
|
// Set selection to null value (we will check
|
|
// if there is a current selection now)
|
|
context_selrange = null;
|
|
|
|
// Our menu layer is invisible initially
|
|
menuHTML = '<table width="150" cellspacing="2" cellpadding="0">';
|
|
|
|
// Write out a table row for all menu points
|
|
for (i in prefs_context_names) {
|
|
|
|
// Label and abstract implementation
|
|
label = prefs_context_names[i];
|
|
impl = prefs_context_values[i];
|
|
|
|
// Special display items start with an underscore
|
|
if (impl.substring(0,1) == "_") {
|
|
|
|
// Find the special printout needed
|
|
switch (impl) {
|
|
|
|
// Menu separator
|
|
case "_Separator_":
|
|
menuHTML +=
|
|
'<tr><td bgcolor="#000000"><img src="_pixel.gif" ' +
|
|
'width="100%" height="1"></td></tr>';
|
|
break;
|
|
|
|
// Google search box (only printed in online mode)
|
|
case "_GoogleSearch_":
|
|
if (prefs_online) {
|
|
menuHTML +=
|
|
'<tr><td style="background-color: #f5f5f5;"><form action="http://www.google.com/search" class="thin"' +
|
|
'onsubmit="contextMenuClose()" method="GET" target="_blank">' +
|
|
'<img src="_google.gif" align="absmiddle" alt="Google"><input type="text" name="q" ' +
|
|
'style="width:120px;"></form></td></tr>';
|
|
}
|
|
break;
|
|
|
|
// Alltheweb search box (only printed in online mode)
|
|
case "_ATWSearch_":
|
|
if (prefs_online) {
|
|
menuHTML +=
|
|
'<tr><td style="background-color: #f5f5f5;"><form action="http://www.alltheweb.com/search" class="thin"' +
|
|
'onsubmit="contextMenuClose()" method="GET" target="_blank">' +
|
|
'<img src="_atw.gif" align="absmiddle" alt="AlltheWeb"><input name="cat" type="hidden" value="web">' +
|
|
'<input type="text" name="query" style="width:120px;"></form></td></tr>';
|
|
}
|
|
break;
|
|
|
|
// This should not be accessed in any valid situation, but
|
|
// is here to at least print out something in case of error...
|
|
default:
|
|
menuHTML += contextLink(i, label);
|
|
break;
|
|
|
|
}
|
|
}
|
|
|
|
// Special functions that may need to be printed out conditionally
|
|
else if (impl.substring(impl.length-2) == "()") {
|
|
|
|
// Do something depending on function name
|
|
switch (impl.substring(0, impl.length-2)) {
|
|
|
|
// Copy selection
|
|
case "copySelection":
|
|
// For the first time there is actually no document... [4+]
|
|
if (document.selection && !first) {
|
|
context_selrange = document.selection.createRange();
|
|
if (context_selrange.text.length > 0) {
|
|
menuHTML += contextLink(i, label);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Google or AlltheWeb search for selection (need to be in online mode)
|
|
case "searchSelGoogle":
|
|
case "searchSelATW":
|
|
// For the first time there is actually no document... [4+]
|
|
if (document.selection && !first) {
|
|
context_selrange = document.selection.createRange();
|
|
if (context_selrange.text.length > 0 && prefs_online) {
|
|
menuHTML += contextLink(i, label);
|
|
}
|
|
}
|
|
break;
|
|
|
|
// Misc functions like print() and selectAll()
|
|
default:
|
|
menuHTML += contextLink(i, label);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Not a special display or function,
|
|
// so simply print out the line for this item
|
|
else { menuHTML += contextLink(i, label); }
|
|
}
|
|
|
|
// End table
|
|
menuHTML += '</table>';
|
|
|
|
// We do not have this element if this is the first run, but we
|
|
// need to rewrite the element content if it's not the first time
|
|
if (first) { document.write(menuHTML); }
|
|
else {
|
|
document.all['contextMenu'].innerHTML = menuHTML;
|
|
}
|
|
}
|
|
|
|
// Write out one context menu link table row [called from contextMenuRewrite()]
|
|
function contextLink (number, label)
|
|
{
|
|
return '<tr><td nowrap onmouseover="this.style.backgroundColor=\'#c0c0c0\';" ' +
|
|
'onmouseout="this.style.backgroundColor=\'#f5f5f5\';" ' +
|
|
'onclick="contextParse(' + number + ')" ' +
|
|
'style="cursor:hand; background-color: #f5f5f5;"><p class="context">' +
|
|
label + '</p></td></tr>';
|
|
}
|
|
|
|
// Parse the jump string, and do appropriate action [called when the user
|
|
// clicks on a table row in the context menu]
|
|
function contextParse(i)
|
|
{
|
|
var control = prefs_context_values[i];
|
|
|
|
// If the control string ends in (), then it is
|
|
// a function, not a file name
|
|
if (control.substring(control.length-2) == "()") {
|
|
|
|
// Switch by function name
|
|
switch (control.substring(0, control.length-2)) {
|
|
|
|
// Print out this page
|
|
case "print":
|
|
print();
|
|
break;
|
|
|
|
// Copy the selection from the current document
|
|
case "copySelection":
|
|
if (context_selrange != null) {
|
|
context_selrange.execCommand("Copy"); // [4+]
|
|
}
|
|
break;
|
|
|
|
// Search for the selected text on Google
|
|
case "searchSelGoogle":
|
|
sel = contextGetSelection();
|
|
if (sel != '') { window.open('http://www.google.com/search?q=' + escape(sel)); }
|
|
break;
|
|
|
|
// Search for the selected text on AlltheWeb
|
|
case "searchSelATW":
|
|
sel = contextGetSelection();
|
|
if (sel != '') { window.open('http://www.alltheweb.com/search?cat=web&query=' + escape(sel)); }
|
|
break;
|
|
|
|
// Go back and forward in history
|
|
case "back": history.back(); break;
|
|
case "forward": history.forward(); break;
|
|
|
|
// Refresh page dispplay
|
|
case "refresh": window.location.reload(true); break;
|
|
|
|
// Select all text in the document [4+]
|
|
case "selectAll": document.body.createTextRange().select(); break;
|
|
|
|
// View source of current page (not working!!)
|
|
// case "viewSource": window.location = "view-source:" + window.location.href; break;
|
|
|
|
// This should never be accessed, but here to alert if there is an error
|
|
default:
|
|
alert('This context menu function is not supported');
|
|
break;
|
|
}
|
|
}
|
|
|
|
// If this is not a "function call", then jump
|
|
// to that page in the CHM or outside of it
|
|
else {
|
|
// Link with protocol
|
|
if (control.indexOf(":") > 0) {
|
|
window.open(control);
|
|
}
|
|
|
|
// Link without protocol
|
|
else {
|
|
location = control;
|
|
}
|
|
}
|
|
}
|
|
|
|
// Returns the current selection [called when a context menu
|
|
// item is clicked involving an operation on a selection]
|
|
function contextGetSelection()
|
|
{
|
|
// Test if anything is selected [4+]
|
|
if (context_selrange != null && context_selrange.text.length > 0) {
|
|
return context_selrange.text;
|
|
} else {
|
|
alert("Nothing is selected");
|
|
return "";
|
|
}
|
|
}
|
|
|
|
// Handle mousedown events in a document [called when a mouse click
|
|
// is issued on a document]
|
|
function contextMenu(e)
|
|
{
|
|
// Close context menu, if it was open before
|
|
contextMenuClose();
|
|
|
|
// We enable the original context menu with the CTRL key if
|
|
// then user selected to override it
|
|
if (event.ctrlKey && prefs_context_override) {
|
|
return true;
|
|
}
|
|
|
|
// We also enable the original one, if it is not overriden
|
|
// and the user have not pressed the CTRL key
|
|
else if (!event.ctrlKey && !prefs_context_override) {
|
|
return true;
|
|
}
|
|
|
|
// Otherwise (overriden or overriden+CTRL) we display our menu
|
|
else {
|
|
|
|
// Rewrite contents of context menu
|
|
contextMenuRewrite(false);
|
|
|
|
// IE6+ is in standard compliant mode because of our !DOCTYPE
|
|
// [ http://msdn.microsoft.com/workshop/author/dhtml/reference/objects/doctype.asp ]
|
|
// so we need to use the "html" tag instead of the "body" to measure scrolled distance.
|
|
// For older browsers, we need to use the body.
|
|
if (ie_version_major >= 6) { delement = document.body.parentElement; }
|
|
else { delement = document.body; }
|
|
|
|
// Find out if menu would be outside the window
|
|
rightedge = delement.clientWidth - event.clientX;
|
|
bottomedge = delement.clientHeight - event.clientY;
|
|
|
|
// Shortcut for the context menu
|
|
cmenu = document.all['contextMenu'];
|
|
|
|
// Place menu to the right position, not to extend the window size
|
|
if (rightedge < cmenu.offsetWidth) {
|
|
cmenu.style.left = delement.scrollLeft + event.clientX - cmenu.offsetWidth;
|
|
} else {
|
|
cmenu.style.left = delement.scrollLeft + event.clientX;
|
|
}
|
|
|
|
if (bottomedge < cmenu.offsetHeight) {
|
|
cmenu.style.top = delement.scrollTop + event.clientY - cmenu.offsetHeight;
|
|
} else {
|
|
cmenu.style.top = delement.scrollTop + event.clientY;
|
|
}
|
|
|
|
// Show menu
|
|
cmenu.style.visibility = "visible";
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
// Closes the context menu [called when the time is out]
|
|
function contextMenuClose()
|
|
{
|
|
// Hide context menu
|
|
document.all['contextMenu'].style.visibility = "hidden";
|
|
}
|
|
|
|
// Sets timeout for menu close [called by document onclick event]
|
|
function contextMenuCloseTimeout()
|
|
{
|
|
// Support for form focus event (form in context menu)
|
|
if (document.activeElement.tagName != 'INPUT') {
|
|
setTimeout('contextMenuClose()', 200);
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Example clipboard copy links
|
|
|
|
// Copy an example from a HTML container with id "example_" + number [called
|
|
// when a user clicks on that copy link]
|
|
function copyExample(number)
|
|
{
|
|
// moveToElementText is only supported in IE5 and up
|
|
if (ie_version_major < 5) {
|
|
alert("Example copy is not supported in this browser");
|
|
} else {
|
|
BodyRange = document.body.createTextRange();
|
|
BodyRange.moveToElementText(document.all['example_' + number]);
|
|
BodyRange.execCommand("Copy");
|
|
}
|
|
}
|
|
|
|
// =============================================================================
|
|
// Default skin functions
|
|
|
|
// Display the page without online functions if they are disabled
|
|
function defaultDisplayPage() {
|
|
|
|
// Do not display online functions links if they are disabled
|
|
if (!prefs_online) {
|
|
document.all['navOnline'].style.display = 'none';
|
|
}
|
|
|
|
// Show page container
|
|
document.all['pageContent'].style.display = 'block';
|
|
}
|
|
|
|
// =============================================================================
|
|
// Main JS program flow
|
|
|
|
// Default vars for all the pages [generated]
|
|
this_lang = 'LANGUAGE_HERE';
|
|
this_date = 'DATE_HERE';
|
|
|
|
// Vars for online menu of this particular page
|
|
this_page = location.pathname.substring(location.pathname.lastIndexOf("/")+1);
|
|
this_page_php = this_page.substring(0, this_page.lastIndexOf(".")) + '.php';
|
|
if (this_page_php == '_index.php') {
|
|
this_page_php = 'index.php';
|
|
}
|
|
|
|
// Create the chmfile vars for this HTML page
|
|
chmfile_fullname = "";
|
|
chmfile_name = "";
|
|
chmfile_path = "";
|
|
chmfile_page = "";
|
|
getCHMFile();
|
|
|
|
// Default values for preferences (no online functions, no
|
|
// special context menu, low skin)
|
|
prefs_online = false;
|
|
prefs_context_override = false;
|
|
prefs_skin = "Low";
|
|
|
|
// Support for selection sensitive context menus
|
|
context_selrange = null;
|
|
|
|
// Find out major and minor IE version number
|
|
var ie_version_start = navigator.appVersion.indexOf("MSIE");
|
|
var ie_version_end = navigator.appVersion.indexOf(".", ie_version_start);
|
|
ie_version_major = parseInt(navigator.appVersion.substring(ie_version_start+5, ie_version_end));
|
|
ie_version_minor = parseInt(navigator.appMinorVersion);
|
|
|
|
// Get the preferences file from outside
|
|
document.write('<script src="' + chmfile_path + 'php_manual_prefs.js"><'+ '/script>');
|