From 13725b379793d51f06efaf7c409c8718cf95b6e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20S=CC=8Ckoda?= Date: Sat, 21 Jul 2012 19:23:44 +0200 Subject: [PATCH] MDL-34299 remove xmlstrictheaders setting and switch to html5 doctype by default This fixes WCAG 2.0 compliance because we were already using HTML5 markup. The strict XML headers setting never worked for production servers, developers used browser validators for compliance testing. XHTML 5 option is relatively similar to this obsolete option, but still it can not be used on production servers. XHTML Strict 1.x was a standardised dead end, HTML5 is the new de-facto-standard supported by all major browsers including latest versions of IE. Please note nothing changes in our coding style because HTML5 is a superset of several previous standards, it is recommended to use only features that are already implemented in all our supported browsers. --- admin/index.php | 8 ------- admin/settings/development.php | 1 - blocks/login/block_login.php | 2 +- lang/en/admin.php | 2 -- lib/db/upgrade.php | 7 ++++++ lib/editor/tinymce/lib.php | 2 +- lib/form/password.php | 19 +++++++-------- lib/form/passwordunmask.php | 20 ++++++++-------- lib/formslib.php | 19 +++++++-------- lib/medialib.php | 21 +---------------- lib/outputlib.php | 10 +++++++- lib/outputrenderers.php | 42 ++++++++++++++++------------------ lib/tests/medialib_test.php | 3 --- login/index_form.html | 2 +- version.php | 2 +- 15 files changed, 66 insertions(+), 94 deletions(-) diff --git a/admin/index.php b/admin/index.php index d4a7d4e285b..ffc923cff5c 100644 --- a/admin/index.php +++ b/admin/index.php @@ -104,10 +104,6 @@ if (!$version or !$release) { print_error('withoutversion', 'debug'); // without version, stop } -// Turn off xmlstrictheaders during upgrade. -$origxmlstrictheaders = !empty($CFG->xmlstrictheaders); -$CFG->xmlstrictheaders = false; - if (!core_tables_exist()) { $PAGE->set_pagelayout('maintenance'); $PAGE->set_popup_notification_allowed(false); @@ -380,10 +376,6 @@ if (during_initial_install()) { upgrade_finished('upgradesettings.php'); } -// Turn xmlstrictheaders back on now. -$CFG->xmlstrictheaders = $origxmlstrictheaders; -unset($origxmlstrictheaders); - // Check for valid admin user - no guest autologin require_login(0, false); $context = get_context_instance(CONTEXT_SYSTEM); diff --git a/admin/settings/development.php b/admin/settings/development.php index cb77515a84c..4d9cd84ab52 100644 --- a/admin/settings/development.php +++ b/admin/settings/development.php @@ -25,7 +25,6 @@ if ($hassiteconfig) { // speedup for non-admins, add all caps used on this page $temp = new admin_settingpage('debugging', new lang_string('debugging', 'admin')); $temp->add(new admin_setting_special_debug()); $temp->add(new admin_setting_configcheckbox('debugdisplay', new lang_string('debugdisplay', 'admin'), new lang_string('configdebugdisplay', 'admin'), ini_get_bool('display_errors'))); - $temp->add(new admin_setting_configcheckbox('xmlstrictheaders', new lang_string('xmlstrictheaders', 'admin'), new lang_string('configxmlstrictheaders', 'admin'), 0)); $temp->add(new admin_setting_configcheckbox('debugsmtp', new lang_string('debugsmtp', 'admin'), new lang_string('configdebugsmtp', 'admin'), 0)); $temp->add(new admin_setting_configcheckbox('perfdebug', new lang_string('perfdebug', 'admin'), new lang_string('configperfdebug', 'admin'), '7', '15', '7')); $temp->add(new admin_setting_configcheckbox('debugstringids', new lang_string('debugstringids', 'admin'), new lang_string('debugstringids_desc', 'admin'), 0)); diff --git a/blocks/login/block_login.php b/blocks/login/block_login.php index 2d92009e486..e834e114526 100644 --- a/blocks/login/block_login.php +++ b/blocks/login/block_login.php @@ -35,7 +35,7 @@ class block_login extends block_base { // TODO: now that we have multiauth it is hard to find out if there is a way to change password $forgot = $wwwroot . '/login/forgot_password.php'; - if (empty($CFG->xmlstrictheaders) and !empty($CFG->loginpasswordautocomplete)) { + if (!empty($CFG->loginpasswordautocomplete)) { $autocomplete = 'autocomplete="off"'; } else { $autocomplete = ''; diff --git a/lang/en/admin.php b/lang/en/admin.php index 30253fd9911..eda9930cc82 100644 --- a/lang/en/admin.php +++ b/lang/en/admin.php @@ -339,7 +339,6 @@ $string['configvariables'] = 'Variables'; $string['configverifychangedemail'] = 'Enables verification of changed email addresses using allowed and denied email domains settings. If this setting is disabled the domains are enforced only when creating new users.'; $string['configvisiblecourses'] = 'Display courses in hidden categories normally'; $string['configwarning'] = 'Be careful modifying these settings - strange values could cause problems.'; -$string['configxmlstrictheaders'] = 'Set to on, each page will be generated using XML http headers and prolog, so browsers will show XHTML errors inline. This is only useful for developers.'; $string['configyuicomboloading'] = 'This options enables combined file loading optimisation for YUI libraries. This setting should be enabled on production sites for performance reasons.'; $string['configzip'] = 'Indicate the location of your zip program (Unix only, optional). If specified, this will be used to create zip archives on the server. If you leave this blank, then Moodle will use internal routines.'; $string['confirmation'] = 'Confirmation'; @@ -1061,6 +1060,5 @@ $string['warningiconvbuggy'] = 'Your version of the iconv library does not suppo $string['webproxy'] = 'Web proxy'; $string['webproxyinfo'] = 'Fill in following options if your Moodle server can not access internet directly. Internet access is required for download of environment data, language packs, RSS feeds, timezones, etc.
PHP cURL extension is highly recommended.'; $string['xmlrpcrecommended'] = 'The xmlrpc extension is needed for hub communication, and useful for web services and Moodle networking'; -$string['xmlstrictheaders'] = 'XML strict headers'; $string['yuicomboloading'] = 'YUI combo loading'; $string['ziprequired'] = 'The Zip PHP extension is now required by Moodle, info-ZIP binaries or PclZip library are not used anymore.'; diff --git a/lib/db/upgrade.php b/lib/db/upgrade.php index 060fc002c00..0fa473c65c2 100644 --- a/lib/db/upgrade.php +++ b/lib/db/upgrade.php @@ -1045,6 +1045,13 @@ function xmldb_main_upgrade($oldversion) { upgrade_main_savepoint(true, 2012070600.11); } + if ($oldversion < 2012071900.01) { + // Remove obsolete xhtml strict setting - use THEME->doctype in theme config if necessary, + // see theme_config->doctype in lib/outputlib.php for more details. + unset_config('xmlstrictheaders'); + upgrade_main_savepoint(true, 2012071900.01); + } + return true; } diff --git a/lib/editor/tinymce/lib.php b/lib/editor/tinymce/lib.php index 3fca21ed0a8..815bed06b4b 100644 --- a/lib/editor/tinymce/lib.php +++ b/lib/editor/tinymce/lib.php @@ -172,7 +172,7 @@ class tinymce_texteditor extends texteditor { $params['moodleemoticon_emoticons'] = json_encode($imgs); } - if (empty($CFG->xmlstrictheaders) and (!empty($options['legacy']) or !empty($options['noclean']) or !empty($options['trusted']))) { + if (!empty($options['legacy']) or !empty($options['noclean']) or !empty($options['trusted'])) { // now deal somehow with non-standard tags, people scream when we do not make moodle code xtml strict, // but they scream even more when we strip all tags that are not strict :-( $params['valid_elements'] = 'script[src|type],*[*]'; // for some reason the *[*] does not inlcude javascript src attribute MDL-25836 diff --git a/lib/form/password.php b/lib/form/password.php index c443bad7c2a..1d031b3932c 100644 --- a/lib/form/password.php +++ b/lib/form/password.php @@ -51,17 +51,14 @@ class MoodleQuickForm_password extends HTML_QuickForm_password{ */ function MoodleQuickForm_password($elementName=null, $elementLabel=null, $attributes=null) { global $CFG; - if (empty($CFG->xmlstrictheaders)) { - // no standard mform in moodle should allow autocomplete of passwords - // this is valid attribute in html5, sorry, we have to ignore validation errors in legacy xhtml 1.0 - if (empty($attributes)) { - $attributes = array('autocomplete'=>'off'); - } else if (is_array($attributes)) { - $attributes['autocomplete'] = 'off'; - } else { - if (strpos($attributes, 'autocomplete') === false) { - $attributes .= ' autocomplete="off" '; - } + // no standard mform in moodle should allow autocomplete of passwords + if (empty($attributes)) { + $attributes = array('autocomplete'=>'off'); + } else if (is_array($attributes)) { + $attributes['autocomplete'] = 'off'; + } else { + if (strpos($attributes, 'autocomplete') === false) { + $attributes .= ' autocomplete="off" '; } } diff --git a/lib/form/passwordunmask.php b/lib/form/passwordunmask.php index e14eb6cb38b..bd256fcf123 100644 --- a/lib/form/passwordunmask.php +++ b/lib/form/passwordunmask.php @@ -53,19 +53,17 @@ class MoodleQuickForm_passwordunmask extends MoodleQuickForm_password { */ function MoodleQuickForm_passwordunmask($elementName=null, $elementLabel=null, $attributes=null) { global $CFG; - if (empty($CFG->xmlstrictheaders)) { - // no standard mform in moodle should allow autocomplete of passwords - // this is valid attribute in html5, sorry, we have to ignore validation errors in legacy xhtml 1.0 - if (empty($attributes)) { - $attributes = array('autocomplete'=>'off'); - } else if (is_array($attributes)) { - $attributes['autocomplete'] = 'off'; - } else { - if (strpos($attributes, 'autocomplete') === false) { - $attributes .= ' autocomplete="off" '; - } + // no standard mform in moodle should allow autocomplete of passwords + if (empty($attributes)) { + $attributes = array('autocomplete'=>'off'); + } else if (is_array($attributes)) { + $attributes['autocomplete'] = 'off'; + } else { + if (strpos($attributes, 'autocomplete') === false) { + $attributes .= ' autocomplete="off" '; } } + parent::MoodleQuickForm_password($elementName, $elementLabel, $attributes); } diff --git a/lib/formslib.php b/lib/formslib.php index 72003796eca..37fc1efd8d3 100644 --- a/lib/formslib.php +++ b/lib/formslib.php @@ -158,17 +158,14 @@ abstract class moodleform { */ function moodleform($action=null, $customdata=null, $method='post', $target='', $attributes=null, $editable=true) { global $CFG, $FULLME; - if (empty($CFG->xmlstrictheaders)) { - // no standard mform in moodle should allow autocomplete with the exception of user signup - // this is valid attribute in html5, sorry, we have to ignore validation errors in legacy xhtml 1.0 - if (empty($attributes)) { - $attributes = array('autocomplete'=>'off'); - } else if (is_array($attributes)) { - $attributes['autocomplete'] = 'off'; - } else { - if (strpos($attributes, 'autocomplete') === false) { - $attributes .= ' autocomplete="off" '; - } + // no standard mform in moodle should allow autocomplete with the exception of user signup + if (empty($attributes)) { + $attributes = array('autocomplete'=>'off'); + } else if (is_array($attributes)) { + $attributes['autocomplete'] = 'off'; + } else { + if (strpos($attributes, 'autocomplete') === false) { + $attributes .= ' autocomplete="off" '; } } diff --git a/lib/medialib.php b/lib/medialib.php index 57a9e902bb0..fe28a95e405 100644 --- a/lib/medialib.php +++ b/lib/medialib.php @@ -526,8 +526,6 @@ OET; */ class core_media_player_youtube extends core_media_player_external { protected function embed_external(moodle_url $url, $name, $width, $height, $options) { - global $CFG; - $site = $this->matches[1]; $videoid = $this->matches[3]; @@ -539,27 +537,10 @@ class core_media_player_youtube extends core_media_player_external { self::pick_video_size($width, $height); - if (empty($CFG->xmlstrictheaders)) { - return << OET; - } - - // NOTE: we can not use any link fallback because it breaks built-in - // player on iOS devices. - $output = << - - - - - - -OET; - - return $output; } protected function get_regex() { diff --git a/lib/outputlib.php b/lib/outputlib.php index 0cf29d8fef8..69c13934e52 100644 --- a/lib/outputlib.php +++ b/lib/outputlib.php @@ -275,6 +275,14 @@ class theme_config { */ public $enablecourseajax = true; + /** + * @var string Determines served document types + * - 'html5' the only officially supported doctype in Moodle + * - 'xhtml5' may be used in development for validation (not intended for production servers!) + * - 'xhtml' XHTML 1.0 Strict for legacy themes only + */ + public $doctype = 'html5'; + //==Following properties are not configurable from theme config.php== /** @@ -390,7 +398,7 @@ class theme_config { $configurable = array('parents', 'sheets', 'parents_exclude_sheets', 'plugins_exclude_sheets', 'javascripts', 'javascripts_footer', 'parents_exclude_javascripts', 'layouts', 'enable_dock', 'enablecourseajax', 'supportscssoptimisation', - 'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'hidefromselector'); + 'rendererfactory', 'csspostprocess', 'editor_sheets', 'rarrow', 'larrow', 'hidefromselector', 'doctype'); foreach ($config as $key=>$value) { if (in_array($key, $configurable)) { diff --git a/lib/outputrenderers.php b/lib/outputrenderers.php index b2d0e491005..8d383fd2d09 100644 --- a/lib/outputrenderers.php +++ b/lib/outputrenderers.php @@ -304,34 +304,22 @@ class core_renderer extends renderer_base { * Get the DOCTYPE declaration that should be used with this page. Designed to * be called in theme layout.php files. * - * @return string the DOCTYPE declaration (and any XML prologue) that should be used. + * @return string the DOCTYPE declaration that should be used. */ public function doctype() { - global $CFG; + if ($this->page->theme->doctype === 'html5') { + $this->contenttype = 'text/html; charset=utf-8'; + return "\n"; - $doctype = '' . "\n"; - $this->contenttype = 'text/html; charset=utf-8'; - - if (empty($CFG->xmlstrictheaders)) { - return $doctype; - } - - // We want to serve the page with an XML content type, to force well-formedness errors to be reported. - $prolog = '' . "\n"; - if (isset($_SERVER['HTTP_ACCEPT']) && strpos($_SERVER['HTTP_ACCEPT'], 'application/xhtml+xml') !== false) { - // Firefox and other browsers that can cope natively with XHTML. + } else if ($this->page->theme->doctype === 'xhtml5') { $this->contenttype = 'application/xhtml+xml; charset=utf-8'; - - } else if (preg_match('/MSIE.*Windows NT/', $_SERVER['HTTP_USER_AGENT'])) { - // IE can't cope with application/xhtml+xml, but it will cope if we send application/xml with an XSL stylesheet. - $this->contenttype = 'application/xml; charset=utf-8'; - $prolog .= 'httpswwwroot . '/lib/xhtml.xsl"?>' . "\n"; + return "\n"; } else { - $prolog = ''; + // legacy xhtml 1.0 + $this->contenttype = 'text/html; charset=utf-8'; + return ('' . "\n"); } - - return $prolog . $doctype; } /** @@ -341,7 +329,11 @@ class core_renderer extends renderer_base { * @return string HTML fragment. */ public function htmlattributes() { - return get_html_lang(true) . ' xmlns="http://www.w3.org/1999/xhtml"'; + $return = get_html_lang(true); + if ($this->page->theme->doctype !== 'html5') { + $return .= ' xmlns="http://www.w3.org/1999/xhtml"'; + } + return $return; } /** @@ -354,6 +346,12 @@ class core_renderer extends renderer_base { public function standard_head_html() { global $CFG, $SESSION; $output = ''; + if ($this->page->theme->doctype === 'html5' or $this->page->theme->doctype === 'xhtml5') { + // Make sure we set 'X-UA-Compatible' only if script did not request something else (such as MDL-29213). + if (empty($CFG->additionalhtmlhead) or stripos($CFG->additionalhtmlhead, 'X-UA-Compatible') === false) { + $output .= '' . "\n"; + } + } $output .= '' . "\n"; $output .= '' . "\n"; if (!$this->page->cacheable) { diff --git a/lib/tests/medialib_test.php b/lib/tests/medialib_test.php index dd12e90ba69..baf1ae98eb5 100644 --- a/lib/tests/medialib_test.php +++ b/lib/tests/medialib_test.php @@ -57,9 +57,6 @@ class medialib_testcase extends advanced_testcase { $CFG->core_media_enable_vimeo = false; $CFG->core_media_enable_swf = false; - // Strict headers turned off. - $CFG->xmlstrictheaders = false; - $_SERVER = array('HTTP_USER_AGENT' => ''); $this->pretend_to_be_safari(); } diff --git a/login/index_form.html b/login/index_form.html index 1765064cd10..a875067b04a 100644 --- a/login/index_form.html +++ b/login/index_form.html @@ -5,7 +5,7 @@ if ($show_instructions) { $columns = 'onecolumn'; } -if (empty($CFG->xmlstrictheaders) and !empty($CFG->loginpasswordautocomplete)) { +if (!empty($CFG->loginpasswordautocomplete)) { $autocomplete = 'autocomplete="off"'; } else { $autocomplete = ''; diff --git a/version.php b/version.php index e56fa0976be..4827eb80874 100644 --- a/version.php +++ b/version.php @@ -30,7 +30,7 @@ defined('MOODLE_INTERNAL') || die(); -$version = 2012071900.00; // YYYYMMDD = weekly release date of this DEV branch +$version = 2012071900.01; // YYYYMMDD = weekly release date of this DEV branch // RR = release increments - 00 in DEV branches // .XX = incremental changes