r24534 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r24533‎ | r24534 | r24535 >
Date:01:15, 2 August 2007
Author:yaron
Status:old
Tags:
Comment:
Version 4.2 - major Javascript fix (now works across all browsers), fix for "restricted" property
Modified paths:
  • /trunk/extensions/SemanticForms/INSTALL (modified) (history)
  • /trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc (modified) (history)
  • /trunk/extensions/SemanticForms/includes/SF_GlobalFunctions.php (modified) (history)

Diff [purge]

Index: trunk/extensions/SemanticForms/INSTALL
@@ -1,4 +1,4 @@
2 -[[Semantic Forms 0.4.1]]
 2+[[Semantic Forms 0.4.2]]
33
44 Contents:
55 * Disclaimer
Index: trunk/extensions/SemanticForms/includes/SF_FormPrinter.inc
@@ -4,11 +4,11 @@
55 *
66 * @author Yaron Koren
77 * @author Nils Oppermann
 8+ * @author Jeffrey Stuckman
89 */
910
1011 class SFFormPrinter {
1112
12 -
1313 function formHTML($form_def, $form_submitted, $source_is_page, $existing_page_content = null, $page_title = null) {
1414 global $wgRequest, $wgUser;
1515 global $gTabIndex; // used to represent the current tab index in the form
@@ -72,6 +72,8 @@
7373 $instance_num = 0;
7474 $all_instances_printed = false;
7575 $strict_parsing = false;
 76+ $autocomplete_value_array = array();
 77+ $autocomplete_value_array['mappings'] = array();
7678 for ($section_num = 0; $section_num < count($form_def_sections); $section_num++) {
7779 $tif = new SFTemplateInForm();
7880 $start_position = 0;
@@ -269,8 +271,12 @@
270272 // determine whether user is a sysop by whether or not they're
271273 // allowed to delete things - if there's a better way, please let
272274 // me know
273 - if ($is_restricted && ! $wgUser->isAllowed('delete')) {
 275+ if ($is_restricted && (! $wgUser || ! $wgUser->isAllowed('delete'))) {
 276+ // set background color to get around weird IE behavior (field
 277+ // is disabled, but color stays white)
274278 $gDisabledText = "disabled";
 279+ //$gDisabledText = "disabled style=\"background-color: #dddddd; border: 1px solid #ccccff;\"";
 280+ //$gDisabledText = "disabled readonly";
275281 }
276282
277283 // handle non-template fields - 'page title' and 'free text'
@@ -343,7 +349,21 @@
344350 $input_name = $query_template_name . '[' . $field_name . ']';
345351 $new_text = SFFormPrinter::formTemplateFieldHTML($field_name, $input_name, $allow_multiple,
346352 $cur_value, $is_mandatory, $is_hidden, $is_restricted, $input_type, $size, $num_rows, $num_cols, $no_autocomplete,
347 - $autocomplete_category, $all_fields, $strict_parsing);
 353+ $autocomplete_category, $all_fields, $strict_parsing, $autocomplete_value_array);
 354+
 355+ // if this was field was disabled due to being 'restricted',
 356+ // restore $gDisabledText back to its actual value, and add
 357+ // a hidden field holding the value of this field, because
 358+ // disabled inputs for some reason don't submit their value
 359+ if ($is_restricted && ! $wgUser->isAllowed('delete')) {
 360+ $gDisabledText = $actual_disabled_text;
 361+ if ($field_name == 'free text') {
 362+ $new_text .= SFFormPrinter::hiddenFieldHTML('free_text', '<free_text>');
 363+ } else {
 364+ $new_text .= SFFormPrinter::hiddenFieldHTML($input_name, $cur_value);
 365+ }
 366+ }
 367+
348368 if ($new_text) {
349369 if (is_numeric($field_name)) {
350370 // if the value is null, don't include it at all -
@@ -366,8 +386,6 @@
367387 $start_position = $brackets_end_loc;
368388 }
369389 }
370 - // restore back to actual value, if it changed
371 - $gDisabledText = $actual_disabled_text;
372390 } else { // tag is not one of the three allowed values
373391 // ignore tag
374392 $start_position = $brackets_end_loc;
@@ -396,7 +414,7 @@
397415 $form_text .=<<<END
398416 <div id="wrapper_$gTabIndex" class="multiple_template">
399417 $section
400 - <input type="button" onclick="blankInstance('wrapper_$gTabIndex');" value="$remove_text" tabindex="$gTabIndex" />
 418+ <input type="button" onclick="removeInstance('wrapper_$gTabIndex');" value="$remove_text" tabindex="$gTabIndex" />
401419 </div>
402420
403421 END;
@@ -415,7 +433,6 @@
416434 $add_another = wfMsg('sf_editdata_addanother');
417435 $form_text .=<<<END
418436 <p style="margin-left:10px;">
419 - <input type="hidden" value="0" id="numElements" />
420437 <p><input type="button" onclick="addInstance('starter_$query_template_name', 'main_$query_template_name', '$gTabIndex');" value="$add_another" tabindex="$gTabIndex" /></p>
421438
422439 END;
@@ -483,51 +500,130 @@
484501 return (num_errors == 0);
485502 }
486503
487 -// This Javascript code is heavily indebted to Dustin Diaz's 'add and remove
488 -// HTML elements' tutorial - http://www.dustindiaz.com/add-and-remove-html-elements-dynamically-with-javascript/
489 -function addInstance(starter_div_id, main_div_id, tab_index) {
490 - var starter_div = document.getElementById(starter_div_id);
491 - var main_div = document.getElementById(main_div_id);
492 - var numi = document.getElementById('numElements');
493 - var num = (document.getElementById('numElements').value -1)+ 2;
494 - numi.value = num;
495 - var newdiv = document.createElement('div');
496 - var div_id = 'div_' + num;
497 - newdiv.setAttribute('id', div_id);
498 - newdiv.setAttribute('class', 'multiple_template');
499 - // workaround for IE 6 bug
500 - newdiv.setAttribute('className', 'multiple_template');
501 - // make internal ID unique for the relevant divs and spans, and replace
502 - // the [num] index with an actual unique index
503 - var orig_html = starter_div.innerHTML;
504 - orig_html = orig_html.replace(/input_/g, 'input_' + num + '_');
505 - orig_html = orig_html.replace(/info_/g, 'info_' + num + '_');
506 - orig_html = orig_html.replace(/div_/g, 'div_' + num + '_');
507 - orig_html = orig_html.replace(/\[num\]/g, '[' + num + ']');
508 - newdiv.innerHTML = orig_html + '<input type="button" onclick="removeInstance(\'' + main_div_id + '\', \'' + div_id + '\');" value="$remove_text" tabindex="' + tab_index + '" />';
509 - main_div.appendChild(newdiv);
 504+var num_elements = 0;
 505+
 506+function addInstance(starter_div_id, main_div_id, tab_index)
 507+{
 508+ var starter_div = document.getElementById(starter_div_id);
 509+ var main_div = document.getElementById(main_div_id);
 510+ num_elements++;
 511+
 512+ //Create the new instance
 513+ var new_div = starter_div.cloneNode(true);
 514+ var div_id = 'div_gen_' + num_elements;
 515+ new_div.className = 'multiple_template';
 516+ new_div.id = div_id;
 517+ new_div.style.display = 'block';
 518+
 519+ // make internal ID unique for the relevant divs and spans, and replace
 520+ // the [num] index in the element names with an actual unique index
 521+ var children = new_div.getElementsByTagName('*');
 522+ var x;
 523+ for (x=0;x<children.length;x++)
 524+ {
 525+ if (children[x].name)
 526+ children[x].name = children[x].name.replace(/\[num\]/g, '[' + num_elements + ']');
 527+ if (children[x].id)
 528+ children[x].id = children[x].id
 529+ .replace(/input_/g, 'input_' + num_elements + '_')
 530+ .replace(/info_/g, 'info_' + num_elements + '_')
 531+ .replace(/div_/g, 'div_' + num_elements + '_');
 532+ }
 533+
 534+ //Create remove button
 535+ var remove_button = document.createElement('input');
 536+ remove_button.type = 'button';
 537+ remove_button.value = '$remove_text';
 538+ remove_button.tabIndex = tab_index;
 539+ remove_button.onclick = removeInstanceEventHandler(div_id);
 540+ new_div.appendChild(remove_button);
 541+
 542+ //Add the new instance
 543+ main_div.appendChild(new_div);
 544+ attachAutocompleteToAllFields(new_div);
510545 }
511546
512 -function removeInstance(main_div_id, this_div_id) {
513 - var d = document.getElementById(main_div_id);
514 - var olddiv = document.getElementById(this_div_id);
515 - d.removeChild(olddiv);
 547+function removeInstanceEventHandler(this_div_id)
 548+{
 549+ return function()
 550+ {
 551+ removeInstance(this_div_id);
 552+ };
516553 }
517554
518 -// hack function - an element that's not a child of anything can't be
519 -// removed, so do the next best thing: set its contents to blank and its
520 -// display to 'none'
521 -function blankInstance(div_id) {
522 - var d = document.getElementById(div_id);
523 - d.innerHTML = "";
524 - d.style.display = "none";
 555+function removeInstance(div_id) {
 556+ var olddiv = document.getElementById(div_id);
 557+ olddiv.parentNode.removeChild(olddiv);
525558 }
526559
 560+var autocompletestrings = new Array();
 561+var autocompletemappings = new Array();
 562+
 563+//Activate autocomplete functionality for every field on the document
 564+function attachAutocompleteToAllDocumentFields()
 565+{
 566+ var forms = document.getElementsByTagName("form");
 567+ var x;
 568+ for (x=0;x<forms.length;x++)
 569+ {
 570+ if (forms[x].name == "createbox")
 571+ {
 572+ attachAutocompleteToAllFields(forms[x]);
 573+ }
 574+ }
 575+}
 576+
 577+//Activate autocomplete functionality for every field under the specified element
 578+function attachAutocompleteToAllFields(base)
 579+{
 580+ var inputs = base.getElementsByTagName("input");
 581+ var y;
 582+ for (y=0;y<inputs.length;y++)
 583+ {
 584+ attachAutocompleteToField(inputs[y].id);
 585+ }
 586+}
 587+
 588+//Activate autocomplete functionality for the specified field
 589+function attachAutocompleteToField(input_id)
 590+{
 591+ //Check input id for the proper format, to ensure this is for SF
 592+ if (input_id.substr(0,6) == 'input_')
 593+ {
 594+ //Extract the field ID number from the input field
 595+ var field_num = parseInt(input_id.substring(input_id.lastIndexOf('_') + 1, input_id.length),10);
 596+ //Add the autocomplete string, if a mapping exists.
 597+ if (autocompletemappings[field_num])
 598+ {
 599+ var div_id = input_id.replace(/input_/g, 'div_');
 600+ new Autocompleter.Local(input_id, div_id, autocompletestrings[autocompletemappings[field_num]], {});
 601+ }
 602+ }
 603+}
 604+
 605+Event.observe(window, 'load', attachAutocompleteToAllDocumentFields);
 606+
527607 END;
 608+
 609+ //Send the autocomplete values to the browser, along with the mappings of which values should apply to which fields
 610+ foreach ($autocomplete_value_array as $autocomplete_key => $autocomplete_string)
 611+ {
 612+ if ($autocomplete_key == "mappings")
 613+ {
 614+ foreach ($autocomplete_string as $field_number => $field_key)
 615+ {
 616+ $javascript_text .= "autocompletemappings[$field_number] = '" . str_replace("'", "\'", $field_key) . "';\n";
 617+ }
 618+ }
 619+ else
 620+ {
 621+ $javascript_text .= "autocompletestrings['" . str_replace("'", "\'", $autocomplete_key) . "'] = $autocomplete_string;\n";
 622+ }
 623+ }
528624 return array($form_text, $javascript_text, $title, $data_text);
529625 }
530626
531 - function formTemplateFieldHTML($field_name, $input_name, $part_of_multiple, $cur_value, $is_mandatory, $is_hidden, $is_restricted, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $all_fields, $strict_parsing) {
 627+ function formTemplateFieldHTML($field_name, $input_name, $part_of_multiple, $cur_value, $is_mandatory, $is_hidden, $is_restricted, $input_type, $size, $num_rows, $num_cols, $no_autocomplete, $autocomplete_category, $all_fields, $strict_parsing, &$out_autocomplete_values) {
532628 global $gTabIndex;
533629
534630 // see if this field matches one of the fields defined for this template -
@@ -565,19 +661,21 @@
566662 $the_field->autocomplete_category = $autocomplete_category;
567663 $the_field->input_name = $input_name;
568664 $the_field->part_of_multiple = $part_of_multiple;
569 - $text = SFFormPrinter::formFieldHTML($the_field, $cur_value);
 665+ $text = SFFormPrinter::formFieldHTML($the_field, $cur_value, $out_autocomplete_values);
570666 return $text;
571667 }
572668
573 - function formFieldHTML($template_field, $cur_value) {
 669+ function formFieldHTML($template_field, $cur_value, &$out_autocomplete_values) {
574670 global $smwgContLang;
575 -
 671+ //When a field is generated that requires autocomplete, the autocomplete string will be added to out_autocomplete_values. Then, at the end,
 672+ //Javascript will be generated to activate autocomplete field at once.
 673+
576674 if ($template_field->is_hidden) {
577675 $text = SFFormPrinter::hiddenFieldHTML($template_field->input_name, $cur_value);
578676 } elseif ($template_field->autocomplete_category != null) {
579677 $size = $template_field->size;
580678 if ($size == null) $size = 35;
581 - $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->autocomplete_category, false, $cur_value);
 679+ $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->autocomplete_category, false, $cur_value, $out_autocomplete_values);
582680 } elseif ($template_field->input_type == 'text') {
583681 $size = $template_field->size;
584682 if ($size == null) $size = 35;
@@ -598,7 +696,7 @@
599697 if ($template_field->no_autocomplete) {
600698 $text = SFFormPrinter::textEntryHTML($size, $template_field->input_name, $cur_value);
601699 } else {
602 - $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->semantic_field, true, $cur_value);
 700+ $text = SFFormPrinter::textEntryWithAutocompleteHTML($size, $template_field->input_name, $template_field->part_of_multiple, $template_field->semantic_field, true, $cur_value, $out_autocomplete_values);
603701 }
604702 } else { // input type not defined in form, and not a relation
605703 $attr_type = $template_field->attribute_type;
@@ -663,7 +761,7 @@
664762 $info_id = "info_$gTabIndex";
665763
666764 $text =<<<END
667 - <input id="$input_id" tabindex="$gTabIndex" class="createboxInput" name="$input_name" type="text"
 765+ <input id="$input_id" tabindex="$gTabIndex" class="createboxInput" name="$input_name" type="text"
668766 value="$cur_value" size="$size" $gDisabledText/>
669767 <span id="$info_id" class="error_message"></span>
670768
@@ -690,23 +788,25 @@
691789 return $text;
692790 }
693791
694 - function textEntryWithAutocompleteHTML($size, $input_name, $part_of_multiple, $semantic_field_name, $is_relation, $cur_value) {
 792+ function textEntryWithAutocompleteHTML($size, $input_name, $part_of_multiple, $semantic_field_name, $is_relation, $cur_value, &$out_autocomplete_values) {
695793 global $gTabIndex, $gDisabledText;
696794 $gTabIndex++;
697795
698796 $input_id = "input_" . $gTabIndex;
699797 $info_id = "info_" . $gTabIndex;
700798 $div_name = "div_" . $gTabIndex;
701 - $options_str = SFFormPrinter::createAutocompleteValuesString(str_replace(' ', '_', $semantic_field_name), $is_relation);
702799 $text =<<<END
703800 <input tabindex="$gTabIndex" id="$input_id" name="$input_name" type="text"
704801 value="" size="$size" $gDisabledText/>
705802 <span id="$info_id" class="error_message"></span>
706803 <div class="page_name_auto_complete" id="$div_name" style="display:none"></div>
707804 <script type="text/javascript">
708 -new Autocompleter.Local('$input_id', '$div_name', $options_str, {});
709805
710806 END;
 807+ $options_str_key = $semantic_field_name . ',' . $is_relation;
 808+ if (!$out_autocomplete_values[$options_str_key])
 809+ $out_autocomplete_values[$options_str_key] = SFFormPrinter::createAutocompleteValuesString(str_replace(' ', '_', $semantic_field_name), $is_relation);
 810+ $out_autocomplete_values['mappings'][$gTabIndex] = $options_str_key;
711811 if ($cur_value) {
712812 $text .= "document.getElementById('$input_id').value = \"$cur_value\"\n";
713813 }
@@ -880,7 +980,7 @@
881981
882982 // Much of this function is based on MediaWiki's EditPage::showEditForm()
883983 function formBottom($target_title = null) {
884 - global $wgUser, $wgRightsText, $wgParser;
 984+ global $wgVersion, $wgUser, $wgRightsText, $wgParser;
885985 global $gTabIndex, $gDisabledText;
886986 $sk = $wgUser->getSkin();
887987
@@ -899,10 +999,20 @@
9001000 else
9011001 $cancel = $sk->makeKnownLink( $target_title->getPrefixedText(),
9021002 wfMsgExt('cancel', array('parseinline')) );
903 - $edithelpurl = Skin::makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ));
 1003+
 1004+ //Fix so extension works with MediaWiki 1.7
 1005+ if (substr_compare($wgVersion, '1.7', 0, 3) == 0)
 1006+ {
 1007+ $edithelpurl = $sk->makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ));
 1008+ }
 1009+ else
 1010+ {
 1011+ $edithelpurl = Skin::makeInternalOrExternalUrl( wfMsgForContent( 'edithelppage' ));
 1012+ }
 1013+
9041014 $edithelp = '<a target="helpwindow" href="'.$edithelpurl.'">'.
905 - htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
906 - htmlspecialchars( wfMsg( 'newwindow' ) );
 1015+ htmlspecialchars( wfMsg( 'edithelp' ) ).'</a> '.
 1016+ htmlspecialchars( wfMsg( 'newwindow' ) );
9071017
9081018 $gTabIndex++;
9091019 $text =<<<END
Index: trunk/extensions/SemanticForms/includes/SF_GlobalFunctions.php
@@ -3,7 +3,7 @@
44 * Global functions and constants for Semantic Forms.
55 */
66
7 -define('SF_VERSION','0.4.1');
 7+define('SF_VERSION','0.4.2');
88
99 $wgExtensionFunctions[] = 'sfgSetupExtension';
1010

Status & tagging log