4 * Copyright 1999,2000,2001,2002,2006 $ThePhpWikiProgrammingTeam
6 * This file is part of PhpWiki.
8 * PhpWiki is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * PhpWiki is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License along
19 * with PhpWiki; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 * Transclude: Include an external web page within the body of a wiki page.
28 * src=http://www.internet-technology.de/fourwins_de.htm
31 * @author Geoffrey T. Dairiki
33 * @see http://www.cs.tut.fi/~jkorpela/html/iframe.html
36 * Will only work if the browser supports <iframe>s (which is a recent,
39 * The auto-vertical resize javascript code only works if the transcluded
40 * page comes from the PhpWiki server. Otherwise (due to "tainting"
41 * security checks in JavaScript) I can't figure out how to deduce the
42 * height of the transcluded page via JavaScript... :-/
44 * Sometimes the auto-vertical resize code doesn't seem to make the iframe
45 * quite big enough --- the scroll bars remain. Not sure why.
47 class WikiPlugin_Transclude
50 function getDescription()
52 return _("Include an external web page within the body of a wiki page.");
55 function getDefaultArguments()
57 return array('src' => false, // the src url to include
58 'title' => _("Transcluded page"), // title of the iframe
59 'height' => 450, // height of the iframe
60 'quiet' => false // if set, iframe appears as normal content
64 function run($dbi, $argstr, &$request, $basepage)
67 $args = ($this->getArgs($argstr, $request));
71 return $this->error(fmt("%s parameter missing", "'src'"));
73 // Expand possible interwiki link for src
75 and (!strstr($src, '://'))
76 and ($intermap = getInterwikiMap())
77 and preg_match("/^" . $intermap->getRegexp() . ":/", $src)
79 $link = $intermap->link($src);
80 $src = $link->getAttr('href');
83 // FIXME: Better recursion detection.
84 // FIXME: Currently this doesnt work at all.
85 if ($src == $request->getURLtoSelf()) {
86 return $this->error(fmt("Recursive inclusion of url %s", $src));
88 if (!IsSafeURL($src)) {
89 return $this->error(_("Bad url in src: remove all of <, >, \""));
92 $params = array('title' => $title,
98 'class' => 'transclude',
99 "onload" => "adjust_iframe_height(this);");
101 $noframe_msg[] = fmt("See: %s", HTML::a(array('href' => $src), $src));
103 $noframe_msg = HTML::div(array('class' => 'transclusion'),
104 HTML::p(array(), $noframe_msg));
106 $iframe = HTML::iframe($params, $noframe_msg);
108 /* This doesn't work very well... maybe because CSS screws up NS4 anyway...
109 $iframe = new HtmlElement('ilayer', array('src' => $src), $iframe);
113 return HTML($this->_js(), $iframe);
115 return HTML(HTML::p(array('class' => 'transclusion-title'),
116 fmt("Transcluded from %s", LinkURL($src))),
117 $this->_js(), $iframe);
122 * Produce our javascript.
124 * This is used to resize the iframe to fit the content.
125 * Currently it only works if the transcluded document comes
126 * from the same server as the wiki server.
130 private function _js()
132 static $seen = false;
139 function adjust_iframe_height(frame) {
140 var content = frame.contentDocument;
142 frame.height = content.height + 2 * frame.marginHeight;
145 // Cannot get content.height unless transcluded doc
146 // is from the same server...
151 window.addEventListener("resize", function() {
152 f = this.document.body.getElementsByTagName("iframe");
153 for (var i = 0; i < f.length; i++)
154 adjust_iframe_height(f[i]);
164 // c-hanging-comment-ender-p: nil
165 // indent-tabs-mode: nil