mark: A photo of Mark kneeling on top of the Taal Volcano in the Philippines. It was a long hike. (Default)
Mark Smith ([staff profile] mark) wrote in [site community profile] changelog2009-11-25 04:06 am

[dw-free] set up RTE to use the cross-site tags

[commit: http://hg.dwscoalition.org/dw-free/rev/13b9b8990773]

http://bugs.dwscoalition.org/show_bug.cgi?id=496

Allow RTE to support external site tags.

Patch by [personal profile] afuna.

Files modified:
  • bin/upgrading/en.dat
  • cgi-bin/weblib.pl
  • htdocs/js/rte.js
  • htdocs/stc/entry.css
  • htdocs/stc/fck/editor/plugins/livejournal/fckplugin.js
  • htdocs/tools/endpoints/ljuser.bml
--------------------------------------------------------------------------------
diff -r 0e9424044833 -r 13b9b8990773 bin/upgrading/en.dat
--- a/bin/upgrading/en.dat	Wed Nov 25 03:56:46 2009 +0000
+++ b/bin/upgrading/en.dat	Wed Nov 25 04:06:39 2009 +0000
@@ -2031,6 +2031,10 @@ fcklang.readmore=Read more...
 
 fcklang.userprompt=Enter their username
 
+fcklang.userprompt.site=External Site (optional)
+
+fcklang.userprompt.user=Username
+
 fcklang.videoprompt=Please enter the YouTube, PhotoBucket, or Google Video URL:
 
 feeds.link=syndicated feeds
diff -r 0e9424044833 -r 13b9b8990773 cgi-bin/weblib.pl
--- a/cgi-bin/weblib.pl	Wed Nov 25 03:56:46 2009 +0000
+++ b/cgi-bin/weblib.pl	Wed Nov 25 04:06:39 2009 +0000
@@ -10,6 +10,7 @@ require "crumbs.pl";
 require "crumbs.pl";
 
 use Carp;
+use DW::External::Site;
 use DW::Request;
 use LJ::Event;
 use LJ::Subscription::Pending;
@@ -1407,9 +1408,18 @@ sub entry_form {
         if (t) {
 RTE
 
+    my @sites = DW::External::Site->get_sites;
+    my @sitevalues;
+    foreach my $site (sort { $a->{sitename} cmp $b->{sitename} } @sites) {
+        push @sitevalues, { domain => $site->{domain}, sitename => $site->{sitename} };
+    }
+
     $out .= "var FCKLang;\n";
     $out .= "if (!FCKLang) FCKLang = {};\n";
     $out .= "FCKLang.UserPrompt = \"".LJ::ejs(BML::ml('fcklang.userprompt'))."\";\n";
+    $out .= "FCKLang.UserPrompt_User = \"".LJ::ejs(BML::ml('fcklang.userprompt.user'))."\";\n";
+    $out .= "FCKLang.UserPrompt_Site = \"".LJ::ejs(BML::ml('fcklang.userprompt.site'))."\";\n";
+    $out .= "FCKLang.UserPrompt_SiteList =" . LJ::js_dumper( \@sitevalues ) . ";\n";
     $out .= "FCKLang.InvalidChars = \"".LJ::ejs(BML::ml('fcklang.invalidchars'))."\";\n";
     $out .= "FCKLang.LJUser = \"".LJ::ejs(BML::ml('fcklang.ljuser'))."\";\n";
     $out .= "FCKLang.VideoPrompt = \"".LJ::ejs(BML::ml('fcklang.videoprompt'))."\";\n";
diff -r 0e9424044833 -r 13b9b8990773 htdocs/js/rte.js
--- a/htdocs/js/rte.js	Wed Nov 25 03:56:46 2009 +0000
+++ b/htdocs/js/rte.js	Wed Nov 25 04:06:39 2009 +0000
@@ -8,15 +8,22 @@ function LJUser(textArea) {
 
     var html = oEditor.GetXHTML(false);
     if (html) html = html.replace(/<\/(lj|user)>/, '');
-    var regexp = /<(?:lj user|user name)=['"](\w+?)['"] ?\/?>\s?(?:<\/(?:lj|user)>)?\s?/g;
+    var regexp = /<(?:lj|user)( (?:user|name|site)=[^/>]+)\/?>\s?(?:<\/(?:lj|user)>)?\s?/g;
+    var attrs_regexp = /(user|name|site)=['"]([.\w]+?)['"]/g;
     var userstr;
     var users = [];
     var username;
+
     while ((users = regexp.exec(html))) {
-        username = users[1];
-        var postData = {
-            "username" : username
-        };
+        var attrs = [];
+        var postData = {};
+
+        while (( attrs=attrs_regexp.exec(users[1]) )) {
+            if (attrs[1] == 'user' || attrs[1] == 'name')
+                postData.username = attrs[2];
+            else 
+                postData[attrs[1]] = attrs[2];
+        }
         var url = window.parent.Site.siteroot + "/tools/endpoints/ljuser";
 
         var gotError = function(err) {
@@ -24,18 +31,27 @@ function LJUser(textArea) {
             return;
         }
 
-        var gotInfo = function (data) {
+        var gotInfo = (function (userstr, username, site) { return function(data) {
+            // trim any trailing spaces from the userstr
+            // so that we don't get rid of them when we do the replace below
+            userstr = userstr.replace(/\s\s*$/, '');
+
             if (data.error) {
                 alert(data.error+' '+username);
                 return;
             }
             if (!data.success) return;
-            data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser">');
+
+            if ( site ) 
+                data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser" site="' + site + '">');
+            else 
+                data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser">');
+
             data.ljuser = data.ljuser.replace(/<\/span>\s?/,'</div>');
-            html = html.replace(data.userstr,data.ljuser);
+            html = html.replace(userstr,data.ljuser);
             oEditor.SetData(html);
             oEditor.Focus();
-        }
+        }})(users[0], postData.username, postData.site);
 
         var opts = {
             "data": window.parent.HTTPReq.formEncoded(postData),
@@ -245,7 +261,10 @@ function doLinkedFieldUpdate(oEditor) {
 }
 
 function convertToTags(html) {
+    // no site
     html = html.replace(/<div class=['"]ljuser['"]>.+?<b>(\w+?)<\/b><\/a><\/div>/g, '<user name=\"$1\">');
+    // with site
+    html = html.replace(/<div(?: site=['"](.+?)['"]) class=['"]ljuser['"]>.+?<b>(\w+?)<\/b><\/a><\/div>/g, '<user name=\"$2\" site=\"$1\">');
     html = html.replace(/<div class=['"]ljvideo['"] url=['"](\S+)['"]><img.+?\/><\/div>/g, '<site-template name=\"video\">$1</site-template>');
     html = html.replace(/<div class=['"]ljvideo['"] url=['"](\S+)['"]><br \/><\/div>/g, '');
     html = html.replace(/<div class=['"]ljraw['"]>(.+?)<\/div>/g, '<raw-code>$1</raw-code>');
diff -r 0e9424044833 -r 13b9b8990773 htdocs/stc/entry.css
--- a/htdocs/stc/entry.css	Wed Nov 25 03:56:46 2009 +0000
+++ b/htdocs/stc/entry.css	Wed Nov 25 04:06:39 2009 +0000
@@ -554,3 +554,9 @@ td.tabs {
 td.tabs {
     width:41%;
 }
+
+
+/* for entering the user tag */
+.userprompt {  padding: 0 1em 0.5em 1em; }
+.userprompt .submitbtncontainer {  margin-top: 1em; }
+.userprompt label { display: block; padding: 0.5em 0 0.1em 0; }
diff -r 0e9424044833 -r 13b9b8990773 htdocs/stc/fck/editor/plugins/livejournal/fckplugin.js
--- a/htdocs/stc/fck/editor/plugins/livejournal/fckplugin.js	Wed Nov 25 03:56:46 2009 +0000
+++ b/htdocs/stc/fck/editor/plugins/livejournal/fckplugin.js	Wed Nov 25 04:06:39 2009 +0000
@@ -7,11 +7,6 @@ LJUserCommand.GetState=function() {
     return FCK_TRISTATE_OFF; //we dont want the button to be toggled
 }
 
-// Check for allowed lj user characters
-LJUserCommand.validUsername = function(str) {
-    var pattern = /^\w{1,15}$/i;
-    return pattern.test(str);
-}
 
 LJUserCommand.Execute=function() {
     var username;
@@ -37,47 +32,135 @@ LJUserCommand.Execute=function() {
         }
     }
 
+    function do_insert( username, site ) {
+        var postData = {
+            "username" : username,
+            "site"     : site
+        };
+    
+        if (username == null) return;
+    
+        var url = window.parent.Site.siteroot + "/tools/endpoints/ljuser";
+    
+        var gotError = function(err) {
+            alert(err);
+        }
+    
+        var gotInfo = function (data) {
+            if (data.error) {
+                alert(data.error);
+                return;
+            }
+
+            if (!data.success) return;
+
+            if ( site ) 
+                data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser" site="' + site + '">');
+            else 
+                data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser">');
+
+            data.ljuser = data.ljuser.replace(/<\/span>/,'</div>');
+            FCK.InsertHtml(data.ljuser);
+            FCK.InsertHtml('&nbsp;')
+            if (selection != '') FCKSelection.Collapse();
+            FCK.Focus();
+        }
+    
+        var opts = {
+            "data": window.parent.HTTPReq.formEncoded(postData),
+            "method": "POST",
+            "url": url,
+            "onError": gotError,
+            "onData": gotInfo
+        };
+    
+        window.parent.HTTPReq.getJSON(opts);
+    }
+
     if (selection != '') {
         username = selection;
+        do_insert( username );
     } else {
-        username = prompt(window.parent.FCKLang.UserPrompt, '');
+        var DOM = window.parent.DOM;
+        var _textDiv = window.parent._textDiv;
+        var userPopup = new window.parent.LJ_IPPU( window.parent.FCKLang.UserPrompt );
+        userPopup.hide =   function() {
+            window.parent.LJ_IPPU.superClass.hide.apply(this);
+            DOM.removeEventListener( window.parent.document, "keyup", LJUserCommand.KeyUpHandler );
+        }
+
+
+        var inner = document.createElement( "div" );
+        DOM.addClassName( inner, "userprompt" );
+
+        var label = document.createElement( "label" );
+        label.appendChild( _textDiv( window.parent.FCKLang.UserPrompt_User ) );
+        label.setAttribute( "for", "userprompt-username" );
+        inner.appendChild( label );
+
+        var username = document.createElement( "input" );
+        username.name = "username";
+        username.id = "userprompt-username";
+        inner.appendChild( username );
+
+        label = document.createElement( "label" );
+        label.appendChild( _textDiv( window.parent.FCKLang.UserPrompt_Site ) );
+        label.setAttribute( "for", "userprompt-site" );
+        inner.appendChild( label );
+
+        var siteList = document.createElement( "select" );
+        siteList.name = "site";
+        siteList.id = "userprompt-site";
+        var option = new Option( "--", "" );
+        option.selected = "selected";
+        siteList.appendChild( option );
+        inner.appendChild( siteList );
+
+        for ( var i = 0; i < window.parent.FCKLang.UserPrompt_SiteList.length; i++ ) {
+            var site = window.parent.FCKLang.UserPrompt_SiteList[i];
+            var option = new Option( site.sitename, site.domain );
+            siteList.appendChild( option );
+        }
+
+        var btncont = document.createElement( "div" );
+        DOM.addClassName( btncont, "submitbtncontainer" );
+        var btn = document.createElement( "input" );
+        DOM.addClassName ( btn, "submitbtn" );
+        btn.type = "button";
+        btn.value = "Insert";
+        btncont.appendChild( btn );
+        inner.appendChild( btncont );
+
+        userPopup.setContentElement( inner );
+
+        userPopup.setAutoCenter( true, true );
+        userPopup.setDimensions( "15em", "auto" );
+        userPopup.show();
+        username.focus();
+
+        DOM.addEventListener( window.parent.document, "keyup", function(userPopup) { 
+            return  LJUserCommand.KeyUpHandler = function(e) {
+                var code = e.keyCode || e.which;
+                // enter
+                if ( code == 13 ) {            
+                    userPopup.hide();
+                    do_insert( username.value, siteList.value );
+                    return;
+                }
+                // escape
+                if ( code == 27 ) {
+                    userPopup.hide();
+                    return;
+                }
+            } }(userPopup)
+        );
+
+        DOM.addEventListener( btn, "click", function (e) {
+            userPopup.hide();
+            do_insert( username.value, siteList.value );
+        } );
     }
 
-    var postData = {
-        "username" : username
-    };
-    if (username == null) return;
-
-    var url = window.parent.Site.siteroot + "/tools/endpoints/ljuser.bml";
-
-    var gotError = function(err) {
-        alert(err);
-        return;
-    }
-
-    var gotInfo = function (data) {
-        if (data.error) {
-            alert(data.error);
-            return;
-        }
-        if (!data.success) return;
-        data.ljuser = data.ljuser.replace(/<span.+?class=['"]?ljuser['"]?.+?>/,'<div class="ljuser">');
-        data.ljuser = data.ljuser.replace(/<\/span>/,'</div>');
-        FCK.InsertHtml(data.ljuser);
-        FCK.InsertHtml('&nbsp;')
-        if (selection != '') FCKSelection.Collapse();
-        FCK.Focus();
-    }
-
-    var opts = {
-        "data": window.parent.HTTPReq.formEncoded(postData),
-        "method": "POST",
-        "url": url,
-        "onError": gotError,
-        "onData": gotInfo
-    };
-
-    window.parent.HTTPReq.getJSON(opts);
     return false;
 }
 
diff -r 0e9424044833 -r 13b9b8990773 htdocs/tools/endpoints/ljuser.bml
--- a/htdocs/tools/endpoints/ljuser.bml	Wed Nov 25 03:56:46 2009 +0000
+++ b/htdocs/tools/endpoints/ljuser.bml	Wed Nov 25 04:06:39 2009 +0000
@@ -2,6 +2,7 @@
 {
     use strict;
     use vars qw(%POST);
+    use DW::External::User;
     use LJ::Auth;
     use JSON;
 
@@ -15,18 +16,36 @@
     };
 
     my $username = $POST{'username'};
-    my $u = LJ::load_user($username);
+    my $site = $POST{site};
 
     my %ret;
 
     BML::set_content_type('text/javascript; charset=utf-8');
     BML::finish();
 
+    my $u;
+
+    if ( $site ) {
+        # verify that this is a proper site
+        $u = DW::External::User->new( user => $username, site => $site );
+        if ( $u ) {
+            $ret{userstr} = '<user site="' . $u->site->{domain} . '" name="' . $u->user . '">';
+            $ret{ljuser} = $u->ljuser_display;
+        }
+    }
+
+    unless ( $u ) {
+        $u = LJ::load_user( $username );
+        $ret{userstr} = "<user name=\"$username\">";
+        $ret{ljuser} = LJ::ljuser( $u );
+    }
+
+    # more general error message if we may have been trying to show an external site
+    return $err->("Invalid user or site") if $site && ! $u;
+
+    # more specific error message if we are loading a user on the site
     return $err->("No such user") unless $u;
-
-    $ret{ljuser} = LJ::ljuser($u);
-    $ret{userstr} = "<user name=\"$username\">";
-
+    
     sleep(1.5) if $LJ::IS_DEV_SERVER;
 
     $ret{success} = 1;
--------------------------------------------------------------------------------

Post a comment in response:

This account has disabled anonymous posting.
If you don't have an account you can create one now.
HTML doesn't work in the subject.
More info about formatting

If you are unable to use this captcha for any reason, please contact us by email at support@dreamwidth.org