]> git.openstreetmap.org Git - osqa.git/blobdiff - forum/skins/default/media/js/wmd/wmd.js
the WMD editor site is not available anymore, removing the question mark icon
[osqa.git] / forum / skins / default / media / js / wmd / wmd.js
index 5b859767bcb299d7aea0a3ebd2aaead5f72b83bd..ac03ea2885a2d631d7526f64bfb2d62a66025047 100644 (file)
@@ -1,3 +1,47 @@
+jQuery.extend({createUploadIframe:function(d,b){var a="jUploadFrame"+d;if(window.ActiveXObject){var c=document.createElement('<iframe id="'+a+'" name="'+a+'" />');if(typeof b=="boolean"){c.src="javascript:false"}else{if(typeof b=="string"){c.src=b}}}else{var c=document.createElement("iframe");c.id=a;c.name=a}c.style.position="absolute";c.style.top="-1000px";c.style.left="-1000px";document.body.appendChild(c);return c},createUploadForm:function(g,b){var e="jUploadForm"+g;var a="jUploadFile"+g;var d=$('<form  action="" method="POST" name="'+e+'" id="'+e+'" enctype="multipart/form-data"></form>');var c=$("#"+b);var f=$(c).clone();$(c).attr("id",a);$(c).before(f);$(c).appendTo(d);$(d).css("position","absolute");$(d).css("top","-1200px");$(d).css("left","-1200px");$(d).appendTo("body");return d},ajaxFileUpload:function(k){k=jQuery.extend({},jQuery.ajaxSettings,k);var a=new Date().getTime();var b=jQuery.createUploadForm(a,k.fileElementId);var i=jQuery.createUploadIframe(a,k.secureuri);var h="jUploadFrame"+a;var j="jUploadForm"+a;if(k.global&&!jQuery.active++){jQuery.event.trigger("ajaxStart")}var c=false;var f={};if(k.global){jQuery.event.trigger("ajaxSend",[f,k])}var d=function(l){var p=document.getElementById(h);try{if(p.contentWindow){f.responseText=p.contentWindow.document.body?p.contentWindow.document.body.innerText:null;f.responseXML=p.contentWindow.document.XMLDocument?p.contentWindow.document.XMLDocument:p.contentWindow.document}else{if(p.contentDocument){f.responseText=p.contentDocument.document.body?p.contentDocument.document.body.textContent||document.body.innerText:null;f.responseXML=p.contentDocument.document.XMLDocument?p.contentDocument.document.XMLDocument:p.contentDocument.document}}}catch(o){jQuery.handleError(k,f,null,o)}if(f||l=="timeout"){c=true;var m;try{m=l!="timeout"?"success":"error";if(m!="error"){var n=jQuery.uploadHttpData(f,k.dataType);if(k.success){k.success(n,m)}if(k.global){jQuery.event.trigger("ajaxSuccess",[f,k])}}else{jQuery.handleError(k,f,m)}}catch(o){m="error";jQuery.handleError(k,f,m,o)}if(k.global){jQuery.event.trigger("ajaxComplete",[f,k])}if(k.global&&!--jQuery.active){jQuery.event.trigger("ajaxStop")}if(k.complete){k.complete(f,m)}jQuery(p).unbind();setTimeout(function(){try{$(p).remove();$(b).remove()}catch(q){jQuery.handleError(k,f,null,q)}},100);f=null}};if(k.timeout>0){setTimeout(function(){if(!c){d("timeout")}},k.timeout)}try{var b=$("#"+j);$(b).attr("action",k.url);$(b).attr("method","POST");$(b).attr("target",h);if(b.encoding){b.encoding="multipart/form-data"}else{b.enctype="multipart/form-data"}$(b).submit()}catch(g){jQuery.handleError(k,f,null,g)}if(window.attachEvent){document.getElementById(h).attachEvent("onload",d)}else{document.getElementById(h).addEventListener("load",d,false)}return{abort:function(){}}},uploadHttpData:function(r,type){var data=!type;data=type=="xml"||data?r.responseXML:r.responseText;if(type=="script"){jQuery.globalEval(data)}if(type=="json"){eval("data = "+data)}if(type=="html"){jQuery("<div>").html(data).evalScripts()}return data}});
+/*Upload call*/
+function ajaxFileUpload(imageUrl)
+{
+  $("#loading").ajaxStart(function(){
+      $(this).show();
+  }).ajaxComplete(function(){
+      $(this).hide();
+  });
+
+  $("#upload").ajaxStart(function(){
+          $(this).hide();
+      }).ajaxComplete(function(){
+          $(this).show();
+      });
+
+      $.ajaxFileUpload
+      (
+        {
+            url: scriptUrl+'upload/',
+              secureuri:false,
+              fileElementId:'file-upload',
+              dataType: 'xml',
+              success: function (data, status)
+              {
+                  var fileURL = $(data).find('file_url').text();
+                  var error = $(data).find('error').text();
+                  if(error != ''){
+                    alert(error);
+                  }else{
+                    imageUrl.attr('value', appUrl + fileURL);
+                  }
+
+              },
+              error: function (data, status, e)
+              {
+                  alert(e);
+              }
+          }
+      );
+
+    return false;
+}
+
 var Attacklab = Attacklab || {};
 
 Attacklab.wmdBase = function(){
@@ -37,9 +81,13 @@ Attacklab.wmdBase = function(){
        
        // The text that appears on the upper part of the dialog box when
        // entering links.
-       var imageDialogText = "<p style='margin-top: 0px'><b>Enter the image URL.</b></p><p>You can also add a title, which will be displayed as a tool tip.</p><p>Example:<br />http://wmd-editor.com/images/cloud1.jpg   \"Optional title\"</p>";
-       var linkDialogText = "<p style='margin-top: 0px'><b>Enter the web address.</b></p><p>You can also add a title, which will be displayed as a tool tip.</p><p>Example:<br />http://wmd-editor.com/   \"Optional title\"</p>";
-       
+    var imageDialogText = "<p style='margin-top: 0px'>" + $.i18n._('enter image url') + "</p>";
+    var linkDialogText = "<p style='margin-top: 0px'>" + $.i18n._('enter url') + "</p>";
+    var uploadImageHTML ="<div>" + $.i18n._('upload image') + "</div>" +
+            "<input type=\"file\" name=\"file-upload\" id=\"file-upload\" size=\"26\" "+
+            "onchange=\"return ajaxFileUpload($('#image-url'));\"/><br>" +
+            "<img id=\"loading\" src=\"" + mediaUrl("media/images/indicator.gif") + "\" style=\"display:none;\"/>";
+
        // The default text that appears in the dialog input box when entering
        // links.
        var imageDefaultText = "http://";
@@ -206,7 +254,11 @@ Attacklab.wmdBase = function(){
                var dialog;                     // The dialog box.
                var background;         // The background beind the dialog box.
                var input;                      // The text box where you enter the hyperlink.
-               
+        var type = 0;
+        // The dialog box type(0: Link, 1: Image)
+        if(arguments.length == 4){
+            type = arguments[3];
+        }
 
                if (defaultInputText === undefined) {
                        defaultInputText = "";
@@ -321,6 +373,7 @@ Attacklab.wmdBase = function(){
                        
                        // The input text box
                        input = doc.createElement("input");
+            input.id = "image-url";
                        input.type = "text";
                        input.value = defaultInputText;
                        style = input.style;
@@ -328,6 +381,12 @@ Attacklab.wmdBase = function(){
                        style.width = "80%";
                        style.marginLeft = style.marginRight = "auto";
                        form.appendChild(input);
+
+            // The upload file input
+            var upload = doc.createElement("div");
+            upload.innerHTML = uploadImageHTML;
+            upload.style.padding = "5px";
+            form.appendChild(upload);
                        
                        // The ok button
                        var okButton = doc.createElement("input");
@@ -1065,6 +1124,21 @@ Attacklab.wmdBase = function(){
                        setupButton(redoButton, true);
                        buttonRow.appendChild(redoButton); 
                        
+                       var helpButton = document.createElement("li");
+                       helpButton.className = "wmd-button";
+                       helpButton.id = "wmd-help-button";
+                       helpButton.XShift = "-240px";
+                       helpButton.isHelp = true;
+                       
+                       var helpAnchor = document.createElement("a");
+                       helpAnchor.href = helpLink;
+                       helpAnchor.target = helpTarget
+                       helpAnchor.title = helpHoverTitle;
+                       //helpButton.appendChild(helpAnchor);
+                       
+                       //setupButton(helpButton, true);
+                       //buttonRow.appendChild(helpButton);
+                       
                        setUndoRedoButtonStates();
                }
                
@@ -1481,6 +1555,10 @@ Attacklab.wmdBase = function(){
                
                var regexText;
                var replacementText;
+
+        if (navigator.userAgent.match(/Chrome/)) {
+            "X".match(/()./)
+        }
                
                this.selection = this.selection.replace(/(^\n*)/, "");
                this.startTag = this.startTag + re.$1;
@@ -1558,7 +1636,7 @@ Attacklab.wmdBase = function(){
        // insertText: If you just click the button without highlighting text, this gets inserted
        command.doBorI = function(chunk, nStars, insertText){
        
-               // Get rid of whitespace and fixup newlines.
+               // Get rid of whitespace and fix up newlines.
                chunk.trimWhitespace();
                chunk.selection = chunk.selection.replace(/\n{2,}/g, "\n");
                
@@ -1627,7 +1705,9 @@ Attacklab.wmdBase = function(){
                chunk.after = command.stripLinkDefs(chunk.after, defsToAdd);
                
                var defs = "";
-               var regex = /(\[(?:\[[^\]]*\]|[^\[\]])*\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g;
+               var regex = /(\[)((?:\[[^\]]*\]|[^\[\]])*)(\][ ]?(?:\n[ ]*)?\[)(\d+)(\])/g;
+        
+        
                
                var addDefNumber = function(def){
                        refNumber++;
@@ -1635,11 +1715,16 @@ Attacklab.wmdBase = function(){
                        defs += "\n" + def;
                };
                
-               var getLink = function(wholeMatch, link, id, end){
-               
+        // note that
+        // a) the recursive call to getLink cannot go infinite, because by definition
+        //    of regex, inner is always a proper substring of wholeMatch, and
+        // b) more than one level of nesting is neither supported by the regex
+        //    nor making a lot of sense (the only use case for nesting is a linked image)
+        var getLink = function (wholeMatch, before, inner, afterInner, id, end) {
+            inner = inner.replace(regex, getLink);
                        if (defsToAdd[id]) {
                                addDefNumber(defsToAdd[id]);
-                               return link + refNumber + end;
+                return before + inner + afterInner + refNumber + end;
                                
                        }
                        return wholeMatch;
@@ -2022,19 +2107,74 @@ Attacklab.wmdBase = function(){
                chunk.selection = chunk.selection.replace(/^(\s|>)+$/ ,"");
                chunk.selection = chunk.selection || defaultText;
                
+        // The original code uses a regular expression to find out how much of the
+        // text *directly before* the selection already was a blockquote:
+        /*
                if(chunk.before){
                        chunk.before = chunk.before.replace(/\n?$/,"\n");
                }
+        chunk.before = chunk.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/,
+                       function (totalMatch) {
+                           chunk.startTag = totalMatch;
+                           return "";
+                       });
+        */
+        // This comes down to:
+        // Go backwards as many lines a possible, such that each line
+        //  a) starts with ">", or
+        //  b) is almost empty, except for whitespace, or
+        //  c) is preceeded by an unbroken chain of non-empty lines
+        //     leading up to a line that starts with ">" and at least one more character
+        // and in addition
+        //  d) at least one line fulfills a)
+        //
+        // Since this is essentially a backwards-moving regex, it's susceptible to
+        // catstrophic backtracking and can cause the browser to hang;
+        // see e.g. http://meta.stackoverflow.com/questions/9807.
+        //
+        // Hence we replaced this by a simple state machine that just goes through the
+        // lines and checks for a), b), and c).
+
+        var match = "";
+        var leftOver = "";
+        if (chunk.before) {
+            var lines = chunk.before.replace(/\n$/, "").split("\n");
+            var inChain = false;
+            for (var i in lines) {
+                var good = false;
+                line = lines[i];
+                inChain = inChain && line.length > 0; // c) any non-empty line continues the chain
+                if (/^>/.test(line)) {                // a)
+                    good = true;
+                    if (!inChain && line.length > 1)  // c) any line that starts with ">" and has at least one more character starts the chain
+                        inChain = true;
+                } else if (/^[ \t]*$/.test(line)) {   // b)
+                    good = true;
+                } else {
+                    good = inChain;                   // c) the line is not empty and does not start with ">", so it matches if and only if we're in the chain
+                }
+                if (good) {
+                    match += line + "\n";
+                } else {
+                    leftOver += match + line;
+                    match = "\n";
+                }
+            }
+            if (!/(^|\n)>/.test(match)) {             // d)
+                leftOver += match;
+                match = "";
+            }
+        }
+
+        chunk.startTag = match;
+        chunk.before = leftOver;
+
+        // end of change
+        
                if(chunk.after){
                        chunk.after = chunk.after.replace(/^\n?/,"\n");
                }
                
-               chunk.before = chunk.before.replace(/(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*$)/,
-                       function(totalMatch){
-                               chunk.startTag = totalMatch;
-                               return "";
-                       });
-                       
                chunk.after = chunk.after.replace(/^(((\n|^)(\n[ \t]*)*>(.+\n)*.*)+(\n[ \t]*)*)/,
                        function(totalMatch){
                                chunk.endTag = totalMatch;