diff --git a/docs/changelog/7.x.x.txt b/docs/changelog/7.x.x.txt index f8b042f1e..6d707c912 100644 --- a/docs/changelog/7.x.x.txt +++ b/docs/changelog/7.x.x.txt @@ -1,3 +1,17 @@ +7.10.2 + - fixed #11884: Editing Templates impossible / Code editor not loaded + - recommitted ukplayer. Removal broke Matrix. Licencing information was available but overlooked. + - fixed #11883: Wiki "Add page" link does not encode special chars + - fixed #11886: profile knows it's me, but doesn't display edit + - fixed #11789: Date form reports 1 day earlier on Edit for the time zone corresponding to Europe/Berlin. + - fixed #11894: Europe London timezone decrements birth date + - fixed #11857: make page printable? + - fixed #11891: Shop credit not displayed in payment method screen + - fixed #11871: Metadata display and criteria builder problems + - fixed #10189: pbworkflow000000000007 Hanging + - fixed #11897: Continue to the site link loses current page + - fixed #11618: Code Editor: Content loses it's whitespace formatting + 7.10.1 - fixed #11851: Story Topic: top story variables should be available all the time - fixed #11854: CS doesn't return Not Found page diff --git a/docs/gotcha.txt b/docs/gotcha.txt index e7a78128e..c650c9a2e 100644 --- a/docs/gotcha.txt +++ b/docs/gotcha.txt @@ -21,6 +21,19 @@ save you many hours of grief. Account Macro template Admin Toggle Macro template +7.10.2 +-------------------------------------------------------------------- + * The URL used by Display Message on Login always returns the user to + the page where they logged in. If your site depended on the old, + buggy behavior of returning the user to the home page after showing + a message, then in the Settings you can assign Redirect After Login Url + to /. + + * The UKPLayer - a slideshow that displays images as a movie - + is in WebGUI again. Licencing information was overlooked. An + upgrade to 7.10.1 will break the Matrix. This is fixed now. + + 7.10.1 -------------------------------------------------------------------- * WebGUI now depends on PerlIO::eol, for doing line ending translation. diff --git a/docs/templates.txt b/docs/templates.txt index e9bdc7e56..0aba47215 100644 --- a/docs/templates.txt +++ b/docs/templates.txt @@ -11,8 +11,19 @@ templates, you will need to apply these changes manually to your copies. toggle.url => toggle_url toggle.text => toggle_text +7.10.2 + + * The Make Page Printable template has changed (as per bug #11857). The HTML + is now consistent with other default Style templates. The Plain Black logo and + copyright info have been removed and a stylesheet was added to provide very + simple default formatting for text, header and footer (makepageprintable.css). + 7.10.1 + * Profile templates - root/import/account/profile/default-view-profile-template + - root/import/account/profile/profile-account-layout + Moved the "back to profile" link from the Profile View template to the Profile Layout template. + * Asset Report Template - asset-report/asset-report-default-template Remove the empty template attachment diff --git a/docs/upgrades/packages-7.10.1/root_import_account_profile.wgpkg b/docs/upgrades/packages-7.10.1/root_import_account_profile.wgpkg new file mode 100644 index 000000000..f609b3d3b Binary files /dev/null and b/docs/upgrades/packages-7.10.1/root_import_account_profile.wgpkg differ diff --git a/docs/upgrades/packages-7.10.2/root_import_style.wgpkg b/docs/upgrades/packages-7.10.2/root_import_style.wgpkg new file mode 100644 index 000000000..f1a4000a9 Binary files /dev/null and b/docs/upgrades/packages-7.10.2/root_import_style.wgpkg differ diff --git a/docs/upgrades/upgrade_7.10.1-7.10.2.pl b/docs/upgrades/upgrade_7.10.1-7.10.2.pl new file mode 100644 index 000000000..d2f49d9fc --- /dev/null +++ b/docs/upgrades/upgrade_7.10.1-7.10.2.pl @@ -0,0 +1,123 @@ +#!/usr/bin/env perl + +#------------------------------------------------------------------- +# WebGUI is Copyright 2001-2009 Plain Black Corporation. +#------------------------------------------------------------------- +# Please read the legal notices (docs/legal.txt) and the license +# (docs/license.txt) that came with this distribution before using +# this software. +#------------------------------------------------------------------- +# http://www.plainblack.com info@plainblack.com +#------------------------------------------------------------------- + +our ($webguiRoot); + +BEGIN { + $webguiRoot = "../.."; + unshift (@INC, $webguiRoot."/lib"); +} + +use strict; +use Getopt::Long; +use WebGUI::Session; +use WebGUI::Storage; +use WebGUI::Asset; + + +my $toVersion = '7.10.2'; +my $quiet; # this line required + + +my $session = start(); # this line required + +# upgrade functions go here + +finish($session); # this line required + + +#---------------------------------------------------------------------------- +# Describe what our function does +#sub exampleFunction { +# my $session = shift; +# print "\tWe're doing some stuff here that you should know about... " unless $quiet; +# # and here's our code +# print "DONE!\n" unless $quiet; +#} + + +# -------------- DO NOT EDIT BELOW THIS LINE -------------------------------- + +#---------------------------------------------------------------------------- +# Add a package to the import node +sub addPackage { + my $session = shift; + my $file = shift; + + print "\tUpgrading package $file\n" unless $quiet; + # Make a storage location for the package + my $storage = WebGUI::Storage->createTemp( $session ); + $storage->addFileFromFilesystem( $file ); + + # Import the package into the import node + my $package = eval { + my $node = WebGUI::Asset->getImportNode($session); + $node->importPackage( $storage, { + overwriteLatest => 1, + clearPackageFlag => 1, + setDefaultTemplate => 1, + } ); + }; + + if ($package eq 'corrupt') { + die "Corrupt package found in $file. Stopping upgrade.\n"; + } + if ($@ || !defined $package) { + die "Error during package import on $file: $@\nStopping upgrade\n."; + } + + return; +} + +#------------------------------------------------- +sub start { + my $configFile; + $|=1; #disable output buffering + GetOptions( + 'configFile=s'=>\$configFile, + 'quiet'=>\$quiet + ); + my $session = WebGUI::Session->open($webguiRoot,$configFile); + $session->user({userId=>3}); + my $versionTag = WebGUI::VersionTag->getWorking($session); + $versionTag->set({name=>"Upgrade to ".$toVersion}); + return $session; +} + +#------------------------------------------------- +sub finish { + my $session = shift; + updateTemplates($session); + my $versionTag = WebGUI::VersionTag->getWorking($session); + $versionTag->commit; + $session->db->write("insert into webguiVersion values (".$session->db->quote($toVersion).",'upgrade',".time().")"); + $session->close(); +} + +#------------------------------------------------- +sub updateTemplates { + my $session = shift; + return undef unless (-d "packages-".$toVersion); + print "\tUpdating packages.\n" unless ($quiet); + opendir(DIR,"packages-".$toVersion); + my @files = readdir(DIR); + closedir(DIR); + my $newFolder = undef; + foreach my $file (@files) { + next unless ($file =~ /\.wgpkg$/); + # Fix the filename to include a path + $file = "packages-" . $toVersion . "/" . $file; + addPackage( $session, $file ); + } +} + +#vim:ft=perl diff --git a/lib/WebGUI/Account/Profile.pm b/lib/WebGUI/Account/Profile.pm index 203ba95be..f0071ec21 100644 --- a/lib/WebGUI/Account/Profile.pm +++ b/lib/WebGUI/Account/Profile.pm @@ -82,7 +82,8 @@ sub appendCategoryVars { $var->{'profile_category_'.$categoryId."_shortLabel"} = $shortCategoryLabel; $var->{'profile_category_'.$categoryId."_index" } = $index; $var->{'profile_category_'.$categoryId."_fields" } = $fields; - + + $var->{'can_edit_profile' } = $self->uid eq $self->session->user->userId; #Update the isActive flag to determine the default active tab $self->store->{hasActiveTab} = ($self->store->{hasActiveTab} || $isActive); @@ -471,8 +472,6 @@ sub www_view { $self->appendCommonVars($var); - $var->{'can_edit_profile' } = $uid eq $session->user->userId; - my $privacySetting = $user->profileField('publicProfile') || 'none'; $var->{"profile_privacy_$privacySetting"} = "true"; diff --git a/lib/WebGUI/Asset.pm b/lib/WebGUI/Asset.pm index b5ed67201..b1888daa5 100644 --- a/lib/WebGUI/Asset.pm +++ b/lib/WebGUI/Asset.pm @@ -2642,7 +2642,7 @@ sub www_changeUrl { my $i18n = WebGUI::International->new($self->session, "Asset"); my $f = WebGUI::HTMLForm->new($self->session, action=>$self->getUrl); $f->hidden(name=>"func", value=>"changeUrlConfirm"); - $f->hidden(name=>"proceed", value=>$self->session->form->param("proceed")); + $f->hidden(name=>"proceed", value=>scalar($self->session->form->param("proceed"))); $f->text(name=>"url", value=>$self->get('url'), label=>$i18n->get("104"), hoverHelp=>$i18n->get('104 description')); $f->yesNo(name=>"confirm", value=>0, label=>$i18n->get("confirm change"), hoverHelp=>$i18n->get("confirm change url message"), subtext=>'
'.$i18n->get("confirm change url message")); $f->submit; diff --git a/lib/WebGUI/Asset/Event.pm b/lib/WebGUI/Asset/Event.pm index c521828b8..da48ff407 100644 --- a/lib/WebGUI/Asset/Event.pm +++ b/lib/WebGUI/Asset/Event.pm @@ -1440,7 +1440,7 @@ override processEditForm => sub { my $assetId = $self->getId; my $revisionDate = $self->revisionDate; - $session->db->write("UPDATE Event SET sequenceNumber =? WHERE assetId = ? AND revisionDate =?",[($form->param('sequenceNumber') || $top_val), $assetId, $revisionDate]); + $session->db->write("UPDATE Event SET sequenceNumber =? WHERE assetId = ? AND revisionDate =?",[(scalar($form->param('sequenceNumber')) || $top_val), $assetId, $revisionDate]); # Pre-process Related Links and manage changes diff --git a/lib/WebGUI/Asset/Shortcut.pm b/lib/WebGUI/Asset/Shortcut.pm index ada7e15df..e4b0bdf51 100644 --- a/lib/WebGUI/Asset/Shortcut.pm +++ b/lib/WebGUI/Asset/Shortcut.pm @@ -90,6 +90,9 @@ sub _drawQueryBuilder { "!=" => $i18n->get("isnt") }; } + $operator{checkList} = { + "+~" => $i18n->get("contains"), + }; $operator{integer} = { "=" => $i18n->get("equal to"), "!=" => $i18n->get("not equal to"), @@ -145,6 +148,8 @@ sub _drawQueryBuilder { # The value select field my $valFieldName = "val_field".$i; my $options = $fields->{$field}{possibleValues}; + ##Only allow one at a time to be selected, and work with current JS for choosing which one. + $fieldType = 'radioList' if $fieldType eq 'checkList'; my $valueField = WebGUI::Form::dynamicField($session, fieldType=>$fieldType, name=>$valFieldName, @@ -374,7 +379,6 @@ sub getFieldsList { foreach my $field (@{WebGUI::ProfileField->getFields($session)}) { my $fieldId = $field->getId; next if $fieldId =~ /contentPositions/; - $session->log->warn($fieldId); $fieldNames{$fieldId} = $field->getLabel.' ['.$fieldId.']'; } $output .= '
'; @@ -388,8 +392,6 @@ sub getFieldsList { -vertical=>1, -uiLevel=>9 ); - $session->log->warn($list->get('uiLevel')); - $session->log->warn($list->passUiLevelCheck); $output .= $list->toHtmlWithWrapper; $output .= '
'; my @prefFieldsToImport = $self->getPrefFieldsToImport; @@ -601,8 +603,8 @@ sub getShortcutByCriteria { # | | | # |- $field |_ $operator |- $value # |_ $attribute |_ $attribute - my $operator = qr/<>|!=|=|>=|<=|>|<|like/i; - my $attribute = qr/['"][^()|=>|!=|=|>=|<=|>|<|like|\+~/i; + my $attribute = qr/['"][^()|=>session->db; my $counter = "b"; my @joins = (); + ##Transform the expression into valid SQL foreach my $expression ($criteria =~ /($attribute\s*$operator\s*$attribute)/gi) { # $expression will match "State = Wisconsin" @@ -617,9 +620,10 @@ sub getShortcutByCriteria { # We need it later. push(@joins," left join metaData_values ".$counter."_v on a.assetId=".$counter."_v.assetId "); # Get the field (State) and the value (Wisconsin) from the $expression. - $expression =~ /($attribute)\s*$operator\s*($attribute)/gi; + $expression =~ /($attribute)\s*($operator)\s*($attribute)/gi; my $field = $1; - my $value = $2; + my $current_operator = $2; + my $value = $3; # quote the field / value variables. my $quotedField = $field; @@ -627,18 +631,21 @@ sub getShortcutByCriteria { unless ($field =~ /^\s*['"].*['"]\s*/) { $quotedField = $db->quote($field); } - unless ($value =~ /^\s*['"].*['"]\s*/) { - $quotedValue = $db->quote($value); - } + unless ($value =~ /^\s*['"].*['"]\s*/) { + $quotedValue = $db->quote($value); + } # transform replacement from "State = Wisconsin" to # "(fieldname=State and value = Wisconsin)" my $clause = "(".$counter."_p.fieldName=".$quotedField." and ".$counter."_v.value "; - $replacement =~ s/\Q$field/$clause/; - $replacement =~ s/\Q$value/$quotedValue )/i; + $replacement =~ s/\Q$field/$clause/; + $replacement =~ s/\Q$value/$quotedValue )/i; # replace $expression with the new $replacement in $constraint. - $constraint =~ s/\Q$expression/$replacement/; + $constraint =~ s/\Q$expression/$replacement/; + if ($current_operator eq '+~') { + $constraint =~ s/and ${counter}_v\.value\s*\+~\s*$quotedValue/and FIND_IN_SET($quotedValue, REPLACE(${counter}_v.value,"\\n",","))/; + } push (@joins, " left join metaData_properties ".$counter."_p on ".$counter."_p.fieldId=".$counter."_v.fieldId "); $counter++; } diff --git a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm index e7a3c7357..2004e33aa 100644 --- a/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm +++ b/lib/WebGUI/Asset/Wobject/EventManagementSystem.pm @@ -2023,7 +2023,7 @@ sub www_importEvents { -label => $i18n->get('ignore first line'), -name => 'ignore_first_line', -hoverHelp => $i18n->get('import hoverhelp first line'), - -defaultValue => $form->param('ignore_first_line'), + -defaultValue => scalar $form->param('ignore_first_line'), ); # create the std & meta fields part of the form @@ -2040,7 +2040,7 @@ sub www_importEvents { name => 'fieldsToImport', defaultValue => \@defaultImportableFields, options => \%importableFields, - value => $form->get('fieldsToImport'), + value => scalar $form->get('fieldsToImport'), ); $f->submit(-value=>$i18n->get('import events')); diff --git a/lib/WebGUI/Asset/Wobject/Thingy.pm b/lib/WebGUI/Asset/Wobject/Thingy.pm index b48093f62..bbc2a1501 100644 --- a/lib/WebGUI/Asset/Wobject/Thingy.pm +++ b/lib/WebGUI/Asset/Wobject/Thingy.pm @@ -2610,7 +2610,7 @@ sub www_editThingDataSaveViaAjax { return '{}'; } else { - warn "thingId not found in thingProperties\n"; + $session->log->warn("thingId ".$thingProperties->{thingId}." not found in thingProperties"); $session->http->setStatus(404); return JSON->new->encode({message => "The thingId you requested can not be found."}); } diff --git a/lib/WebGUI/Asset/Wobject/WikiMaster.pm b/lib/WebGUI/Asset/Wobject/WikiMaster.pm index 17212ba33..ee7c4eff8 100644 --- a/lib/WebGUI/Asset/Wobject/WikiMaster.pm +++ b/lib/WebGUI/Asset/Wobject/WikiMaster.pm @@ -196,6 +196,7 @@ use WebGUI::International; use HTML::Parser; use URI::Escape; use WebGUI::Form; +use WebGUI::Search; use Clone qw/clone/; #------------------------------------------------------------------- @@ -993,7 +994,7 @@ sub www_search { mostPopularUrl=>$self->getUrl("func=mostPopular"), mostPopularLabel=>$i18n->get("mostPopularLabel"), wikiHomeUrl=>$self->getUrl, - addPageUrl=>$self->getUrl("func=add;class=WebGUI::Asset::WikiPage;title=".$queryString), + addPageUrl=>$self->getUrl("func=add;class=WebGUI::Asset::WikiPage;title=".$self->session->url->escape($queryString)), }; $self->appendSearchBoxVars($var, $queryString); if (length $queryString) { diff --git a/lib/WebGUI/Auth.pm b/lib/WebGUI/Auth.pm index ab0c907ad..31c00b70a 100644 --- a/lib/WebGUI/Auth.pm +++ b/lib/WebGUI/Auth.pm @@ -1056,10 +1056,13 @@ sub showMessageOnLogin { WebGUI::Macro::process( $self->session, \$output ); # Add the link to continue + my $session = $self->session; + $session->log->warn("returnUrl: >".$self->session->form->get( 'returnUrl' )."<"); + $session->log->warn("redirectAfterLoginUrl: >".$self->session->form->get( 'returnUrl' )."<"); my $redirectUrl = $self->session->form->get( 'returnUrl' ) || $self->session->setting->get("redirectAfterLoginUrl") || $self->session->scratch->get( 'redirectAfterLogin' ) - || $self->session->url->getSiteURL . $self->session->url->gateway() + || $self->session->url->getBackToSiteURL ; $output .= '

' . $i18n->get( 'showMessageOnLogin return' ) diff --git a/lib/WebGUI/Form/Codearea.pm b/lib/WebGUI/Form/Codearea.pm index 2d896d537..03a42cea2 100644 --- a/lib/WebGUI/Form/Codearea.pm +++ b/lib/WebGUI/Form/Codearea.pm @@ -16,7 +16,6 @@ package WebGUI::Form::Codearea; use strict; use base 'WebGUI::Form::Textarea'; -use HTML::Entities qw(encode_entities decode_entities); use WebGUI::International; =head1 NAME @@ -90,18 +89,6 @@ sub definition { #------------------------------------------------------------------- -=head2 getDatabaseFieldType ( ) - -Returns "MEDIUMTEXT". - -=cut - -sub getDatabaseFieldType { - return "MEDIUMTEXT"; -} - -#------------------------------------------------------------------- - =head2 getName ( session ) Returns the human readable name of this control. @@ -113,101 +100,4 @@ sub getName { return WebGUI::International->new($session, 'WebGUI')->get('codearea'); } -#------------------------------------------------------------------- - -=head2 getValue ( [value] ) - -Return the value, HTML decoded - -=cut - -sub getValue { - my ( $self, @args ) = @_; - my $value = $self->SUPER::getValue( @args ); - return decode_entities( $value ); -} - -#------------------------------------------------------------------- - -=head2 headTags ( ) - -Set the head tags for this form plugin - -=cut - -sub headTags { - my $self = shift; - my ($style, $url) = $self->session->quick(qw(style url)); - $style->setCss($url->extras("yui/build/resize/assets/skins/sam/resize.css")); - $style->setCss($url->extras("yui/build/assets/skins/sam/skin.css")); - $style->setScript($url->extras("yui/build/utilities/utilities.js")); - $style->setScript($url->extras("yui/build/container/container_core-min.js")); - $style->setScript($url->extras("yui/build/menu/menu-min.js")); - $style->setScript($url->extras("yui/build/button/button-min.js")); - $style->setScript($url->extras("yui/build/resize/resize-min.js")); - $style->setScript($url->extras("yui/build/editor/editor-min.js")); - $style->setScript($url->extras("yui-webgui/build/code-editor/code-editor.js")); - #$style->setCss($url->extras("yui/build/logger/assets/logger.css")); - #$style->setCss($url->extras("yui/build/logger/assets/skins/sam/logger.css")); - #$style->setScript($url->extras("yui/build/logger/logger.js")); - $self->SUPER::headTags(); -} - -#------------------------------------------------------------------- - -=head2 isDynamicCompatible ( ) - -A class method that returns a boolean indicating whether this control is compatible with the DynamicField control. - -=cut - -sub isDynamicCompatible { - return 1; -} - -#------------------------------------------------------------------- - -=head2 toHtml ( ) - -Renders a code area field. - -=cut - -sub toHtml { - my $self = shift; - - my $value = encode_entities( $self->fixMacros($self->fixTags($self->fixSpecialCharacters(scalar $self->getOriginalValue))) ); - my $width = $self->get('width'); - if ( $width !~ /%|px/ ) { - $width .= 'px'; - } - my $height = $self->get('height'); - if ( $height !~ /%|px/ ) { - $height .= 'px'; - } - - my $id = $self->get('id'); - my $name = $self->get('name'); - my $extras = $self->get('extras'); - my $syntax = $self->get('syntax'); - my $styleAttr = $self->get('style'); - - my $codeCss = $self->session->url->extras("yui-webgui/build/code-editor/code.css"); - my $out = <<"END_HTML"; - - -END_HTML - return $out; -} - 1; - diff --git a/lib/WebGUI/Form/Date.pm b/lib/WebGUI/Form/Date.pm index e488072c0..346160032 100644 --- a/lib/WebGUI/Form/Date.pm +++ b/lib/WebGUI/Form/Date.pm @@ -18,6 +18,7 @@ use strict; use base 'WebGUI::Form::Text'; use WebGUI::Form::Hidden; use WebGUI::International; +use Scalar::Util qw/blessed/; my $isaEpoch = qr/^-?\d+$/; @@ -241,8 +242,11 @@ sub toHtml { $value = $self->set("value",''); } else { - $value = eval { WebGUI::DateTime->new($session, $self->getOriginalValue)->toMysqlDate; }; - $value = WebGUI::DateTime->new($session,0)->toMysqlDate if $value eq ''; + my $originalValue = $self->getOriginalValue; + my $dt = eval { WebGUI::DateTime->new($session, $originalValue); }; + $dt = WebGUI::DateTime->new($session,0) if ! (blessed $dt && $dt->isa('DateTime')); ##Parsing error + $dt->set_time_zone($session->datetime->getTimeZone); + $value = $dt->toMysqlDate; } my $field = WebGUI::Form::Text->new($self->session, diff --git a/lib/WebGUI/Form/HTMLArea.pm b/lib/WebGUI/Form/HTMLArea.pm index 427d07984..3cc4e225a 100644 --- a/lib/WebGUI/Form/HTMLArea.pm +++ b/lib/WebGUI/Form/HTMLArea.pm @@ -197,7 +197,6 @@ sub toHtml { $self->set("extras", $self->get('extras') . q{ onblur="fixChars(this.form['}.$self->get("name").q{'])" mce_editable="true" }); $self->set("resizable", 0); return $self->SUPER::toHtml.$self->{_richEdit}->getRichEditor($self->get('id')); - } #------------------------------------------------------------------- diff --git a/lib/WebGUI/Form/Slider.pm b/lib/WebGUI/Form/Slider.pm index e49c2e066..414f52127 100644 --- a/lib/WebGUI/Form/Slider.pm +++ b/lib/WebGUI/Form/Slider.pm @@ -276,7 +276,7 @@ sub headTags { =head2 toHtml ( ) -Renders an input tag of type text. +Set the head tags for this form plugin =cut diff --git a/lib/WebGUI/Form/Textarea.pm b/lib/WebGUI/Form/Textarea.pm index c69992d86..ba5141ab0 100644 --- a/lib/WebGUI/Form/Textarea.pm +++ b/lib/WebGUI/Form/Textarea.pm @@ -163,16 +163,9 @@ Renders an input tag of type text. sub toHtml { my $self = shift; my $value = $self->fixMacros($self->fixTags($self->fixSpecialCharacters(scalar $self->getOriginalValue))); - my $width = $self->get('width') || '100%'; - if ( $width !~ /%|px/ ) { - $width .= 'px'; - } - my $height = $self->get('height') || '100%'; - if ( $height !~ /%|px/ ) { - $height .= 'px'; - } - my ($style, $url, $stow) = $self->session->quick(qw(style url stow)); - my $sizeStyle = ' width: ' . $width . '; height: ' . $height . ';'; + my $width = $self->get('width') || 400; + my $height = $self->get('height') || 150; + my $sizeStyle = ' width: ' . $width . 'px; height: ' . $height . 'px;'; my $out = ' + + + diff --git a/www/extras/yui-webgui/build/code-editor/code-editor.js b/www/extras/yui-webgui/build/code-editor/code-editor.js deleted file mode 100755 index 7908dff6d..000000000 --- a/www/extras/yui-webgui/build/code-editor/code-editor.js +++ /dev/null @@ -1,747 +0,0 @@ -/* - * HTML Parser By John Resig (ejohn.org) - * Original code by Erik Arvidsson, Mozilla Public License - * http://erik.eae.net/simplehtmlparser/simplehtmlparser.js - * - * // Use like so: - * HTMLParser(htmlString, { - * start: function(tag, attrs, unary) {}, - * end: function(tag) {}, - * chars: function(text) {}, - * comment: function(text) {} - * }); - * - * // or to get an XML string: - * HTMLtoXML(htmlString); - * - * // or to get an XML DOM Document - * HTMLtoDOM(htmlString); - * - * // or to inject into an existing document/DOM node - * HTMLtoDOM(htmlString, document); - * HTMLtoDOM(htmlString, document.body); - * - */ - -(function(){ - - // Regular Expressions for parsing tags and attributes - var startTag = /^<(\w+)((?:\s+\w+(?:\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|[^>\s]+))?)*)\s*(\/?)>/, - endTag = /^<\/(\w+)[^>]*>/, - attr = /(\w+)(?:\s*=\s*(?:(?:"((?:\\.|[^"])*)")|(?:'((?:\\.|[^'])*)')|([^>\s]+)))?/g; - - // Empty Elements - HTML 4.01 - var empty = makeMap("area,base,basefont,br,col,frame,hr,img,input,isindex,link,meta,param,embed"); - - // Block Elements - HTML 4.01 - var block = makeMap("address,applet,blockquote,button,center,dd,del,dir,div,dl,dt,fieldset,form,frameset,hr,iframe,ins,isindex,li,map,menu,noframes,noscript,object,ol,p,pre,script,table,tbody,td,tfoot,th,thead,tr,ul"); - - // Inline Elements - HTML 4.01 - var inline = makeMap("a,abbr,acronym,applet,b,basefont,bdo,big,br,button,cite,code,del,dfn,em,font,i,iframe,img,input,ins,kbd,label,map,object,q,s,samp,script,select,small,span,strike,strong,sub,sup,textarea,tt,u,var"); - - // Elements that you can, intentionally, leave open - // (and which close themselves) - var closeSelf = makeMap("colgroup,dd,dt,li,options,p,td,tfoot,th,thead,tr"); - - // Attributes that have their values filled in disabled="disabled" - var fillAttrs = makeMap("checked,compact,declare,defer,disabled,ismap,multiple,nohref,noresize,noshade,nowrap,readonly,selected"); - - // Special Elements (can contain anything) - var special = makeMap("script,style"); - - var HTMLParser = this.HTMLParser = function( html, handler ) { - var index, chars, match, stack = [], last = html; - stack.last = function(){ - return this[ this.length - 1 ]; - }; - - while ( html ) { - chars = true; - - // Make sure we're not in a script or style element - if ( !stack.last() || !special[ stack.last() ] ) { - - // Comment - if ( html.indexOf(""); - - if ( index >= 0 ) { - if ( handler.comment ) - handler.comment( html.substring( 4, index ) ); - html = html.substring( index + 3 ); - chars = false; - } - - // end tag - } else if ( html.indexOf("]*>"), function(all, text){ - text = text.replace(//g, "$1") - .replace(//g, "$1"); - - if ( handler.chars ) - handler.chars( text ); - - return ""; - }); - - parseEndTag( "", stack.last() ); - } - - if ( html == last ) - throw "Parse Error: " + html; - last = html; - } - - // Clean up any remaining tags - parseEndTag(); - - function parseStartTag( tag, tagName, rest, unary ) { - if ( block[ tagName ] ) { - while ( stack.last() && inline[ stack.last() ] ) { - parseEndTag( "", stack.last() ); - } - } - - if ( closeSelf[ tagName ] && stack.last() == tagName ) { - parseEndTag( "", tagName ); - } - - unary = empty[ tagName ] || !!unary; - - if ( !unary ) - stack.push( tagName ); - - if ( handler.start ) { - var attrs = []; - - rest.replace(attr, function(match, name) { - var value = arguments[2] ? arguments[2] : - arguments[3] ? arguments[3] : - arguments[4] ? arguments[4] : - fillAttrs[name] ? name : ""; - - attrs.push({ - name: name, - value: value, - escaped: value.replace(/(^|[^\\])"/g, '$1\\\"') //" - }); - }); - - if ( handler.start ) - handler.start( tagName, attrs, unary ); - } - } - - function parseEndTag( tag, tagName ) { - // If no tag name is provided, clean shop - if ( !tagName ) - var pos = 0; - - // Find the closest opened tag of the same type - else - for ( var pos = stack.length - 1; pos >= 0; pos-- ) - if ( stack[ pos ] == tagName ) - break; - - if ( pos >= 0 ) { - // Close all the open elements, up the stack - for ( var i = stack.length - 1; i >= pos; i-- ) - if ( handler.end ) - handler.end( stack[ i ] ); - - // Remove the open elements from the stack - stack.length = pos; - } - } - }; - - this.HTMLtoXML = function( html ) { - var results = ""; - - HTMLParser(html, { - start: function( tag, attrs, unary ) { - results += "<" + tag; - - for ( var i = 0; i < attrs.length; i++ ) - results += " " + attrs[i].name + '="' + attrs[i].escaped + '"'; - - results += (unary ? "/" : "") + ">"; - }, - end: function( tag ) { - results += ""; - }, - chars: function( text ) { - results += text; - }, - comment: function( text ) { - results += ""; - } - }); - - return results; - }; - - this.HTMLtoDOM = function( html, doc ) { - // There can be only one of these elements - var one = makeMap("html,head,body,title"); - - // Enforce a structure for the document - var structure = { - link: "head", - base: "head" - }; - - if ( !doc ) { - if ( typeof DOMDocument != "undefined" ) - doc = new DOMDocument(); - else if ( typeof document != "undefined" && document.implementation && document.implementation.createDocument ) - doc = document.implementation.createDocument("", "", null); - else if ( typeof ActiveX != "undefined" ) - doc = new ActiveXObject("Msxml.DOMDocument"); - - } else - doc = doc.ownerDocument || - doc.getOwnerDocument && doc.getOwnerDocument() || - doc; - - var elems = [], - documentElement = doc.documentElement || - doc.getDocumentElement && doc.getDocumentElement(); - - // If we're dealing with an empty document then we - // need to pre-populate it with the HTML document structure - if ( !documentElement && doc.createElement ) (function(){ - var html = doc.createElement("html"); - var head = doc.createElement("head"); - head.appendChild( doc.createElement("title") ); - html.appendChild( head ); - html.appendChild( doc.createElement("body") ); - doc.appendChild( html ); - })(); - - // Find all the unique elements - if ( doc.getElementsByTagName ) - for ( var i in one ) - one[ i ] = doc.getElementsByTagName( i )[0]; - - // If we're working with a document, inject contents into - // the body element - var curParentNode = one.body; - - HTMLParser( html, { - start: function( tagName, attrs, unary ) { - // If it's a pre-built element, then we can ignore - // its construction - if ( one[ tagName ] ) { - curParentNode = one[ tagName ]; - return; - } - - var elem = doc.createElement( tagName ); - - for ( var attr in attrs ) - elem.setAttribute( attrs[ attr ].name, attrs[ attr ].value ); - - if ( structure[ tagName ] && typeof one[ structure[ tagName ] ] != "boolean" ) - one[ structure[ tagName ] ].appendChild( elem ); - - else if ( curParentNode && curParentNode.appendChild ) - curParentNode.appendChild( elem ); - - if ( !unary ) { - elems.push( elem ); - curParentNode = elem; - } - }, - end: function( tag ) { - elems.length -= 1; - - // Init the new parentNode - curParentNode = elems[ elems.length - 1 ]; - }, - chars: function( text ) { - curParentNode.appendChild( doc.createTextNode( text ) ); - }, - comment: function( text ) { - // create comment node - } - }); - - return doc; - }; - - function makeMap(str){ - var obj = {}, items = str.split(","); - for ( var i = 0; i < items.length; i++ ) - obj[ items[i] ] = true; - return obj; - } -})(); - - -(function() { - var Dom = YAHOO.util.Dom, - Event = YAHOO.util.Event, - Lang = YAHOO.lang - ; - - YAHOO.widget.CodeEditor = function (id, cfg) { - // TODO: Make a cfg for off by default - this.editorState = "on"; - - // Disable Editor configs that don't apply - cfg["animate"] = false; - cfg["dompath"] = false; - cfg["focusAtStart"] = false; - - // Default toolbar is different - cfg["toolbar"] = cfg["toolbar"] || { - titlebar : "Code Editor", - buttons : [] - }; - - YAHOO.widget.CodeEditor.superclass.constructor.call(this, id, cfg); - - // Allow us to have no buttons - // This will be fixed in a future version of YUI Editor - YAHOO.widget.Toolbar.prototype.disableAllButtons - = function () { - if (!this._buttonList) { - this._buttonList = []; - } - if (this.get('disabled')) { - return false; - } - var len = this._buttonList.length; - for (var i = 0; i < len; i++) { - this.disableButton(this._buttonList[i]); - } - }; - // End allow us to have no buttons - - this.on('editorContentLoaded', function() { - // Add the code stylesheet - var link = this._getDoc().createElement('link'); - link.rel = "stylesheet"; - link.type = "text/css"; - link.href = this.get('css_url'); - this._getDoc().getElementsByTagName('head')[0].appendChild(link); - // Highlight the initial value - if ( this.getEditorText() != this.old_text ) { - Lang.later(10, this, function () { this.highlight(true) } ); - if ( this.status ) { - Lang.later(100, this, this._writeStatus); - } - this.old_text = this.getEditorText(); - } - // Setup resize - if ( this.status ) { - this._setupResize(); - } - }, this, true); - - this.on('editorKeyUp', function(ev) { - // Highlight only if content has changed - if ( this.getEditorText() != this.old_text ) { - Lang.later(10, this, this.highlight); - if ( this.status ) { - Lang.later(100, this, this._writeStatus); - } - this.old_text = this.getEditorText(); - } - }, this, true); - - - //Borrowed this from CodePress: http://codepress.sourceforge.net - this.cc = '\u2009'; // carret char - // TODO: Make this configurable based on a syntax definition - this.keywords = [ - { code: /(<DOCTYPE.*?-->.)/g, tag: '$1' }, // comments - { code: /(<[^!]*?>)/g, tag: '$1' }, // all tags - { code: /(<!--.*?-->.)/g, tag: '$1' }, // comments - { code: /\b(YAHOO|widget|util|Dom|Event|lang)\b/g, tag: '$1' }, // reserved words - { code: /\b(break|continue|do|for|new|this|void|case|default|else|function|return|typeof|while|if|label|switch|var|with|catch|boolean|int|try|false|throws|null|true|goto)\b/g, tag: '$1' }, // reserved words - { code: /\"(.*?)(\"|
|<\/P>)/gi, tag: '"$1$2' }, // strings double quote - { code: /\'(.*?)(\'|
|<\/P>)/gi, tag: '\'$1$2' }, // strings single quote - { code: /\b(alert|isNaN|parent|Array|parseFloat|parseInt|blur|clearTimeout|prompt|prototype|close|confirm|length|Date|location|Math|document|element|name|self|elements|setTimeout|navigator|status|String|escape|Number|submit|eval|Object|event|onblur|focus|onerror|onfocus|onclick|top|onload|toString|onunload|unescape|open|valueOf|window|onmouseover|innerHTML)\b/g, tag: '$1' }, // special words - { code: /([^:]|^)\/\/(.*?)(//$2$3' }, // comments // - { code: /\/\*(.*?)\*\//g, tag: '/*$1*/' } // comments / * */ - ]; - //End Borrowed Content - - - if ( cfg["toggleButton"] ) { - var editor = this; - - // Add toggle button - var button = document.createElement("input"); - - button.type = "button"; - button.value = "Toggle Editor"; - - Event.addListener( button, "click", function () { - if ( editor.editorState == "off" ) { - editor.editorState = "on"; - var fc = editor.get('element').previousSibling, - el = editor.get('element'); - - Dom.setStyle(fc, 'position', 'static'); - Dom.setStyle(fc, 'top', '0'); - Dom.setStyle(fc, 'left', '0'); - Dom.setStyle(el, 'visibility', 'hidden'); - Dom.setStyle(el, 'top', '-9999px'); - Dom.setStyle(el, 'left', '-9999px'); - Dom.setStyle(el, 'position', 'absolute'); - editor.get('element_cont').addClass('yui-editor-container'); - YAHOO.log('Reset designMode on the Editor', 'info', 'example'); - editor._setDesignMode('on'); - YAHOO.log('Inject the HTML from the textarea into the editor', 'info', 'example'); - - // Escape HTML - var div = document.createElement("div"); - var text = editor.get('textarea').value; - // IE truncates whitespace internally, so go line by line - var lines = text.split(/\n/); - for ( var i = 0; i < lines.length; i++ ) { - var line = lines[i]; - YAHOO.log( i + ": " + line, "info", "CodeEditor" ); - div.appendChild( document.createTextNode( line ) ); - div.appendChild( document.createElement( "br" ) ); - } - var html = div.innerHTML; - // We have
, not \n - html = html.replace(/\n/g,""); - - YAHOO.log( html, "info", "CodeEditor" ); - editor.setEditorHTML(html); - editor.highlight(); - } - else { - editor.editorState = "off"; - editor.saveHTML(); - var fc = editor.get('element').previousSibling, - el = editor.get('element'); - - Dom.setStyle(fc, 'position', 'absolute'); - Dom.setStyle(fc, 'top', '-9999px'); - Dom.setStyle(fc, 'left', '-9999px'); - editor.get('element_cont').removeClass('yui-editor-container'); - Dom.setStyle(el, 'visibility', 'visible'); - Dom.setStyle(el, 'top', ''); - Dom.setStyle(el, 'left', ''); - Dom.setStyle(el, 'position', 'static'); - - // Unescape HTML - var div = document.createElement("div"); - var text = editor.getEditorText(); - // IE truncates all whitespace internally, so add HTML for it - if ( editor.browser.ie && editor.browser.ie <= 8 ) { - text = text.replace(/\n/g, " 
"); - text = text.replace(/\t/g, "    "); - } - div.innerHTML = text; - editor.get('element').value = ""; - for ( var i = 0; i < div.childNodes.length; i++ ) { - if ( div.childNodes[i].nodeName == "#text" ) { - editor.get('element').value = editor.get('element').value - + div.childNodes[i].nodeValue - + "\n" - ; - } - } - YAHOO.log( editor.getEditorText(), "info", "CodeEditor" ); - YAHOO.log( div.childNodes[0].nodeValue, "info", "CodeEditor" ); - YAHOO.log( editor.get('element').value, "info", "CodeEditor" ); - } - } ); - - // Put it right after the text area - var ta = document.getElementById( id ); - if ( ta.nextSibling ) { - ta.parentNode.insertBefore( button, ta.nextSibling ); - } - else { - ta.parentNode.appendChild( button ); - } - } - }; - Lang.extend( YAHOO.widget.CodeEditor, YAHOO.widget.SimpleEditor, { - /** - * @property _defaultCSS - * @description The default CSS used in the config for 'css'. This way you can add to the config like this: { css: YAHOO.widget.SimpleEditor.prototype._defaultCSS + 'ADD MYY CSS HERE' } - * @type String - */ - _defaultCSS: 'html { height: 95%; } body { background-color: #fff; font:13px/1.22 arial,helvetica,clean,sans-serif;*font-size:small;*font:x-small; } a, a:visited, a:hover { color: blue !important; text-decoration: underline !important; cursor: text !important; } .warning-localfile { border-bottom: 1px dashed red !important; } .yui-busy { cursor: wait !important; } img.selected { border: 2px dotted #808080; } img { cursor: pointer !important; border: none; } body.ptags.webkit div { margin: 11px 0; }' - }); - - /** - * @private - * @method _cleanIncomingHTML - * @description Clean up the HTML that the textarea starts with - */ - YAHOO.widget.CodeEditor.prototype._cleanIncomingHTML = function(str) { - // Workaround for bug in Lang.substitute - str = str.replace(/{/gi, 'RIGHT_BRACKET'); - str = str.replace(/}/gi, 'LEFT_BRACKET'); - - //   before
for IE8- so lines show up correctly - if ( this.browser.ie && this.browser.ie <= 8 ) { - str = str.replace(/\r?\n/g, " 
"); - } - - // Fix tabs into softtabs - str = str.replace(/\t/g, '    '); // TODO: Make softtabs configurable - - return str; - }; - - /* Override to fix problem with the rest of what the normal _handleFormSubmit does - * ( it doesn't properly click the correct submit button ) - */ - YAHOO.widget.CodeEditor.prototype._handleFormSubmit = function () { - if ( this.editorState == "on" ) { - this.saveHTML(); - } - return; - }; - /* End override to fix problem */ - - /** - * @private - * @method _writeStatus - * @description Write the number of Characters and Lines to the status line - */ - YAHOO.widget.CodeEditor.prototype._writeStatus = function () { - if ( this.status ) { - var text = this.getEditorText(); - this.status.innerHTML - = 'C: ' + text.length - + ' L: ' + text.split(/\r?\n/).length - ; - } - }; - - /** - * @private - * @method _setupResize - * @description Creates the Resize instance and binds its events. - */ - YAHOO.widget.CodeEditor.prototype._setupResize - = function() { - if (!YAHOO.util.DD || !YAHOO.util.Resize) { return false; } - if (this.get('resize')) { - var config = {}; - Lang.augmentObject(config, this._resizeConfig); //Break the config reference - this.resize = new YAHOO.util.Resize(this.get('element_cont').get('element'), config); - this.resize.on('resize', function(args) { - var anim = this.get('animate'); - this.set('animate', false); - this.set('width', args.width + 'px'); - var h = args.height, - th = (this.toolbar.get('element').clientHeight + 2), - dh = 0; - if (this.status) { - dh = (this.status.clientHeight + 1); //It has a 1px top border.. - } - var newH = (h - th - dh); - this.set('height', newH + 'px'); - this.get('element_cont').setStyle('height', ''); - this.set('animate', anim); - }, this, true); - } - }; - - /* - * @method cleanHTML - * @description Reduce the HTML in the editor to plain text to be put back in the - * textarea. Called by saveHTML() - */ - YAHOO.widget.CodeEditor.prototype.cleanHTML = function (html) { - if (!html) { - html = this.getEditorHTML(); - } - - // Handle special-case HTML - html = html.replace(/( ){4}/g,"\t"); // TODO: make softtabs configurable - html = html.replace(/ /g," "); - // Remove spaces at end of lines - html = html.replace(/ ?
/gi,'\n'); - - // Parse the text out of the remaining HTML - text = ""; - HTMLParser( html, { - chars : function (t) { text += t } - } ); - - // If, after all this, we are left with only a \n, user didn't add anything - // (editor adds a
if it starts blank) - if ( text == "\n" ) { - text = ""; - } - - return text; - }; - - /* - * @method focusCaret - * @description I don't actually know what this does, it was like this when I got here - */ - YAHOO.widget.CodeEditor.prototype.focusCaret = function() { - if (this.browser.gecko) { - if (this._getWindow().find(this.cc)) { - this._getSelection().getRangeAt(0).deleteContents(); - } - } else if (this.browser.webkit || this.browser.ie || this.browser.opera) { - var cur = this._getDoc().getElementById('cur'); - if ( cur ) { - cur.id = ''; - cur.innerHTML = ''; - this._selectNode(cur); - } - } - }; - - /** - * @method getEditorText - * @description Get the text inside the editor, removing any HTML used for highlighting - */ - YAHOO.widget.CodeEditor.prototype.getEditorText - = function () { - var html = this.getEditorHTML(); - var text = this.cleanHTML( html ); - return text; - }; - - /** - * @method highlight - * @description Apply the syntax highlighting to the content of the editor - * @param {Boolean} focus If true, editor currently has focus - */ - YAHOO.widget.CodeEditor.prototype.highlight = function(focus) { - - // Opera support is not working yet - if ( this.browser.opera ) { - return; - } - // Firefox < 3 support is not working yet - if ( this.browser.gecko && this.browser.gecko <= 1.8 ) { - return; - } - - // Keep track of where the cursor is right now - if (!focus) { - if (this.browser.gecko) { - this._getSelection().getRangeAt(0).insertNode(this._getDoc().createTextNode(this.cc)); - } else if (this.browser.webkit || this.browser.ie || this.browser.opera) { - try { - this.execCommand('inserthtml', this.cc); - } - catch (e) {} - } - } - - // Remove existing highlighting - var html = this.getEditorText(); - - // Fix line breaks - html = html.replace( /\t/g, "    " ); - if ( this.browser.ie ) { - html = html.replace( /\n/g, " 
" ); - } - else { - html = html.replace( /\n/g, "
"); - } - - // Apply new highlighting - for (var i = 0; i < this.keywords.length; i++) { - html = html.replace(this.keywords[i].code, this.keywords[i].tag); - } - - // Replace cursor - if ( !this.browser.gecko ) { - html = html.replace(this.cc, '|'); - } - - this._getDoc().body.innerHTML = html; - if (!focus) { - this.focusCaret(); - } - }; - - /** - * @method initAttributes - * @description Initializes all of the configuration attributes used to create - * the editor. - * @param {Object} attr Object literal specifying a set of - * configuration attributes used to create the editor. - */ - YAHOO.widget.CodeEditor.prototype.initAttributes - = function(attr) { - YAHOO.widget.CodeEditor.superclass.initAttributes.call(this, attr); - var self = this; - /** - * @attribute status - * @description Toggle the display of a status line below the editor - * @default false - * @type Boolean - */ - this.setAttributeConfig('status', { - value: attr.status || false, - method: function(status) { - if (status && !this.status) { - this.status = document.createElement('DIV'); - this.status.id = this.get('id') + '_status'; - Dom.addClass(this.status, 'dompath'); // Piggy-back on Editor's dompath - this.get('element_cont').get('firstChild').appendChild(this.status); - if (this.get('iframe')) { - this._writeStatus(); - } - } else if (!status && this.status) { - this.status.parentNode.removeChild(this.status); - this.status = null; - } - } - }); - /** - * @attribute css_url - * @description The URL to the CSS file for the inside of the code editor - * @default 'code.css' - * @type String - */ - this.setAttributeConfig('css_url', { - value: attr.css_url || 'code.css' - } ); - }; - -})(); - diff --git a/www/extras/yui-webgui/build/code-editor/code.css b/www/extras/yui-webgui/build/code-editor/code.css deleted file mode 100755 index 783326044..000000000 --- a/www/extras/yui-webgui/build/code-editor/code.css +++ /dev/null @@ -1,9 +0,0 @@ -body { background:white url(line-numbers.png) repeat-y scroll 0pt -4px; font-family:monospace; font-size:13px; height:100%; line-height:16px; margin-left:32px; margin-top:8px; white-space:pre; } -b, i, s, u, a, em, tt, ins, big, cite, strong, var, dfn {text-decoration:none;font-weight:normal;font-style:normal;font-size:13px;} -b, cite {color:#7F0055;font-weight:bold;} /* reserved words */ -u {color:darkblue;font-weight:bold;} /* special words */ -i, i b, i s, i u {color:green;font-weight:normal;} /* comments */ -s, s b, s u {color:#2A00FF;font-weight:normal;} /* strings */ -ins, ins b, ins s, ins em {color:green;} /* comments */ -a {color:blue; text-decoration: underline; } /* links */ -body.ie { padding-left: 32px; margin-left: 0px; background-position: 0 -10px; margin-top: 0px;} diff --git a/www/extras/yui-webgui/build/code-editor/line-numbers.png b/www/extras/yui-webgui/build/code-editor/line-numbers.png deleted file mode 100755 index ffea4e6aa..000000000 Binary files a/www/extras/yui-webgui/build/code-editor/line-numbers.png and /dev/null differ