This script performs the bulk of the upgrade translation to translate declarative tags from older versions of dojo up to the 1.6 format.
The script was written to work with tags in Smarty templates, so it includes a little extra logic to avoid confusion with Smarty syntax within the tags. If you’re not using Smarty, the script should still run fine, but you will need to change {ldelim} to { and {rdelim} to }.
Example of a simple translation performed by the tool.
Original
XML:
<label for="iDisplayMaxOffset">{#max_offset#}</label> | |
<input type="text" class="medium" | |
name="iDisplayMaxOffset" id="iDisplayMaxOffset" | |
dojoType="dijit.form.ValidationTextBox" | |
readonly="true" | |
value="{$iMaxOffset+1}" /> |
XML:
<label for="iDisplayMaxOffset">{#max_offset#}</label> | |
<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="'type':'text','class':'medium','name':'iDisplayMaxOffset','id':'iDisp | |
layMaxOffset','readonly':'true','value':'{$iMaxOffset+1}'"> |
Note that the attribute names are enclosed in single quotes. If there is a class attribute, for a custom CSS override, Internet Explorer (version 7, possibly others) requires the class attribute name to be quoted, or it may cause errors.
If a tag is too complex for this tool, it will output text recommending manual review, as well as the original tag, so you can fix any errors. In the translation below, the tool removed some of the message text.
XML:
{**** MANUAL REVIEW RECOMMENDED ****} | |
{**** | |
<input type="text" | |
name="sText" id="sText" | |
regExp="{$sExtLngRegExp}" | |
dojoType="dijit.form.ValidationTextBox" | |
promptMessage="{#C_enter#} {#text#}" | |
invalidMessage="{#C_invalid#} {#text#}" | |
errorMessage="{#C_invalid#} {#text#} {#C_refer_to_documentation#}" | |
value="{$sText}" | |
onChange="setDataChanged()" /> | |
****} | |
<input data-dojo-type="dijit.form.ValidationTextBox" data-dojo-props="'type':'text','name':'sText','id':'sText','regExp':'{$sExtLngRegExp}','promptMe | |
ssage':'{#C_enter#}','invalidMessage':'{#C_invalid#}','errorMessage':'{#C_invalid#}','value':'{$sText}','onChange':function(e){ldelim}setDataChanged(){rdelim}"> |
This is a command line script, run it with php dojo-tag.php old.file.html
PHP:
<?php | |
| |
$aEvents=array | |
('onblur'=>'onBlur', | |
'onchange'=>'onChange', | |
'onclick'=>'onClick', | |
'onclose'=>'onClose', | |
'ondblclick'=>'onDblClick', | |
'onfocus'=>'onFocus', | |
'onkeydown'=>'onKeyDown', | |
'onkeypress'=>'onKeyPress', | |
'onmousedown'=>'onMouseDown', | |
'onmouseenter'=>'onMouseEnter', | |
'onmouseleave'=>'onMouseLeave', | |
'onmousemove'=>'onMouseMove', | |
'onmouseout'=>'onMouseOut', | |
'onmouseover'=>'onMouseOver', | |
'onmouseup'=>'onMouseUp'); | |
| |
$aDeprecated=array('dijit.layout.AccordionPane'=>'dijit.layout.ContentPane'); | |
| |
$aDojoRequires=array(); | |
| |
$sFileText=file_get_contents($argv[1]); | |
| |
$sNewText=preg_replace_callback('/(^\s*dojo\.require\s*\([\'"]([^\'^"]*)[\'"]\);[\r\n\s]*$)/m','requires',$sFileText); | |
| |
$sUpdatedText=preg_replace_callback('/(<)(\w+) +([^>]*)(\/?>)/im','tags',$sNewText); | |
| |
echo $sUpdatedText.PHP_EOL; | |
| |
file_put_contents('/tmp/NEW',$sUpdatedText); | |
| |
function requires($aMatches) | |
{ | |
global $aDeprecated,$aDojoRequires; | |
$sDijit=trim($aMatches[2]); | |
if (array_key_exists($sDijit,$aDeprecated)) | |
$sDijit=$aDeprecated[$sDijit]; | |
if (!in_array($sDijit,$aDojoRequires)) | |
{ | |
$aDojoRequires[]=$sDijit; | |
return 'dojo.require("'.$sDijit.'");'; | |
} | |
return ''; | |
} | |
| |
function tags($aMatches) | |
{ | |
global $aDeprecated; | |
$sText=$aMatches[0]; | |
if (strpos($sText,'dojoType')!==false) | |
{ | |
$sDataDojoType='';$aDojoText=array();$sDojoText='data-dojo-props=';$bFlagForReview=false; | |
$sDataDojoId=''; | |
$aText=array(); | |
| |
$sAttributeText=$aMatches[3]; | |
if (($iLeft=strpos($sAttributeText,'{'))!==false) | |
{ | |
$iRight=strpos($sAttributeText,'}'); | |
$iCountLeft=substr_count($sAttributeText,'{'); | |
$iCountRight=substr_count($sAttributeText,'}'); | |
if (($iLeft>$iRight) || ($iCountLeft>1) || ($iCountRight>1)) | |
$bFlagForReview=true; | |
} | |
| |
preg_match_all('/([a-zA-Z]+=[^>\s]+)/m',$sAttributeText,$aText); | |
foreach ($aText[0] as $k => $v) | |
{ | |
if (stripos($v,'dojoType=')!==false) | |
{ | |
$sDataDojoType=substr(str_replace(array('\'','"'),'',trim($v)),9); | |
$bDeprecated=array_key_exists($sDataDojoType,$aDeprecated); | |
if ($bDeprecated!==false) | |
{ | |
$bFlagForReview=true; | |
$sDataDojoType=$aDeprecated[$sDataDojoType]; | |
} | |
$sDataDojoType='"'.$sDataDojoType.'"'; | |
} | |
else | |
if (stripos($v,'jsId=')!==false) | |
$sDataDojoId='data-dojo-id='.substr($v,5); | |
else | |
$aDojoText[]=pair($v,$bFlagForReview); | |
} | |
if (count($aDojoText)>0) | |
$sDojoText.='"'.implode(',',$aDojoText).'"'; | |
$sFlag=($bFlagForReview)?'{**** MANUAL REVIEW RECOMMENDED ****}'.PHP_EOL. | |
'{**** '.PHP_EOL.$sText.PHP_EOL.'****}'.PHP_EOL:''; | |
$sClose=(strpos($sText,'/>')===false)?'>':' />'; | |
return $sFlag.$aMatches[1].$aMatches[2].' data-dojo-type='.$sDataDojoType.' '.$sDojoText.$sClose; | |
} | |
else | |
return $sText; | |
} | |
| |
| |
function pair($value,&$bFlagForReview) | |
{ | |
global $aEvents; | |
$iEqual=strpos($value,'='); | |
$sProperty=substr($value,0,$iEqual); | |
$sValue=substr($value,$iEqual+1); | |
$sProperty=str_replace(array('\'','"'),'',trim($sProperty)); | |
$sValue=str_replace(array('\'','"'),'',trim($sValue)); | |
$bEvent=array_key_exists($sPropertyIndex=strtolower($sProperty),$aEvents); | |
if ($bEvent===false) | |
$sRetVal='\''.$sProperty.'\':\''.$sValue.'\''; | |
else | |
{ | |
$bFlagForReview=true; | |
$sRetVal='\''.$aEvents[$sPropertyIndex].'\':function(e){ldelim}'.$sValue.'{rdelim}'; | |
} | |
| |
return $sRetVal; | |
} |
This is a simple tool, it is intended to be run on one file at a time, with the output reviewed carefully.
This script will upgrade most of the javascript, be sure to check the code carefully after it runs.
Code:
#!/bin/bash | |
| |
# dojo 1.1.1 to dojo 1.6.1 javascript upgrade script | |
| |
if [ $# -lt 1 ] | |
then | |
echo 'Usage: dojo-js.sh <filename>' | |
exit; | |
fi | |
| |
NEW='/tmp/NEW' | |
cp $1 $NEW | |
| |
sed --in-place "/attr([^\,^)]*)/s/attr/get/g" $NEW | |
| |
# Must run AFTER the line above | |
sed --in-place "s/attr/set/g" $NEW | |
sed --in-place "s/\(\.set('value',[^\)]*\))/\1,false)/g" $NEW | |
| |
sed --in-place "s/\.setValue\ *( *\([^\)]* *\))/.set('value',\1,false)/g" $NEW | |
| |
sed --in-place "s/\.getValue\ *( *\([^\)]* *)\)/.get('value')/g" $NEW | |
| |
sed --in-place "s/json-comment-filtered/json/" $NEW | |
| |
sed --in-place "s/getDescendants\(.*\)$/getChildren\1 \/\/**** MANUAL REVIEW RECOMMENDED/" $NEW | |
| |
sed --in-place "s/setHref(/set('href',/g" $NEW | |
| |
sed --in-place "s/setAttribute/set/g" $NEW | |
| |
sed --in-place "s/\.checked\s*\=\s*\(true\|false\)/.set('checked',\1)/g" $NEW | |
sed --in-place "s/\.checked/.get('checked')/g" $NEW | |
| |
sed --in-place "s/getDisplayedValue()/get('displayedValue')/g" $NEW | |
| |
sed --in-place "s/setLabel(/set('label',/g" $NEW |
*** Make a backup before using these tools ***