+sub heading()
+{
+my($class)=@_;
+
+ if (!$W->{"header_only"}) {
+ header("Content-Style-Type"=>"text/css");
+ # Do not: text/javascript
+ # as it does not look as registered, at least according to: MIME::Types $VERSION 1.15
+ # "application/javascript" so far standardized till 2005-12-08 by:
+ # http://www.ietf.org/internet-drafts/draft-hoehrmann-script-types-03.txt
+ header("Content-Script-Type"=>"application/javascript");
+ # $W->{"r"}->content_languages() ?
+ do { header("Content-Language"=>$_) if $_; } for $W->{"language"};
+ }
+ # TODO: Support also: private
+ header("Cache-Control"=>"public"); # HTTP/1.1
+
+ # Use $W->{"charset"}=0 to disable charset.
+ $W->{"charset"}="us-ascii"
+ if !defined $W->{"charset"} && (!defined($W->{"content_type"}) || $W->{"content_type"});
+
+ # Workaround bug
+ # https://bugzilla.mozilla.org/show_bug.cgi?id=120556
+ # of at least
+ # Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8b) Gecko/20050217
+ # http://validator.w3.org/ does not send ANY "Accept" headers!
+ if (!defined $W->{"content_type"}) {
+ # Be _stable_ for "headers_in".
+ my $accept=$W->{"headers_in"}{"Accept"};
+ my $user_agent=$W->{"headers_in"}{"User-Agent"}||"";
+ $W->{"content_type"}="application/xhtml+xml"
+ if !$accept && $user_agent=~m{^W3C_Validator/}i;
+ # Be _stable_:
+ my $negotiated=$class->Negotiate_choose([
+ # Put the fallback variant as the first one.
+ # Rate both variants the same to prefer "text/html" for undecided clients.
+ # At least
+ # Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8b) Gecko/20050217
+ # prefers "application/xhtml+xml" over "text/html" itself:
+ # text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
+ negotiate_variant(
+ "id"=>"text/html",
+ "content-type"=>"text/html",
+ "qs"=>0.6,
+ (!$W->{"charset"} ? () : "charset"=>$W->{"charset"}),
+ "lang"=>$W->{"language"},
+ ),
+ negotiate_variant(
+ "id"=>"application/xhtml+xml",
+ "content-type"=>"application/xhtml+xml",
+ "qs"=>0.6,
+ (!$W->{"charset"} ? () : "charset"=>$W->{"charset"}),
+ "lang"=>$W->{"language"},
+ ),
+ # application/xml ?
+ # text/xml ?
+ ]);
+ $W->{"content_type"}=$negotiated if !defined $W->{"content_type"};
+ }
+ # mod_perl doc: If you set this header via the headers_out table directly, it
+ # will be ignored by Apache. So do not do that.
+ my $type;
+ if ($W->{"content_type"}) {
+ $type=MIME::Types->new()->type($W->{"content_type"});
+ cluck "MIME::Types type '".$W->{"content_type"}."' not known" if !$type;
+ }
+ cluck "charset='".$W->{"charset"}."' does not match content-type='".$W->{"content_type"}."'"
+ if ($W->{"charset"} ? 1 : 0) != (!$type ? 0 : $type->isAscii());
+ $W->{"r"}->content_type($W->{"content_type"}.(!$W->{"charset"} ? "" : "; charset=".$W->{"charset"}))
+ if $W->{"content_type"};
+
+ cache_start();
+ # We still can append headers before we put out some text.
+ # FIXME: It is not clean to still append them without overwriting.
+ return if $W->{"heading_done"};
+ Wprint '<?xml version="1.0" encoding="'.$W->{"charset"}.'"?>'."\n"
+ if (!$W->{"header_only"} || $W->{"header_only"} eq "xml") && (0
+ || $W->{"content_type"}=~m{^application/\w+[+]xml$}
+ || $W->{"content_type"} eq "text/vnd.wap.wml");
+ return if $W->{"header_only"};
+ # Split 'heading_done' for the proper handling of: /project/Rel.pm
+ $W->{"heading_done"}++;
+
+ Wprint '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">'."\n";
+ Wprint '<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="'.$W->{"language"}.'">'."\n";
+ my $title=$W->{"title_prefix"}.join("",map({ ': '.$_; } ($W->{"title"} || ())));
+ # Do not: cluck if $title=~/[<>]/;
+ # as it is not solved just by: &a_href_inhibit
+ # as sometimes titles use also: <i>...</i>
+ $title=~s#<[^>]*>##g;
+ Wprint "<head>";
+ Wprint "<title>$title</title>\n";
+ if ($W->{"have_css"}) {
+ # Everything can get overriden later.
+ for my $css ("/My/Web.css",@{$W->{"css_push"}}) {
+ Wprint <<"HERE";
+<link rel="stylesheet" type="text/css" href="@{[ uri_escaped(path_web $css) ]}" />
+HERE
+ }
+ if ($W->{"css_inherit"}) {
+ # Do not: <script />
+ # as at least Lynx inhibits any further HTML output.
+ # Do not: text/javascript
+ # as it does not look as registered, at least according to: MIME::Types $VERSION 1.15
+ # "application/javascript" so far standardized till 2005-12-08 by:
+ # http://www.ietf.org/internet-drafts/draft-hoehrmann-script-types-03.txt
+ Wprint <<"HERE";
+<script type="application/javascript" src="@{[ uri_escaped(path_web('/My/css_inherit.js')) ]}"></script>
+HERE
+ }
+ }
+ Wprint '<meta name="robots" content="'.($W->{"indexme"} ? "" : "no" ).'index,follow" />'."\n";
+ Wprint $W->{"head"};
+ for my $type (qw(prev next index contents start up)) {
+ do { Wprint '<link rel="'.$type.'" href="'.uri_escaped(path_web $_).'" />'."\n" if $_; }
+ for ($W->{"rel_$type"});
+ }
+ Wprint "</head><body";
+# Wprint ' bgcolor="black" text="white" link="aqua" vlink="teal"'
+# if $W->{"browser"}->netscape() && (!$W->{"browser"}->major() || $W->{"browser"}->major()<=4);
+ Wprint $W->{"body_attr"};
+ Wprint ">\n";
+
+ do { Wprint $_ if $_; } for $W->{"heading"};
+}
+
+BEGIN {
+ delete $W->{"__My::Web_init"};
+ }
+