From 27521df744159fb0d983490a8251daee41a9962f Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 5 Nov 2009 03:08:41 +0000 Subject: [PATCH 001/483] MINOR Changed silverstripe.com references to silverstripe.org git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@90887 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 29f349c2..9b5d69cd 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -111,7 +111,7 @@ class LeftAndMain extends Controller { CMSMenu::add_link( 'Help', _t('LeftAndMain.HELP', 'Help', PR_HIGH, 'Menu title'), - 'http://userhelp.silverstripe.com' + 'http://userhelp.silverstripe.org' ); // set reading lang From 9b49ebf8b495c6f0fc1b26e6025d4cbcaa24bdea Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 5 Nov 2009 22:54:17 +0000 Subject: [PATCH 002/483] BUGFIX Fixed pages not being manipulated properly in the CMS because of a PHP error in CMSBatchAction git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@90936 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSBatchAction.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/CMSBatchAction.php b/code/CMSBatchAction.php index 185e7334..e44e0147 100644 --- a/code/CMSBatchAction.php +++ b/code/CMSBatchAction.php @@ -172,9 +172,6 @@ class CMSBatchAction_DeleteFromLive extends CMSBatchAction { FormResponse::add("if(node && node.parentTreeNode) node.parentTreeNode.removeTreeNode(node);"); FormResponse::add("$('Form_EditForm').reloadIfSetTo($id);"); } - - $page->destroy(); - unset($page); } $message = sprintf(_t('CMSBatchActions.DELETED_PAGES', 'Deleted %d pages from the published site'), $pages->Count()); From e4d9e265d24de7c7a434d16f33ed5801b9f6ec2b Mon Sep 17 00:00:00 2001 From: Andrew O'Neil Date: Tue, 10 Nov 2009 21:27:42 +0000 Subject: [PATCH 003/483] BUGFIX: Fix concurrent editing message always being displayed on page version history. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91203 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 4771989b..573faef1 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -874,7 +874,7 @@ var CurrentPage = { } setInterval(function() { - if ($('Form_EditForm_ID')) { + if ($('Form_EditForm_ID') && !($('Form_EditForm_ArchiveURL'))) { new Ajax.Request("admin/pageStatus?ID="+CurrentPage.id()+'&Version='+CurrentPage.version(), { onSuccess: function(t) { var data = eval('('+t.responseText+')'); From d6a2e66c891e3aa71ac5e54076612977173b1216 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Tue, 10 Nov 2009 21:37:11 +0000 Subject: [PATCH 004/483] MINOR removed concurrent editing (merged from r91198) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91205 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSBatchAction.php | 2 +- code/LeftAndMain.php | 46 +--------------------------- javascript/LeftAndMain.js | 63 ++------------------------------------- 3 files changed, 4 insertions(+), 107 deletions(-) diff --git a/code/CMSBatchAction.php b/code/CMSBatchAction.php index e44e0147..d060b61a 100644 --- a/code/CMSBatchAction.php +++ b/code/CMSBatchAction.php @@ -138,7 +138,7 @@ class CMSBatchAction_Delete extends CMSBatchAction { } /** - * Delete items batch action. + * Unpublish (delete from live site) items batch action. * * @package cms * @subpackage batchaction diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 9b5d69cd..903e3d6c 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -32,8 +32,6 @@ class LeftAndMain extends Controller { static $tree_class = null; - static $edit_timeout = 180; - static $ForceReload; static $allowed_actions = array( @@ -51,7 +49,6 @@ class LeftAndMain extends Controller { 'Member_ProfileForm', 'EditorToolbar', 'EditForm', - 'pageStatus', ); /** @@ -719,9 +716,6 @@ JS; FormResponse::add("\$('Form_EditForm_StageURLSegment').value = \"{$record->URLSegment}\";"); } - $newVersion = ((int)$record->Version) + 1; - FormResponse::add("if(\$('Form_EditForm_Version')) \$('Form_EditForm_Version').value = {$newVersion};"); - // If the 'Save & Publish' button was clicked, also publish the page if (isset($urlParams['publish']) && $urlParams['publish'] == 1) { $this->extend('onAfterSave', $record); @@ -751,7 +745,7 @@ JS; $result .= $this->getActionUpdateJS($record); FormResponse::status_message($message, "good"); FormResponse::update_status($record->Status); - + $this->extend('onAfterSave', $record); return FormResponse::respond(); @@ -1062,44 +1056,6 @@ JS; * when multiple users are editing a single page. It echoes a json * encoded string to the UA. */ - public function pageStatus() { - // If no ID is set, we're merely keeping the session alive - if (!isset($_REQUEST['ID'])) return 1; - - $page = $this->getRecord($_REQUEST['ID']); - if (!$page) { - // Page has not been found - $return = array('status' => 'not_found'); - } elseif ($page->getIsDeletedFromStage()) { - // Page has been deleted from stage - $return = array('status' => 'deleted'); - } else { - // Mark me as editing if I'm not already - $page->UsersCurrentlyEditing()->add(Member::currentUser()); - DB::query("UPDATE SiteTree_UsersCurrentlyEditing SET LastPing = '".date('Y-m-d H:i:s')."' - WHERE MemberID = ".Member::currentUserID()." AND SiteTreeID = {$page->ID}"); - - // Page exists, who else is editing it? - $names = array(); - foreach($page->UsersCurrentlyEditing() as $user) { - if ($user->ID == Member::currentUserId()) continue; - $names[] = trim($user->FirstName . ' ' . $user->Surname); - } - $return = array('status' => 'editing', 'names' => $names); - - // Has it been published since the CMS first loaded it? - $usersCurrentVersion = isset($_REQUEST['Version']) ? $_REQUEST['Version'] : $page->Version; - if ($usersCurrentVersion < $page->Version) { - $return = array('status' => 'not_current_version'); - } - } - - // Delete pings older than 3 minutes from the cache... - DB::query("DELETE FROM SiteTree_UsersCurrentlyEditing WHERE LastPing < '".date('Y-m-d H:i:s', time()-self::$edit_timeout)."'"); - - echo Convert::array2json($return); - return; - } /** * Return the CMS's HTML-editor toolbar diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 573faef1..5a1d2d82 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -1,5 +1,4 @@ var _AJAX_LOADING = false; -var pagePingInterval = 15; // Resize the tabs once the document is properly loaded // @todo most of this file needs to be tidied up using jQuery @@ -866,67 +865,9 @@ function hideIndicator(id) { Effect.Fade(id, {duration: 0.3}); } -var CurrentPage = { - id: function() { if($('Form_EditForm_ID')) return $('Form_EditForm_ID').value; }, - version: function() { if($('Form_EditForm_Version')) return parseInt($('Form_EditForm_Version').value, 10); }, - setVersion: function(version) { $('Form_EditForm_Version').value = version; }, - isDeleted: function() { if($('SiteTree_Alert')) return $('SiteTree_Alert').getAttribute('deletedfromstage'); } -} - setInterval(function() { - if ($('Form_EditForm_ID') && !($('Form_EditForm_ArchiveURL'))) { - new Ajax.Request("admin/pageStatus?ID="+CurrentPage.id()+'&Version='+CurrentPage.version(), { - onSuccess: function(t) { - var data = eval('('+t.responseText+')'); - var hasAlert = false; - - switch(data.status) { - case 'editing': - $('SiteTree_Alert').style.border = '2px solid #B5D4FE'; - $('SiteTree_Alert').style.backgroundColor = '#F8FAFC'; - if (data.names.length) { - hasAlert = true; - $('SiteTree_Alert').innerHTML = "This page is also being edited by: "+data.names.join(', '); - } - break; - case 'deleted': - // handle deletion by another user (but not us, or if we're already looking at a deleted version) - if (CurrentPage.isDeleted() == 0) { - $('SiteTree_Alert').style.border = '2px solid #ffd324'; - $('SiteTree_Alert').style.backgroundColor = '#fff6bf'; - $('SiteTree_Alert').innerHTML = "This page has been deleted since you opened it."; - hasAlert = true; - } - break; - case 'not_current_version': - // handle another user publishing - $('SiteTree_Alert').style.border = '2px solid #FFD324'; - $('SiteTree_Alert').style.backgroundColor = '#fff6bf'; - $('SiteTree_Alert').innerHTML = "This page has been saved since you opened it. You may want to reload it, or risk overwriting changes."; - hasAlert = true; - break; - case 'not_found': - break; - } - - if (hasAlert) { - $('SiteTree_Alert').style.padding = '5px'; - $('SiteTree_Alert').style.marginBottom = '5px'; - $('SiteTree_Alert').style.display = 'block'; - } else { - $('SiteTree_Alert').innerHTML = ''; - $('SiteTree_Alert').style.padding = '0px'; - $('SiteTree_Alert').style.marginBottom = '0px'; - if ($('SiteTree_Alert').style.display != 'none') $('SiteTree_Alert').style.display = 'none'; - } - } - }); - } else { - // We're not looking at a page, so at this stage, we're just - // pinging to keep the session alive. - new Ajax.Request("admin/pageStatus"); - } -}, pagePingInterval*1000); + new Ajax.Request("Security/ping"); +}, 180*1000); /** * Find and enable TinyMCE on all htmleditor fields From 3e7990d9417c180a46d4d4719d50cade5b258d15 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 12 Nov 2009 10:42:37 +0000 Subject: [PATCH 005/483] BUGFIX Fixed PageComment boolean operators in WHERE SQL clauses that break MSSQL git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91444 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CommentAdmin.php | 8 ++++---- code/sitefeatures/PageComment.php | 2 +- code/sitefeatures/PageCommentInterface.php | 4 ++-- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/code/CommentAdmin.php b/code/CommentAdmin.php index ed0b13c9..3e7b4df5 100644 --- a/code/CommentAdmin.php +++ b/code/CommentAdmin.php @@ -56,13 +56,13 @@ class CommentAdmin extends LeftAndMain { $section = $this->Section(); if($section == 'approved') { - $filter = "\"IsSpam\"=0 AND \"NeedsModeration\"=0"; + $filter = "\"IsSpam\" = 0 AND \"NeedsModeration\" = 0"; $title = "

". _t('CommentAdmin.APPROVEDCOMMENTS', 'Approved Comments')."

"; } else if($section == 'unmoderated') { - $filter = '"NeedsModeration"'; + $filter = '"NeedsModeration" = 1'; $title = "

"._t('CommentAdmin.COMMENTSAWAITINGMODERATION', 'Comments Awaiting Moderation')."

"; } else { - $filter = '"IsSpam"'; + $filter = '"IsSpam" = 1'; $title = "

"._t('CommentAdmin.SPAM', 'Spam')."

"; } @@ -147,7 +147,7 @@ JS; function deleteall() { $numComments = 0; - $spam = DataObject::get('PageComment', '"PageComment"."IsSpam"'); + $spam = DataObject::get('PageComment', '"PageComment"."IsSpam" = 1'); if($spam) { $numComments = $spam->Count(); diff --git a/code/sitefeatures/PageComment.php b/code/sitefeatures/PageComment.php index bfe2524c..907ea432 100755 --- a/code/sitefeatures/PageComment.php +++ b/code/sitefeatures/PageComment.php @@ -166,7 +166,7 @@ class PageComment extends DataObject { class PageComment_Controller extends Controller { function rss() { $parentcheck = isset($_REQUEST['pageid']) ? "\"ParentID\" = " . (int) $_REQUEST['pageid'] : "\"ParentID\" > 0"; - $unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND NOT \"NeedsModeration\""; + $unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND \"NeedsModeration\" = 0"; $comments = DataObject::get("PageComment", "$parentcheck AND \"IsSpam\" = 0 $unmoderatedfilter", "\"Created\" DESC", "", 10); if(!isset($comments)) { $comments = new DataObjectSet(); diff --git a/code/sitefeatures/PageCommentInterface.php b/code/sitefeatures/PageCommentInterface.php index a8602a6e..c34d82bc 100755 --- a/code/sitefeatures/PageCommentInterface.php +++ b/code/sitefeatures/PageCommentInterface.php @@ -210,8 +210,8 @@ class PageCommentInterface extends RequestHandler { $limit['start'] = isset($_GET['commentStart']) ? (int)$_GET['commentStart'] : 0; $limit['limit'] = PageComment::$comments_per_page; - $spamfilter = isset($_GET['showspam']) ? '' : "AND \"IsSpam\"=0"; - $unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND \"NeedsModeration\"=0"; + $spamfilter = isset($_GET['showspam']) ? '' : "AND \"IsSpam\" = 0"; + $unmoderatedfilter = Permission::check('ADMIN') ? '' : "AND \"NeedsModeration\" = 0"; $comments = DataObject::get("PageComment", "\"ParentID\" = '" . Convert::raw2sql($this->page->ID) . "' $spamfilter $unmoderatedfilter", '"Created" DESC', "", $limit); if(is_null($comments)) { From a9427422c0cc99170ee0ace0e60abb4ea89c1a5a Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 13 Nov 2009 00:19:55 +0000 Subject: [PATCH 006/483] FEATURE: added ability to upload images from site content pane. Merged via r9130, r91347, r91350, r91480 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91496 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 34 +++++--- images/swf-upload-button-small.jpg | Bin 0 -> 1916 bytes javascript/CMSMain_upload.js | 9 --- javascript/TinyMCEImageEnhancement.js | 107 +++++++++----------------- javascript/Upload.js | 45 ++++++++--- 5 files changed, 94 insertions(+), 101 deletions(-) create mode 100644 images/swf-upload-button-small.jpg diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index 71e13d3c..c2c0dc0f 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -86,7 +86,7 @@ class AssetAdmin extends LeftAndMain { Requirements::javascript(CMS_DIR . "/javascript/CMSMain_upload.js"); Requirements::javascript(CMS_DIR . "/javascript/Upload.js"); - Requirements::javascript(THIRDPARTY_DIR . "/SWFUpload/SWFUpload.js"); + Requirements::javascript(THIRDPARTY_DIR . "/SWFUpload/swfupload.js"); Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js"); Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js"); @@ -165,23 +165,37 @@ JS * It will save the uploaded files to /assets/ and create new File objects as required. */ function doUpload($data, $form) { - foreach($data['Files'] as $param => $files) { - if(!is_array($files)) $files = array($files); - foreach($files as $key => $value) { - $processedFiles[$key][$param] = $value; + $processedFiles = array(); + + if(!isset($data['Files'])) return Director::set_status_code("404"); + + if(is_array($data['Files'])) { + foreach($data['Files'] as $param => $files) { + if(!is_array($files)) $files = array($files); + foreach($files as $key => $value) { + $processedFiles[$key][$param] = $value; + } } } + else { + $proccessedFiles[] = $data['Files']; + } + + // get the folder to upload to. + if(isset($data['FolderID']) && $data['FolderID'] != "root") { + $folder = DataObject::get_by_id('Folder', $data['FolderID']); + } + else { + $folder = DataObject::get_one('Folder'); + } - if($data['ID'] && $data['ID'] != 'root') $folder = DataObject::get_by_id("Folder", $data['ID']); - else $folder = singleton('Folder'); - $newFiles = array(); $fileSizeWarnings = ''; $uploadErrors = ''; $jsErrors = ''; $status = ''; $statusMessage = ''; - + foreach($processedFiles as $tmpFile) { if($tmpFile['error'] == UPLOAD_ERR_NO_TMP_DIR) { $status = 'bad'; @@ -226,7 +240,7 @@ JS $statusMessage = _t('AssetAdmin.NOTHINGTOUPLOAD','There was nothing to upload'); $status = ""; } - + $fileIDs = array(); $fileNames = array(); foreach($newFiles as $newFile) { diff --git a/images/swf-upload-button-small.jpg b/images/swf-upload-button-small.jpg new file mode 100644 index 0000000000000000000000000000000000000000..8655b8afebb4101a55e0892d83eb8c3f822fc184 GIT binary patch literal 1916 zcma)$dojE!_^~z-znUb2 zMsmyMl4iF2x(FGDG45TcEGm~0Y1V0fzdgJE{oc=c&Uv5LbDrmU%LnA+0C!-&!+rq4 z0AQ~bkWT~rzR2Uju>b-H0D$Ehngz<%>@eS-09&+1Ao&nD15gMA0*OE&k*Ia3wN_L> zp%fIc7>ptYgT-OL35Qiy!Ko-?2?QdMKp<;rX_0mQ5`;#hm9R=A9FC-^idWVAYw-UX zxd`ADfIYB)LwEqgLvTDKZv$KaU~mY6)^h$=Fa&^*a1{C<@Y@W+0T={Bz>#nTq|%=R z2FD}7#`VbU1fsRBDhho_Y@qd5wZ67Zm z1Xwt<76*<8d%?0}*W1&a#3Z*U>IwaPuUd-4rz~&g8PplNBO_(qHGYF}&B0>Hpe6KBvV97cZERE2>17;n*^>->I3`en;uKn_u71dGo$5 zTyQ%*t68w+=5=Ef|LPS>;qwBuFHbAuEois1`&3`5o0)pkEpr%oN-lm7?eX|76_=>D z<(~d2F*co)0kw|vjNDGk%O%cBY$vnnax6MNj2TryeQ6YEVigxI{&WD2y*9?kqI2yI zU_eIA2dL2GO4ReFX~F}^laTs44X^MrPuTG7hk3Lmmc2+#Hbr~eY(6?UH?kk=eeqz! zA0 z5XE2V`@VAI;pAk9pvRL=(7TP9v743Dsuqhj^|RKe`3)MUGzthOxHu)#r-R#YvJ*CG zzh-VAxdw+8W~*xW7?sY+!K!P{a?I)gOijzs0M+To5Jn*DqU(D{o?6a{B0~NhW&@vA zYiB)2iS2@HK2|qyMW^0=kLkUCB4}qeZ*LU*s9@-`&WDe}nux1WLQdz>&IBFzbhz%= z$+T$4u2Ii??F7yP@-ORgdjz*iAbv!zs%HKLub9&t{pxv+_YBsv3M;yA6ut1&cl9G~ zwuW6_@IMPhQ_>v{+ERs74fT1?iz&T_&l?4eMLinn$j%HThpkhd zYf0Dri1O3yVrFfBS`VuX7Y<~1DAi^SyHJfu97e-RP{k3in4T&p;*3bIKgrqkbo-PX zM3#eJ=jbJ@c%EA!%Q-MwjcoHFW$ zIH5s&m>i%n`=-8Joe_Q^8xn5LasM<`a~W&*-k&V>xcfgBwz!A!rjm8bJ#A`wsacS) z{Q0VEm2@VC-AEUjelC&NNxXklogZvdKg`j+q*<&nr9c|5(n`$lI`YeX`tPiUd*}Pn zyg{+6-|^VQQ{=Es{7`&JZUIJlaD2DpM2mJ}YYR<^{4OJ`&qv_#gxV=dWOCDIU4|3B ziW!hstZq-dJ^V-~MI3*~tdF9xmEV20!L?XomczUl+DAf^9;w|ira$x_f8%YTChCWf zFRFJv2vyNoFJ_uE5B~JN7mSJ{>t>UDSswg5cT?6;KiBfld-WDJ4YKk!Te*6AxQ}sd zlLn@vR=KmMM$No$MtxGz&YyVGyi1qo;cEEcol-zJQKa|cx@b}Q=|{7rds(RJORMYV z7w!cN@1O|2ihX&L^vqbVz>ODUZ+f5KVnxg6NBTe7N`e{|GWv}IOkQSk>LzD5>2V@L zU%%!#Rc&x6Y5IMG6y)tmi>p={o{h>~EzD?&-o09=pVz)Oy|lCl+W*63jUqe#=*EideD;8QP@)O`M7r^46NIR1BagHIY|t##WYlW&z7kUsd7?Pji= z)XtFu?7VYYL}FxB0)a1eTdi)3>m-(s^tRk;nCX>qS1cay;wK$mt^sv@k#3iRkNT7g zpE+5k)-4;I*Ld0byx&!ODE1u~4b{TMRDyD-EpqvsR1 xYnwlDCUDcX($yv!9D_%!ntY5iuX{a|N#F2>(V>hl%>m{U?iteRd7r&<*&m8~H$VUY literal 0 HcmV?d00001 diff --git a/javascript/CMSMain_upload.js b/javascript/CMSMain_upload.js index a086add2..1960ae17 100644 --- a/javascript/CMSMain_upload.js +++ b/javascript/CMSMain_upload.js @@ -6,15 +6,6 @@ CMSMain_upload = Class.create(); CMSMain_upload.prototype = { initialize: function() { - // This is disabled until we get it working reliably - return; - - // We require flash 9 - pv = getFlashPlayerVersion(); - if(pv.major < 9) return; - - // Due to a bug in the flash plugin on Linux and Mac, we need at least version 9.0.64 to use SWFUpload - if(pv.major == 9 && pv.minor == 0 && pv.rev < 64) return; // If those 2 checks pass, we can provide upload capabilities to the user this.iframe = window.top.document.getElementById('AssetAdmin_upload'); diff --git a/javascript/TinyMCEImageEnhancement.js b/javascript/TinyMCEImageEnhancement.js index ea6dc96f..d5a43cad 100644 --- a/javascript/TinyMCEImageEnhancement.js +++ b/javascript/TinyMCEImageEnhancement.js @@ -7,21 +7,29 @@ TinyMCEImageEnhancement.prototype = { initialize: function() { this.filesUploaded = 0; this.processInProgress = false; - Event.observe(window,'load',this.onWindowLoad.bind(this)); - }, - - addListeners: function() { - $('Form_EditorToolbarImageForm_FolderID').value = ""; + Event.observe($('AddFolder'),'click',this.onAddFolder.bind(this)); Event.observe($('FolderOk'),'click',this.onFolderOk.bind(this)); - Event.observe($('FolderCancel'),'click',this.onFolderCancel.bind(this)); - Event.observe($('UploadFiles'),'click',this.onUpload.bind(this)); + Event.observe($('FolderCancel'),'click',this.onFolderCancel.bind(this)); + + this.onLoad(); }, - - /** + + onLoad: function() { + this.upload = new Upload({ + fileUploadLimit : '6', + button_image_url : 'cms/images/swf-upload-button-small.jpg', + button_width : 59, + button_height: 18, + fileQueued: this.uploadFileQueuedCallback.bind(this), + fileComplete: this.uploadFileCompleteCallback.bind(this), + queueComplete: this.uploadQueueCompleteCallback.bind(this) + }); + }, + + /** * Method creates HTML element, only reason for this method is DRY. */ - addElement: function(tag, className, parent, properties) { var e = document.createElement(tag); Element.addClassName(e,className); @@ -30,17 +38,6 @@ TinyMCEImageEnhancement.prototype = { return e; }, - onUpload: function(event) { - Event.stop(event); - if(!this.processInProgress) { - if(this.getParentID() != 'root') { - this.upload.browse(); - } else { - statusMessage("Please choose folder","bad"); - } - } - }, - /** * Called when user clicks "add folder" anchor. */ @@ -115,60 +112,31 @@ TinyMCEImageEnhancement.prototype = { return false; }, - /** - * Called on window.onload - */ - - onWindowLoad: function() { - // Due to a bug in the flash plugin on Linux and Mac, - //we need at least version 9.0.64 to use SWFUpload - // see http://open.silverstripe.com/ticket/3023 - pv = getFlashPlayerVersion(); - if(pv.major < 9 || pv.major > 9 || (pv.major == 9 && pv.minor == 0 && pv.rev < 64)) { - if($('AddFolderGroup')) $('AddFolderGroup').style.display = 'none'; - if($('PipeSeparator')) $('PipeSeparator').style.display = 'none'; - if($('UploadGroup')) $('UploadGroup').style.display = 'none'; - return; - } - - if($('FolderID') != null) { - if($('SecurityID')) var securityid=$('SecurityID').value; - else var securityid=null; - this.upload = new Upload( - { - fileTypes : '*.jpeg;*.jpg;*.jpe;*.png;*.gif;', - fileTypesDescription : 'Image files', - fileUploadLimit : '100', - securityID : securityid, - beginUploadOnQueue : true, - buildUI : this.addListeners.bind(this), - fileQueued : this.uploadFileQueuedCallback.bind(this), - fileComplete : this.uploadFileCompleteCallback.bind(this), - queueComplete : this.uploadQueueCompleteCallback.bind(this) - } - ); - } - }, - uploadFileQueuedCallback: function(file,queueLength) { - this.processInProgress = true; - this.upload.setFolderID(this.getParentID()); - $('UploadFiles').innerHTML = "Uploading ... 1/" + this.upload.getFilesToUpload(); - this.upload.startUpload(); + if(this.getParentID() == "root") { + statusMessage("Please choose folder","bad"); + } + else { + this.processInProgress = true; + this.upload.swfu.addPostParam('FolderID', this.getParentID()); + this.upload.swfu.addFileParam(file.id,'ID',this.folderID); + this.upload.swfu.addFileParam(file.id,'Files',file.name); + $('UploadFiles').innerHTML = "Uploading Files...("+ this.filesUploaded +")"; + this.upload.swfu.startUpload(file.id); + } }, uploadFileCompleteCallback: function(file,serverData) { - Element.addClassName($('UploadFiles'),'link');//Safari hack - $('UploadFiles').innerHTML = 'Uploading ... ' + this.upload.getFilesUploaded() + "/" + this.upload.getFilesToUpload(); + this.filesUploaded++; + $('UploadFiles').innerHTML = 'Uploading Files..... ('+ this.filesUploaded +")"; }, - uploadQueueCompleteCallback: function() { + uploadQueueCompleteCallback: function(serverData) { this.filesUploaded = this.upload.getFilesUploaded(); - $('UploadFiles').innerHTML = "upload"; - statusMessage('Uploaded ' + this.upload.getFilesUploaded() + ' files','good'); - if(this.getParentID() != 'root') { - $('Image').ajaxGetFiles(this.getParentID(), null, this.insertImages.bind(this)); - } + $('UploadFiles').innerHTML = ""; + statusMessage('Uploaded Files Successfully','good'); + + $('FolderImages').ajaxGetFiles(this.getParentID(), null); }, /** @@ -187,8 +155,7 @@ TinyMCEImageEnhancement.prototype = { $('Image').reapplyBehaviour(); this.addToTinyMCE = this.addToTinyMCE.bind(this); - - this.processInProgress = false; + this.processInProgress = false; }, /** diff --git a/javascript/Upload.js b/javascript/Upload.js index 75300928..88227c49 100644 --- a/javascript/Upload.js +++ b/javascript/Upload.js @@ -14,23 +14,33 @@ Upload.prototype = { * @param params object contains all configuration data for upload. */ initialize: function(params) { + this.filesUploaded = 0; this.filesToUpload = 0; this.folderID = 'root'; this.uploadInProgress = false; this.uploadMessage = ''; + this.queueComplete = this.uploadQueueCompleteCallback.bind(this); + this.fileComplete = this.uploadFileCompleteCallback.bind(this); + this.fileQueued = this.uploadFileQueuedCallback; + if(typeof params.fileSizeLimit != 'undefined') this.setFileSizeLimit = params.fileSizeLimit; else this.fileSizeLimit = '30720'; if(typeof params.fileTypes != 'undefined') this.fileTypes = params.fileTypes; else this.fileTypes = '*.*'; if(typeof params.fileTypesDescription != 'undefined') this.fileTypesDescription = params.fileTypesDescription; else this.fileTypesDescription = 'All Files'; if(typeof params.fileUploadLimit != 'undefined') this.fileUploadLimit = params.fileUploadLimit; else this.fileUploadLimit = '6'; - if(typeof params.beginUploadOnQueue != 'undefined') this.beginUploadOnQueue = params.beginUploadOnQueue; else this.beginUploadOnQueue = false; + if(typeof params.beginUploadOnQueue != 'undefined') this.beginUploadOnQueue = params.beginUploadOnQueue; else this.beginUploadOnQueue = true; if(typeof params.fileQueued != 'undefined') this.fileQueued = params.fileQueued; + if(typeof params.fileProgress != 'undefined') this.fileProgress = params.fileProgress; else this.fileProgress = Prototype.emptyFunction; if(typeof params.fileCancelled != 'undefined') this.fileCancelled = params.fileCancelled; - if(typeof params.fileComplete != 'undefined') this.fileComplete = params.fileComplete ; + if(typeof params.fileComplete != 'undefined') this.fileComplete = params.fileComplete; if(typeof params.queueComplete != 'undefined') this.queueComplete = params.queueComplete; if(typeof params.buildUI != 'undefined') this.customBuildUI = params.buildUI; if(typeof params.securityID != 'undefined') this.securityID = params.securityID; + if(typeof params.button_image_url != 'undefined') this.buttonImageURL = params.button_image_url; + if(typeof params.button_width != 'undefined') this.buttonWidth = params.button_width; + if(typeof params.button_height != 'undefined') this.buttonHeight = params.button_height; + this.onLoad(); }, @@ -39,10 +49,11 @@ Upload.prototype = { * */ onLoad: function() { + path = this.getBasePath(); sessId = this.getSessionId();//Because flash doesn't send proper cookies, we need to set session id in URL. this.swfu = new SWFUpload({ - upload_url: path + 'admin/assets/UploadForm?SecurityID=' + this.securityID + '&PHPSESSID=' + sessId, // Relative to the SWF file + upload_url: path + 'admin/assets/UploadForm?action_doUpload=1&PHPSESSID=' + sessId, // Relative to the SWF file file_post_name: 'Files', file_size_limit : this.fileSizeLimit, file_types : this.fileTypes, @@ -51,19 +62,25 @@ Upload.prototype = { begin_upload_on_queue : this.beginUploadOnQueue, use_server_data_event : true, validate_files: false, - - file_queued_handler : this.uploadFileQueuedCallback.bind(this), - upload_success_handler : this.uploadFileCompleteCallback.bind(this), + button_placeholder_id: "SWFUploadButton", + file_queued_handler : this.fileQueued, + upload_success_handler : this.queueComplete, + file_dialog_complete_handler : this.fileCompleted, upload_progress_handler: this.uploadFileProgressCallback.bind(this), error_handler : this.uploadErrorCallback.bind(this), file_validation_handler : Prototype.emptyFunction, file_cancelled_handler: Prototype.emptyFunction, - - flash_url : 'jsparty/SWFUpload/swfupload_f9.swf', // Relative to this file + button_image_url : this.buttonImageURL, + button_window_mode : "transparent", + button_width : this.buttonWidth, + button_height : this.buttonHeight, + flash_url : 'jsparty/SWFUpload/swfupload.swf', // Relative to this file swfupload_loaded_handler: this.buildUI.bind(this), - debug: false + debug: false, + preserve_relative_urls: true }); - }, + + }, /** * Retrieves base path from URL. @@ -95,7 +112,7 @@ Upload.prototype = { */ buildUI: function() { - this.customBuildUI(); + return; }, /** @@ -107,7 +124,7 @@ Upload.prototype = { uploadFileQueuedCallback: function(file,queueLength) { this.filesToUpload++; - this.fileQueued(file, queueLength); +// this.swfu.fileQueued(file, queueLength); this.addFileParam(file); }, @@ -151,6 +168,10 @@ Upload.prototype = { this.fileProgress(file, bytes_complete); }, + uploadQueueCompleteCallback: function(event) { + + }, + /** * Called on error. * @param error_code int From dcd6c53ca53df6128d6cb6f462532d54a1d8c0d2 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 13 Nov 2009 02:49:07 +0000 Subject: [PATCH 007/483] MINOR: fixed typo with path git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91541 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 903e3d6c..1f0590da 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -254,7 +254,7 @@ class LeftAndMain extends Controller { 'jsparty/tree/tree.js', 'jsparty/tabstrip/tabstrip.js', 'cms/javascript/TinyMCEImageEnhancement.js', - 'jsparty/SWFUpload/SWFUpload.js', + 'jsparty/SWFUpload/swfupload.js', 'cms/javascript/Upload.js', 'sapphire/javascript/TreeSelectorField.js', 'cms/javascript/ThumbnailStripField.js', From d59b2ad5cfc8705127a07d8e1e58e900f05bd376 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 13 Nov 2009 02:51:25 +0000 Subject: [PATCH 008/483] BUGFIX: fixed order inclusion of js git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91542 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 2 +- javascript/Upload.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 1f0590da..0ce67833 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -253,9 +253,9 @@ class LeftAndMain extends Controller { 'cms/javascript/LeftAndMain_right.js', 'jsparty/tree/tree.js', 'jsparty/tabstrip/tabstrip.js', - 'cms/javascript/TinyMCEImageEnhancement.js', 'jsparty/SWFUpload/swfupload.js', 'cms/javascript/Upload.js', + 'cms/javascript/TinyMCEImageEnhancement.js', 'sapphire/javascript/TreeSelectorField.js', 'cms/javascript/ThumbnailStripField.js', ) diff --git a/javascript/Upload.js b/javascript/Upload.js index 88227c49..578ed88e 100644 --- a/javascript/Upload.js +++ b/javascript/Upload.js @@ -76,7 +76,7 @@ Upload.prototype = { button_height : this.buttonHeight, flash_url : 'jsparty/SWFUpload/swfupload.swf', // Relative to this file swfupload_loaded_handler: this.buildUI.bind(this), - debug: false, + debug: true, preserve_relative_urls: true }); From c35ad8c3e0484d331992c8a865042996120c17b9 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 13 Nov 2009 02:52:03 +0000 Subject: [PATCH 009/483] MINOR: removed debug statements git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91543 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/Upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/Upload.js b/javascript/Upload.js index 578ed88e..88227c49 100644 --- a/javascript/Upload.js +++ b/javascript/Upload.js @@ -76,7 +76,7 @@ Upload.prototype = { button_height : this.buttonHeight, flash_url : 'jsparty/SWFUpload/swfupload.swf', // Relative to this file swfupload_loaded_handler: this.buildUI.bind(this), - debug: true, + debug: false, preserve_relative_urls: true }); From 5c8628e7d40c494991d5fe921bc6476d50fb677a Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Tue, 17 Nov 2009 00:16:29 +0000 Subject: [PATCH 010/483] MINOR added stubs to allow widgets to use treedropdown fields git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91850 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/WidgetAreaEditor.php | 8 ++++++-- javascript/WidgetAreaEditor.js | 13 +++++++++++++ templates/WidgetAreaEditor.ss | 2 +- 3 files changed, 20 insertions(+), 3 deletions(-) diff --git a/code/WidgetAreaEditor.php b/code/WidgetAreaEditor.php index dd4a6d1a..c862df48 100644 --- a/code/WidgetAreaEditor.php +++ b/code/WidgetAreaEditor.php @@ -5,6 +5,10 @@ * @subpackage content */ class WidgetAreaEditor extends FormField { + function __construct($name) { + parent::__construct($name); + } + function FieldHolder() { Requirements::css(CMS_DIR . '/css/WidgetAreaEditor.css'); Requirements::javascript(CMS_DIR . '/javascript/WidgetAreaEditor.js'); @@ -26,7 +30,7 @@ class WidgetAreaEditor extends FormField { function UsedWidgets() { $relationName = $this->name; - $widgets = $this->form->getRecord()->getComponent($relationName)->Widgets(); + $widgets = $this->form->getRecord()->getComponent($relationName)->Items(); return $widgets; } @@ -48,7 +52,7 @@ class WidgetAreaEditor extends FormField { $record->$idName = $widgetarea->ID; - $widgets = $widgetarea->Widgets(); + $widgets = $widgetarea->Items(); // store the field IDs and delete the missing fields // alternatively, we could delete all the fields and re add them diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js index 02e2deb1..213acdf3 100644 --- a/javascript/WidgetAreaEditor.js +++ b/javascript/WidgetAreaEditor.js @@ -160,6 +160,10 @@ WidgetAreaEditorClass.prototype = { $('usedWidgets-'+this.name).parentNode.parentNode.rewriteWidgetAreaAttributes(); UsedWidget.applyToChildren($('usedWidgets-'+this.name), 'div.Widget'); + // Repply some common form controls + WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); + + Sortable.create('usedWidgets-SideBar', { tag: 'div', handle: 'handle', @@ -231,6 +235,15 @@ UsedWidget.prototype = { } } +WidgetTreeDropdownField = Class.extend('TreeDropdownField'); +WidgetTreeDropdownField.prototype = { + getName: function() { + return 'Widget_TDF_Endpoint'; + } +} + +WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); + // Loop over all WidgetAreas and fire 'em up var wAs = $$('.WidgetAreaEditor'); for(var i = 0; i < wAs.length; i++) { diff --git a/templates/WidgetAreaEditor.ss b/templates/WidgetAreaEditor.ss index 187e33e4..6b1989f6 100644 --- a/templates/WidgetAreaEditor.ss +++ b/templates/WidgetAreaEditor.ss @@ -17,7 +17,7 @@

<% _t('INUSE', 'Widgets currently used') %>

-

<% _t('TOADD', 'To add widgets, drag them from the left area to here.') %>

+

<% _t('TOADD', 'To add widgets, click on the purple header on the left') %>

<% if UsedWidgets %> From a3a70c85ebddf038ba7a462deb7f54001ade8d52 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Tue, 17 Nov 2009 20:30:27 +0000 Subject: [PATCH 011/483] BUGFIX FolderID was not present in post, so file would not be uploaded to the correct place. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@91958 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index c2c0dc0f..30846a4e 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -141,6 +141,7 @@ JS // see r54952 (originally committed in r42014) $form = new Form($this,'UploadForm', new FieldSet( new HiddenField("ID", "", $this->currentPageID()), + new HiddenField("FolderID", "", $this->currentPageID()), // needed because the button-action is triggered outside the iframe new HiddenField("action_doUpload", "", "1"), new FileField("Files[0]" , _t('AssetAdmin.CHOOSEFILE','Choose file: ')), From 9433580f952d4ff241de30b5b3c7e802f04a7e36 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Wed, 18 Nov 2009 23:54:43 +0000 Subject: [PATCH 012/483] MINOR Removed MemberTableField::setController() - this is now redundant from r92134 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@92135 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/MemberTableField.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 78f63657..5191dc0c 100755 --- a/code/MemberTableField.php +++ b/code/MemberTableField.php @@ -278,10 +278,6 @@ class MemberTableField extends ComplexTableField { $this->group = $group; } - function setController($controller) { - $this->controller = $controller; - } - function GetControllerName() { return $this->controller->class; } From 73681b0afa62bba0a938e41416b5019b4f4cbee8 Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Fri, 20 Nov 2009 03:49:57 +0000 Subject: [PATCH 013/483] APICHANGE: add the ability to remove some permissions specified by their code in the rendered field html of PermissionChecksetBoxField and full-covered unit tests of this ability. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@92428 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/SecurityAdmin.php | 12 ++++++++++++ tests/SecurityAdminTest.php | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index bdce356f..f54fc3fc 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -276,6 +276,18 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { ) ); } + + /** + * the permissions represented in the $codes will not appearing in the form + * containning {@link PermissionCheckboxSetField} so as not to be checked / unchecked. + * @param $codes array of permission code + * @return void + */ + static function hide_permissions($codes){ + foreach($codes as $code){ + Permission::add_to_hidden_permissions($code); + } + } } ?> diff --git a/tests/SecurityAdminTest.php b/tests/SecurityAdminTest.php index 4522c7eb..035c9a5e 100644 --- a/tests/SecurityAdminTest.php +++ b/tests/SecurityAdminTest.php @@ -36,6 +36,16 @@ class SecurityAdminTest extends FunctionalTest { $this->assertEquals($lines[1], '', "Empty export only has no content row"); } + function testHidePermissions() { + $permissionCheckboxSet = new PermissionCheckboxSetField('Permissions','Permissions','Permission','GroupID'); + $this->assertContains('CMS_ACCESS_CMSMain', $permissionCheckboxSet->Field()); + $this->assertContains('CMS_ACCESS_AssetAdmin', $permissionCheckboxSet->Field()); + + SecurityAdmin::hide_permissions(array('CMS_ACCESS_CMSMain','CMS_ACCESS_AssetAdmin')); + $this->assertNotContains('CMS_ACCESS_CMSMain', $permissionCheckboxSet->Field()); + $this->assertNotContains('CMS_ACCESS_AssetAdmin', $permissionCheckboxSet->Field()); + } + } ?> \ No newline at end of file From b261d3cadc111bd33fee108974594db21f69d9b1 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 21 Nov 2009 11:11:26 +0000 Subject: [PATCH 014/483] ENHANCEMENT Allowing to hide certain permission from showing in SecurityAdmin? through add_hidden_permission() (refactored from r92428) (from r92866) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@92879 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/SecurityAdmin.php | 46 ++++++++++++++++++++++++++++------ tests/SecurityAdminTest.php | 49 +++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 15 deletions(-) diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index f54fc3fc..cb374f7a 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -27,6 +27,11 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { 'EditForm' ); + /** + * @var Array + */ + static $hidden_permissions = array(); + public function init() { parent::init(); @@ -73,6 +78,10 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { $form->setFields($readonlyFields); } + // Filter permissions + $permissionField = $form->Fields()->dataFieldByName('Permissions'); + if($permissionField) $permissionField->setHiddenPermissions(self::$hidden_permissions); + return $form; } @@ -278,15 +287,36 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { } /** - * the permissions represented in the $codes will not appearing in the form - * containning {@link PermissionCheckboxSetField} so as not to be checked / unchecked. - * @param $codes array of permission code - * @return void + * The permissions represented in the $codes will not appearing in the form + * containing {@link PermissionCheckboxSetField} so as not to be checked / unchecked. + * + * @param $codes String|Array */ - static function hide_permissions($codes){ - foreach($codes as $code){ - Permission::add_to_hidden_permissions($code); - } + static function add_hidden_permission($codes){ + if(is_string($codes)) $codes = array($codes); + self::$hidden_permissions += $codes; + } + + /** + * @param $codes String|Array + */ + static function remove_hidden_permission($codes){ + if(is_string($codes)) $codes = array($codes); + self::$hidden_permissions = array_diff(self::$hidden_permissions, $codes); + } + + /** + * @return Array + */ + static function get_hidden_permissions(){ + return self::$hidden_permissions; + } + + /** + * Clear all permissions previously hidden with {@link add_hidden_permission} + */ + static function clear_hidden_permissions(){ + self::$hidden_permissions = array(); } } diff --git a/tests/SecurityAdminTest.php b/tests/SecurityAdminTest.php index 035c9a5e..086c5b22 100644 --- a/tests/SecurityAdminTest.php +++ b/tests/SecurityAdminTest.php @@ -36,16 +36,51 @@ class SecurityAdminTest extends FunctionalTest { $this->assertEquals($lines[1], '', "Empty export only has no content row"); } - function testHidePermissions() { - $permissionCheckboxSet = new PermissionCheckboxSetField('Permissions','Permissions','Permission','GroupID'); - $this->assertContains('CMS_ACCESS_CMSMain', $permissionCheckboxSet->Field()); - $this->assertContains('CMS_ACCESS_AssetAdmin', $permissionCheckboxSet->Field()); + function testAddHiddenPermission() { + SecurityAdmin::add_hidden_permission('CMS_ACCESS_ReportAdmin'); + $this->assertContains('CMS_ACCESS_ReportAdmin', SecurityAdmin::get_hidden_permissions()); - SecurityAdmin::hide_permissions(array('CMS_ACCESS_CMSMain','CMS_ACCESS_AssetAdmin')); - $this->assertNotContains('CMS_ACCESS_CMSMain', $permissionCheckboxSet->Field()); - $this->assertNotContains('CMS_ACCESS_AssetAdmin', $permissionCheckboxSet->Field()); + // reset to defaults + SecurityAdmin::clear_hidden_permissions(); } + function testRemoveHiddenPermission() { + SecurityAdmin::add_hidden_permission('CMS_ACCESS_ReportAdmin'); + $this->assertContains('CMS_ACCESS_ReportAdmin', SecurityAdmin::get_hidden_permissions()); + SecurityAdmin::remove_hidden_permission('CMS_ACCESS_ReportAdmin'); + $this->assertNotContains('CMS_ACCESS_ReportAdmin', SecurityAdmin::get_hidden_permissions()); + + // reset to defaults + SecurityAdmin::clear_hidden_permissions(); + } + + function testClearHiddenPermission() { + SecurityAdmin::add_hidden_permission('CMS_ACCESS_ReportAdmin'); + $this->assertContains('CMS_ACCESS_ReportAdmin', SecurityAdmin::get_hidden_permissions()); + SecurityAdmin::clear_hidden_permissions('CMS_ACCESS_ReportAdmin'); + $this->assertNotContains('CMS_ACCESS_ReportAdmin', SecurityAdmin::get_hidden_permissions()); + } + + function testPermissionFieldRespectsHiddenPermissions() { + $this->session()->inst_set('loggedInAs', $this->idFromFixture('Member', 'admin')); + + $group = $this->objFromFixture('Group', 'admin'); + + SecurityAdmin::add_hidden_permission('CMS_ACCESS_ReportAdmin'); + $response = $this->get('admin/security/show/' . $group->ID); + + $this->assertContains( + 'CMS_ACCESS_CMSMain', + $response->getBody() + ); + $this->assertNotContains( + 'CMS_ACCESS_ReportAdmin', + $response->getBody() + ); + + // reset to defaults + SecurityAdmin::clear_hidden_permissions(); + } } ?> \ No newline at end of file From e7f61e1aa4aaf02374b97708f730f0032dd25fb3 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 03:16:26 +0000 Subject: [PATCH 015/483] MINOR Copied jsparty/multifile to cms/thirdparty/multifile git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93557 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- thirdparty/multifile/example.html | 26 ++++ thirdparty/multifile/multifile.css | 82 +++++++++++++ thirdparty/multifile/multifile.js | 189 +++++++++++++++++++++++++++++ 3 files changed, 297 insertions(+) create mode 100755 thirdparty/multifile/example.html create mode 100755 thirdparty/multifile/multifile.css create mode 100755 thirdparty/multifile/multifile.js diff --git a/thirdparty/multifile/example.html b/thirdparty/multifile/example.html new file mode 100755 index 00000000..b1111702 --- /dev/null +++ b/thirdparty/multifile/example.html @@ -0,0 +1,26 @@ + + + + + + + + + + +
+ + + +
+Files: + +
+ + + \ No newline at end of file diff --git a/thirdparty/multifile/multifile.css b/thirdparty/multifile/multifile.css new file mode 100755 index 00000000..03536d07 --- /dev/null +++ b/thirdparty/multifile/multifile.css @@ -0,0 +1,82 @@ +#Form_UploadForm { + padding: 5px; + line-height: 1.4em; +} + +#Form_UploadForm a { + font-weight: bold; +} + +#Form_UploadForm ol li { + list-style: decimal outside; +} + +#Form_UploadForm ul li { + list-style-type: square; +} + +#Form_UploadForm form { + text-align: left; +} + +#Form_UploadForm label { + font-size: 1.2em; +} + +#Form_UploadForm input.delete { + margin: 2px auto; + padding: 0px; + background-color: #FFFFFF; + border:1px solid #D6D3CE; +} + +#Form_UploadForm input[value="Submit"] { + cursor: pointer; +} + +#Form_UploadForm input[value="Submit"]:hover{ + background-color: #F6F6E8; +} + +#Form_UploadForm #Form_UploadForm_FilesList div { + font-size: 1.2em; + vertical-align: middle; +} + +#Form_UploadForm #Form_UploadForm_FilesList input { + margin-left: 10px; +} + +#Form_UploadForm #Form_UploadForm_FilesList .clear { + height: 0; + line-height: 0; +} + +#Form_UploadForm div.file { + display: inline; +} + +#Form_UploadForm #Form_UploadForm_action_upload { + display: inline; + margin: 5px 0; +} + +#Form_UploadForm p { + margin-top: 5px; +} + +#Form_UploadForm_FilesList { + margin-top: 5px; +} + +#Form_UploadForm_FilesList div { + width: auto; + border: 1px solid #F1EFE2; + padding: 5px; + margin-bottom: 5px; +} + +#Form_UploadForm_FilesList div .delete:hover { + background: red; + font-weight: bold; +} diff --git a/thirdparty/multifile/multifile.js b/thirdparty/multifile/multifile.js new file mode 100755 index 00000000..99a68a81 --- /dev/null +++ b/thirdparty/multifile/multifile.js @@ -0,0 +1,189 @@ +/** + * Convert a single file-input element into a 'multiple' input list + * + * Modified 2006-11-06 by Silverstripe Ltd. + * + * Usage: + * + * 1. Create a file input element (no name) + * eg. + * + * 2. Create a DIV for the output to be written to + * eg.
+ * + * 3. Instantiate a MultiSelector object, passing in the DIV and an (optional) maximum number of files + * eg. var multi_selector = new MultiSelector( document.getElementById( 'files_list' ), 3 ); + * + * 4. Add the first element + * eg. multi_selector.addElement( document.getElementById( 'first_file_element' ) ); + * + * 5. That's it. + * + * You might (will) want to play around with the addListRow() method to make the output prettier. + * + * You might also want to change the line + * element.name = 'file_' + this.count; + * ...to a naming convention that makes more sense to you. + * + * Licence: + * Use this however/wherever you like, just don't blame me if it breaks anything. + * + * Credit: + * If you're nice, you'll leave this bit: + * + * Class by Stickman -- http://www.the-stickman.com + * with thanks to: + * [for Safari fixes] + * Luis Torrefranca -- http://www.law.pitt.edu + * and + * Shawn Parker & John Pennypacker -- http://www.fuzzycoconut.com + * [for duplicate name bug] + * 'neal' + */ + +// Modified by: Silverstripe Ltd. (changed naming of file-input-elements) + +function MultiSelector( list_target, max, upload_button ){ + + this.upload_button = upload_button; + this.upload_button.setAttribute("disabled", "disabled"); + + // Where to write the list + this.list_target = list_target; + // How many elements? + this.count = -1; + // How many elements? + this.id = 0; + // Is there a maximum? + if( max ){ + this.max = max; + } else { + this.max = -1; + }; + + /** + * Add a new file input element + */ + this.addElement = function( element ){ + + // Make sure it's a file input element + if( element.tagName == 'INPUT' && element.type == 'file' ){ + + // Element name -- what number am I? + // Modified by: Silverstripe Ltd. (changed naming of file-input-elements) + element.name = 'Files[' + this.id++ + ']' + + // If we've reached maximum number, disable input element + if( this.max != -1 && this.count >= this.max ){ + element.disabled = true; + }; + + // File element counter + this.count++; + + // Add reference to this object + element.__scope = this; + element.multi_selector = this; + + // What to do when a file is selected + element.onchange = function(){ + + // New file input + var new_element = document.createElement( 'input' ); + new_element.type = 'file'; + + // Add new element + this.parentNode.insertBefore( new_element, this ); + + // Apply 'update' to element + this.multi_selector.addElement( new_element ); + + // Update list + this.multi_selector.addListRow( this ); + + // Hide this: we can't use display:none because Safari doesn't like it + this.style.position = 'absolute'; + this.style.left = '-1000px'; + + element.__scope.toggleUploadButton(); + }; + + // Most recent element + this.current_element = element; + + } else { + // This can only be applied to file input elements! + alert( 'Error: not a file input element' ); + }; + + }; + + this.toggleUploadButton = function() { + if(this.count > 0) { + this.upload_button.removeAttribute("disabled"); + } else { + this.upload_button.setAttribute("disabled", "disabled"); + } + } + + /** + * Add a new row to the list of files + */ + this.addListRow = function( element ){ + + // Modified 2006-11-06 by Silverstripe Ltd. + var filenameMatches = element.value.match(/([^\/\\]+)$/); + var filename = filenameMatches[1]; + + // Row div + var new_row = document.createElement('div'); + + // Delete button + var new_row_button = document.createElement('input'); + new_row_button.type = 'button'; + new_row_button.value = 'Delete'; + new_row_button.setAttribute('class', 'delete'); + + // References + new_row.element = element; + element.__scope = this, + + // Delete function + new_row_button.onclick= function(){ + + // Remove element from form + this.parentNode.element.parentNode.removeChild( this.parentNode.element ); + + // Remove this row from the list + this.parentNode.parentNode.removeChild( this.parentNode ); + + // Decrement counter + this.parentNode.element.multi_selector.count--; + + // Re-enable input element (if it's disabled) + this.parentNode.element.multi_selector.current_element.disabled = false; + + element.__scope.toggleUploadButton(); + + // Appease Safari + // without it Safari wants to reload the browser window + // which nixes your already queued uploads + return false; + }; + + // Set row value + // Modified 2006-11-06 by Silverstripe Ltd. + new_row.innerHTML = filename; + + // Add button + new_row.appendChild( new_row_button ); + + // Add it to the list + this.list_target.appendChild( new_row ); + + // Modified 2006-11-06 by Silverstripe Ltd. + window.ontabschanged(); + + }; + +}; \ No newline at end of file From bcb48ddb18b5372bc1e0237e47c810d0d26ee07b Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 03:17:27 +0000 Subject: [PATCH 016/483] MINOR Moved jsparty/SWFUpload to cms/thirdparty/swfupload git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93559 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- thirdparty/swfupload/license.txt | 11 + thirdparty/swfupload/swfupload.js | 1052 +++++++++++++++++++++++ thirdparty/swfupload/swfupload.queue.js | 98 +++ thirdparty/swfupload/swfupload.swf | Bin 0 -> 33328 bytes 4 files changed, 1161 insertions(+) create mode 100644 thirdparty/swfupload/license.txt create mode 100755 thirdparty/swfupload/swfupload.js create mode 100755 thirdparty/swfupload/swfupload.queue.js create mode 100755 thirdparty/swfupload/swfupload.swf diff --git a/thirdparty/swfupload/license.txt b/thirdparty/swfupload/license.txt new file mode 100644 index 00000000..dd26171a --- /dev/null +++ b/thirdparty/swfupload/license.txt @@ -0,0 +1,11 @@ +/** + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzn and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * + * SWFUpload Revision 7.0 is (c) 2007 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ \ No newline at end of file diff --git a/thirdparty/swfupload/swfupload.js b/thirdparty/swfupload/swfupload.js new file mode 100755 index 00000000..e1aaa3f7 --- /dev/null +++ b/thirdparty/swfupload/swfupload.js @@ -0,0 +1,1052 @@ +/** + * SWFUpload: http://www.swfupload.org, http://swfupload.googlecode.com + * + * mmSWFUpload 1.0: Flash upload dialog - http://profandesign.se/swfupload/, http://www.vinterwebb.se/ + * + * SWFUpload is (c) 2006-2007 Lars Huring, Olov Nilzn and Mammon Media and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + * SWFUpload 2 is (c) 2007-2008 Jake Roberts and is released under the MIT License: + * http://www.opensource.org/licenses/mit-license.php + * + */ + + +/* ******************* */ +/* Constructor & Init */ +/* ******************* */ +var SWFUpload; + +if (SWFUpload == undefined) { + SWFUpload = function (settings) { + this.initSWFUpload(settings); + }; +} + +SWFUpload.prototype.initSWFUpload = function (userSettings) { + try { + this.customSettings = {}; // A container where developers can place their own settings associated with this instance. + this.settings = {}; + this.eventQueue = []; + this.movieName = "SWFUpload_" + SWFUpload.movieCount++; + this.movieElement = null; + + + // Setup global control tracking + SWFUpload.instances[this.movieName] = this; + + // Load the settings. Load the Flash movie. + this.initSettings(userSettings); + this.loadFlash(); + this.displayDebugInfo(); + } catch (ex) { + delete SWFUpload.instances[this.movieName]; + throw ex; + } +}; + +/* *************** */ +/* Static Members */ +/* *************** */ +SWFUpload.instances = {}; +SWFUpload.movieCount = 0; +SWFUpload.version = "2.5.0 2009-11-04 Alpha"; +SWFUpload.QUEUE_ERROR = { + QUEUE_LIMIT_EXCEEDED : -100, + FILE_EXCEEDS_SIZE_LIMIT : -110, + ZERO_BYTE_FILE : -120, + INVALID_FILETYPE : -130 +}; +SWFUpload.UPLOAD_ERROR = { + HTTP_ERROR : -200, + MISSING_UPLOAD_URL : -210, + IO_ERROR : -220, + SECURITY_ERROR : -230, + UPLOAD_LIMIT_EXCEEDED : -240, + UPLOAD_FAILED : -250, + SPECIFIED_FILE_ID_NOT_FOUND : -260, + FILE_VALIDATION_FAILED : -270, + FILE_CANCELLED : -280, + UPLOAD_STOPPED : -290, + RESIZE_ERROR : -300 +}; +SWFUpload.FILE_STATUS = { + QUEUED : -1, + IN_PROGRESS : -2, + ERROR : -3, + COMPLETE : -4, + CANCELLED : -5 +}; +SWFUpload.UPLOAD_TYPE = { + NORMAL : -1, + RESIZED : -2 +}; + +SWFUpload.BUTTON_ACTION = { + SELECT_FILE : -100, + SELECT_FILES : -110, + START_UPLOAD : -120, + JAVASCRIPT : -130 +}; +SWFUpload.CURSOR = { + ARROW : -1, + HAND : -2 +}; +SWFUpload.WINDOW_MODE = { + WINDOW : "window", + TRANSPARENT : "transparent", + OPAQUE : "opaque" +}; + +SWFUpload.RESIZE_ENCODING = { + JPEG : -1, + PNG : -2 +}; + +// Private: takes a URL, determines if it is relative and converts to an absolute URL +// using the current site. Only processes the URL if it can, otherwise returns the URL untouched +SWFUpload.completeURL = function (url) { + try { + var path = "", indexSlash = -1; + if (typeof(url) !== "string" || url.match(/^https?:\/\//i) || url.match(/^\//) || url === "") { + return url; + } + + indexSlash = window.location.pathname.lastIndexOf("/"); + if (indexSlash <= 0) { + path = "/"; + } else { + path = window.location.pathname.substr(0, indexSlash) + "/"; + } + + return path + url; + } catch (ex) { + return url; + } +}; + + +/* ******************** */ +/* Instance Members */ +/* ******************** */ + +// Private: initSettings ensures that all the +// settings are set, getting a default value if one was not assigned. +SWFUpload.prototype.initSettings = function (userSettings) { + this.ensureDefault = function (settingName, defaultValue) { + var setting = userSettings[settingName]; + if (setting != undefined) { + this.settings[settingName] = setting; + } else { + this.settings[settingName] = defaultValue; + } + }; + + // Upload backend settings + this.ensureDefault("upload_url", ""); + + this.ensureDefault("preserve_relative_urls", false); + this.ensureDefault("file_post_name", "Filedata"); + this.ensureDefault("post_params", {}); + this.ensureDefault("use_query_string", false); + this.ensureDefault("requeue_on_error", false); + this.ensureDefault("http_success", []); + this.ensureDefault("assume_success_timeout", 0); + + // File Settings + this.ensureDefault("file_types", "*.*"); + this.ensureDefault("file_types_description", "All Files"); + this.ensureDefault("file_size_limit", 0); // Default zero means "unlimited" + this.ensureDefault("file_upload_limit", 0); + this.ensureDefault("file_queue_limit", 0); + + // Flash Settings + this.ensureDefault("flash_url", "swfupload.swf"); + this.ensureDefault("prevent_swf_caching", true); + + // Button Settings + this.ensureDefault("button_image_url", ""); + this.ensureDefault("button_width", 1); + this.ensureDefault("button_height", 1); + this.ensureDefault("button_text", ""); + this.ensureDefault("button_text_style", "color: #000000; font-size: 16pt;"); + this.ensureDefault("button_text_top_padding", 0); + this.ensureDefault("button_text_left_padding", 0); + this.ensureDefault("button_action", SWFUpload.BUTTON_ACTION.SELECT_FILES); + this.ensureDefault("button_disabled", false); + this.ensureDefault("button_placeholder_id", ""); + this.ensureDefault("button_placeholder", null); + this.ensureDefault("button_cursor", SWFUpload.CURSOR.ARROW); + this.ensureDefault("button_window_mode", SWFUpload.WINDOW_MODE.WINDOW); + + // Debug Settings + this.ensureDefault("debug", false); + this.settings.debug_enabled = this.settings.debug; // Here to maintain v2 API + + // Event Handlers + this.settings.return_upload_start_handler = this.returnUploadStart; + this.ensureDefault("swfupload_loaded_handler", null); + this.ensureDefault("file_dialog_start_handler", null); + this.ensureDefault("file_queued_handler", null); + this.ensureDefault("file_queue_error_handler", null); + this.ensureDefault("file_dialog_complete_handler", null); + + this.ensureDefault("upload_start_handler", null); + this.ensureDefault("upload_progress_handler", null); + this.ensureDefault("upload_error_handler", null); + this.ensureDefault("upload_success_handler", null); + this.ensureDefault("upload_complete_handler", null); + + this.ensureDefault("button_action_handler", null); + + this.ensureDefault("debug_handler", this.debugMessage); + + this.ensureDefault("custom_settings", {}); + + // Other settings + this.customSettings = this.settings.custom_settings; + + // Update the flash url if needed + if (!!this.settings.prevent_swf_caching) { + this.settings.flash_url = this.settings.flash_url + (this.settings.flash_url.indexOf("?") < 0 ? "?" : "&") + "preventswfcaching=" + new Date().getTime(); + } + + if (!this.settings.preserve_relative_urls) { + this.settings.upload_url = SWFUpload.completeURL(this.settings.upload_url); + this.settings.button_image_url = SWFUpload.completeURL(this.settings.button_image_url); + } + + delete this.ensureDefault; +}; + +// Private: loadFlash replaces the button_placeholder element with the flash movie. +SWFUpload.prototype.loadFlash = function () { + var targetElement, tempParent, wrapperType; + + // Make sure an element with the ID we are going to use doesn't already exist + if (document.getElementById(this.movieName) !== null) { + throw "ID " + this.movieName + " is already in use. The Flash Object could not be added"; + } + + // Get the element where we will be placing the flash movie + targetElement = document.getElementById(this.settings.button_placeholder_id) || this.settings.button_placeholder; + + if (targetElement == undefined) { + throw "Could not find the placeholder element: " + this.settings.button_placeholder_id; + } + + wrapperType = (targetElement.currentStyle && targetElement.currentStyle["display"] || window.getComputedStyle && document.defaultView.getComputedStyle(targetElement, null).getPropertyValue("display")) !== "block" ? "span" : "div"; + + // Append the container and load the flash + tempParent = document.createElement(wrapperType); + tempParent.innerHTML = this.getFlashHTML(); // Using innerHTML is non-standard but the only sensible way to dynamically add Flash in IE (and maybe other browsers) + + // Experiment -- try to get the movie element immediately + var els = tempParent.getElementsByTagName("object"); // FIXME - JSLint if this works + if (!els || els.length > 1 || els.length === 0) { + // Oh crap...bail + } else if (els.length === 1) { + this.movieElement = els[0]; + this.debug("Got the movie. WOOT!"); + } + + targetElement.parentNode.replaceChild(tempParent.firstChild, targetElement); + + // Fix IE Flash/Form bug + if (window[this.movieName] == undefined) { + window[this.movieName] = this.getMovieElement(); + } + +}; + +// Private: getFlashHTML generates the object tag needed to embed the flash in to the document +SWFUpload.prototype.getFlashHTML = function () { + // Flash Satay object syntax: http://www.alistapart.com/articles/flashsatay + return ['', + '', + '', + '', + '', + '', + '', + ''].join(""); +}; + +// Private: getFlashVars builds the parameter string that will be passed +// to flash in the flashvars param. +SWFUpload.prototype.getFlashVars = function () { + // Build a string from the post param object + var httpSuccessString, paramString; + + paramString = this.buildParamString(); + httpSuccessString = this.settings.http_success.join(","); + + // Build the parameter string + return ["movieName=", encodeURIComponent(this.movieName), + "&uploadURL=", encodeURIComponent(this.settings.upload_url), + "&useQueryString=", encodeURIComponent(this.settings.use_query_string), + "&requeueOnError=", encodeURIComponent(this.settings.requeue_on_error), + "&httpSuccess=", encodeURIComponent(httpSuccessString), + "&assumeSuccessTimeout=", encodeURIComponent(this.settings.assume_success_timeout), + "&params=", encodeURIComponent(paramString), + "&filePostName=", encodeURIComponent(this.settings.file_post_name), + "&fileTypes=", encodeURIComponent(this.settings.file_types), + "&fileTypesDescription=", encodeURIComponent(this.settings.file_types_description), + "&fileSizeLimit=", encodeURIComponent(this.settings.file_size_limit), + "&fileUploadLimit=", encodeURIComponent(this.settings.file_upload_limit), + "&fileQueueLimit=", encodeURIComponent(this.settings.file_queue_limit), + "&debugEnabled=", encodeURIComponent(this.settings.debug_enabled), + "&buttonImageURL=", encodeURIComponent(this.settings.button_image_url), + "&buttonWidth=", encodeURIComponent(this.settings.button_width), + "&buttonHeight=", encodeURIComponent(this.settings.button_height), + "&buttonText=", encodeURIComponent(this.settings.button_text), + "&buttonTextTopPadding=", encodeURIComponent(this.settings.button_text_top_padding), + "&buttonTextLeftPadding=", encodeURIComponent(this.settings.button_text_left_padding), + "&buttonTextStyle=", encodeURIComponent(this.settings.button_text_style), + "&buttonAction=", encodeURIComponent(this.settings.button_action), + "&buttonDisabled=", encodeURIComponent(this.settings.button_disabled), + "&buttonCursor=", encodeURIComponent(this.settings.button_cursor) + ].join(""); +}; + +// Public: get retrieves the DOM reference to the Flash element added by SWFUpload +// The element is cached after the first lookup +SWFUpload.prototype.getMovieElement = function () { + if (this.movieElement == undefined) { + this.movieElement = document.getElementById(this.movieName); + } + + if (this.movieElement === null) { + throw "Could not find Flash element"; + } + + return this.movieElement; +}; + +// Private: buildParamString takes the name/value pairs in the post_params setting object +// and joins them up in to a string formatted "name=value&name=value" +SWFUpload.prototype.buildParamString = function () { + var name, postParams, paramStringPairs = []; + + postParams = this.settings.post_params; + + if (typeof(postParams) === "object") { + for (name in postParams) { + if (postParams.hasOwnProperty(name)) { + paramStringPairs.push(encodeURIComponent(name.toString()) + "=" + encodeURIComponent(postParams[name].toString())); + } + } + } + + return paramStringPairs.join("&"); +}; + +// Public: Used to remove a SWFUpload instance from the page. This method strives to remove +// all references to the SWF, and other objects so memory is properly freed. +// Returns true if everything was destroyed. Returns a false if a failure occurs leaving SWFUpload in an inconsistant state. +// Credits: Major improvements provided by steffen +SWFUpload.prototype.destroy = function () { + var movieElement; + + try { + // Make sure Flash is done before we try to remove it + this.cancelUpload(null, false); + + // Stop the external interface check from running + this.callFlash("StopExternalInterfaceCheck"); + + movieElement = this.cleanUp(); + + // Remove the SWFUpload DOM nodes + if (movieElement) { + // Remove the Movie Element from the page + try { + movieElement.parentNode.removeChild(movieElement); + } catch (ex) {} + } + + // Remove IE form fix reference + window[this.movieName] = null; + + // Destroy other references + SWFUpload.instances[this.movieName] = null; + delete SWFUpload.instances[this.movieName]; + + this.movieElement = null; + this.settings = null; + this.customSettings = null; + this.eventQueue = null; + this.movieName = null; + + + return true; + } catch (ex2) { + return false; + } +}; + + +// Public: displayDebugInfo prints out settings and configuration +// information about this SWFUpload instance. +// This function (and any references to it) can be deleted when placing +// SWFUpload in production. +SWFUpload.prototype.displayDebugInfo = function () { + this.debug( + [ + "---SWFUpload Instance Info---\n", + "Version: ", SWFUpload.version, "\n", + "Movie Name: ", this.movieName, "\n", + "Settings:\n", + "\t", "upload_url: ", this.settings.upload_url, "\n", + "\t", "flash_url: ", this.settings.flash_url, "\n", + "\t", "use_query_string: ", this.settings.use_query_string.toString(), "\n", + "\t", "requeue_on_error: ", this.settings.requeue_on_error.toString(), "\n", + "\t", "http_success: ", this.settings.http_success.join(", "), "\n", + "\t", "assume_success_timeout: ", this.settings.assume_success_timeout, "\n", + "\t", "file_post_name: ", this.settings.file_post_name, "\n", + "\t", "post_params: ", this.settings.post_params.toString(), "\n", + "\t", "file_types: ", this.settings.file_types, "\n", + "\t", "file_types_description: ", this.settings.file_types_description, "\n", + "\t", "file_size_limit: ", this.settings.file_size_limit, "\n", + "\t", "file_upload_limit: ", this.settings.file_upload_limit, "\n", + "\t", "file_queue_limit: ", this.settings.file_queue_limit, "\n", + "\t", "debug: ", this.settings.debug.toString(), "\n", + + "\t", "prevent_swf_caching: ", this.settings.prevent_swf_caching.toString(), "\n", + + "\t", "button_placeholder_id: ", this.settings.button_placeholder_id.toString(), "\n", + "\t", "button_placeholder: ", (this.settings.button_placeholder ? "Set" : "Not Set"), "\n", + "\t", "button_image_url: ", this.settings.button_image_url.toString(), "\n", + "\t", "button_width: ", this.settings.button_width.toString(), "\n", + "\t", "button_height: ", this.settings.button_height.toString(), "\n", + "\t", "button_text: ", this.settings.button_text.toString(), "\n", + "\t", "button_text_style: ", this.settings.button_text_style.toString(), "\n", + "\t", "button_text_top_padding: ", this.settings.button_text_top_padding.toString(), "\n", + "\t", "button_text_left_padding: ", this.settings.button_text_left_padding.toString(), "\n", + "\t", "button_action: ", this.settings.button_action.toString(), "\n", + "\t", "button_disabled: ", this.settings.button_disabled.toString(), "\n", + + "\t", "custom_settings: ", this.settings.custom_settings.toString(), "\n", + "Event Handlers:\n", + "\t", "swfupload_loaded_handler assigned: ", (typeof this.settings.swfupload_loaded_handler === "function").toString(), "\n", + "\t", "file_dialog_start_handler assigned: ", (typeof this.settings.file_dialog_start_handler === "function").toString(), "\n", + "\t", "file_queued_handler assigned: ", (typeof this.settings.file_queued_handler === "function").toString(), "\n", + "\t", "file_queue_error_handler assigned: ", (typeof this.settings.file_queue_error_handler === "function").toString(), "\n", + "\t", "upload_start_handler assigned: ", (typeof this.settings.upload_start_handler === "function").toString(), "\n", + "\t", "upload_progress_handler assigned: ", (typeof this.settings.upload_progress_handler === "function").toString(), "\n", + "\t", "upload_error_handler assigned: ", (typeof this.settings.upload_error_handler === "function").toString(), "\n", + "\t", "upload_success_handler assigned: ", (typeof this.settings.upload_success_handler === "function").toString(), "\n", + "\t", "upload_complete_handler assigned: ", (typeof this.settings.upload_complete_handler === "function").toString(), "\n", + "\t", "debug_handler assigned: ", (typeof this.settings.debug_handler === "function").toString(), "\n" + ].join("") + ); +}; + +/* Note: addSetting and getSetting are no longer used by SWFUpload but are included + the maintain v2 API compatibility +*/ +// Public: (Deprecated) addSetting adds a setting value. If the value given is undefined or null then the default_value is used. +SWFUpload.prototype.addSetting = function (name, value, default_value) { + if (value == undefined) { + return (this.settings[name] = default_value); + } else { + return (this.settings[name] = value); + } +}; + +// Public: (Deprecated) getSetting gets a setting. Returns an empty string if the setting was not found. +SWFUpload.prototype.getSetting = function (name) { + if (this.settings[name] != undefined) { + return this.settings[name]; + } + + return ""; +}; + + + +// Private: callFlash handles function calls made to the Flash element. +// Calls are made with a setTimeout for some functions to work around +// bugs in the ExternalInterface library. +SWFUpload.prototype.callFlash = function (functionName, argumentArray) { + var movieElement, returnValue, returnString; + + argumentArray = argumentArray || []; + movieElement = this.getMovieElement(); + + // Flash's method if calling ExternalInterface methods (code adapted from MooTools). + try { + if (movieElement && movieElement.CallFunction) { + returnString = movieElement.CallFunction('' + __flash__argumentsToXML(argumentArray, 0) + ''); + returnValue = eval(returnString); + } else { + this.debug("Can't call flash because the movie wasn't found."); + } + } catch (ex) { + this.debug("Exception calling flash: " + ex.message); + } + + // Unescape file post param values + if (returnValue != undefined && typeof returnValue.post === "object") { + returnValue = this.unescapeFilePostParams(returnValue); + } + + return returnValue; +}; + +/* ***************************** + -- Flash control methods -- + Your UI should use these + to operate SWFUpload + ***************************** */ + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFile causes a File Selection Dialog window to appear. This +// dialog only allows 1 file to be selected. +SWFUpload.prototype.selectFile = function () { + this.callFlash("SelectFile"); +}; + +// WARNING: this function does not work in Flash Player 10 +// Public: selectFiles causes a File Selection Dialog window to appear/ This +// dialog allows the user to select any number of files +// Flash Bug Warning: Flash limits the number of selectable files based on the combined length of the file names. +// If the selection name length is too long the dialog will fail in an unpredictable manner. There is no work-around +// for this bug. +SWFUpload.prototype.selectFiles = function () { + this.callFlash("SelectFiles"); +}; + + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startUpload = function (fileID) { + this.callFlash("StartUpload", [fileID]); +}; + +// Public: startUpload starts uploading the first file in the queue unless +// the optional parameter 'fileID' specifies the ID +SWFUpload.prototype.startResizedUpload = function (fileID, width, height, encoding, quality) { + this.callFlash("StartUpload", [fileID, { "width": width, "height" : height, "encoding" : encoding, "quality" : quality }]); +}; + +// Public: cancelUpload cancels any queued file. The fileID parameter may be the file ID or index. +// If you do not specify a fileID the current uploading file or first file in the queue is cancelled. +// If you do not want the uploadError event to trigger you can specify false for the triggerErrorEvent parameter. +SWFUpload.prototype.cancelUpload = function (fileID, triggerErrorEvent) { + if (triggerErrorEvent !== false) { + triggerErrorEvent = true; + } + this.callFlash("CancelUpload", [fileID, triggerErrorEvent]); +}; + +// Public: stopUpload stops the current upload and requeues the file at the beginning of the queue. +// If nothing is currently uploading then nothing happens. +SWFUpload.prototype.stopUpload = function () { + this.callFlash("StopUpload"); +}; + + +// Public: requeueUpload requeues any file. If the file is requeued or already queued true is returned. +// If the file is not found or is currently uploading false is returned. Requeuing a file bypasses the +// file size, queue size, upload limit and other queue checks. Certain files can't be requeued (e.g, invalid or zero bytes files). +SWFUpload.prototype.requeueUpload = function (indexOrFileID) { + return this.callFlash("RequeueUpload", [indexOrFileID]); +}; + + +/* ************************ + * Settings methods + * These methods change the SWFUpload settings. + * SWFUpload settings should not be changed directly on the settings object + * since many of the settings need to be passed to Flash in order to take + * effect. + * *********************** */ + +// Public: getStats gets the file statistics object. +SWFUpload.prototype.getStats = function () { + return this.callFlash("GetStats"); +}; + +// Public: setStats changes the SWFUpload statistics. You shouldn't need to +// change the statistics but you can. Changing the statistics does not +// affect SWFUpload accept for the successful_uploads count which is used +// by the upload_limit setting to determine how many files the user may upload. +SWFUpload.prototype.setStats = function (statsObject) { + this.callFlash("SetStats", [statsObject]); +}; + +// Public: getFile retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + +// Public: getFileFromQueue retrieves a File object by ID or Index. If the file is +// not found then 'null' is returned. +SWFUpload.prototype.getQueueFile = function (fileID) { + if (typeof(fileID) === "number") { + return this.callFlash("GetFileByQueueIndex", [fileID]); + } else { + return this.callFlash("GetFile", [fileID]); + } +}; + + +// Public: addFileParam sets a name/value pair that will be posted with the +// file specified by the Files ID. If the name already exists then the +// exiting value will be overwritten. +SWFUpload.prototype.addFileParam = function (fileID, name, value) { + return this.callFlash("AddFileParam", [fileID, name, value]); +}; + +// Public: removeFileParam removes a previously set (by addFileParam) name/value +// pair from the specified file. +SWFUpload.prototype.removeFileParam = function (fileID, name) { + this.callFlash("RemoveFileParam", [fileID, name]); +}; + +// Public: setUploadUrl changes the upload_url setting. +SWFUpload.prototype.setUploadURL = function (url) { + this.settings.upload_url = url.toString(); + this.callFlash("SetUploadURL", [url]); +}; + +// Public: setPostParams changes the post_params setting +SWFUpload.prototype.setPostParams = function (paramsObject) { + this.settings.post_params = paramsObject; + this.callFlash("SetPostParams", [paramsObject]); +}; + +// Public: addPostParam adds post name/value pair. Each name can have only one value. +SWFUpload.prototype.addPostParam = function (name, value) { + this.settings.post_params[name] = value; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: removePostParam deletes post name/value pair. +SWFUpload.prototype.removePostParam = function (name) { + delete this.settings.post_params[name]; + this.callFlash("SetPostParams", [this.settings.post_params]); +}; + +// Public: setFileTypes changes the file_types setting and the file_types_description setting +SWFUpload.prototype.setFileTypes = function (types, description) { + this.settings.file_types = types; + this.settings.file_types_description = description; + this.callFlash("SetFileTypes", [types, description]); +}; + +// Public: setFileSizeLimit changes the file_size_limit setting +SWFUpload.prototype.setFileSizeLimit = function (fileSizeLimit) { + this.settings.file_size_limit = fileSizeLimit; + this.callFlash("SetFileSizeLimit", [fileSizeLimit]); +}; + +// Public: setFileUploadLimit changes the file_upload_limit setting +SWFUpload.prototype.setFileUploadLimit = function (fileUploadLimit) { + this.settings.file_upload_limit = fileUploadLimit; + this.callFlash("SetFileUploadLimit", [fileUploadLimit]); +}; + +// Public: setFileQueueLimit changes the file_queue_limit setting +SWFUpload.prototype.setFileQueueLimit = function (fileQueueLimit) { + this.settings.file_queue_limit = fileQueueLimit; + this.callFlash("SetFileQueueLimit", [fileQueueLimit]); +}; + +// Public: setFilePostName changes the file_post_name setting +SWFUpload.prototype.setFilePostName = function (filePostName) { + this.settings.file_post_name = filePostName; + this.callFlash("SetFilePostName", [filePostName]); +}; + +// Public: setUseQueryString changes the use_query_string setting +SWFUpload.prototype.setUseQueryString = function (useQueryString) { + this.settings.use_query_string = useQueryString; + this.callFlash("SetUseQueryString", [useQueryString]); +}; + +// Public: setRequeueOnError changes the requeue_on_error setting +SWFUpload.prototype.setRequeueOnError = function (requeueOnError) { + this.settings.requeue_on_error = requeueOnError; + this.callFlash("SetRequeueOnError", [requeueOnError]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setHTTPSuccess = function (http_status_codes) { + if (typeof http_status_codes === "string") { + http_status_codes = http_status_codes.replace(" ", "").split(","); + } + + this.settings.http_success = http_status_codes; + this.callFlash("SetHTTPSuccess", [http_status_codes]); +}; + +// Public: setHTTPSuccess changes the http_success setting +SWFUpload.prototype.setAssumeSuccessTimeout = function (timeout_seconds) { + this.settings.assume_success_timeout = timeout_seconds; + this.callFlash("SetAssumeSuccessTimeout", [timeout_seconds]); +}; + +// Public: setDebugEnabled changes the debug_enabled setting +SWFUpload.prototype.setDebugEnabled = function (debugEnabled) { + this.settings.debug_enabled = debugEnabled; + this.callFlash("SetDebugEnabled", [debugEnabled]); +}; + +// Public: setButtonImageURL loads a button image sprite +SWFUpload.prototype.setButtonImageURL = function (buttonImageURL) { + if (buttonImageURL == undefined) { + buttonImageURL = ""; + } + + this.settings.button_image_url = buttonImageURL; + this.callFlash("SetButtonImageURL", [buttonImageURL]); +}; + +// Public: setButtonDimensions resizes the Flash Movie and button +SWFUpload.prototype.setButtonDimensions = function (width, height) { + this.settings.button_width = width; + this.settings.button_height = height; + + var movie = this.getMovieElement(); + if (movie != undefined) { + movie.style.width = width + "px"; + movie.style.height = height + "px"; + } + + this.callFlash("SetButtonDimensions", [width, height]); +}; +// Public: setButtonText Changes the text overlaid on the button +SWFUpload.prototype.setButtonText = function (html) { + this.settings.button_text = html; + this.callFlash("SetButtonText", [html]); +}; +// Public: setButtonTextPadding changes the top and left padding of the text overlay +SWFUpload.prototype.setButtonTextPadding = function (left, top) { + this.settings.button_text_top_padding = top; + this.settings.button_text_left_padding = left; + this.callFlash("SetButtonTextPadding", [left, top]); +}; + +// Public: setButtonTextStyle changes the CSS used to style the HTML/Text overlaid on the button +SWFUpload.prototype.setButtonTextStyle = function (css) { + this.settings.button_text_style = css; + this.callFlash("SetButtonTextStyle", [css]); +}; +// Public: setButtonDisabled disables/enables the button +SWFUpload.prototype.setButtonDisabled = function (isDisabled) { + this.settings.button_disabled = isDisabled; + this.callFlash("SetButtonDisabled", [isDisabled]); +}; +// Public: setButtonAction sets the action that occurs when the button is clicked +SWFUpload.prototype.setButtonAction = function (buttonAction) { + this.settings.button_action = buttonAction; + this.callFlash("SetButtonAction", [buttonAction]); +}; + +// Public: setButtonCursor changes the mouse cursor displayed when hovering over the button +SWFUpload.prototype.setButtonCursor = function (cursor) { + this.settings.button_cursor = cursor; + this.callFlash("SetButtonCursor", [cursor]); +}; + + +/* ******************************* + Flash Event Interfaces + These functions are used by Flash to trigger the various + events. + + All these functions a Private. + + Because the ExternalInterface library is buggy the event calls + are added to a queue and the queue then executed by a setTimeout. + This ensures that events are executed in a determinate order and that + the ExternalInterface bugs are avoided. +******************************* */ + +SWFUpload.prototype.queueEvent = function (handlerName, argumentArray) { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + var self = this; + + if (argumentArray == undefined) { + argumentArray = []; + } else if (!(argumentArray instanceof Array)) { + argumentArray = [argumentArray]; + } + + if (typeof this.settings[handlerName] === "function") { + // Queue the event + this.eventQueue.push(function () { + this.settings[handlerName].apply(this, argumentArray); + }); + + // Execute the next queued event + setTimeout(function () { + self.executeNextEvent(); + }, 0); + + } else if (this.settings[handlerName] !== null) { + throw "Event handler " + handlerName + " is unknown or is not a function"; + } +}; + +// Private: Causes the next event in the queue to be executed. Since events are queued using a setTimeout +// we must queue them in order to garentee that they are executed in order. +SWFUpload.prototype.executeNextEvent = function () { + // Warning: Don't call this.debug inside here or you'll create an infinite loop + + var f = this.eventQueue ? this.eventQueue.shift() : null; + if (typeof(f) === "function") { + f.apply(this); + } +}; + +// Private: unescapeFileParams is part of a workaround for a flash bug where objects passed through ExternalInterface cannot have +// properties that contain characters that are not valid for JavaScript identifiers. To work around this +// the Flash Component escapes the parameter names and we must unescape again before passing them along. +SWFUpload.prototype.unescapeFilePostParams = function (file) { + var reg = /[$]([0-9a-f]{4})/i, unescapedPost = {}, uk, k, match; + + if (file != undefined) { + for (k in file.post) { + if (file.post.hasOwnProperty(k)) { + uk = k; + while ((match = reg.exec(uk)) !== null) { + uk = uk.replace(match[0], String.fromCharCode(parseInt("0x" + match[1], 16))); + } + unescapedPost[uk] = file.post[k]; + } + } + + file.post = unescapedPost; + } + + return file; +}; + +// Private: Called by Flash to see if JS can call in to Flash (test if External Interface is working) +SWFUpload.prototype.testExternalInterface = function () { + try { + return this.callFlash("TestExternalInterface"); + } catch (ex) { + return false; + } +}; + +// Private: This event is called by Flash when it has finished loading. Don't modify this. +// Use the swfupload_loaded_handler event setting to execute custom code when SWFUpload has loaded. +SWFUpload.prototype.flashReady = function () { + // Check that the movie element is loaded correctly with its ExternalInterface methods defined + var movieElement = this.getMovieElement(); + + if (!movieElement) { + this.debug("Flash called back ready but the flash movie can't be found."); + return; + } + + this.cleanUp(); + + this.queueEvent("swfupload_loaded_handler"); +}; + +// Private: removes Flash added fuctions to the DOM node to prevent memory leaks in IE. +// This function is called by Flash each time the ExternalInterface functions are created. +SWFUpload.prototype.cleanUp = function () { + var key, movieElement = this.getMovieElement(); + + // Pro-actively unhook all the Flash functions + try { + if (movieElement && typeof(movieElement.CallFunction) === "unknown") { // We only want to do this in IE + this.debug("Removing Flash functions hooks (this should only run in IE and should prevent memory leaks)"); + for (key in movieElement) { + try { + if (typeof(movieElement[key]) === "function") { + movieElement[key] = null; + } + } catch (ex) { + } + } + } + } catch (ex1) { + + } + + // Fix Flashes own cleanup code so if the SWF Movie was removed from the page + // it doesn't display errors. + window["__flash__removeCallback"] = function (instance, name) { + try { + if (instance) { + instance[name] = null; + } + } catch (flashEx) { + + } + }; + + return movieElement; +}; + +/* When the button_action is set to JavaScript this event gets fired and executes the button_action_handler */ +SWFUpload.prototype.buttonAction = function () { + this.queueEvent("button_action_handler"); +}; + +/* This is a chance to do something before the browse window opens */ +SWFUpload.prototype.fileDialogStart = function () { + this.queueEvent("file_dialog_start_handler"); +}; + + +/* Called when a file is successfully added to the queue. */ +SWFUpload.prototype.fileQueued = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queued_handler", file); +}; + + +/* Handle errors that occur when an attempt to queue a file fails. */ +SWFUpload.prototype.fileQueueError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("file_queue_error_handler", [file, errorCode, message]); +}; + +/* Called after the file dialog has closed and the selected files have been queued. + You could call startUpload here if you want the queued files to begin uploading immediately. */ +SWFUpload.prototype.fileDialogComplete = function (numFilesSelected, numFilesQueued, numFilesInQueue) { + this.queueEvent("file_dialog_complete_handler", [numFilesSelected, numFilesQueued, numFilesInQueue]); +}; + +SWFUpload.prototype.uploadStart = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("return_upload_start_handler", file); +}; + +SWFUpload.prototype.returnUploadStart = function (file) { + var returnValue; + if (typeof this.settings.upload_start_handler === "function") { + file = this.unescapeFilePostParams(file); + returnValue = this.settings.upload_start_handler.call(this, file); + } else if (this.settings.upload_start_handler != undefined) { + throw "upload_start_handler must be a function"; + } + + // Convert undefined to true so if nothing is returned from the upload_start_handler it is + // interpretted as 'true'. + if (returnValue === undefined) { + returnValue = true; + } + + returnValue = !!returnValue; + + this.callFlash("ReturnUploadStart", [returnValue]); +}; + + + +SWFUpload.prototype.uploadProgress = function (file, bytesComplete, bytesTotal) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_progress_handler", [file, bytesComplete, bytesTotal]); +}; + +SWFUpload.prototype.uploadError = function (file, errorCode, message) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_error_handler", [file, errorCode, message]); +}; + +SWFUpload.prototype.uploadSuccess = function (file, serverData, responseReceived) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_success_handler", [file, serverData, responseReceived]); +}; + +SWFUpload.prototype.uploadComplete = function (file) { + file = this.unescapeFilePostParams(file); + this.queueEvent("upload_complete_handler", file); +}; + +/* Called by SWFUpload JavaScript and Flash functions when debug is enabled. By default it writes messages to the + internal debug console. You can override this event and have messages written where you want. */ +SWFUpload.prototype.debug = function (message) { + this.queueEvent("debug_handler", message); +}; + + +/* ********************************** + Debug Console + The debug console is a self contained, in page location + for debug message to be sent. The Debug Console adds + itself to the body if necessary. + + The console is automatically scrolled as messages appear. + + If you are using your own debug handler or when you deploy to production and + have debug disabled you can remove these functions to reduce the file size + and complexity. +********************************** */ + +// Private: debugMessage is the default debug_handler. If you want to print debug messages +// call the debug() function. When overriding the function your own function should +// check to see if the debug setting is true before outputting debug information. +SWFUpload.prototype.debugMessage = function (message) { + var exceptionMessage, exceptionValues, key; + + if (this.settings.debug) { + exceptionValues = []; + + // Check for an exception object and print it nicely + if (typeof message === "object" && typeof message.name === "string" && typeof message.message === "string") { + for (key in message) { + if (message.hasOwnProperty(key)) { + exceptionValues.push(key + ": " + message[key]); + } + } + exceptionMessage = exceptionValues.join("\n") || ""; + exceptionValues = exceptionMessage.split("\n"); + exceptionMessage = "EXCEPTION: " + exceptionValues.join("\nEXCEPTION: "); + SWFUpload.Console.writeLine(exceptionMessage); + } else { + SWFUpload.Console.writeLine(message); + } + } +}; + +SWFUpload.Console = {}; +SWFUpload.Console.writeLine = function (message) { + var console, documentForm; + + try { + console = document.getElementById("SWFUpload_Console"); + + if (!console) { + documentForm = document.createElement("form"); + document.getElementsByTagName("body")[0].appendChild(documentForm); + + console = document.createElement("textarea"); + console.id = "SWFUpload_Console"; + console.style.fontFamily = "monospace"; + console.setAttribute("wrap", "off"); + console.wrap = "off"; + console.style.overflow = "auto"; + console.style.width = "400px"; + console.style.height = "450px"; + + // ss fixes + console.style.position = "absolute"; + console.style.top = "5px"; + console.style.zIndex = "100"; + + documentForm.appendChild(console); + } + + console.value += message + "\n"; + + console.scrollTop = console.scrollHeight - console.clientHeight; + } catch (ex) { + alert("Exception: " + ex.name + " Message: " + ex.message); + } +}; diff --git a/thirdparty/swfupload/swfupload.queue.js b/thirdparty/swfupload/swfupload.queue.js new file mode 100755 index 00000000..69e619da --- /dev/null +++ b/thirdparty/swfupload/swfupload.queue.js @@ -0,0 +1,98 @@ +/* + Queue Plug-in + + Features: + *Adds a cancelQueue() method for cancelling the entire queue. + *All queued files are uploaded when startUpload() is called. + *If false is returned from uploadComplete then the queue upload is stopped. + If false is not returned (strict comparison) then the queue upload is continued. + *Adds a QueueComplete event that is fired when all the queued files have finished uploading. + Set the event handler with the queue_complete_handler setting. + + */ + +var SWFUpload; +if (typeof(SWFUpload) === "function") { + SWFUpload.queue = {}; + + SWFUpload.prototype.initSettings = (function (oldInitSettings) { + return function () { + if (typeof(oldInitSettings) === "function") { + oldInitSettings.call(this); + } + + this.queueSettings = {}; + + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + + this.queueSettings.user_upload_complete_handler = this.settings.upload_complete_handler; + this.queueSettings.user_upload_start_handler = this.settings.upload_start_handler; + this.settings.upload_complete_handler = SWFUpload.queue.uploadCompleteHandler; + this.settings.upload_start_handler = SWFUpload.queue.uploadStartHandler; + + this.settings.queue_complete_handler = this.settings.queue_complete_handler || null; + }; + })(SWFUpload.prototype.initSettings); + + SWFUpload.prototype.startUpload = function (fileID) { + this.queueSettings.queue_cancelled_flag = false; + this.callFlash("StartUpload", [fileID]); + }; + + SWFUpload.prototype.cancelQueue = function () { + this.queueSettings.queue_cancelled_flag = true; + this.stopUpload(); + + var stats = this.getStats(); + while (stats.files_queued > 0) { + this.cancelUpload(); + stats = this.getStats(); + } + }; + + SWFUpload.queue.uploadStartHandler = function (file) { + var returnValue; + if (typeof(this.queueSettings.user_upload_start_handler) === "function") { + returnValue = this.queueSettings.user_upload_start_handler.call(this, file); + } + + // To prevent upload a real "FALSE" value must be returned, otherwise default to a real "TRUE" value. + returnValue = (returnValue === false) ? false : true; + + this.queueSettings.queue_cancelled_flag = !returnValue; + + return returnValue; + }; + + SWFUpload.queue.uploadCompleteHandler = function (file) { + var user_upload_complete_handler = this.queueSettings.user_upload_complete_handler; + var continueUpload; + + if (file.filestatus === SWFUpload.FILE_STATUS.COMPLETE) { + this.queueSettings.queue_upload_count++; + } + + if (typeof(user_upload_complete_handler) === "function") { + continueUpload = (user_upload_complete_handler.call(this, file) === false) ? false : true; + } else if (file.filestatus === SWFUpload.FILE_STATUS.QUEUED) { + // If the file was stopped and re-queued don't restart the upload + continueUpload = false; + } else { + continueUpload = true; + } + + if (continueUpload) { + var stats = this.getStats(); + if (stats.files_queued > 0 && this.queueSettings.queue_cancelled_flag === false) { + this.startUpload(); + } else if (this.queueSettings.queue_cancelled_flag === false) { + this.queueEvent("queue_complete_handler", [this.queueSettings.queue_upload_count]); + this.queueSettings.queue_upload_count = 0; + } else { + this.queueSettings.queue_cancelled_flag = false; + this.queueSettings.queue_upload_count = 0; + } + } + }; +} \ No newline at end of file diff --git a/thirdparty/swfupload/swfupload.swf b/thirdparty/swfupload/swfupload.swf new file mode 100755 index 0000000000000000000000000000000000000000..71ff884c33caf257d0d4bc101027d4b0a974d42e GIT binary patch literal 33328 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 E+CYH~eE Date: Thu, 26 Nov 2009 03:22:35 +0000 Subject: [PATCH 017/483] MINOR Moved jsparty/tinymce_ssbuttons to cms/javascript/tinymce_ssbuttons git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93563 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- .../tinymce_ssbuttons/editor_plugin_src.js | 113 ++++++++++++++++++ javascript/tinymce_ssbuttons/img/flash.gif | Bin 0 -> 241 bytes javascript/tinymce_ssbuttons/langs/de.js | 5 + javascript/tinymce_ssbuttons/langs/en.js | 5 + 4 files changed, 123 insertions(+) create mode 100644 javascript/tinymce_ssbuttons/editor_plugin_src.js create mode 100644 javascript/tinymce_ssbuttons/img/flash.gif create mode 100644 javascript/tinymce_ssbuttons/langs/de.js create mode 100644 javascript/tinymce_ssbuttons/langs/en.js diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js new file mode 100644 index 00000000..c97187f8 --- /dev/null +++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js @@ -0,0 +1,113 @@ +(function() { + tinymce.PluginManager.requireLangPack("../../tinymce_ssbuttons"); + var each = tinymce.each; + + tinymce.create('tinymce.plugins.SSButtons', { + /** + * Returns information about the plugin as a name/value array. + * The current keys are longname, author, authorurl, infourl and version. + * + * @returns Name/value array containing information about the plugin. + * @type Array + */ + getInfo : function() { + return { + longname : 'Special buttons for SilverStripe CMS', + author : 'Sam Minnée', + authorurl : 'http://www.siverstripe.com/', + infourl : 'http://www.silverstripe.com/', + version : "1.0" + }; + }, + + + init : function(ed, url) { + /** + * These map the action buttons to the IDs of the forms that they open/close + */ + forms = { + 'sslink' : 'Form_EditorToolbarLinkForm', + 'ssimage' : 'Form_EditorToolbarImageForm', + 'ssflash' : 'Form_EditorToolbarFlashForm' + }; + + ed.addButton('sslink', {title : ed.getLang('tinymce_ssbuttons.insertlink'), cmd : 'sslink', 'class' : 'mce_link'}); + ed.addButton('ssimage', {title : ed.getLang('tinymce_ssbuttons.insertimage'), cmd : 'ssimage', 'class' : 'mce_image'}); + ed.addButton('ssflash', {title : ed.getLang('tinymce_ssbuttons.insertflash'), cmd : 'ssflash', 'class' : 'mce_flash', 'image': url + '/img/flash.gif'}); + + /** + * Show a side panel, hiding others + * If showCommand isn't set, then this will simply hide panels + */ + function showSidePanel(showCommand, hideCommands) { + hideCommands.each(function(command) { + ed.controlManager.setActive(command,false); + Element.hide(forms[command]); + }); + + var showForm = null; + if(forms[showCommand]) { + showForm = $(forms[showCommand]); + showForm.toggle(ed); + } + + if(!showForm || showForm.style.display == "none") { + ed.controlManager.setActive(showCommand, false); + // Can't use $('contentPanel'), as its in a different window + window.parent.document.getElementById('contentPanel').style.display = "none"; + } else { + ed.controlManager.setActive(showCommand, true); + window.parent.document.getElementById('contentPanel').style.display = "block"; + } + window.onresize(); + } + + ed.addCommand("ssclosesidepanel", function(ed) { + showSidePanel('', [ 'sslink', 'ssimage', 'ssflash' ]); + }); + + ed.addCommand("sslink", function(ed) { + showSidePanel('sslink', [ 'ssimage', 'ssflash' ]); + }); + + ed.addCommand("ssimage", function(ed) { + showSidePanel('ssimage', [ 'sslink', 'ssflash' ]); + }); + + ed.addCommand("ssflash", function(ed) { + showSidePanel('ssflash', [ 'ssimage', 'sslink' ]); + }); + + ed.onNodeChange.add(function(ed, o) { + $('Form_EditorToolbarLinkForm').updateSelection(ed); + $('Form_EditorToolbarLinkForm').respondToNodeChange(ed); + }); + ed.onKeyUp.add(function(ed, o) { + $('Form_EditorToolbarLinkForm').updateSelection(ed); + }); + + // resize image containers when the image is resized. + if(!tinymce.isOpera && !tinymce.isWebKit) ed.onMouseUp.add(function(ed, o) { + var node = ed.selection.getNode(); + if(node.nodeName == 'IMG' && ed.dom.getParent(node, 'div')) { + // we have to delay the resize check here, as this event handler is called before the actual image + // resizing is done. + setTimeout(function() { + var ed = tinyMCE.activeEditor, // we need to redeclare these for IE. + node = ed.selection.getNode(), + container = ed.dom.getParent(node, 'div'); + + if(node.width && node.width != parseInt(ed.dom.getStyle(container, 'width'))) { + ed.dom.setStyle(container, 'width', parseInt(node.width)); + ed.execCommand('mceRepaint'); + } + }, 1); + } + }); + } + }); + + + // Adds the plugin class to the list of available TinyMCE plugins + tinymce.PluginManager.add("../../tinymce_ssbuttons", tinymce.plugins.SSButtons); +})(); \ No newline at end of file diff --git a/javascript/tinymce_ssbuttons/img/flash.gif b/javascript/tinymce_ssbuttons/img/flash.gif new file mode 100644 index 0000000000000000000000000000000000000000..cb192e6ceda8d19ad8e7d08dd1cfde0aa72ead2a GIT binary patch literal 241 zcmVOzlLa+Za}7>m0&NpCfJ0FQc3~F7DE)S%o1)Qi1n@vxX46qnD4hRS-NE*Pw!4UvE=#^N( literal 0 HcmV?d00001 diff --git a/javascript/tinymce_ssbuttons/langs/de.js b/javascript/tinymce_ssbuttons/langs/de.js new file mode 100644 index 00000000..0948d6ff --- /dev/null +++ b/javascript/tinymce_ssbuttons/langs/de.js @@ -0,0 +1,5 @@ +tinyMCE.addI18n('de.tinymce_ssbuttons',{ +insertlink: 'Link einfügen', +insertimage: 'Bild einfügen', +insertflash: 'Flash Objekt einfügen' +}); \ No newline at end of file diff --git a/javascript/tinymce_ssbuttons/langs/en.js b/javascript/tinymce_ssbuttons/langs/en.js new file mode 100644 index 00000000..91ed8fb0 --- /dev/null +++ b/javascript/tinymce_ssbuttons/langs/en.js @@ -0,0 +1,5 @@ +tinyMCE.addI18n('en.tinymce_ssbuttons', { +insertlink: 'Insert Link', +insertimage: 'Insert Image', +insertflash: 'Insert Flash Object' +}); \ No newline at end of file From b18fee9e0dfa8d59ca12d46ee23446827b0a5c75 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 03:23:08 +0000 Subject: [PATCH 018/483] MINOR Moved jsparty/tinymce_ssmacron to cms/javascript/tinymce_ssmacron git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93564 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- .../tinymce_ssmacron/editor_plugin_src.js | 40 ++++++++++ javascript/tinymce_ssmacron/img/macron.png | Bin 0 -> 3260 bytes javascript/tinymce_ssmacron/js/macron.js | 71 ++++++++++++++++++ javascript/tinymce_ssmacron/macron.htm | 31 ++++++++ 4 files changed, 142 insertions(+) create mode 100644 javascript/tinymce_ssmacron/editor_plugin_src.js create mode 100644 javascript/tinymce_ssmacron/img/macron.png create mode 100644 javascript/tinymce_ssmacron/js/macron.js create mode 100644 javascript/tinymce_ssmacron/macron.htm diff --git a/javascript/tinymce_ssmacron/editor_plugin_src.js b/javascript/tinymce_ssmacron/editor_plugin_src.js new file mode 100644 index 00000000..2faef38c --- /dev/null +++ b/javascript/tinymce_ssmacron/editor_plugin_src.js @@ -0,0 +1,40 @@ +(function() { + var each = tinymce.each; + + tinymce.create('tinymce.plugins.InsertMacron', { + getInfo : function() { + return { + longname : 'Button to insert macrons', + author : 'Hamish Friedlander. Heavily based on charmap that comes with TinyMCE', + authorurl : 'http://www.siverstripe.com/', + infourl : 'http://www.silverstripe.com/', + version : "1.0" + }; + }, + + + init : function(ed, url) { + // Register commands + ed.addCommand('mceInsertMacron', function() { + ed.windowManager.open({ + file : url + '/macron.htm', + width : 350 + parseInt(ed.getLang('advanced.charmap_delta_width', 0)), + height : 150 + parseInt(ed.getLang('advanced.charmap_delta_height', 0)), + inline : true + }, { + plugin_url : url + }); + }); + + // Register buttons + ed.addButton('ssmacron', { + title : 'Insert a Macron', + cmd : 'mceInsertMacron', + image : url + '/img/macron.png' + }); + } + }); + + // Adds the plugin class to the list of available TinyMCE plugins + tinymce.PluginManager.add("../../tinymce_ssmacron", tinymce.plugins.InsertMacron); +})(); diff --git a/javascript/tinymce_ssmacron/img/macron.png b/javascript/tinymce_ssmacron/img/macron.png new file mode 100644 index 0000000000000000000000000000000000000000..80caf6dab1e5b64a1090f34c79faec373177839d GIT binary patch literal 3260 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 ut*Yu{#+c~!df)BbVYyr;R'; + var cols=-1; + + for (i=0; i' + + '' + + charmap[i][1] + + ''; + if ((cols+1) % charsPerRow == 0) + html += ''; + } + } + + if (cols % charsPerRow > 0) { + var padd = charsPerRow - (cols % charsPerRow); + for (var i=0; i '; + } + + html += ''; + + return html; +} + +function insertChar(chr) { + tinyMCEPopup.execCommand('mceInsertContent', false, '&#' + chr + ';'); + + // Refocus in window + if (tinyMCEPopup.isWindow) + window.focus(); + + tinyMCEPopup.editor.focus(); + tinyMCEPopup.close(); +} + +function previewChar(codeA, codeB, codeN) { + var elmV = document.getElementById('codeV'); + var elmN = document.getElementById('codeN'); + + if (codeA=='#160;') { + elmV.innerHTML = '__'; + } else { + elmV.innerHTML = '&' + codeA; + } + + elmN.innerHTML = codeN; +} diff --git a/javascript/tinymce_ssmacron/macron.htm b/javascript/tinymce_ssmacron/macron.htm new file mode 100644 index 00000000..1fc769e5 --- /dev/null +++ b/javascript/tinymce_ssmacron/macron.htm @@ -0,0 +1,31 @@ + + + + Insert a Macron + + + + + + + + + + + + +
Insert a Macron
+ + + + + + + + + +
 
 
+
+ + + From 1c28f6588249701d4f56bbae23cbe2683e7ce0f5 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 03:26:45 +0000 Subject: [PATCH 019/483] MINOR Moved jsparty/highlight.js to cms/javascript/highlight.js git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93568 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/highlight.js | 236 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100755 javascript/highlight.js diff --git a/javascript/highlight.js b/javascript/highlight.js new file mode 100755 index 00000000..cfc0b0c2 --- /dev/null +++ b/javascript/highlight.js @@ -0,0 +1,236 @@ +/* +highlightImages_over * common/js/highlight.js + * Behaviour-abstracted highligher modul + * + * Usage: + * - include in the header of your file + * - set the class of the container to "highlight". The class will have ' over' appended to it on mouseover + * - set the overSrc attribute on any images inside that, if you want them to be changed + */ + +/* + * Initialise all items that have a highlight or highlightImages class with the appropriate event handlers + */ + + +function onload_init_highlight() { + var allElements = getAllElements(); + var tester,j,overSrc; + + for(var i = 0;i 0) { + overSrc = allImages[j].src; + for(k=0;k<_IMAGE_HIGHLIGHT_REWRITING.length;k++) + overSrc = overSrc.replace(_IMAGE_HIGHLIGHT_REWRITING[k].norm,_IMAGE_HIGHLIGHT_REWRITING[k].over); + if(overSrc != allImages[j].src) { + allImages[j].normSrc = allImages[j].src; + allImages[j].overSrc = overSrc; + } + } + } + } + } + } +} + +/* + * Highlight handlers + */ +function highlightImages_over() { + var el = this; +// if(el.id) document.getElementById('SearchField').document.getElementById('SearchField').innerHTML += "Over: " + el.id + "
"; + + // Reset any timer that may exist + if(el.timer != null) { + clearTimeout(el.timer); + try { + delete el.timer; + } catch(er) {} + } + + // Class + if(el) { + addClass(el, 'over'); + removeClass(el, 'stale'); + + if(el.parentNode) { + el.parentNode.highlightedChild = el; + addClass(el.parentNode,'childOver'); + } + } + + // Images + var allImages = el.getElementsByTagName('img'); + for(var j=0;j 0) { + var el = _HIGHLIGHTED_OBJECTS[idx]; + delete _HIGHLIGHTED_OBJECTS[idx]; + unhighlightDelay = null; + + } else { + var el = this; + if(el && el.getAttribute) { + unhighlightDelay = el.getAttribute("unhighlightDelay"); + if(unhighlightDelay == null) { + if(_DEFAULT_UNHIGHLIGHT_DELAY[el.parentNode.className]) unhighlightDelay = _DEFAULT_UNHIGHLIGHT_DELAY[el.parentNode.className]; + else if(_DEFAULT_UNHIGHLIGHT_DELAY[el.parentNode.id]) unhighlightDelay = _DEFAULT_UNHIGHLIGHT_DELAY[el.parentNode.id]; + else if(_DEFAULT_UNHIGHLIGHT_DELAY['default']) unhighlightDelay = _DEFAULT_UNHIGHLIGHT_DELAY['default']; + } + } + } + + if(unhighlightDelay) { + nextIdx = _HIGHLIGHTED_OBJECTS.length; + if(nextIdx == 0) nextIdx = 1; + _HIGHLIGHTED_OBJECTS[nextIdx] = el; + el.timer = setTimeout("highlightImages_out(" + nextIdx + ")", unhighlightDelay); + + } else { + // Class + if(el) { + removeClass(el, 'over'); + removeClass(el, 'stale'); + + + if(el.parentNode) { + if(!el.parentNode.highlightedChild || el == el.parentNode.highlightedChild) { + removeClass(el.parentNode,'childOver'); + el.parentNode.highlightedChild = null; + } + } + + // Images + var allImages = document.getElementsByTagName('img'); + for(var j=0;j 0) { + nextIdx = _HIGHLIGHTED_OBJECTS.length; + _HIGHLIGHTED_OBJECTS[nextIdx] = el; + el.timer = setTimeout("highlightImages_makeStale(" + nextIdx + ")", staleDelay); + } + } + + if(el.old_onmouseout) el.old_onmouseout(); + + } + } + +} + +// Add the stale class to the given item +function highlightImages_makeStale(idx) { + var el = _HIGHLIGHTED_OBJECTS[idx]; + delete _HIGHLIGHTED_OBJECTS[idx]; + addClass(el, 'stale'); +} + +/* + * Preload the given image + */ + +var _PRELOADED_IMAGES = Array(); +function preload(filename) { + var i = new Image; + i.src = filename; + _PRELOADED_IMAGES[_PRELOADED_IMAGES.length] = i; +} + +//go to the specified page. +//Works for nested elements. Always calls the most nested. +//Includes Bubble hack for mozilla + +var pagelocation; +function go(url){ + if(pagelocation == null){ + window.location=url; + pagelocation = url; + } +} + + + +/* + * This function will show or hide a div when you + * pass it a element ID + * Created by sgow added @ 16-09-2004 + */ + +/* variables needed */ +var showDiv; +var oldDiv = 1; + +function toggleDiv( el ){ + if(oldDiv == 1){ + //the first time you call this function + if(showDiv = document.getElementById(el)) { + showDiv.style.display = "block"; + oldDiv = showDiv; + } + } + else{ + showDiv = document.getElementById(el); + if( showDiv && showDiv == oldDiv ){ + if(oldDiv.style.display == "none"){ showDiv.style.display = "block";} + else { showDiv.style.display = "none";} + oldDiv = showDiv; + // if its the same div as before, hide the same div, unless its the first time you use the function + }else{ + oldDiv.style.display = "none"; + showDiv.style.display = "block"; + oldDiv = showDiv; + // if its a different div, hide the first one, and show the second one + } + } +} + +var _IMAGE_HIGHLIGHT_REWRITING = Array(); +function setImageHighlightRewriting(normVal, overVal) { + _IMAGE_HIGHLIGHT_REWRITING[_IMAGE_HIGHLIGHT_REWRITING.length] = { + 'norm' : normVal, 'over' : overVal + } +} + + +appendLoader(onload_init_highlight); From 928529d04b5bc859119a30b6e2e1437413ac7584 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 03:27:06 +0000 Subject: [PATCH 020/483] MINOR Moved jsparty/hover.js to cms/javascript/hover.js git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93569 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/hover.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100755 javascript/hover.js diff --git a/javascript/hover.js b/javascript/hover.js new file mode 100755 index 00000000..6e75349e --- /dev/null +++ b/javascript/hover.js @@ -0,0 +1,12 @@ +function hover_over() { + Element.addClassName(this, 'over'); +} +function hover_out() { + Element.removeClassName(this, 'over'); +} + +hover_behaviour = { + onmouseover : hover_over, + onmouseout : hover_out +} + From ce3365d095ad206c48b4c53cd86ab79a0908fc4a Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Thu, 26 Nov 2009 05:08:34 +0000 Subject: [PATCH 021/483] MINOR Updated paths from jsparty to sapphire/thirdparty, cms/thirdparty and cms/javascript git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93612 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 22 ++--- code/CMSMain.php | 6 +- code/ImageEditor.php | 6 +- code/LeftAndMain.php | 110 ++++++++++----------- code/ModelAdmin.php | 8 +- code/SecurityAdmin.php | 2 +- code/sitefeatures/PageCommentInterface.php | 4 +- css/cms_left.css | 4 +- css/silverstripe.tabs.css | 2 +- javascript/Upload.js | 2 +- javascript/tinymce_ssmacron/macron.htm | 2 +- templates/Includes/ModelAdmin_left.ss | 4 +- 12 files changed, 82 insertions(+), 90 deletions(-) diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index 30846a4e..9c22aa8f 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -86,7 +86,7 @@ class AssetAdmin extends LeftAndMain { Requirements::javascript(CMS_DIR . "/javascript/CMSMain_upload.js"); Requirements::javascript(CMS_DIR . "/javascript/Upload.js"); - Requirements::javascript(THIRDPARTY_DIR . "/SWFUpload/swfupload.js"); + Requirements::javascript(CMS_DIR . "/thirdparty/swfupload/swfupload.js"); Requirements::javascript(THIRDPARTY_DIR . "/greybox/AmiJS.js"); Requirements::javascript(THIRDPARTY_DIR . "/greybox/greybox.js"); @@ -97,9 +97,9 @@ class AssetAdmin extends LeftAndMain { Requirements::customScript(<< Insert a Macron - + diff --git a/templates/Includes/ModelAdmin_left.ss b/templates/Includes/ModelAdmin_left.ss index b5450a42..006ba86d 100755 --- a/templates/Includes/ModelAdmin_left.ss +++ b/templates/Includes/ModelAdmin_left.ss @@ -1,5 +1,5 @@ -<% require javascript(jsparty/tabstrip/tabstrip.js) %> -<% require css(jsparty/tabstrip/tabstrip.css) %> +<% require javascript(sapphire/thirdparty/tabstrip/tabstrip.js) %> +<% require css(sapphire/thirdparty/tabstrip/tabstrip.css) %>
From 0dfa69146dc5ee5cc9fd77b4b972556055bd7593 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 26 Nov 2009 22:11:38 +0000 Subject: [PATCH 022/483] MINOR Removed MemberTableField deprecated methods for adding fields - this should be done by implementing summary fields on a Member decorator instead git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93662 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/MemberTableField.php | 48 ++++++--------------------------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 5191dc0c..2324a336 100755 --- a/code/MemberTableField.php +++ b/code/MemberTableField.php @@ -37,50 +37,16 @@ class MemberTableField extends ComplexTableField { * @var int */ public static $page_size = 20; - - /** - * @deprecated 2.4. See {@link MemberTableField->addPermissions()} - */ - private static $addedPermissions = array(); - - /** - * @deprecated 2.4: See {@link MemberTableField->addMembershipFields()} - */ - private static $addedFields = array(); /** - * @deprecated 2.4: See {@link MemberTableField->addMembershipFields()} + * Constructor method for MemberTableField. + * + * @param Controller $controller Controller class which created this field + * @param string $name Name of the field (e.g. "Members") + * @param mixed $group Can be the ID of a Group instance, or a Group instance itself + * @param DataObjectSet $members Optional set of Members to set as the source items for this field + * @param boolean $hidePassword Hide the password field or not in the summary? */ - private static $addedCsvFields = array(); - - /** - * @deprecated 2.4. Set permissions using setPermissions(Array) on - * the MemberTableField object. - */ - public static function addPermissions($addingPermissionList) { - trigger_error('MemberTableField::addPermissions() is deprecated. Please set permissions using setPermissions(Array) on the MemberTableField object.', E_USER_NOTICE); - self::$addedPermissions = $addingPermissionList; - } - - /** - * @deprecated 2.4: Please use a DataObjectDecorator, implementing updateSummaryFields - * to alter the table overview fields instead. - */ - public static function addMembershipFields($addingFieldList, $addingCsvFieldList = null) { - trigger_error('MemberTableField::addMembershipFields() is deprecated. Please implement updateSummaryFields() on a Member decorator instead.', E_USER_NOTICE); - self::$addedFields = $addingFieldList; - $addingCsvFieldList == null ? self::$addedCsvFields = $addingFieldList : self::$addedCsvFields = $addingCsvFieldList; - } - - /** - * Constructor method for MemberTableField. - * - * @param Controller $controller Controller class which created this field - * @param string $name Name of the field (e.g. "Members") - * @param mixed $group Can be the ID of a Group instance, or a Group instance itself - * @param DataObjectSet $members Optional set of Members to set as the source items for this field - * @param boolean $hidePassword Hide the password field or not in the summary? - */ function __construct($controller, $name, $group, $members = null, $hidePassword = true) { $sourceClass = self::$data_class; $SNG_member = singleton($sourceClass); From 84a591bf2b22b5acaee83e29de98ff86c4883cf2 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 26 Nov 2009 22:38:04 +0000 Subject: [PATCH 023/483] BUGFIX Removed calls to Translatable::is_enabled() since it's deprecated, replaced with Object::has_extension('SiteTree', 'Translatable') instead git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93676 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSMain.php | 2 +- code/LeftAndMain.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/CMSMain.php b/code/CMSMain.php index 0aa78bf7..7f9b78da 100755 --- a/code/CMSMain.php +++ b/code/CMSMain.php @@ -384,7 +384,7 @@ JS; } // Don't open a page from a different locale - if($record && Translatable::is_enabled() && $record->Locale && $record->Locale != Translatable::get_current_locale()) { + if($record && Object::has_extension('SiteTree', 'Translatable') && $record->Locale && $record->Locale != Translatable::get_current_locale()) { $record = null; } diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 2edd4724..56d210f6 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -112,7 +112,7 @@ class LeftAndMain extends Controller { ); // set reading lang - if(Translatable::is_enabled() && !Director::is_ajax()) { + if(Object::has_extension('SiteTree', 'Translatable') && !Director::is_ajax()) { Translatable::choose_site_locale(array_keys(Translatable::get_existing_content_languages('SiteTree'))); } From 5a1a947b9277599faf0bb233a37eed8e3a103d29 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 26 Nov 2009 22:50:26 +0000 Subject: [PATCH 024/483] MINOR Removed ContentNegotiator::disable() since it's disabled by default (in AssetAdmin) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93681 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 3 --- 1 file changed, 3 deletions(-) diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index 9c22aa8f..77197fc2 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -127,9 +127,6 @@ JS if(isset($data['ID']) && $data['ID'] != 'root') $folder = DataObject::get_by_id("Folder", $data['ID']); else $folder = singleton('Folder'); - // Don't modify the output of the template, or it will become invalid - ContentNegotiator::disable(); - return array( 'CanUpload' => $folder->canEdit()); } From 49b720ffd046f1953d664f8e8ed7470064a4f15b Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Thu, 26 Nov 2009 23:09:05 +0000 Subject: [PATCH 025/483] API CHANGE: removed deprecated extend calls (r93632). API CHANGE: removed fieldExists(). Use hasField() (r93633). API CHANGE removed listOfFields() (r93647). API CHANGE: removed Tag() and URL() from Image. Use getTag() and getURL(). BUGFIX: updated Image.php to use getTag() (r93639, r93646). API CHANGE: removed val(). Use XML_val() (r93650). API CHANGE: removed $add_action. Use singlar_name or lang tables (r93658). API CHANGE: removed ConfirmedFormAction (r93674). API CHANGE: removed ajax_render on CTF (r93679). git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93685 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 4 ---- code/SideReport.php | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 56d210f6..3a082f0b 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -277,10 +277,6 @@ class LeftAndMain extends Controller { ) ); - // DEPRECATED 2.3: Use init() - $dummy = null; - $this->extend('augmentInit', $dummy); - $dummy = null; $this->extend('init', $dummy); } diff --git a/code/SideReport.php b/code/SideReport.php index 35c1a1f4..e9edab34 100755 --- a/code/SideReport.php +++ b/code/SideReport.php @@ -48,7 +48,7 @@ abstract class SideReport extends Object { if(is_string($fieldSource)) { $val .= Convert::raw2xml($record->$fieldSource); } else { - $val .= $record->val($fieldSource[0], $fieldSource[1]); + $val .= $record->XML_val($fieldSource[0], $fieldSource[1]); } if(isset($fieldInfo['newline']) && $fieldInfo['newline']) $result .= "
"; From a12f9c987f8110e7823406d931343804e29ef22b Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Thu, 26 Nov 2009 23:13:45 +0000 Subject: [PATCH 026/483] API CHANGE: removed deprecated LeftAndMain::add_menu_item. Use CMSMenu::add_menu_item() git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93687 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 3a082f0b..89932529 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -346,14 +346,6 @@ class LeftAndMain extends Controller { $parts = split(']*>', $html); return $parts[sizeof($parts)-2]; } - - /** - * @deprecated Use CMSMenu::add_menu_item(); - */ - static function add_menu_item($code, $menuTitle, $url, $controllerClass = null, $priority = -1) { - user_error("LeftAndMain::add_menu_item is deprecated; use CMSMenu::add_menu_item", E_USER_NOTICE); - return CMSMenu::add_menu_item($code, $menuTitle, $url, $controllerClass, $priority); - } //------------------------------------------------------------------------------------------// // Main UI components From 4e9d2c3663a925d3b521ef9451f83fe4e68c9e3a Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Thu, 26 Nov 2009 23:56:00 +0000 Subject: [PATCH 027/483] BUGFIX Removed code that relied on deprecated functions in MemberTableField git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93707 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/MemberTableField.php | 4 ---- 1 file changed, 4 deletions(-) diff --git a/code/MemberTableField.php b/code/MemberTableField.php index 2324a336..7a17292e 100755 --- a/code/MemberTableField.php +++ b/code/MemberTableField.php @@ -68,10 +68,6 @@ class MemberTableField extends ComplexTableField { $this->group = DataObject::get_by_id('Group', $_REQUEST['ctf'][$this->Name()]["ID"]); } - foreach(self::$addedFields as $key => $value) { - $fieldList[$key] = $value; - } - if(!$hidePassword) { $fieldList["SetPassword"] = "Password"; } From 064aa648861e11fbe20e8ba8563c5a598d699e33 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Fri, 27 Nov 2009 01:42:24 +0000 Subject: [PATCH 028/483] MINOR Javascript variable declarations in CMSMain_left.js (#4741) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93762 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/CMSMain_left.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/javascript/CMSMain_left.js b/javascript/CMSMain_left.js index 7ea18dcf..136f75a6 100755 --- a/javascript/CMSMain_left.js +++ b/javascript/CMSMain_left.js @@ -9,6 +9,7 @@ _NEW_PAGES = new Array(); /** * Add page action */ +var addpageclass; addpageclass = Class.create(); addpageclass.applyTo('#addpage'); addpageclass.prototype = { @@ -95,11 +96,12 @@ addpageclass.prototype = { showAddPageError: function(response) { errorMessage(ss.i18n._t('CMSMAIN.ERRORADDINGPAGE'), response); } -} +}; /** * Search button click action */ +var searchclass; searchclass = Class.create(); searchclass.applyTo('#search'); searchclass.prototype = { @@ -118,7 +120,7 @@ searchclass.prototype = { } } -SiteTreeFilter = Class.create(); +var SiteTreeFilter = Class.create(); SiteTreeFilter.applyTo('#siteTreeFilterList'); SiteTreeFilter.prototype = { initialize: function () { @@ -156,7 +158,7 @@ SiteTreeFilter.prototype = { /** * Control the site tree filter */ -SiteTreeFilterForm = Class.create(); +var SiteTreeFilterForm = Class.create(); SiteTreeFilterForm.applyTo('form#search_options'); SiteTreeFilterForm.prototype = { initialize: function() { @@ -230,7 +232,7 @@ SiteTreeFilterForm.prototype = { /** * Add Criteria Drop-down onchange action which allows more criteria to be shown */ -SiteTreeFilterAddCriteria = Class.create(); +var SiteTreeFilterAddCriteria = Class.create(); SiteTreeFilterAddCriteria.applyTo('#SiteTreeFilterAddCriteria'); SiteTreeFilterAddCriteria.prototype = { onchange : function() { @@ -244,7 +246,7 @@ SiteTreeFilterAddCriteria.prototype = { /** * Batch Actions button click action */ -batchactionsclass = Class.create(); +var batchactionsclass = Class.create(); batchactionsclass.applyTo('#batchactions'); batchactionsclass.prototype = { @@ -415,7 +417,7 @@ Behaviour.register({ /** * Publish selected pages action */ -publishpage = Class.create(); +var publishpage = Class.create(); publishpage.applyTo('#batchactions_options'); publishpage.prototype = { onsubmit : function() { @@ -457,12 +459,13 @@ publishpage.prototype = { return false; } -} +}; /** * Delete selected pages action */ +var deletepage; deletepage = Class.create(); deletepage.applyTo('#Form_DeleteItemsForm'); deletepage.prototype = { @@ -511,7 +514,7 @@ deletepage.prototype = { return false; } -} +}; /** * Tree context menu From 8eddb47344d75ed3a6be204550284ad38f30a406 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Fri, 27 Nov 2009 02:11:34 +0000 Subject: [PATCH 029/483] API CHANGE: removed Director::Link(). Use Controller::join_links() instead git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93785 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 4 ++-- code/LeftAndMain.php | 2 +- code/SecurityAdmin.php | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index 77197fc2..8647a040 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -454,7 +454,7 @@ JS; $siteTreeList = $obj->getChildrenAsUL( '', '"
  • ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' . - '"Link(),0,-1), "show", $child->ID) . "\" class=\"" . ($child->hasChildFolders() ? " contents" : "") . "\" >" . $child->TreeTitle() . "" ', + '"Link(),0,-1), "show", $child->ID) . "\" class=\"" . ($child->hasChildFolders() ? " contents" : "") . "\" >" . $child->TreeTitle() . "" ', $this, true, "ChildFolders" @@ -482,7 +482,7 @@ JS; $results = $obj->getChildrenAsUL( '', '"
  • ID\" class=\"$child->class" . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' . - '"Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "" ', + '"Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "" ', $this, true ); diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 89932529..91f67406 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -474,7 +474,7 @@ class LeftAndMain extends Controller { // getChildrenAsUL is a flexible and complex way of traversing the tree $titleEval = ' "
  • ID\" class=\"" . $child->CMSTreeClasses($extraArg) . "\">" . - "Link(),0,-1), "show", $child->ID) . "\" class=\"" . $child->CMSTreeClasses($extraArg) . "\" title=\"' . _t('LeftAndMain.PAGETYPE','Page type: ') . '".$child->class."\" >" . + "Link(),0,-1), "show", $child->ID) . "\" class=\"" . $child->CMSTreeClasses($extraArg) . "\" title=\"' . _t('LeftAndMain.PAGETYPE','Page type: ') . '".$child->class."\" >" . ($child->TreeTitle()) . "" '; diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index 0ce89819..c8c0ca0a 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -237,7 +237,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { $siteTreeList = $obj->getChildrenAsUL( '', '"
  • ID\" class=\"$child->class " . ($child->Locked ? " nodelete" : "") . $child->markingClasses() . ($extraArg->isCurrentPage($child) ? " current" : "") . "\">" . ' . - '"Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "" ', + '"Link(),0,-1), "show", $child->ID) . "\" >" . $child->TreeTitle() . "" ', $this, true ); From 0b115b27239a56b569316cb1baec654973bc270f Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Mon, 30 Nov 2009 01:02:10 +0000 Subject: [PATCH 030/483] BUGFIX: fix bug that can't find tinymce_ssbuttons under sapphire/thirdpaty. this is a change merged from r92853 http://open.silverstripe.org/changeset/92853#file3 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93950 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.php b/_config.php index e3088201..92bf86af 100644 --- a/_config.php +++ b/_config.php @@ -42,7 +42,7 @@ HtmlEditorConfig::get('cms')->setOptions(array( )); -HtmlEditorConfig::get('cms')->enablePlugins('media', '../../tinymce_ssbuttons', 'fullscreen'); +HtmlEditorConfig::get('cms')->enablePlugins('media', '../../../../cms/tinymce_ssbuttons', 'fullscreen'); HtmlEditorConfig::get('cms')->insertButtonsBefore('formatselect', 'styleselect'); HtmlEditorConfig::get('cms')->insertButtonsBefore('advcode', 'ssimage', 'ssflash', 'sslink', 'unlink', 'anchor', 'separator' ); From cbda994c675b6be81e4333395f5d21a6cb79b4cd Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Mon, 30 Nov 2009 01:11:18 +0000 Subject: [PATCH 031/483] BUGFIX: fix bug that can't find tinymce_ssbuttons under sapphire/thirdpaty. this is a change merged from r92853 http://open.silverstripe.org/changeset/92853#file3 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93955 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_config.php b/_config.php index 92bf86af..fc4e6a00 100644 --- a/_config.php +++ b/_config.php @@ -42,7 +42,7 @@ HtmlEditorConfig::get('cms')->setOptions(array( )); -HtmlEditorConfig::get('cms')->enablePlugins('media', '../../../../cms/tinymce_ssbuttons', 'fullscreen'); +HtmlEditorConfig::get('cms')->enablePlugins('media', '../../../../cms/javascript/tinymce_ssbuttons', 'fullscreen'); HtmlEditorConfig::get('cms')->insertButtonsBefore('formatselect', 'styleselect'); HtmlEditorConfig::get('cms')->insertButtonsBefore('advcode', 'ssimage', 'ssflash', 'sslink', 'unlink', 'anchor', 'separator' ); From 406c4816a49b487346d55947f2cc30aa75a33e4c Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Mon, 30 Nov 2009 01:28:04 +0000 Subject: [PATCH 032/483] BUGFIX: Changed paths according to moved thirdparty dependencies. This bit change is merged from r92613. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93965 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/tinymce_ssbuttons/editor_plugin_src.js | 2 +- javascript/tinymce_ssmacron/editor_plugin_src.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js index c97187f8..df591457 100644 --- a/javascript/tinymce_ssbuttons/editor_plugin_src.js +++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js @@ -109,5 +109,5 @@ // Adds the plugin class to the list of available TinyMCE plugins - tinymce.PluginManager.add("../../tinymce_ssbuttons", tinymce.plugins.SSButtons); + tinymce.PluginManager.add("../../../../cms/javascript/tinymce_ssbuttons", tinymce.plugins.SSButtons); })(); \ No newline at end of file diff --git a/javascript/tinymce_ssmacron/editor_plugin_src.js b/javascript/tinymce_ssmacron/editor_plugin_src.js index 2faef38c..c6e80dc3 100644 --- a/javascript/tinymce_ssmacron/editor_plugin_src.js +++ b/javascript/tinymce_ssmacron/editor_plugin_src.js @@ -36,5 +36,5 @@ }); // Adds the plugin class to the list of available TinyMCE plugins - tinymce.PluginManager.add("../../tinymce_ssmacron", tinymce.plugins.InsertMacron); + tinymce.PluginManager.add("../../../../cms/javascript/tinymce_ssmacron", tinymce.plugins.InsertMacron); })(); From 429de60890eed0ea90fc746caff6bb2e09568857 Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Mon, 30 Nov 2009 02:19:21 +0000 Subject: [PATCH 033/483] BUGFIX: add proper language link broken git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@93984 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/tinymce_ssbuttons/editor_plugin_src.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js index df591457..7abc479b 100644 --- a/javascript/tinymce_ssbuttons/editor_plugin_src.js +++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js @@ -1,5 +1,5 @@ (function() { - tinymce.PluginManager.requireLangPack("../../tinymce_ssbuttons"); + tinymce.PluginManager.requireLangPack("../../../../cms/javascript/tinymce_ssbuttons"); var each = tinymce.each; tinymce.create('tinymce.plugins.SSButtons', { From a8fdcbd967c55259b32e49a9790550ad85d64c21 Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Mon, 30 Nov 2009 21:51:17 +0000 Subject: [PATCH 034/483] ENHANCEMENT Loading of tinymce_ssbuttons plugin via relative paths in HtmlEditorConfig rather than using the plugin name as a path spec (see r94060) API CHANGE Changed cms/javascript/tinymce_ssbuttons plugin name to "ssbuttons" (see r94060) API CHANGE Changed cms/javascript/tinymce_ssmacron plugin name to "ssmacron" (see r94060) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94062 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 3 ++- javascript/tinymce_ssbuttons/editor_plugin_src.js | 4 ++-- javascript/tinymce_ssmacron/editor_plugin_src.js | 5 ++++- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/_config.php b/_config.php index fc4e6a00..962298c6 100644 --- a/_config.php +++ b/_config.php @@ -42,7 +42,8 @@ HtmlEditorConfig::get('cms')->setOptions(array( )); -HtmlEditorConfig::get('cms')->enablePlugins('media', '../../../../cms/javascript/tinymce_ssbuttons', 'fullscreen'); +HtmlEditorConfig::get('cms')->enablePlugins('media', 'fullscreen'); +HtmlEditorConfig::get('cms')->enablePlugins(array('ssbuttons' => '../../../cms/javascript/tinymce_ssbuttons/editor_plugin_src.js')); HtmlEditorConfig::get('cms')->insertButtonsBefore('formatselect', 'styleselect'); HtmlEditorConfig::get('cms')->insertButtonsBefore('advcode', 'ssimage', 'ssflash', 'sslink', 'unlink', 'anchor', 'separator' ); diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js index 7abc479b..e67bed5f 100644 --- a/javascript/tinymce_ssbuttons/editor_plugin_src.js +++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js @@ -1,5 +1,5 @@ (function() { - tinymce.PluginManager.requireLangPack("../../../../cms/javascript/tinymce_ssbuttons"); + tinymce.PluginManager.requireLangPack("ssbuttons"); var each = tinymce.each; tinymce.create('tinymce.plugins.SSButtons', { @@ -109,5 +109,5 @@ // Adds the plugin class to the list of available TinyMCE plugins - tinymce.PluginManager.add("../../../../cms/javascript/tinymce_ssbuttons", tinymce.plugins.SSButtons); + tinymce.PluginManager.add("ssbuttons", tinymce.plugins.SSButtons); })(); \ No newline at end of file diff --git a/javascript/tinymce_ssmacron/editor_plugin_src.js b/javascript/tinymce_ssmacron/editor_plugin_src.js index c6e80dc3..9b2a8121 100644 --- a/javascript/tinymce_ssmacron/editor_plugin_src.js +++ b/javascript/tinymce_ssmacron/editor_plugin_src.js @@ -1,6 +1,9 @@ (function() { var each = tinymce.each; + /** + * Load via: HtmlEditorConfig::get('cms')->enablePlugins(array('ssmacron', '../../../../cms/javascript/tinymce_ssmacron')) + */ tinymce.create('tinymce.plugins.InsertMacron', { getInfo : function() { return { @@ -36,5 +39,5 @@ }); // Adds the plugin class to the list of available TinyMCE plugins - tinymce.PluginManager.add("../../../../cms/javascript/tinymce_ssmacron", tinymce.plugins.InsertMacron); + tinymce.PluginManager.add("ssmacron", tinymce.plugins.InsertMacron); })(); From 6ce7428bdc61459a419dc9285c660f4409bdff24 Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Tue, 1 Dec 2009 02:57:52 +0000 Subject: [PATCH 035/483] BUGFIX: if SecurityAdmin::add_hidden_permission() is called more than once, the later one is never added due two array operator "+" git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94100 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/SecurityAdmin.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index c8c0ca0a..743f8fd1 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -294,7 +294,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { */ static function add_hidden_permission($codes){ if(is_string($codes)) $codes = array($codes); - self::$hidden_permissions += $codes; + self::$hidden_permissions = array_merge(self::$hidden_permissions, $codes); } /** From dc76a9535711ea7505254d40b979a775872110da Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Tue, 1 Dec 2009 22:34:23 +0000 Subject: [PATCH 036/483] BUGFIX Fixed IE bug in ReportAdmin_left.js git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94170 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/ReportAdmin_left.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/ReportAdmin_left.js b/javascript/ReportAdmin_left.js index 2664ac0e..4ca13fbe 100755 --- a/javascript/ReportAdmin_left.js +++ b/javascript/ReportAdmin_left.js @@ -50,6 +50,6 @@ function reloadSiteTree() { appendLoader(function () { if($('sitetree')) { var selectedNode = $('sitetree').getElementsByTagName('li')[1]; - selectedNode.onselect(); + //selectedNode.onselect(); } }); \ No newline at end of file From d99445c01bc171b00f6359a577984dde68e737bb Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Wed, 2 Dec 2009 00:23:37 +0000 Subject: [PATCH 037/483] MINOR fixed widget area MINOR added select box listing anchors in text git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94198 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/WidgetAreaEditor.js | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js index 213acdf3..35c1d199 100644 --- a/javascript/WidgetAreaEditor.js +++ b/javascript/WidgetAreaEditor.js @@ -109,6 +109,17 @@ WidgetAreaEditorClass.prototype = { }, addWidget: function(className, holder) { + + if ($('WidgetAreaEditor-'+holder).getAttribute('maxwidgets')) { + var maxCount = $('WidgetAreaEditor-'+holder).getAttribute('maxwidgets'); + var count = $$('#usedWidgets-'+holder+' .Widget').length; + if (count > maxCount) { + alert('Sorry, you have reached the maximum number of widgets in this area'); + return; + } + } + + this.name = holder; new Ajax.Request('Widget_Controller/EditableSegment/' + className, { onSuccess : $('usedWidgets-'+holder).parentNode.parentNode.insertWidgetEditor.bind(this) @@ -164,7 +175,7 @@ WidgetAreaEditorClass.prototype = { WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); - Sortable.create('usedWidgets-SideBar', { + Sortable.create('usedWidgets-'+this.name, { tag: 'div', handle: 'handle', containment: ['availableWidgets-'+this.name, 'usedWidgets-'+this.name], From 233690b24dfc5695d7d31928aa2e14f65050bdd2 Mon Sep 17 00:00:00 2001 From: Normann Lou Date: Wed, 2 Dec 2009 05:20:13 +0000 Subject: [PATCH 038/483] BUGFIX: is tinyMCE is not loaded, we cannot call its function. This is specially important in a pop-up of ComplexTableField git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94238 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain.js | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 5a1d2d82..687b1f7a 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -881,14 +881,16 @@ function nullConverter(url) { Behaviour.register({ 'textarea.htmleditor' : { initialize : function() { - tinyMCE.execCommand("mceAddControl", true, this.id); - this.isChanged = function() { - return tinyMCE.getInstanceById(this.id).isDirty(); - } - this.resetChanged = function() { - inst = tinyMCE.getInstanceById(this.id); - if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1})); - } + if(typeof tinyMCE != 'undefined'){ + tinyMCE.execCommand("mceAddControl", true, this.id); + this.isChanged = function() { + return tinyMCE.getInstanceById(this.id).isDirty(); + } + this.resetChanged = function() { + inst = tinyMCE.getInstanceById(this.id); + if (inst) inst.startContent = tinymce.trim(inst.getContent({format : 'raw', no_events : 1})); + } + } } } }) From 2eea820daf95f179517919940b65323654c05530 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Thu, 3 Dec 2009 01:31:10 +0000 Subject: [PATCH 039/483] BUGFIX: Cleanup after aborted drag operation in Assets (#4735) (from r93071) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94319 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/AssetAdmin.js | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/javascript/AssetAdmin.js b/javascript/AssetAdmin.js index 0a28abbe..a3f08fbf 100755 --- a/javascript/AssetAdmin.js +++ b/javascript/AssetAdmin.js @@ -164,7 +164,7 @@ Object.extend(Class, { var SubsDraggable = Class.create(); SubsDraggable.prototype = Object.extend({}, Draggable.prototype); -Class.superrise(SubsDraggable.prototype, ['initialize', 'startDrag', 'finishDrag']) +Class.superrise(SubsDraggable.prototype, ['initialize', 'startDrag', 'finishDrag', 'endDrag']) Object.extend( SubsDraggable.prototype , { initialize: function(event) { this.super_initialize.apply(this, arguments); @@ -198,6 +198,15 @@ Object.extend( SubsDraggable.prototype , { } this.super_startDrag(event); }, + endDrag: function(event) { + this.super_endDrag(event); + // Remove any remaining orphaned NumFilesIndicator spans + // See ticket #4735 + var elts = $$('.NumFilesIndicator') + if (elts) { + elts.each(function(x){ Element.remove(x); }); + } + }, finishDrag: function(event, success) { this.super_finishDrag(event, success); @@ -348,7 +357,7 @@ FilesystemSyncClass.prototype = { /** * Delete folder action */ -deletefolder = { +var deletefolder = { button_onclick : function() { if(treeactions.toggleSelection(this)) { deletefolder.o1 = $('sitetree').observeMethod('SelectionChanged', deletefolder.treeSelectionChanged); @@ -490,7 +499,15 @@ appendLoader(function () { if($('deletepage')) { $('deletepage').onclick = deletefolder.button_onclick; $('deletepage').getElementsByTagName('button')[0].onclick = function() { return false; }; - $('Form_DeleteItemsForm').onsubmit = deletefolder.form_submit; + // Prevent bug #4740, particularly with IE + Behaviour.register({ + '#Form_DeleteItemsForm' : { + onsubmit: function(event) { + deletefolder.form_submit(); + Event.stop(event); + } + } + }); Element.hide('Form_DeleteItemsForm'); } From f17dd0c37e7adc980cbda878cc8a82fa4f43e4da Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Thu, 3 Dec 2009 03:53:40 +0000 Subject: [PATCH 040/483] BUGFIX: Fix default inclusion of (theme|project)/css/editor.css into the WYSWIWYG editor. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94350 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- _config.php | 2 -- code/LeftAndMain.php | 13 +++++++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/_config.php b/_config.php index 962298c6..91ed9372 100644 --- a/_config.php +++ b/_config.php @@ -23,7 +23,6 @@ HtmlEditorConfig::get('cms')->setOptions(array( 'priority' => '50', 'mode' => 'none', 'language' => i18n::get_tinymce_lang(), - 'content_css' => 'cms/css/editor.css, '.(SSViewer::current_theme() ? THEMES_DIR . "/" . SSViewer::current_theme() : project()) . "/css/editor.css", 'body_class' => 'typography', 'document_base_url' => Director::absoluteBaseURL(), @@ -41,7 +40,6 @@ HtmlEditorConfig::get('cms')->setOptions(array( 'extended_valid_elements' => "img[class|src|alt|title|hspace|vspace|width|height|align|onmouseover|onmouseout|name|usemap],iframe[src|name|width|height|align|frameborder|marginwidth|marginheight|scrolling],object[width|height|data|type],param[name|value],map[class|name|id],area[shape|coords|href|target|alt]" )); - HtmlEditorConfig::get('cms')->enablePlugins('media', 'fullscreen'); HtmlEditorConfig::get('cms')->enablePlugins(array('ssbuttons' => '../../../cms/javascript/tinymce_ssbuttons/editor_plugin_src.js')); diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 91f67406..f95d96e8 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -153,6 +153,19 @@ class LeftAndMain extends Controller { // Set the members html editor config HtmlEditorConfig::set_active(Member::currentUser()->getHtmlEditorConfigForCMS()); + + + // Set default values in the config if missing. These things can't be defined in the config + // file because insufficient information exists when that is being processed + $htmlEditorConfig = HtmlEditorConfig::get_active(); + if(!$htmlEditorConfig->getOption('content_css')) { + $cssFiles = 'cms/css/editor.css'; + if(SSViewer::current_theme()) $cssFiles .= ', ' . THEMES_DIR . "/" . SSViewer::current_theme() . '/css/editor.css'; + else if(project()) $cssFiles .= ', ' . project() . '/css/editor.css'; + + $htmlEditorConfig->setOption('content_css', $cssFiles); + } + Requirements::css(CMS_DIR . '/css/typography.css'); Requirements::css(CMS_DIR . '/css/layout.css'); From 419da4d67c399a5b1b956e1458c320eb06b1a1a5 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Mon, 7 Dec 2009 05:13:02 +0000 Subject: [PATCH 041/483] MINOR: Added a first cut of some cucumber tests for the CMS git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94529 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- tests/cuke/create-page.feature | 115 ++++++++++++++++++ tests/cuke/delete-page.feature | 40 ++++++ tests/cuke/login.feature | 36 ++++++ tests/cuke/logout.feature | 20 +++ tests/cuke/step_definitions/content.rb | 92 ++++++++++++++ tests/cuke/step_definitions/front-end.rb | 21 ++++ tests/cuke/step_definitions/general.rb | 25 ++++ tests/cuke/step_definitions/log-in.rb | 25 ++++ tests/cuke/step_definitions/security.rb | 23 ++++ tests/test_windmill/__init__.py | 1 - tests/test_windmill/test_admin/__init__.py | 24 ---- .../test_admin/test_CreateGroup.py | 26 ---- 12 files changed, 397 insertions(+), 51 deletions(-) create mode 100644 tests/cuke/create-page.feature create mode 100644 tests/cuke/delete-page.feature create mode 100644 tests/cuke/login.feature create mode 100644 tests/cuke/logout.feature create mode 100644 tests/cuke/step_definitions/content.rb create mode 100644 tests/cuke/step_definitions/front-end.rb create mode 100644 tests/cuke/step_definitions/general.rb create mode 100644 tests/cuke/step_definitions/log-in.rb create mode 100644 tests/cuke/step_definitions/security.rb delete mode 100644 tests/test_windmill/__init__.py delete mode 100644 tests/test_windmill/test_admin/__init__.py delete mode 100644 tests/test_windmill/test_admin/test_CreateGroup.py diff --git a/tests/cuke/create-page.feature b/tests/cuke/create-page.feature new file mode 100644 index 00000000..7bfe5179 --- /dev/null +++ b/tests/cuke/create-page.feature @@ -0,0 +1,115 @@ +Feature: Page creation in the CMS + As a content author + I want to create a basic text page at the root level and save it + So that our website can be kept up to date + + Scenario: An initial change to page name modifies key fields + Given I log into the CMS as admin + And I create a new page + When I put "Change Name" in the "Page name" field + And I click on the "Metadata" tab + Then the "URLSegment" field is "change-name" + And the "MetaTitle" field is "Change Name" + When I click on the "Main" tab + Then the "Navigation label" field is "Change Name" + + Scenario: Every subsequent change does not change the key fields + Given I save the page + And I cancel pop-ups + When I put "Change Again" in the "Page name" field + And I click on the "Metadata" tab + Then the "URLSegment" field is "change-name" + And the "MetaTitle" field is "Change Name" + When I click on the "Main" tab + Then the "Navigation label" field is "Change Name" + Then I delete the current page + + Scenario: I can populate all fields + And I create a new page + And I set "Page name" to "Populate name" + And I set "Navigation label" to "Populate label" + And I click on the "Metadata" tab + And I set "URLSegment" to "populate-url-segment" + And I set "MetaTitle" to "Populate MetaTitle" + And I set "Description" to "Populate Description" + And I set "Keywords" to "Populate Keywords" + And I set "Custom Meta Tags" to "Populate Custom Meta Tags" + And I click on the "Main" tab + And I save the page + When I load the "Populate label" page + Then the "Page name" field is "Populate name" + And the "Navigation label" field is "Populate label" + When I click on the "Metadata" tab + Then the "URLSegment" field is "populate-url-segment" + And the "MetaTitle" field is "Populate MetaTitle" + And the "Description" field is "Populate Description" + And the "Custom Meta Tags" field is "Populate Custom Meta Tags" + And I click on the "Main" tab + Then I delete the current page + + Scenario: I can create 2 identical pages + When I create a new page + And I create a new page + Then there are 2 root pages with navigation label "New Page" + Then I delete the current page + And I load the "New Page" root-level page + Then I delete the current page + + Scenario: Each change to page name changes the URL + When I create a new page + And I set "Page name" to "First Change" + And I click on the "Metadata" tab + Then the "URLSegment" field is "first-change" + + When I confirm pop-ups + And I click on the "Main" tab + And I set "Page name" to "Second Change" + And I click on the "Metadata" tab + Then the "URLSegment" field is "second-change" + + When I cancel pop-ups + And I click on the "Main" tab + And I set "Page name" to "Third Change" + And I click on the "Metadata" tab + Then the "URLSegment" field is "second-change" + And I click on the "Main" tab + + Then I delete the current page + + Scenario: Changes aren't saved if I cancel the warning + Given I create a new page + And I set "Page name" to "Change name" + When I confirm pop-ups to ignore the warning that their is unsaved content + And I load the "New Page" page + Then the "Page name" field is "New Page" + + Then I delete the current page + + Scenario: Page name and navigation label default to new page + Given I create a new page + Then the "Page name" field is "New Page" + And the "Navigation label" field is "New Page" + + When I click on the "Metadata" tab + Then the "URLSegment" field is "new-page" + And the "MetaTitle" field is blank + And the "Description" field is blank + And the "Keywords" field is blank + And the "Custom Meta Tags" field is blank + And I click on the "Main" tab + + Then I delete the current page + + Scenario: The navigation label is displayed in the site tree + Given I create a new page + And I set "Navigation label" to "New Label" + And I save the page + When I load the "New Label" page + Then the "Navigation label" field is "New Label" + + Scenario: If the navigation label is blanked out, it takes the value in the Page Name field + Given I set "Page name" to "Page Title" + When I set "Navigation label" to "" + And I save the page + And I load the "Page Title" page + Then the "Navigation label" field is "Page Title" \ No newline at end of file diff --git a/tests/cuke/delete-page.feature b/tests/cuke/delete-page.feature new file mode 100644 index 00000000..d80aa2a0 --- /dev/null +++ b/tests/cuke/delete-page.feature @@ -0,0 +1,40 @@ +Feature: Page deletion in the CMS + As a content author + I want to delete pages in the CMS + So that out of date content can be removed + + Scenario: User can delete a page without making any changes + Given I log into the CMS as admin + And I create a new page + And I save the page + When I delete the current page + Then there are 0 root pages with navigation label "New Page" + + Scenario: A deleted page can't be viewed + Given I create a new page + And I save the page + When I delete the current page + And I log out + Then url new-page does not exist + + Scenario: A deleted URL can be re-used + Given I log into the CMS as admin + And I create a new page + And I click on the "Metadata" tab + And the "URLSegment" field is "new-page" + And I save the page + And I delete the current page + When I create a new page + And I click on the "Metadata" tab + Then the "URLSegment" field is "new-page" + + Then delete the current page + + Scenario: A deleted page doesn't appear after re-login + Given I create a new page + And I save the page + And I delete the current page + When I log out + And I log into the CMS as admin + Then there are 0 root pages with navigation label "New Page" + \ No newline at end of file diff --git a/tests/cuke/login.feature b/tests/cuke/login.feature new file mode 100644 index 00000000..b9408434 --- /dev/null +++ b/tests/cuke/login.feature @@ -0,0 +1,36 @@ +Feature: Log in + As a CMS user + I want to security log into the CMS + So that I can make changes, knowing that other people can't. + + Background: + Given I visit Security/logout + + Scenario: opening admin asks user log-in + And I visit admin + Then I am sent to Security/login + + Scenario: valid login + When I fill out the log in form with user "admin" and password "password" + Then I see "Your are logged in as" + + Scenario: no password login + When I fill out the log in form with user "admin" and password "password" + Then I see "That doesn't seem to be the right e-mail address or password." + + Scenario: no user login + When I fill out the log in form with user "" and password "password" + Then I see "That doesn't seem to be the right e-mail address or password." + + Scenario: invalid login, getting right 2nd time + Given I visit admin + And I put "admin" in the "Email" field + And I put "wrongpassword" in the "Password" field + And I click the "Log in" button + Then I am sent to Security/login + And I see "That doesn't seem to be the right e-mail address or password." + Given I put "admin" in the "Email" field + And I put "password" in the "Password" field + And I click the "Log in" button + Then I am sent to admin + diff --git a/tests/cuke/logout.feature b/tests/cuke/logout.feature new file mode 100644 index 00000000..1a5b4368 --- /dev/null +++ b/tests/cuke/logout.feature @@ -0,0 +1,20 @@ +Feature: Log out + As a CMS user + I want to be able to log and be locked out of the CMS + So that I can know other people can't edit my site + + Scenario: Log out from CMS + Given I log into the CMS as admin + And I click the "log out" link + When I visit admin/ + Then I see "Enter your username and password to access the CMS." + When I visit admin/assets/ + Then I see "Enter your username and password to access the CMS." + When I visit admin/comments/ + Then I see "Enter your username and password to access the CMS." + When I visit admin/reports/ + Then I see "Enter your username and password to access the CMS." + When I visit admin/security/ + Then I see "Enter your username and password to access the CMS." + When I visit admin/subsites/ + Then I see "Enter your username and password to access the CMS." \ No newline at end of file diff --git a/tests/cuke/step_definitions/content.rb b/tests/cuke/step_definitions/content.rb new file mode 100644 index 00000000..7bcbad4f --- /dev/null +++ b/tests/cuke/step_definitions/content.rb @@ -0,0 +1,92 @@ +## FIXTURE GENERATON + +Given /^the site can be edited by the "([^\"]*)" group$/i do |arg1| + pending +end + +Given /^the "([^\"]*)" page can be edited by the "([^\"]*)" group$/i do |arg1, arg2| + pending +end + +Given /a "(.*)" page called "(.*)" as a child of "(.*)"/i do |type, title, parent| + Given "I click the \"#{parent}\" link" + And 'I click the "Create" button' + And "I select \"#{type}\" from \"PageType\"" + And 'I click the "Go" button' + And 'I click the "Create" button' + And "I put \"#{title}\" in the \"Title\" field" + And "I click \"Save\"" +end + +Given /^a top\-level "(.*)" page called "(.*)"$/i do |type,title| + Given "I click the \"Site Content\" link" + And "I create a page " + And "I put \"#{title}\" in the \"Title\" field" + And "I click \"Save\"" +end + +## ACTIONS + +Given /load the "(.*)" page/i do |title| + Given "I click the \"#{title}\" link" +end + +Given /I load the "(.*)" root-level page/ do |nav| + @browser.link(:xpath, "//ul[@id='sitetree']/li/ul/li//a[.='#{nav}']").click +end + +Given /I load the root node/ do + Given 'I click the "admin/0" link' +end + +Given /create a new page$/i do + Given "I create a new page using template \"Page\"" +end + +Given /create a new page using template \"(.*)\"/i do |type| + Given 'I load the root node (ajax)' + And 'I click the "Create" button' + And "I select \"#{type}\" from \"PageType\"" + And 'I click the "Go" button (ajax)' + And 'I click the "Create" button' +end + +Given /save the page$/i do + Given 'I click the "Form_EditForm_action_save" button (ajax)' +end + +Given /delete the current page$/i do + Given 'I click the "Delete from the draft site" button' +end + + +## ASSERTIONS + +Given /There are ([0-9]+) root pages with navigation label "(.*)"/i do |count, nav| + @browser.elements_by_xpath("//ul[@id='sitetree']/li/ul/li//a[.='#{nav}']").count.should == count.to_i +end + +Given /The "(.*)" page does not exist/i do | page| + @browser.link(:title, title).should empty? + #|''get url''|@{root_url}PAGE| + #|''title''|'''is not'''|PAGE| +end + + +## Current Page + +Given /^The (.*) of the current page is "([^\"]*)"$/i do |arg1| + pending +end + +Then /^The current page is editable$/i do + pending +end + +Then /^The current page is read-only$/i do + pending +end + +Then /^The current page is at the top\-level$/i do + pending +end diff --git a/tests/cuke/step_definitions/front-end.rb b/tests/cuke/step_definitions/front-end.rb new file mode 100644 index 00000000..93633dff --- /dev/null +++ b/tests/cuke/step_definitions/front-end.rb @@ -0,0 +1,21 @@ +## +## Step definitions for testing the front-end site +## + + +Given /I go to the draft site/ do + pending + Given 'I click the "viewStageSite" link' +# |''element''|//a[@id="viewStageSite"]|''exists''| +# |''checking timeout''|@{fast_checking_timeout}| +# |''optionally''|''element''|//a[@id="viewStageSite"][@style=""]|''exists''| +# |''checking timeout''|@{checking_timeout}| +# |''click''|viewStageSite| +end + +Given /I close window and go back to clean state/ do +# |''close''| +# |''select initial window''| +# |default frame| +# |''go to root node''| +end diff --git a/tests/cuke/step_definitions/general.rb b/tests/cuke/step_definitions/general.rb new file mode 100644 index 00000000..487769fc --- /dev/null +++ b/tests/cuke/step_definitions/general.rb @@ -0,0 +1,25 @@ +## +## General rules for the SilverStripe CMS as a whole. They mostly have to do with the LeftAndMain +## interface + +Given /I click on the "([^\"]*)" tab/ do |tab| + Given "I click the \"tab-Root_Content_set_#{tab}\" link" +end + +Given /I wait for a status message/ do + Watir::Waiter::wait_until { + @browser.p(:id, 'statusMessage').exists? && @browser.p(:id, 'statusMessage').visible? + } +end + +Given /I wait for a success message/ do + # We have to wait until after messages of the form 'Saving...', to get either a good message or + # a bad message + Watir::Waiter::wait_until { + @browser.p(:id, 'statusMessage').exists? && @browser.p(:id, 'statusMessage').visible? && @browser.p(:id, 'statusMessage').class_name != "" + } + + @browser.p(:id, 'statusMessage').class_name.should == 'good' +end + + diff --git a/tests/cuke/step_definitions/log-in.rb b/tests/cuke/step_definitions/log-in.rb new file mode 100644 index 00000000..c94f45e4 --- /dev/null +++ b/tests/cuke/step_definitions/log-in.rb @@ -0,0 +1,25 @@ + +# Log in +Given /log in as (.*)$/ do |user| + Given "I fill out the log in form with user \"#{user}\" and password \"password\"" + And 'I see "Your are logged in as"' +end + +Given /log into the CMS as (.*)/ do |user| + Given "I log in as #{user}" + And "I visit admin/" + And "I load the root node" +end + +Given /log out$/ do + Given "I visit Security/logout" +end + +Given /fill out the log in form with user "(.*)" and password "(.*)"/ do |user, password| + Given 'I visit Security/logout' + And 'I visit Security/login?BackURL=Security/login' + And "I put \"#{user}\" in the \"Email\" field" + And "I put \"#{password}\" in the \"Password\" field" + And "I click the \"Log in\" button" +end + \ No newline at end of file diff --git a/tests/cuke/step_definitions/security.rb b/tests/cuke/step_definitions/security.rb new file mode 100644 index 00000000..3278a033 --- /dev/null +++ b/tests/cuke/step_definitions/security.rb @@ -0,0 +1,23 @@ +# Steps definitions for security + +# Fixture instantiation +Given /a "(.*)" group/ do |group| + Given 'I visit admin/security' + And 'I click the "Security Groups" link' + And 'I click the "Create" button' + And "I put \"#{group}\" in the \"Title\" field" + And 'I click the "Save" button' +end + +Given /a user called "(.*)" in the "(.*)" group/ do |user, group| + Given 'I visit admin/security' + And "I click the \"#{group} (global group)\" link" + And "I put \"#{user}\" in the \"FirstName\" field" + And "I put \"#{user}\" in the \"Email\" field" + And "I put \"password\" in the \"SetPassword\" field" + And "I click the \"Add\" button" +end + +Given /^I get a permission denied error$/ do + pending +end diff --git a/tests/test_windmill/__init__.py b/tests/test_windmill/__init__.py deleted file mode 100644 index 6883e0ca..00000000 --- a/tests/test_windmill/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from windmill.authoring import setup_module, teardown_module, enable_collector diff --git a/tests/test_windmill/test_admin/__init__.py b/tests/test_windmill/test_admin/__init__.py deleted file mode 100644 index 20305d35..00000000 --- a/tests/test_windmill/test_admin/__init__.py +++ /dev/null @@ -1,24 +0,0 @@ -from windmill.authoring import setup_module, teardown_module, enable_collector, WindmillTestClient -import windmill - -def setup_module(module): - client = WindmillTestClient(__name__) - - client.type(text=u'cms/tests/CMSMainTest.yml', id=u'fixture-file') - client.click(id=u'start-session') - - client.waits.forPageLoad(timeout=u'20000') - client.click(id=u'admin-link') - client.waits.forPageLoad(timeout=u'20000') - - client.type(text=u'admin@example.com', id=u'MemberLoginForm_LoginForm_Email') - client.type(text=u'ZXXlkwecxz2390232233', id=u'MemberLoginForm_LoginForm_Password') - client.click(id=u'MemberLoginForm_LoginForm_action_dologin') - client.waits.forPageLoad(timeout=u'300000') - -def teardown_module(module): - client = WindmillTestClient(__name__) - - client.open(url=windmill.settings['TEST_URL'], id=u'fixture-file') - client.click(id=u'end-session') - \ No newline at end of file diff --git a/tests/test_windmill/test_admin/test_CreateGroup.py b/tests/test_windmill/test_admin/test_CreateGroup.py deleted file mode 100644 index d53c18ec..00000000 --- a/tests/test_windmill/test_admin/test_CreateGroup.py +++ /dev/null @@ -1,26 +0,0 @@ -# Generated by the windmill services transformer -from windmill.authoring import WindmillTestClient - -def test(): - client = WindmillTestClient(__name__) - - client.click(link=u'Security') - client.waits.forPageLoad(timeout=u'20000') - client.click(xpath=u"/html/body/div[@id='left']/div[@id='treepanes']/ul[@id='TreeActions']/li[@id='addgroup']/button") - client.waits.sleep(milliseconds=u'5000') - - client.asserts.assertText(validator=u'New Group', id=u'record-2') - client.asserts.assertValue(validator=u'New Group', id=u'Form_EditForm_Title') - - client.click(id=u'Form_EditForm_Title') - client.type(text=u'Test Group', id=u'Form_EditForm_Title') - client.click(id=u'Form_EditForm_action_save') - client.waits.sleep(milliseconds=u'5000') - - client.asserts.assertText(validator=u'Test Group', id=u'record-2') - - client.click(id=u'Form_AddRecordForm_FirstName') - client.type(text=u'Test', id=u'Form_AddRecordForm_FirstName') - client.type(text=u'Person', id=u'Form_AddRecordForm_Surname') - client.type(text=u'test@example.com', id=u'Form_AddRecordForm_Email') - client.click(id=u'Form_AddRecordForm_action_addtogroup') \ No newline at end of file From 56a4bf0129b1164015bcc7b6033e8482e84eb2fd Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Mon, 7 Dec 2009 05:33:37 +0000 Subject: [PATCH 042/483] MINOR: Fixed a few glitches in the cuke tests git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94531 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- tests/cuke/create-page.feature | 4 +++- tests/cuke/logout.feature | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/cuke/create-page.feature b/tests/cuke/create-page.feature index 7bfe5179..e12675b9 100644 --- a/tests/cuke/create-page.feature +++ b/tests/cuke/create-page.feature @@ -112,4 +112,6 @@ Feature: Page creation in the CMS When I set "Navigation label" to "" And I save the page And I load the "Page Title" page - Then the "Navigation label" field is "Page Title" \ No newline at end of file + Then the "Navigation label" field is "Page Title" + Then I delete the current page + \ No newline at end of file diff --git a/tests/cuke/logout.feature b/tests/cuke/logout.feature index 1a5b4368..97761fef 100644 --- a/tests/cuke/logout.feature +++ b/tests/cuke/logout.feature @@ -5,7 +5,7 @@ Feature: Log out Scenario: Log out from CMS Given I log into the CMS as admin - And I click the "log out" link + And I click the "Log out" link When I visit admin/ Then I see "Enter your username and password to access the CMS." When I visit admin/assets/ From 0e65de67f8fccd954b94e3d2eda3288bdf583379 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 8 Dec 2009 01:29:19 +0000 Subject: [PATCH 043/483] BUGFIX: check akismet is enabled before saving spam. PATCH via simon_w - #4812 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94568 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/sitefeatures/PageComment.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/sitefeatures/PageComment.php b/code/sitefeatures/PageComment.php index 907ea432..8f82c087 100755 --- a/code/sitefeatures/PageComment.php +++ b/code/sitefeatures/PageComment.php @@ -239,7 +239,7 @@ class PageComment_Controller extends Controller { } } if(Director::is_ajax()) { - if(SSAkismet::getSaveSpam()) { + if(SSAkismet::isEnabled() && SSAkismet::getSaveSpam()) { echo $comment->renderWith('PageCommentInterface_singlecomment'); } else { echo ''; From 7d48f2c1c857b23ce08343ac92454480e04ea974 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 8 Dec 2009 01:50:35 +0000 Subject: [PATCH 044/483] BUGFIX: fixed spam not being turned into ham if spamprotection isnt enabled. PATCH via simon_w #4813 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94571 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/sitefeatures/PageComment.php | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/code/sitefeatures/PageComment.php b/code/sitefeatures/PageComment.php index 8f82c087..c80aa4c4 100755 --- a/code/sitefeatures/PageComment.php +++ b/code/sitefeatures/PageComment.php @@ -259,8 +259,6 @@ class PageComment_Controller extends Controller { // if spam protection module exists if(class_exists('SpamProtectorManager')) { SpamProtectorManager::send_feedback($comment, 'ham'); - $comment->setField('IsSpam', false); - $comment->write(); } if(SSAkismet::isEnabled()) { @@ -272,9 +270,9 @@ class PageComment_Controller extends Controller { } catch (Exception $e) { // Akismet didn't work, most likely the service is down. } - $comment->setField('IsSpam', false); - $comment->write(); } + $comment->setField('IsSpam', false); + $comment->write(); } } if(Director::is_ajax()) { From 6c160db32240106ddfa79a2359369ecadf8a2307 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Thu, 10 Dec 2009 00:29:32 +0000 Subject: [PATCH 045/483] MINOR fixed bug where widget area editor would not be activated git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94829 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/WidgetAreaEditor.js | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js index 35c1d199..43f23eee 100644 --- a/javascript/WidgetAreaEditor.js +++ b/javascript/WidgetAreaEditor.js @@ -5,8 +5,7 @@ WidgetAreaEditorClass.prototype = { this.name = this.getAttribute('name'); this.rewriteWidgetAreaAttributes(); UsedWidget.applyToChildren($('usedWidgets-'+this.name), 'div.Widget'); - - // Make available widgets draggable + var availableWidgets = $('availableWidgets-'+this.name).childNodes; for(var i = 0; i < availableWidgets.length; i++) { @@ -113,8 +112,8 @@ WidgetAreaEditorClass.prototype = { if ($('WidgetAreaEditor-'+holder).getAttribute('maxwidgets')) { var maxCount = $('WidgetAreaEditor-'+holder).getAttribute('maxwidgets'); var count = $$('#usedWidgets-'+holder+' .Widget').length; - if (count > maxCount) { - alert('Sorry, you have reached the maximum number of widgets in this area'); + if (count+1 > maxCount) { + alert(ss.i18n._t('WidgetAreaEditor.TOOMANY')); return; } } @@ -254,11 +253,4 @@ WidgetTreeDropdownField.prototype = { } WidgetTreeDropdownField.applyTo('div.usedWidgets .TreeDropdownField'); - -// Loop over all WidgetAreas and fire 'em up -var wAs = $$('.WidgetAreaEditor'); -for(var i = 0; i < wAs.length; i++) { - WidgetAreaEditorClass.applyTo('div#'+wAs[i].id); - -} - +WidgetAreaEditorClass.applyTo('.WidgetAreaEditor'); \ No newline at end of file From 34c1943a26339054d110ed8ca8ec5966c23776bf Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Fri, 11 Dec 2009 02:51:42 +0000 Subject: [PATCH 046/483] MINOR adding maori macron button back git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@94986 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/tinymce_ssmacron/macron.htm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/tinymce_ssmacron/macron.htm b/javascript/tinymce_ssmacron/macron.htm index 7c270fd3..44346f3b 100644 --- a/javascript/tinymce_ssmacron/macron.htm +++ b/javascript/tinymce_ssmacron/macron.htm @@ -2,7 +2,7 @@ Insert a Macron - + From ee49d36dd7393edad155a51cd0472dc1c44bd6e2 Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Sun, 13 Dec 2009 22:55:10 +0000 Subject: [PATCH 047/483] MINOR remove relic of concurrent editing git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95070 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 1 - 1 file changed, 1 deletion(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index f95d96e8..df890236 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -977,7 +977,6 @@ JS; DataObject::delete_by_id($this->stat('tree_class'), $id); $script .= "node = st.getTreeNodeByIdx($id); if(node) node.parentTreeNode.removeTreeNode(node); $('Form_EditForm').closeIfSetTo($id); \n"; - if ($id == $this->currentPageID()) FormResponse::add('CurrentPage.isDeleted = 1;'); } } FormResponse::add($script); From 2d3365f7b27f6a3e4bd26353a35304f8d7342e9d Mon Sep 17 00:00:00 2001 From: Tom Rix Date: Mon, 14 Dec 2009 01:26:49 +0000 Subject: [PATCH 048/483] MINOR make widgetarea/editor more suitable for generic use git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95086 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/WidgetAreaEditor.php | 27 ++++++++++++++++++++++----- javascript/lang/en_US.js | 3 ++- templates/WidgetAreaEditor.ss | 8 ++++---- 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/code/WidgetAreaEditor.php b/code/WidgetAreaEditor.php index c862df48..035d6e07 100644 --- a/code/WidgetAreaEditor.php +++ b/code/WidgetAreaEditor.php @@ -5,7 +5,21 @@ * @subpackage content */ class WidgetAreaEditor extends FormField { - function __construct($name) { + /** + * 3 variables to hold titles for the template + */ + public $InUseTitle; + public $AvailableTitle; + public $ToAddTitle; + + function __construct($name, $widgetClasses = array('Widget'), $maxWidgets = 0) { + $this->InUseTitle = _t('WidgetAreaEditor.ss', 'INUSE'); + $this->AvailableTitle = _t('WidgetAreaEditor.ss', 'AVAILABLE'); + $this->ToAddTitle = _t('WidgetAreaEditor.ss', 'TOADD'); + $this->MaxWidgets = $maxWidgets; + + $this->widgetClasses = $widgetClasses; + parent::__construct($name); } @@ -17,12 +31,15 @@ class WidgetAreaEditor extends FormField { } function AvailableWidgets() { - $classes = ClassInfo::subclassesFor('Widget'); - array_shift($classes); + $widgets= new DataObjectSet(); - foreach($classes as $class) { - $widgets->push(singleton($class)); + foreach($this->widgetClasses as $widgetClass) { + $classes = ClassInfo::subclassesFor($widgetClass); + array_shift($classes); + foreach($classes as $class) { + $widgets->push(singleton($class)); + } } return $widgets; diff --git a/javascript/lang/en_US.js b/javascript/lang/en_US.js index 8464316e..9b0e6118 100644 --- a/javascript/lang/en_US.js +++ b/javascript/lang/en_US.js @@ -24,6 +24,7 @@ if(typeof(ss) == 'undefined' || typeof(ss.i18n) == 'undefined') { 'ModelAdmin.DELETED': "Deleted", 'ModelAdmin.VALIDATIONERROR': "Validation Error", 'LeftAndMain.PAGEWASDELETED': "This page was deleted. To edit a page, select it from the left.", - 'LeftAndMain.CONFIRMUNSAVED': "Are you sure you want to navigate away from this page?\n\nWARNING: Your changes have not been saved.\n\nPress OK to continue, or Cancel to stay on the current page." + 'LeftAndMain.CONFIRMUNSAVED': "Are you sure you want to navigate away from this page?\n\nWARNING: Your changes have not been saved.\n\nPress OK to continue, or Cancel to stay on the current page.", + 'WidgetAreaEditor.TOOMANY': 'Sorry, you have reached the maximum number of widgets in this area' }); } \ No newline at end of file diff --git a/templates/WidgetAreaEditor.ss b/templates/WidgetAreaEditor.ss index 6b1989f6..450386d3 100644 --- a/templates/WidgetAreaEditor.ss +++ b/templates/WidgetAreaEditor.ss @@ -1,7 +1,7 @@ -
    +
    maxwidgets="$MaxWidgets"<% end_if %>>
    -

    <% _t('AVAILABLE', 'Available Widgets') %>

    +

    $AvailableTitle

     

    <% if AvailableWidgets %> @@ -16,8 +16,8 @@
    -

    <% _t('INUSE', 'Widgets currently used') %>

    -

    <% _t('TOADD', 'To add widgets, click on the purple header on the left') %>

    +

    $InUseTitle

    +

    $ToAddTitle

    <% if UsedWidgets %> From 77dfeb267f98509133d7ac89b2326537f36673b3 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Mon, 14 Dec 2009 01:27:40 +0000 Subject: [PATCH 049/483] BUGFIX #4848 Fixed ComplexTableField undefined error in IE8 when it is not available git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95088 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/MemberTableField.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/javascript/MemberTableField.js b/javascript/MemberTableField.js index 33f7fa98..c857c7d0 100755 --- a/javascript/MemberTableField.js +++ b/javascript/MemberTableField.js @@ -6,7 +6,9 @@ */ // no confirm message for removal from a group -ComplexTableField.prototype.deleteConfirmMessage = null; +if(ComplexTableField && ComplexTableField != undefined) { + ComplexTableField.prototype.deleteConfirmMessage = null; +} /** * Auto-lookup on ajax fields From 99166edd248f96e627148a688b7cddd4fd27e98e Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Mon, 14 Dec 2009 01:37:35 +0000 Subject: [PATCH 050/483] BUGFIX #4847 Fixed ComplexTableField undefined in IE8 when opening a CTF popup in the Security section of the CMS git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95091 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/MemberTableField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/MemberTableField.js b/javascript/MemberTableField.js index c857c7d0..f376a882 100755 --- a/javascript/MemberTableField.js +++ b/javascript/MemberTableField.js @@ -6,7 +6,7 @@ */ // no confirm message for removal from a group -if(ComplexTableField && ComplexTableField != undefined) { +if(typeof(ComplexTableField) != 'undefined') { ComplexTableField.prototype.deleteConfirmMessage = null; } From a578804987011071221ef41f44cc0429683c6529 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Mon, 14 Dec 2009 22:40:03 +0000 Subject: [PATCH 051/483] ENHANCEMENT: added translatable support to mathspamprotection. PATCH via noini (#4755) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95194 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/sitefeatures/MathSpamProtection.php | 40 ++++++++++++++++++------ 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/code/sitefeatures/MathSpamProtection.php b/code/sitefeatures/MathSpamProtection.php index 29567d52..4b770610 100644 --- a/code/sitefeatures/MathSpamProtection.php +++ b/code/sitefeatures/MathSpamProtection.php @@ -25,7 +25,12 @@ class MathSpamProtection { $v1 = Session::get("mathQuestionV1"); $v2 = Session::get("mathQuestionV2"); } - return "What is ".MathSpamProtection::digitToWord($v1)." plus ".MathSpamProtection::digitToWord($v2)."?"; + + return sprintf( + _t('MathSpamProtection.WHATIS',"What is %s plus %s?"), + MathSpamProtection::digitToWord($v1), + MathSpamProtection::digitToWord($v2) + ); } /** @@ -49,13 +54,29 @@ class MathSpamProtection { * Helper method for converting digits to their equivelant english words */ static function digitToWord($num){ - $numbers = array("zero","one","two","three","four","five","six","seven","eight","nine", - "ten","eleven","twelve","thirteen","fourteen","fifteen","sixteen","seventeen","eighteen"); - if($num < 0){ - return "minus ".($numbers[-1*$num]); - } - //TODO: add checking or return null for bad value?? - return $numbers[$num]; + $numbers = array(_t('MathSpamProtection.ZERO', 'zero'), + _t('MathSpamProtection.ONE', 'one'), + _t('MathSpamProtection.TWO', 'two'), + _t('MathSpamProtection.THREE', 'three'), + _t('MathSpamProtection.FOUR', 'four'), + _t('MathSpamProtection.FIVE', 'five'), + _t('MathSpamProtection.SIX', 'six'), + _t('MathSpamProtection.SEVEN', 'seven'), + _t('MathSpamProtection.EIGHT', 'eight'), + _t('MathSpamProtection.NINE', 'nine'), + _t('MathSpamProtection.TEN', 'ten'), + _t('MathSpamProtection.ELEVEN', 'eleven'), + _t('MathSpamProtection.TWELVE', 'twelve'), + _t('MathSpamProtection.THIRTEEN', 'thirteen'), + _t('MathSpamProtection.FOURTEEN', 'fourteen'), + _t('MathSpamProtection.FIFTEEN', 'fifteen'), + _t('MathSpamProtection.SIXTEEN', 'sixteen'), + _t('MathSpamProtection.SEVENTEEN', 'seventeen'), + _t('MathSpamProtection.EIGHTEEN', 'eighteen')); + + if($num < 0) return "minus ".($numbers[-1*$num]); + + return $numbers[$num]; } @@ -67,5 +88,4 @@ class MathSpamProtection { self::$mathProtection = $math; } -} -?> \ No newline at end of file +} \ No newline at end of file From 19670e7b27b266901a776142d1d9f2e0cada6f09 Mon Sep 17 00:00:00 2001 From: Will Rossiter Date: Tue, 15 Dec 2009 03:33:38 +0000 Subject: [PATCH 052/483] FEATURE: added delete all link to page comments. Patch via #4427. Thanks walec51 git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95418 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/sitefeatures/PageComment.php | 21 +++++++++ code/sitefeatures/PageCommentInterface.php | 12 +++++- templates/PageCommentInterface.ss | 3 ++ tests/PageCommentsTest.php | 31 ++++++++++++++ tests/PageCommentsTest.yml | 50 ++++++++++++++++++++++ 5 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 tests/PageCommentsTest.php create mode 100644 tests/PageCommentsTest.yml diff --git a/code/sitefeatures/PageComment.php b/code/sitefeatures/PageComment.php index c80aa4c4..e0981c3e 100755 --- a/code/sitefeatures/PageComment.php +++ b/code/sitefeatures/PageComment.php @@ -176,6 +176,27 @@ class PageComment_Controller extends Controller { $rss->outputToBrowser(); } + /** + * Deletes all comments on the page referenced by the url param pageid + */ + function deleteallcomments() { + if(Permission::check('CMS_ACCESS_CMSMain')) { + $pageId = $_REQUEST['pageid']; + if(preg_match('/^\d+$/', $pageId)) { + $comments = DataObject::get("PageComment", "ParentID = $pageId"); + if($comments) foreach($comments as $c) { + $c->delete(); + } + } + } + + if(Director::is_ajax()) { + echo ""; + } else { + Director::redirectBack(); + } + } + function deletecomment() { if(Permission::check('CMS_ACCESS_CMSMain')) { $comment = DataObject::get_by_id("PageComment", $this->urlParams['ID']); diff --git a/code/sitefeatures/PageCommentInterface.php b/code/sitefeatures/PageCommentInterface.php index 127191b2..ae1b7716 100755 --- a/code/sitefeatures/PageCommentInterface.php +++ b/code/sitefeatures/PageCommentInterface.php @@ -228,6 +228,16 @@ class PageCommentInterface extends RequestHandler { return Director::absoluteBaseURL() . "PageComment/rss?pageid=" . $this->page->ID; } + /** + * A link to PageComment_Controller.deleteallcomments() which deletes all + * comments on a page referenced by the url param pageid + */ + function DeleteAllLink() { + if(Permission::check('CMS_ACCESS_CMSMain')) { + return Director::absoluteBaseURL() . "PageComment/deleteallcomments?pageid=" . $this->page->ID; + } + } + } /** @@ -337,4 +347,4 @@ class PageCommentInterface_Controller extends ContentController { } } -?> \ No newline at end of file +?> diff --git a/templates/PageCommentInterface.ss b/templates/PageCommentInterface.ss index 90a91e70..b0f9509a 100755 --- a/templates/PageCommentInterface.ss +++ b/templates/PageCommentInterface.ss @@ -53,6 +53,9 @@

    <% _t('NOCOMMENTSYET','No one has commented on this page yet.') %>

    <% end_if %>
    + <% if DeleteAllLink %> +

    Delete all comments on this page

    + <% end_if %>

    <% _t('RSSFEEDCOMMENTS', 'RSS feed for comments on this page') %> | <% _t('RSSFEEDALLCOMMENTS', 'RSS feed for all comments') %> diff --git a/tests/PageCommentsTest.php b/tests/PageCommentsTest.php new file mode 100644 index 00000000..b4c08976 --- /dev/null +++ b/tests/PageCommentsTest.php @@ -0,0 +1,31 @@ +objFromFixture('Page', 'second'); + $this->autoFollowRedirection = false; + $this->logInAs('admin'); + Director::test('second-page', null, $this->session()); + Director::test('PageComment/deleteallcomments?pageid='.$second->ID, + null, $this->session()); + Director::test('second-page', null, $this->session()); + + $secondComments = DataObject::get('PageComment', 'ParentID = '.$second->ID); + $this->assertNull($secondComments); + + $first = $this->objFromFixture('Page', 'first'); + $firstComments = DataObject::get('PageComment', 'ParentID = '.$first->ID); + $this->assertNotNull($firstComments); + + $third = $this->objFromFixture('Page', 'third'); + $thirdComments = DataObject::get('PageComment', 'ParentID = '.$third->ID); + $this->assertEquals($thirdComments->Count(), 3); + } +} +?> diff --git a/tests/PageCommentsTest.yml b/tests/PageCommentsTest.yml new file mode 100644 index 00000000..b70d5c0f --- /dev/null +++ b/tests/PageCommentsTest.yml @@ -0,0 +1,50 @@ +Member: + admin: + FirstName: admin + +Group: + admin: + Title: Admin + Members: =>Member.admin + +Permission: + admin: + Code: ADMIN + Group: =>Group.admin + +Page: + first: + Title: First page + URLSegment: first-page + second: + Title: Second page + URLSegment: second-page + third: + Title: Third page + URLSegment:third-page + +PageComment: + firstComA: + ParentID: =>Page.first + Name: FA + Comment: textFA + secondComA: + ParentID: =>Page.second + Name: SA + Comment: textSA + secondComB: + ParentID: =>Page.second + Name: SB + Comment: textSB + thirdComA: + ParentID: =>Page.third + Name: TA + Comment: textTA + thirdComB: + ParentID: =>Page.third + Name: TB + Comment: textTB + thirdComC: + ParentID: =>Page.third + Name: TC + Comment: textTC From c4e11804db001201341dd041e563b5131e8b9dac Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Wed, 16 Dec 2009 01:24:47 +0000 Subject: [PATCH 053/483] BUGFIX: Prevent text-selection during drag operation, Firefox-specific git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95511 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 687b1f7a..7c2482cc 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -26,6 +26,10 @@ DraggableSeparator.prototype = { document.onmousemove = this.document_mousemove.bindAsEventListener(this); document.onmouseup = this.document_mouseup.bindAsEventListener(this); + // MozUserSelect='none' prevents text-selection during drag, in firefox. + Element.setStyle($('right'), {MozUserSelect: 'none'}); + Element.setStyle($('left'), {MozUserSelect: 'none'}); + // onselectstart captured to prevent text-selection in IE document.body.onselectstart = this.body_selectstart.bindAsEventListener(this); }, document_mousemove : function(event) { @@ -33,6 +37,9 @@ DraggableSeparator.prototype = { fixRightWidth(); }, document_mouseup : function(e) { + // MozUserSelect='' re-enables text-selection in firefox. + Element.setStyle($('right'), {MozUserSelect: ''}); + Element.setStyle($('left'), {MozUserSelect: ''}); document.onmousemove = null; }, From 177b3998b3eedc7cdbb5d98bf3b224cc703d63f2 Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Wed, 16 Dec 2009 04:17:52 +0000 Subject: [PATCH 054/483] BUGFIX: Show selected row in autocomplete dropdown git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95558 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- css/cms_right.css | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/css/cms_right.css b/css/cms_right.css index 76dbef64..ea2f5f84 100644 --- a/css/cms_right.css +++ b/css/cms_right.css @@ -318,6 +318,10 @@ padding: 3px; white-space: nowrap; } + .autocomplete li.selected { + background: Highlight; + color: HighlightText; + } .autocomplete .data { display: none; } From b89cb9b01863d4c263d1d83a98de2b361afd5dc1 Mon Sep 17 00:00:00 2001 From: Mateusz Uzdowski Date: Thu, 17 Dec 2009 21:53:03 +0000 Subject: [PATCH 055/483] BUGFIX: fixing CMS_ACCESS_LeftAndMain permission (=access all cms sections). Also added the test. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95788 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 3 ++- tests/CMSMainTest.yml | 10 +++++++++- tests/LeftAndMainTest.php | 11 +++++++++++ 3 files changed, 22 insertions(+), 2 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index df890236..c9efbb68 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -83,7 +83,8 @@ class LeftAndMain extends Controller { } // Default security check for LeftAndMain sub-class permissions - if(!Permission::checkMember($member, "CMS_ACCESS_$this->class")) { + if(!Permission::checkMember($member, "CMS_ACCESS_$this->class") && + !Permission::checkMember($member, "CMS_ACCESS_LeftAndMain")) { return false; } diff --git a/tests/CMSMainTest.yml b/tests/CMSMainTest.yml index 94384142..0b7fc3f5 100644 --- a/tests/CMSMainTest.yml +++ b/tests/CMSMainTest.yml @@ -17,6 +17,8 @@ Group: Title: Empty Group assetsonly: Title: assetsonly + allcmssections: + Title: allcmssections Member: admin: Email: admin@example.com @@ -25,10 +27,16 @@ Member: assetsonlyuser: Email: assetsonlyuser@test.com Groups: =>Group.assetsonly + allcmssectionsuser: + Email: allcmssectionsuser@test.com + Groups: =>Group.allcmssections Permission: admin: Code: ADMIN GroupID: =>Group.admin assetsonly: Code: CMS_ACCESS_AssetAdmin - GroupID: =>Group.assetsonly \ No newline at end of file + GroupID: =>Group.assetsonly + allcmssections: + Code: CMS_ACCESS_LeftAndMain + GroupID: =>Group.allcmssections \ No newline at end of file diff --git a/tests/LeftAndMainTest.php b/tests/LeftAndMainTest.php index 8f9cad55..6835f7c1 100644 --- a/tests/LeftAndMainTest.php +++ b/tests/LeftAndMainTest.php @@ -45,6 +45,7 @@ class LeftAndMainTest extends FunctionalTest { function testCanView() { $adminuser = $this->objFromFixture('Member', 'admin'); $assetsonlyuser = $this->objFromFixture('Member', 'assetsonlyuser'); + $allcmssectionsuser = $this->objFromFixture('Member', 'allcmssectionsuser'); // anonymous user $this->session()->inst_set('loggedInAs', null); @@ -64,6 +65,16 @@ class LeftAndMainTest extends FunctionalTest { 'Groups with limited access can only access the interfaces they have permissions for' ); + // all cms sections user + $this->session()->inst_set('loggedInAs', $allcmssectionsuser->ID); + $menuItems = singleton('LeftAndMain')->MainMenu(); + $requiredSections = array('CMSMain','AssetAdmin','CommentAdmin','SecurityAdmin','Help'); + $this->assertEquals( + array_diff($requiredSections, $menuItems->column('Code')), + array(), + 'Group with CMS_ACCESS_LeftAndMain permission can access all sections' + ); + // admin $this->session()->inst_set('loggedInAs', $adminuser->ID); $menuItems = singleton('LeftAndMain')->MainMenu(); From 451aa6c536a87386edfd66d858d54b0f7e365a43 Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Mon, 21 Dec 2009 00:52:12 +0000 Subject: [PATCH 056/483] MINOR Set url variable in TreeAPI.reload as local variable in LeftAndMain_left.js git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95971 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain_left.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/LeftAndMain_left.js b/javascript/LeftAndMain_left.js index 5de22717..8a7a1445 100755 --- a/javascript/LeftAndMain_left.js +++ b/javascript/LeftAndMain_left.js @@ -52,7 +52,7 @@ TreeAPI.prototype = { var args = {ajax:1, ID:0}; if ($('LangSelector')) args.locale = $('LangSelector').value; - url = this.url(args); + var url = this.url(args); var self = this; new Ajax.Request(url, { From 08e9a352425f1cccbcf0feaf3441efa7f97d3fa9 Mon Sep 17 00:00:00 2001 From: Mateusz Uzdowski Date: Mon, 21 Dec 2009 00:57:14 +0000 Subject: [PATCH 057/483] BUGFIX: when the JS files are combined, swfupload.js gets included in pages where there are no placeholder elements available, failing with exception and killing the javascript for the page. Now the exception is intercepted and ignored. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@95972 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/Upload.js | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/javascript/Upload.js b/javascript/Upload.js index a5b51400..a6c20861 100644 --- a/javascript/Upload.js +++ b/javascript/Upload.js @@ -41,7 +41,14 @@ Upload.prototype = { if(typeof params.button_width != 'undefined') this.buttonWidth = params.button_width; if(typeof params.button_height != 'undefined') this.buttonHeight = params.button_height; - this.onLoad(); + try { + this.onLoad(); + } catch (ex) { + // suppress the exception in case swfupload.js is loaded in a context that has no + // placeholder elements + if ( ex.indexOf('Could not find the placeholder element')==-1 ) + throw ex; + } }, /** From 2e762da45e72b828f10e71fd728f53842f88982d Mon Sep 17 00:00:00 2001 From: Sean Harvey Date: Wed, 23 Dec 2009 01:53:03 +0000 Subject: [PATCH 058/483] MINOR Moved defined variables in AssetAdmin::doUpload() to the top of the method for consistency git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96230 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetAdmin.php | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/code/AssetAdmin.php b/code/AssetAdmin.php index 8647a040..d5990c0d 100755 --- a/code/AssetAdmin.php +++ b/code/AssetAdmin.php @@ -164,6 +164,14 @@ JS */ function doUpload($data, $form) { $processedFiles = array(); + $newFiles = array(); + $fileIDs = array(); + $fileNames = array(); + $fileSizeWarnings = ''; + $uploadErrors = ''; + $jsErrors = ''; + $status = ''; + $statusMessage = ''; if(!isset($data['Files'])) return Director::set_status_code("404"); @@ -174,26 +182,17 @@ JS $processedFiles[$key][$param] = $value; } } - } - else { + } else { $proccessedFiles[] = $data['Files']; } // get the folder to upload to. if(isset($data['FolderID']) && $data['FolderID'] != "root") { $folder = DataObject::get_by_id('Folder', $data['FolderID']); - } - else { + } else { $folder = DataObject::get_one('Folder'); } - $newFiles = array(); - $fileSizeWarnings = ''; - $uploadErrors = ''; - $jsErrors = ''; - $status = ''; - $statusMessage = ''; - foreach($processedFiles as $tmpFile) { if($tmpFile['error'] == UPLOAD_ERR_NO_TMP_DIR) { $status = 'bad'; @@ -232,15 +231,13 @@ JS if($newFiles) { $numFiles = sizeof($newFiles); - $statusMessage = sprintf(_t('AssetAdmin.UPLOADEDX',"Uploaded %s files"),$numFiles) ; + $statusMessage = sprintf(_t('AssetAdmin.UPLOADEDX',"Uploaded %s files"),$numFiles); $status = "good"; } else if($status != 'bad') { $statusMessage = _t('AssetAdmin.NOTHINGTOUPLOAD','There was nothing to upload'); $status = ""; } - $fileIDs = array(); - $fileNames = array(); foreach($newFiles as $newFile) { $fileIDs[] = $newFile; $fileObj = DataObject::get_one('File', "\"File\".\"ID\"=$newFile"); From 904fcf02d0f28e78219fef88b092363431459f2e Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Thu, 7 Jan 2010 01:38:55 +0000 Subject: [PATCH 059/483] FEATURE: Add onLoad callback handler CMSLoadFunctions git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96440 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain_right.js | 41 ++++++++++++++++++++++++++++++++- 1 file changed, 40 insertions(+), 1 deletion(-) diff --git a/javascript/LeftAndMain_right.js b/javascript/LeftAndMain_right.js index ab16360a..18e51777 100755 --- a/javascript/LeftAndMain_right.js +++ b/javascript/LeftAndMain_right.js @@ -1,3 +1,41 @@ +/** + * CMSLoadFunctions provides the ability to have 'onLoad' functions for pages + * in the CMS. + * These callbacks will be executed when a page has been loaded after clicking + * on it in the left-hand Site Content Tree. + * The usual document.ready functions won't work in this case as the page data + * is loaded via AJAX. + * + * A function will not be added twice, even if add() is called twice. + * + * Usage: + * CMSLoadFunctions.add(function(){ ... }); + * + */ +CMSLoadFunctions = { + add: function(fn) { + if (!this.load_functions) { + this.load_functions = []; + } + if (!(fn in this.load_functions)) { + this.load_functions.push(fn); + } + }, + + run: function() { + if (!this.load_functions) { + this.load_functions = []; + return; + } + for(var i=0; i < this.load_functions.length; i++) { + var fn = this.load_functions[i]; + if(typeof(fn) == 'function') { + fn(); + } + } + } +}; + CMSForm = Class.extend('ChangeTracker').extend('Observable'); CMSForm.prototype = { @@ -262,7 +300,8 @@ CMSRightForm.prototype = { } statusMessage(''); } - + + CMSLoadFunctions.run(); // must wait until the javascript has finished document.body.style.cursor = 'default'; From 3a63f1ab52cc7e8c6c19b38e934cebfeda940dab Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Thu, 7 Jan 2010 01:39:21 +0000 Subject: [PATCH 060/483] BUGFIX: Check for empty git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96441 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/WidgetAreaEditor.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/javascript/WidgetAreaEditor.js b/javascript/WidgetAreaEditor.js index 43f23eee..d8a61b71 100644 --- a/javascript/WidgetAreaEditor.js +++ b/javascript/WidgetAreaEditor.js @@ -63,6 +63,9 @@ WidgetAreaEditorClass.prototype = { this.name = this.getAttribute('name'); var monkeyWith = function(widgets, name) { + if (!widgets) { + return; + } for(var i = 0; i < widgets.length; i++) { widget = widgets[i]; if (!widget.getAttribute('rewritten') && (widget.id || widget.name)) { From e4d1eee3c10df53ab6b9b1b640c6fc3fbe9748f6 Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Thu, 7 Jan 2010 01:39:44 +0000 Subject: [PATCH 061/483] BUGFIX: Check for functions existence git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96443 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/tinymce_ssbuttons/editor_plugin_src.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/javascript/tinymce_ssbuttons/editor_plugin_src.js b/javascript/tinymce_ssbuttons/editor_plugin_src.js index e67bed5f..33c4e6dd 100644 --- a/javascript/tinymce_ssbuttons/editor_plugin_src.js +++ b/javascript/tinymce_ssbuttons/editor_plugin_src.js @@ -79,8 +79,10 @@ }); ed.onNodeChange.add(function(ed, o) { - $('Form_EditorToolbarLinkForm').updateSelection(ed); + if ($('Form_EditorToolbarLinkForm').updateSelection) { + $('Form_EditorToolbarLinkForm').updateSelection(ed); $('Form_EditorToolbarLinkForm').respondToNodeChange(ed); + } }); ed.onKeyUp.add(function(ed, o) { $('Form_EditorToolbarLinkForm').updateSelection(ed); @@ -110,4 +112,4 @@ // Adds the plugin class to the list of available TinyMCE plugins tinymce.PluginManager.add("ssbuttons", tinymce.plugins.SSButtons); -})(); \ No newline at end of file +})(); From 305cfe9c368c9aab119f57002626b604e6691ad2 Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Thu, 7 Jan 2010 02:01:16 +0000 Subject: [PATCH 062/483] REVERT: Code duplicated, as Observable interface can be used instead git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96448 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain_right.js | 41 +-------------------------------- 1 file changed, 1 insertion(+), 40 deletions(-) diff --git a/javascript/LeftAndMain_right.js b/javascript/LeftAndMain_right.js index 18e51777..ab16360a 100755 --- a/javascript/LeftAndMain_right.js +++ b/javascript/LeftAndMain_right.js @@ -1,41 +1,3 @@ -/** - * CMSLoadFunctions provides the ability to have 'onLoad' functions for pages - * in the CMS. - * These callbacks will be executed when a page has been loaded after clicking - * on it in the left-hand Site Content Tree. - * The usual document.ready functions won't work in this case as the page data - * is loaded via AJAX. - * - * A function will not be added twice, even if add() is called twice. - * - * Usage: - * CMSLoadFunctions.add(function(){ ... }); - * - */ -CMSLoadFunctions = { - add: function(fn) { - if (!this.load_functions) { - this.load_functions = []; - } - if (!(fn in this.load_functions)) { - this.load_functions.push(fn); - } - }, - - run: function() { - if (!this.load_functions) { - this.load_functions = []; - return; - } - for(var i=0; i < this.load_functions.length; i++) { - var fn = this.load_functions[i]; - if(typeof(fn) == 'function') { - fn(); - } - } - } -}; - CMSForm = Class.extend('ChangeTracker').extend('Observable'); CMSForm.prototype = { @@ -300,8 +262,7 @@ CMSRightForm.prototype = { } statusMessage(''); } - - CMSLoadFunctions.run(); + // must wait until the javascript has finished document.body.style.cursor = 'default'; From ea20f1101f05763ca426b30372622285fb9bedef Mon Sep 17 00:00:00 2001 From: Mateusz Uzdowski Date: Sun, 10 Jan 2010 22:27:40 +0000 Subject: [PATCH 063/483] BUGFIX: getting rid of problem with disappearing buttons on the initial page load (not ajax). The initialization was called twice on the CMSForm, and on the second call the ajaxActionsAtTop was removing the buttons - now the buttons are removed only when there is something to be added. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96551 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/LeftAndMain.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index 7c2482cc..d22118e9 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -255,13 +255,13 @@ function unlockStatusMessage() { */ function ajaxActionsAtTop(formName, actionHolderName, tabName) { var actions = document.getElementsBySelector('#' + formName + ' .Actions')[0]; - var holder; - - if((holder = $(actionHolderName)) && holder != actions) { - holder.parentNode.removeChild(holder); - } + var holder = $(actionHolderName); if(actions) { + if ( holder ) { + holder.parentNode.removeChild(holder); + } + actions.id = actionHolderName; actions.className = 'ajaxActions'; From 3c2dcf4dd21568f4b0d3b6476c1e587b788b1e20 Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Mon, 11 Jan 2010 01:16:37 +0000 Subject: [PATCH 064/483] BUGFIX: Fix IE bug with Files&Images (#4912) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96566 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/AssetTableField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/AssetTableField.js b/javascript/AssetTableField.js index 85205309..50e82ab2 100644 --- a/javascript/AssetTableField.js +++ b/javascript/AssetTableField.js @@ -85,7 +85,7 @@ FileFilterButton.prototype = { updateURL += ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''); // update the field - var field = form.getElementsByClassName('AssetTableField')[0]; + var field = document.getElementsByClassName('AssetTableField')[0]; field.setAttribute('href', updateURL); field.refresh(); } catch(er) { From bf2ed79d8fb52f0e4b023ef00f753cb446b7a6cb Mon Sep 17 00:00:00 2001 From: Mark Stephens Date: Tue, 12 Jan 2010 02:05:59 +0000 Subject: [PATCH 065/483] ENHANCEMENT: Change to TreeDropdownField, giving it filtering behaviour as described in ticket http://open.silverstripe.org/ticket/3007 . Its disabled by default for legacy compatibility, but enabled for HtmlEditorField so that link editor is filterable for local links, via an extra boolean parameter on TreeDowndownField. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96668 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- css/Image_iframe.css | 8 ++++++-- css/cms_right.css | 3 +-- css/layout.css | 10 ++++++++++ 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/css/Image_iframe.css b/css/Image_iframe.css index 3fddfbcd..186ec2c3 100755 --- a/css/Image_iframe.css +++ b/css/Image_iframe.css @@ -58,7 +58,7 @@ h2 { /** - * TreeDropdownField stying + * TreeDropdownField styling */ .SelectionGroup div.TreeDropdownField { width: 241px; @@ -68,7 +68,7 @@ html>body div.TreeDropdownField { position:relative; } -.SelectionGroup div.TreeDropdownField span.items { +.SelectionGroup div.TreeDropdownField .items { display: block; height: 100%; border: 1px #7f9db9 solid; @@ -80,6 +80,10 @@ html>body div.TreeDropdownField { background-color: white; } +.SelectionGroup div.TreeDropdownField input.items { + height: 19px; +} + .SelectionGroup div.TreeDropdownField div.tree_holder { clear: left; cursor: default; diff --git a/css/cms_right.css b/css/cms_right.css index ea2f5f84..df4e431e 100644 --- a/css/cms_right.css +++ b/css/cms_right.css @@ -291,10 +291,9 @@ padding-bottom: 150px; } -#right form.actionparams div.TreeDropdownField span.items { +#right form.actionparams div.TreeDropdownField .items { width: 195px; } - #right form.actionparams div.TreeDropdownField div.tree_holder { width: 214px; } diff --git a/css/layout.css b/css/layout.css index 8e8f67af..360cfaca 100644 --- a/css/layout.css +++ b/css/layout.css @@ -544,6 +544,16 @@ iframe { border:1px solid #A7A7A7; border-right: none; overflow: hidden; +} +#contentPanel div.TreeDropdownField input.items { + float: left; + width: 155px; + background: #fff; + font-size: 12px; + border:1px solid #A7A7A7; + border-right: none; + height: 19px; + overflow: hidden; } #contentPanel div.TreeDropdownField a { overflow: visible; From 7551377671fbae9824a3ac0fb66e936873a159d3 Mon Sep 17 00:00:00 2001 From: Luke Hudson Date: Tue, 12 Jan 2010 03:01:58 +0000 Subject: [PATCH 066/483] BUGFIX: Ensure .js variable defined with var keyword git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96678 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/Upload.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/Upload.js b/javascript/Upload.js index a6c20861..0805ab4c 100644 --- a/javascript/Upload.js +++ b/javascript/Upload.js @@ -5,7 +5,7 @@ */ -Upload = Class.create(); +var Upload = Class.create(); Upload.prototype = { /** From 460fe2e5ab7d4b96ac3fdbdb4202d6c2de775e2d Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:49:00 +0000 Subject: [PATCH 067/483] MINOR: fix javscript syntax that can confuse ie (from r86395) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96776 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/CMSMain_left.js | 20 ++++++++++---------- tests/cuke/step_definitions/content.rb | 3 +++ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/javascript/CMSMain_left.js b/javascript/CMSMain_left.js index 136f75a6..6b03f88e 100755 --- a/javascript/CMSMain_left.js +++ b/javascript/CMSMain_left.js @@ -118,7 +118,7 @@ searchclass.prototype = { $(_HANDLER_FORMS.search).stopObserving(this.o2); batchActionGlobals.unfilterSiteTree(); } -} +}; var SiteTreeFilter = Class.create(); SiteTreeFilter.applyTo('#siteTreeFilterList'); @@ -154,7 +154,7 @@ SiteTreeFilter.prototype = { } }); } -} +}; /** * Control the site tree filter */ @@ -177,7 +177,7 @@ SiteTreeFilterForm.prototype = { }); document.getElementsBySelector('.SearchCriteriaContainer', this).each(function(el){ Element.hide(el); - }) + }); } else { Form.getElements(this).each(function(el){ @@ -199,7 +199,7 @@ SiteTreeFilterForm.prototype = { if ($('sitetree').isDraggable) $('sitetree').stopBeingDraggable(); document.getElementsBySelector('.checkboxAboveTree input[type=checkbox]').each(function(el){ el.value = false; el.disabled = true; - }) + }); } else { // Reset URL to default @@ -208,7 +208,7 @@ SiteTreeFilterForm.prototype = { // Enable checkbox tree controls document.getElementsBySelector('.checkboxAboveTree input[type=checkbox]').each(function(el){ el.disabled = false; - }) + }); } $('SiteTreeSearchButton').className = $('SiteTreeSearchClearButton').className = 'hidden'; @@ -227,7 +227,7 @@ SiteTreeFilterForm.prototype = { return false; } -} +}; /** * Add Criteria Drop-down onchange action which allows more criteria to be shown @@ -241,7 +241,7 @@ SiteTreeFilterAddCriteria.prototype = { // Element.show('Input' + this.value); this.selectedIndex = 0; //reset selected criteria to prompt } -} +}; /** * Batch Actions button click action @@ -261,7 +261,7 @@ batchactionsclass.prototype = { }, actionChanged: function() { - var urlSegment = $('choose_batch_action').value.split('/').pop() + var urlSegment = $('choose_batch_action').value.split('/').pop(); if ($('BatchActionParameters_'+urlSegment)) { jQuery('#actionParams').empty(); jQuery('#BatchActionParameters_'+urlSegment).appendTo('#actionParams'); @@ -297,7 +297,7 @@ batchactionsclass.prototype = { } } } -} +}; // batchActionGlobals is needed because calls to observeMethod doesn't seem to preserve instance variables so a Prototype can't be used batchActionGlobals = { @@ -401,7 +401,7 @@ batchActionGlobals = { }); } } -} +}; Behaviour.register({ diff --git a/tests/cuke/step_definitions/content.rb b/tests/cuke/step_definitions/content.rb index 7bcbad4f..379671dd 100644 --- a/tests/cuke/step_definitions/content.rb +++ b/tests/cuke/step_definitions/content.rb @@ -45,8 +45,11 @@ end Given /create a new page using template \"(.*)\"/i do |type| Given 'I load the root node (ajax)' + puts "Clicking the create button" And 'I click the "Create" button' + puts "Selecting #{type} from PageType" And "I select \"#{type}\" from \"PageType\"" + puts "done selecting" And 'I click the "Go" button (ajax)' And 'I click the "Create" button' end From 879ddce9944b540cacf0cb0325c62ce88d336b22 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:49:09 +0000 Subject: [PATCH 068/483] javascript syntax fixes (from r86396) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96777 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/SideReports.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/javascript/SideReports.js b/javascript/SideReports.js index fc01c0bc..f1433541 100755 --- a/javascript/SideReports.js +++ b/javascript/SideReports.js @@ -105,4 +105,4 @@ Behaviour.register({ $('reports_holder').reportSelected(); } } -}); \ No newline at end of file +}); From b14404922d9cec48fed21e9b2b4b91dcb77f9970 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:50:39 +0000 Subject: [PATCH 069/483] ENHANCEMENT: Files and images section warns if you are deleting a file that is linked to git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96778 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/AssetTableField.js | 57 ++++++++++++++++++++++++++- templates/Includes/AssetTableField.ss | 3 +- 2 files changed, 58 insertions(+), 2 deletions(-) diff --git a/javascript/AssetTableField.js b/javascript/AssetTableField.js index 50e82ab2..3040742b 100644 --- a/javascript/AssetTableField.js +++ b/javascript/AssetTableField.js @@ -18,6 +18,13 @@ AssetTableField.prototype = { } } }); + + var rules = {}; + + // Assume that the delete link uses the deleteRecord method + rules['#'+this.id+' table.data a.deletelink'] = {onclick: this.deleteRecord.bind(this)}; + + Behaviour.register('ComplexTableField_'+this.id,rules); }, // prevent submission of wrong form-button (FileFilterButton) @@ -32,6 +39,54 @@ AssetTableField.prototype = { Event.stop(event); return false; } + }, + + + // Override deleteRecord function, so that we can give warning if there are + // links to this file. This is mostly a copy paste from TableField.js + deleteRecord: function(e) { + var img = Event.element(e); + var link = Event.findElement(e,"a"); + var row = Event.findElement(e,"tr"); + + var linkCount = row.getElementsByClassName('linkCount')[0]; + if(linkCount) linkCount = linkCount.innerHTML; + + var confirmMessage = ss.i18n._t('TABLEFIELD.DELETECONFIRMMESSAGE', 'Are you sure you want to delete this record?'); + if(linkCount) confirmMessage += '\nThere are ' + linkCount + ' page(s) that use this file, please review the list of pages on the Links tab of the file before continuing.'; + + // TODO ajaxErrorHandler and loading-image are dependent on cms, but formfield is in sapphire + var confirmed = confirm(confirmMessage); + if(confirmed) + { + img.setAttribute("src",'cms/images/network-save.gif'); // TODO doesn't work + new Ajax.Request( + link.getAttribute("href"), + { + method: 'post', + postBody: 'forceajax=1' + ($('SecurityID') ? '&SecurityID=' + $('SecurityID').value : ''), + onComplete: function(){ + Effect.Fade( + row, + { + afterFinish: function(obj) { + // remove row from DOM + obj.element.parentNode.removeChild(obj.element); + // recalculate summary if needed (assumes that TableListField.js is present) + // TODO Proper inheritance + if(this._summarise) this._summarise(); + // custom callback + if(this.callback_deleteRecord) this.callback_deleteRecord(e); + }.bind(this) + } + ); + }.bind(this), + onFailure: this.ajaxErrorHandler + } + ); + } + + Event.stop(e); } } @@ -94,4 +149,4 @@ FileFilterButton.prototype = { return false; } -} \ No newline at end of file +} diff --git a/templates/Includes/AssetTableField.ss b/templates/Includes/AssetTableField.ss index 9b7fd7b2..036760ef 100755 --- a/templates/Includes/AssetTableField.ss +++ b/templates/Includes/AssetTableField.ss @@ -21,6 +21,7 @@ Drag +

    <% if Markable %>$MarkingCheckbox<% end_if %> <% control Fields %> @@ -55,4 +56,4 @@ <% end_if %> -
    \ No newline at end of file +
    From 00264e219c839bb8829cafa88e1523991500785c Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:52:10 +0000 Subject: [PATCH 070/483] BUGFIX: Fix highlighting of incorrect page when loading a page in the admin section via URL (from r87320) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96779 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index c9efbb68..24b04276 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -328,10 +328,12 @@ class LeftAndMain extends Controller { return $title; } - public function show($params) { + public function show() { + $params = $this->getURLParams(); if($params['ID']) $this->setCurrentPageID($params['ID']); - if(isset($params['OtherID'])) + if(isset($params['OtherID'])) { Session::set('currentMember', $params['OtherID']); + } if(Director::is_ajax()) { SSViewer::setOption('rewriteHashlinks', false); From fdce9e045df908fcdceec0feea1f223423f60ad1 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:53:34 +0000 Subject: [PATCH 071/483] BUGFIX: Fix deleting folders in Internet Explorer (from r87390) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96780 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/AssetAdmin.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/javascript/AssetAdmin.js b/javascript/AssetAdmin.js index a3f08fbf..0dcdcb51 100755 --- a/javascript/AssetAdmin.js +++ b/javascript/AssetAdmin.js @@ -87,7 +87,7 @@ MarkingPropertiesButton.prototype = { } return false; } -} +}; // CheckBoxRange adapted from: http://jroller.com/page/rmcmahon?entry=checkboxrange_with_prototype @@ -148,23 +148,23 @@ CheckBoxRange.prototype = { break; } } -} +}; // SubsDraggable adapted from http://dev.rubyonrails.org/ticket/5771 // extentions for scriptaculous dragdrop.js Object.extend(Class, { superrise: function(obj, names){ - names.each( function(n){ obj['super_' + n] = obj[n] } ) + names.each( function(n){ obj['super_' + n] = obj[n]; } ); return obj; } -}) +}); // Draggable that allows substitution of draggable element var SubsDraggable = Class.create(); SubsDraggable.prototype = Object.extend({}, Draggable.prototype); -Class.superrise(SubsDraggable.prototype, ['initialize', 'startDrag', 'finishDrag', 'endDrag']) +Class.superrise(SubsDraggable.prototype, ['initialize', 'startDrag', 'finishDrag', 'endDrag']); Object.extend( SubsDraggable.prototype , { initialize: function(event) { this.super_initialize.apply(this, arguments); @@ -216,7 +216,7 @@ Object.extend( SubsDraggable.prototype , { this._originalElement = null; } } -}) +}); // gets element that should be dragged instead of original element // returned element should be added to DOM tree, and will be deleted by dragdrop library function getDragElement(element){ @@ -238,7 +238,7 @@ DragFileItem.prototype = { destroy: function() { this.draggable = null; } -} +}; DragFileItem.applyTo('#Form_EditForm_Files tr td.dragfile'); // Set up folder drop target @@ -267,7 +267,7 @@ DropFileItem.prototype = { if(checkboxes[i].checked) list += (list?',':'') + checkboxes[i].value; } $('Form_EditForm_FileIDs').value = list; - $('Form_EditForm').save(false, null, 'movemarked') + $('Form_EditForm').save(false, null, 'movemarked'); } }); }, @@ -275,7 +275,7 @@ DropFileItem.prototype = { this.droppable = null; this.recordID = null; } -} +}; DropFileItem.applyTo('#sitetree li'); @@ -328,7 +328,7 @@ addfolder.prototype = { showAddPageError: function(response) { errorMessage('Error adding folder', response); } -} +}; /** * Look for new files (FilesystemSync) action @@ -352,7 +352,7 @@ FilesystemSyncClass.prototype = { }); return false; } -} +}; /** * Delete folder action @@ -367,7 +367,7 @@ var deletefolder = { deletefolder.selectedNodes = { }; - var sel = $('sitetree').firstSelected() + var sel = $('sitetree').firstSelected(); if(sel) { var selIdx = $('sitetree').getIdxOf(sel); deletefolder.selectedNodes[selIdx] = true; @@ -411,7 +411,7 @@ var deletefolder = { } }, - form_submit : function() { + form_submit : function(e) { var csvIDs = ""; for(var idx in deletefolder.selectedNodes) { var selectedNode = $('sitetree').getTreeNodeByIdx(idx); @@ -438,7 +438,8 @@ var deletefolder = { } else { alert("Please select at least 1 page."); } - + + Event.stop(e); return false; }, @@ -446,7 +447,7 @@ var deletefolder = { Ajax.Evaluator(response); treeactions.closeSelection($('deletepage')); } -} +}; Behaviour.register({ '#Form_EditForm_Files': { From 7af4414a024acb385e76fd6fe7f51a667a50a855 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:53:43 +0000 Subject: [PATCH 072/483] BUGFIX: Fix changing the URLSegment on a page making the Draft Site link point to the wrong subsite (from r87776) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96781 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index 24b04276..08e22b51 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -717,7 +717,7 @@ JS; if( ($record->class != 'VirtualPage') && $originalURLSegment != $record->URLSegment) { $message .= sprintf(_t('LeftAndMain.CHANGEDURL'," Changed URL to '%s'"),$record->URLSegment); FormResponse::add("\$('Form_EditForm').elements.URLSegment.value = \"$record->URLSegment\";"); - FormResponse::add("\$('Form_EditForm_StageURLSegment').value = \"{$record->URLSegment}\";"); + FormResponse::add("\$('Form_EditForm_StageURLSegment').value = \"" . $record->AbsoluteLink() . "\";"); } // If the 'Save & Publish' button was clicked, also publish the page From 096bfb25652ca56482ce0ab3635ded2cd1ff88ac Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:54:29 +0000 Subject: [PATCH 073/483] BUGFIX: Fix image tracking not working cross subsite (from r88008) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96782 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/AssetTableField.php | 3 +++ javascript/LeftAndMain_right.js | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/code/AssetTableField.php b/code/AssetTableField.php index ce8cae71..44bb612a 100755 --- a/code/AssetTableField.php +++ b/code/AssetTableField.php @@ -197,7 +197,10 @@ class AssetTableField extends ComplexTableField { } if($childData && $childData->hasMethod('BackLinkTracking')) { + if(class_exists('Subsite')) Subsite::disable_subsite_filter(true); $links = $childData->BackLinkTracking(); + if(class_exists('Subsite')) Subsite::disable_subsite_filter(false); + if($links->exists()) { foreach($links as $link) { $backlinks[] = "
  • ID\">" . $link->Breadcrumbs(null,true). "
  • "; diff --git a/javascript/LeftAndMain_right.js b/javascript/LeftAndMain_right.js index ab16360a..75214ab7 100755 --- a/javascript/LeftAndMain_right.js +++ b/javascript/LeftAndMain_right.js @@ -463,4 +463,4 @@ function tinymce_removeAll() { tinymce.EditorManager.editors = {}; } -} \ No newline at end of file +} From 141886d6750935efd75305d70bd197745ea87756 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:55:01 +0000 Subject: [PATCH 074/483] MINOR remove default form actions. Unit tests pass. (from r88065) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96783 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSMain.php | 8 -------- 1 file changed, 8 deletions(-) diff --git a/code/CMSMain.php b/code/CMSMain.php index 7f9b78da..762f7ee4 100755 --- a/code/CMSMain.php +++ b/code/CMSMain.php @@ -428,14 +428,6 @@ JS; $actions = $record->getAllCMSActions(); } else { $actions = $record->getCMSActions(); - // add default actions if none are defined - if(!$actions || !$actions->Count()) { - if($record->canEdit()) { - $actions->push(new FormAction('save',_t('CMSMain.SAVE','Save'))); - $actions->push($deleteAction = new FormAction('delete',_t('CMSMain.DELETE','Delete from the draft site'))); - $deleteAction->addExtraClass('delete'); - } - } } // Add a default or custom validator. From 25ac72ee22d5fa1e974e4bb337bc13528f312495 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:55:12 +0000 Subject: [PATCH 075/483] MINOR create the ability to have some roles only be able to be applied by admins (from r88090) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96784 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/SecurityAdmin.php | 1 + 1 file changed, 1 insertion(+) diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index 743f8fd1..17c9eab7 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -283,6 +283,7 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { 'help' => _t('SecurityAdmin.APPLY_ROLES_HELP', 'Ability to edit the roles assigned to a group. Requires "Access to Security.".'), 'sort' => 0 ) + 'APPLY_ROLES' => _t('SecurityAdmin.APPLY_ROLES', 'Apply roles to groups'), ); } From 291de8d2839ce7fa86c76d5c36d6e3a63db1bd28 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:56:36 +0000 Subject: [PATCH 076/483] BUGFIX: Ignore elements without a name in change detection. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96785 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/SecurityAdmin.php | 1 - javascript/LeftAndMain.js | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/code/SecurityAdmin.php b/code/SecurityAdmin.php index 17c9eab7..743f8fd1 100644 --- a/code/SecurityAdmin.php +++ b/code/SecurityAdmin.php @@ -283,7 +283,6 @@ class SecurityAdmin extends LeftAndMain implements PermissionProvider { 'help' => _t('SecurityAdmin.APPLY_ROLES_HELP', 'Ability to edit the roles assigned to a group. Requires "Access to Security.".'), 'sort' => 0 ) - 'APPLY_ROLES' => _t('SecurityAdmin.APPLY_ROLES', 'Apply roles to groups'), ); } diff --git a/javascript/LeftAndMain.js b/javascript/LeftAndMain.js index d22118e9..0f9ac0fb 100644 --- a/javascript/LeftAndMain.js +++ b/javascript/LeftAndMain.js @@ -591,8 +591,9 @@ ChangeTracker.prototype = { var i, element; for(i=0;element=elements[i];i++) { // NOTE: TinyMCE coupling - // Ignore mce-generated elements + // Ignore mce-generated elements and elements without a name if(element.className.substr(0,3) == 'mce') continue; + if(!element.name) continue; if(!element.isChanged) element.isChanged = this.field_changed; if(!this.changeDetection_fieldsToIgnore[element.name] && element.isChanged()) { From 568f808053bab0b797fefa637ad6023106bbc0c0 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:56:49 +0000 Subject: [PATCH 077/483] MINOR rename deleted pages report (from r88333) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96786 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/CMSSiteTreeFilter.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/code/CMSSiteTreeFilter.php b/code/CMSSiteTreeFilter.php index 353ab89a..3e6ae89f 100644 --- a/code/CMSSiteTreeFilter.php +++ b/code/CMSSiteTreeFilter.php @@ -75,7 +75,7 @@ abstract class CMSSiteTreeFilter extends Object { class CMSSiteTreeFilter_DeletedPages extends CMSSiteTreeFilter { static function title() { - return "Deleted pages"; + return "All pages, including deleted"; } function getTree() { From 2b4366b0d3dd59154ee78f4c8a799b5845bfb966 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:57:47 +0000 Subject: [PATCH 078/483] MINOR fix issue where javascript popup calendar would not fire (from r88836) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96787 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- javascript/CMSMain_left.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/javascript/CMSMain_left.js b/javascript/CMSMain_left.js index 6b03f88e..884373b2 100755 --- a/javascript/CMSMain_left.js +++ b/javascript/CMSMain_left.js @@ -263,13 +263,11 @@ batchactionsclass.prototype = { actionChanged: function() { var urlSegment = $('choose_batch_action').value.split('/').pop(); if ($('BatchActionParameters_'+urlSegment)) { - jQuery('#actionParams').empty(); - jQuery('#BatchActionParameters_'+urlSegment).appendTo('#actionParams'); - $('actionParams').style.display = 'block'; - $('actionParams').style.padding = '4px'; + jQuery('#BatchActionParameters .params').hide(); + jQuery('#BatchActionParameters_'+urlSegment).show(); + jQuery('#BatchActionParameters').show(); } else { - $('actionParams').innerHTML = ''; - $('actionParams').style.display = 'none'; + jQuery('#BatchActionParameters').hide(); } }, From 430f30b7c413e507719fe17b5b5c4227c68b63f7 Mon Sep 17 00:00:00 2001 From: Sam Minnee Date: Tue, 12 Jan 2010 23:57:58 +0000 Subject: [PATCH 079/483] MINOR more fix around batch action parameters (from r88837) git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/branches/2.4@96788 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- templates/Includes/CMSMain_left.ss | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/templates/Includes/CMSMain_left.ss b/templates/Includes/CMSMain_left.ss index b30033bd..fec64957 100755 --- a/templates/Includes/CMSMain_left.ss +++ b/templates/Includes/CMSMain_left.ss @@ -65,9 +65,10 @@
    - $BatchActionParameters