textile_editor_helper 0.0.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +20 -0
 - data/Gemfile +5 -0
 - data/README.md +130 -0
 - data/Rakefile +7 -0
 - data/features/copy_assets.feature +17 -0
 - data/features/step_definitions/common_steps.rb +66 -0
 - data/features/step_definitions/rails_setup_steps.rb +9 -0
 - data/features/support/env.rb +0 -0
 - data/features/support/setup.rb +0 -0
 - data/lib/generators/textile_editor_helper/install_generator.rb +54 -0
 - data/lib/textile_editor_helper.rb +204 -0
 - data/lib/textile_editor_helper/version.rb +3 -0
 - data/test/abstract_unit.rb +16 -0
 - data/test/textile_editor_helper_test.rb +195 -0
 - data/textile_editor_helper.gemspec +27 -0
 - data/travis.yml +5 -0
 - data/vendor/README +95 -0
 - data/vendor/app/controllers/textile_preview_controller.rb +14 -0
 - data/vendor/app/helpers/textile_preview_helper.rb +14 -0
 - data/vendor/app/views/textile_preview/show.js.coffee +2 -0
 - data/vendor/assets/images/textile-editor/background.png +0 -0
 - data/vendor/assets/images/textile-editor/blockquote.png +0 -0
 - data/vendor/assets/images/textile-editor/bold.png +0 -0
 - data/vendor/assets/images/textile-editor/center.png +0 -0
 - data/vendor/assets/images/textile-editor/h1.png +0 -0
 - data/vendor/assets/images/textile-editor/h2.png +0 -0
 - data/vendor/assets/images/textile-editor/h3.png +0 -0
 - data/vendor/assets/images/textile-editor/h4.png +0 -0
 - data/vendor/assets/images/textile-editor/h5.png +0 -0
 - data/vendor/assets/images/textile-editor/h6.png +0 -0
 - data/vendor/assets/images/textile-editor/indent.png +0 -0
 - data/vendor/assets/images/textile-editor/italic.png +0 -0
 - data/vendor/assets/images/textile-editor/justify.png +0 -0
 - data/vendor/assets/images/textile-editor/left.png +0 -0
 - data/vendor/assets/images/textile-editor/list_bullets.png +0 -0
 - data/vendor/assets/images/textile-editor/list_numbers.png +0 -0
 - data/vendor/assets/images/textile-editor/omega.png +0 -0
 - data/vendor/assets/images/textile-editor/outdent.png +0 -0
 - data/vendor/assets/images/textile-editor/paragraph.png +0 -0
 - data/vendor/assets/images/textile-editor/right.png +0 -0
 - data/vendor/assets/images/textile-editor/strikethrough.png +0 -0
 - data/vendor/assets/images/textile-editor/underline.png +0 -0
 - data/vendor/assets/javascripts/textile-editor-config.js +22 -0
 - data/vendor/assets/javascripts/textile-editor.js +687 -0
 - data/vendor/assets/stylesheets/textile-editor.css +53 -0
 - metadata +186 -0
 
| 
         @@ -0,0 +1,687 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            /*
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            Textile Editor v0.2
         
     | 
| 
      
 4 
     | 
    
         
            +
            created by: dave olsen, wvu web services
         
     | 
| 
      
 5 
     | 
    
         
            +
            created on: march 17, 2007
         
     | 
| 
      
 6 
     | 
    
         
            +
            project page: slateinfo.blogs.wvu.edu
         
     | 
| 
      
 7 
     | 
    
         
            +
             
     | 
| 
      
 8 
     | 
    
         
            +
            inspired by: 
         
     | 
| 
      
 9 
     | 
    
         
            +
             - Patrick Woods, http://www.hakjoon.com/code/38/textile-quicktags-redirect & 
         
     | 
| 
      
 10 
     | 
    
         
            +
             - Alex King, http://alexking.org/projects/js-quicktags
         
     | 
| 
      
 11 
     | 
    
         
            +
             
     | 
| 
      
 12 
     | 
    
         
            +
            features:
         
     | 
| 
      
 13 
     | 
    
         
            +
             - supports: IE7, FF2, Safari2
         
     | 
| 
      
 14 
     | 
    
         
            +
             - ability to use "simple" vs. "extended" editor
         
     | 
| 
      
 15 
     | 
    
         
            +
             - supports all block elements in textile except footnote
         
     | 
| 
      
 16 
     | 
    
         
            +
             - supports all block modifier elements in textile
         
     | 
| 
      
 17 
     | 
    
         
            +
             - supports simple ordered and unordered lists
         
     | 
| 
      
 18 
     | 
    
         
            +
             - supports most of the phrase modifiers, very easy to add the missing ones
         
     | 
| 
      
 19 
     | 
    
         
            +
             - supports multiple-paragraph modification
         
     | 
| 
      
 20 
     | 
    
         
            +
             - can have multiple "editors" on one page, access key use in this environment is flaky
         
     | 
| 
      
 21 
     | 
    
         
            +
             - access key support
         
     | 
| 
      
 22 
     | 
    
         
            +
             - select text to add and remove tags, selection stays highlighted
         
     | 
| 
      
 23 
     | 
    
         
            +
             - seamlessly change between tags and modifiers
         
     | 
| 
      
 24 
     | 
    
         
            +
             - doesn't need to be in the body onload tag
         
     | 
| 
      
 25 
     | 
    
         
            +
             - can supply your own, custom IDs for the editor to be drawn around
         
     | 
| 
      
 26 
     | 
    
         
            +
             
     | 
| 
      
 27 
     | 
    
         
            +
            todo:
         
     | 
| 
      
 28 
     | 
    
         
            +
             - a clean way of providing image and link inserts
         
     | 
| 
      
 29 
     | 
    
         
            +
             - get the selection to properly show in IE
         
     | 
| 
      
 30 
     | 
    
         
            +
             
     | 
| 
      
 31 
     | 
    
         
            +
            more on textile:
         
     | 
| 
      
 32 
     | 
    
         
            +
             - Textism, http://www.textism.com/tools/textile/index.php
         
     | 
| 
      
 33 
     | 
    
         
            +
             - Textile Reference, http://hobix.com/textile/
         
     | 
| 
      
 34 
     | 
    
         
            +
             
     | 
| 
      
 35 
     | 
    
         
            +
            */
         
     | 
| 
      
 36 
     | 
    
         
            +
             
     | 
| 
      
 37 
     | 
    
         
            +
            // Define Button Object
         
     | 
| 
      
 38 
     | 
    
         
            +
            function TextileEditorButton(id, display, tagStart, tagEnd, access, title, sve, open) {
         
     | 
| 
      
 39 
     | 
    
         
            +
              this.id = id;       // used to name the toolbar button
         
     | 
| 
      
 40 
     | 
    
         
            +
              this.display = display;   // label on button
         
     | 
| 
      
 41 
     | 
    
         
            +
              this.tagStart = tagStart;   // open tag
         
     | 
| 
      
 42 
     | 
    
         
            +
              this.tagEnd = tagEnd;   // close tag
         
     | 
| 
      
 43 
     | 
    
         
            +
              this.access = access;   // set to -1 if tag does not need to be closed
         
     | 
| 
      
 44 
     | 
    
         
            +
              this.title = title;     // sets the title attribute of the button to give 'tool tips'
         
     | 
| 
      
 45 
     | 
    
         
            +
              this.sve = sve;       // sve = simple vs. extended. add an 's' to make it show up in the simple toolbar
         
     | 
| 
      
 46 
     | 
    
         
            +
              this.open = open;     // set to -1 if tag does not need to be closed
         
     | 
| 
      
 47 
     | 
    
         
            +
              this.standard = true;  // this is a standard button
         
     | 
| 
      
 48 
     | 
    
         
            +
              // this.framework = 'prototype'; // the JS framework used
         
     | 
| 
      
 49 
     | 
    
         
            +
            }
         
     | 
| 
      
 50 
     | 
    
         
            +
             
     | 
| 
      
 51 
     | 
    
         
            +
            function TextileEditorButtonSeparator(sve) {
         
     | 
| 
      
 52 
     | 
    
         
            +
              this.separator = true;
         
     | 
| 
      
 53 
     | 
    
         
            +
              this.sve = sve;
         
     | 
| 
      
 54 
     | 
    
         
            +
            }
         
     | 
| 
      
 55 
     | 
    
         
            +
             
     | 
| 
      
 56 
     | 
    
         
            +
            var TextileEditor = function() {};
         
     | 
| 
      
 57 
     | 
    
         
            +
            TextileEditor.buttons = new Array();
         
     | 
| 
      
 58 
     | 
    
         
            +
            TextileEditor.Methods = {
         
     | 
| 
      
 59 
     | 
    
         
            +
              // class methods
         
     | 
| 
      
 60 
     | 
    
         
            +
             
     | 
| 
      
 61 
     | 
    
         
            +
              // create the toolbar (edToolbar)
         
     | 
| 
      
 62 
     | 
    
         
            +
              initialize: function(canvas, view) {
         
     | 
| 
      
 63 
     | 
    
         
            +
                var toolbar = document.createElement("div");
         
     | 
| 
      
 64 
     | 
    
         
            +
                toolbar.id = "textile-toolbar-" + canvas;
         
     | 
| 
      
 65 
     | 
    
         
            +
                toolbar.className = 'textile-toolbar';
         
     | 
| 
      
 66 
     | 
    
         
            +
                
         
     | 
| 
      
 67 
     | 
    
         
            +
                this.canvas = document.getElementById(canvas);
         
     | 
| 
      
 68 
     | 
    
         
            +
                this.canvas.parentNode.insertBefore(toolbar, this.canvas); 
         
     | 
| 
      
 69 
     | 
    
         
            +
                this.openTags = new Array();      
         
     | 
| 
      
 70 
     | 
    
         
            +
             
     | 
| 
      
 71 
     | 
    
         
            +
             
     | 
| 
      
 72 
     | 
    
         
            +
                // Create the local Button array by assigning theButtons array to edButtons
         
     | 
| 
      
 73 
     | 
    
         
            +
                var edButtons = new Array();
         
     | 
| 
      
 74 
     | 
    
         
            +
                edButtons = this.buttons;
         
     | 
| 
      
 75 
     | 
    
         
            +
                
         
     | 
| 
      
 76 
     | 
    
         
            +
                var standardButtons = new Array();
         
     | 
| 
      
 77 
     | 
    
         
            +
                for(var i = 0; i < edButtons.length; i++) {
         
     | 
| 
      
 78 
     | 
    
         
            +
                  var thisButton = this.prepareButton(edButtons[i]);
         
     | 
| 
      
 79 
     | 
    
         
            +
                  if (view == 's') {
         
     | 
| 
      
 80 
     | 
    
         
            +
                    if (edButtons[i].sve == 's') {
         
     | 
| 
      
 81 
     | 
    
         
            +
                      toolbar.appendChild(thisButton);
         
     | 
| 
      
 82 
     | 
    
         
            +
                      standardButtons.push(thisButton);
         
     | 
| 
      
 83 
     | 
    
         
            +
                    }
         
     | 
| 
      
 84 
     | 
    
         
            +
                  } else {
         
     | 
| 
      
 85 
     | 
    
         
            +
                    if (typeof thisButton == 'string') {
         
     | 
| 
      
 86 
     | 
    
         
            +
                      toolbar.innerHTML += thisButton;
         
     | 
| 
      
 87 
     | 
    
         
            +
                    } else {
         
     | 
| 
      
 88 
     | 
    
         
            +
                      toolbar.appendChild(thisButton);
         
     | 
| 
      
 89 
     | 
    
         
            +
                      standardButtons.push(thisButton);
         
     | 
| 
      
 90 
     | 
    
         
            +
                    }
         
     | 
| 
      
 91 
     | 
    
         
            +
                  }
         
     | 
| 
      
 92 
     | 
    
         
            +
                } // end for
         
     | 
| 
      
 93 
     | 
    
         
            +
                
         
     | 
| 
      
 94 
     | 
    
         
            +
                var te = this;
         
     | 
| 
      
 95 
     | 
    
         
            +
                var buttons = toolbar.getElementsByTagName('button');
         
     | 
| 
      
 96 
     | 
    
         
            +
                for(var i = 0; i < buttons.length; i++) {
         
     | 
| 
      
 97 
     | 
    
         
            +
                //$A(toolbar.getElementsByTagName('button')).each(function(button) {
         
     | 
| 
      
 98 
     | 
    
         
            +
                  if (!buttons[i].onclick) {
         
     | 
| 
      
 99 
     | 
    
         
            +
                    buttons[i].onclick = function() { te.insertTag(this); return false; }
         
     | 
| 
      
 100 
     | 
    
         
            +
                  } // end if
         
     | 
| 
      
 101 
     | 
    
         
            +
                  
         
     | 
| 
      
 102 
     | 
    
         
            +
                  buttons[i].tagStart = buttons[i].getAttribute('tagStart');
         
     | 
| 
      
 103 
     | 
    
         
            +
                  buttons[i].tagEnd = buttons[i].getAttribute('tagEnd');
         
     | 
| 
      
 104 
     | 
    
         
            +
                  buttons[i].open = buttons[i].getAttribute('open');
         
     | 
| 
      
 105 
     | 
    
         
            +
                  buttons[i].textile_editor = te;
         
     | 
| 
      
 106 
     | 
    
         
            +
                  buttons[i].canvas = te.canvas;
         
     | 
| 
      
 107 
     | 
    
         
            +
                  // console.log(buttons[i].canvas);
         
     | 
| 
      
 108 
     | 
    
         
            +
                //});
         
     | 
| 
      
 109 
     | 
    
         
            +
                }
         
     | 
| 
      
 110 
     | 
    
         
            +
              }, // end initialize
         
     | 
| 
      
 111 
     | 
    
         
            +
              
         
     | 
| 
      
 112 
     | 
    
         
            +
              // draw individual buttons (edShowButton)
         
     | 
| 
      
 113 
     | 
    
         
            +
              prepareButton: function(button) {
         
     | 
| 
      
 114 
     | 
    
         
            +
                if (button.separator) {
         
     | 
| 
      
 115 
     | 
    
         
            +
                  var theButton = document.createElement('span');
         
     | 
| 
      
 116 
     | 
    
         
            +
                  theButton.className = 'ed_sep';
         
     | 
| 
      
 117 
     | 
    
         
            +
                  return theButton;
         
     | 
| 
      
 118 
     | 
    
         
            +
                }
         
     | 
| 
      
 119 
     | 
    
         
            +
             
     | 
| 
      
 120 
     | 
    
         
            +
                if (button.standard) {
         
     | 
| 
      
 121 
     | 
    
         
            +
                  var theButton = document.createElement("button");
         
     | 
| 
      
 122 
     | 
    
         
            +
                  theButton.id = button.id;
         
     | 
| 
      
 123 
     | 
    
         
            +
                  theButton.setAttribute('class', 'standard');
         
     | 
| 
      
 124 
     | 
    
         
            +
                  theButton.setAttribute('tagStart', button.tagStart);
         
     | 
| 
      
 125 
     | 
    
         
            +
                  theButton.setAttribute('tagEnd', button.tagEnd);
         
     | 
| 
      
 126 
     | 
    
         
            +
                  theButton.setAttribute('open', button.open);
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                  var img = document.createElement('img');
         
     | 
| 
      
 129 
     | 
    
         
            +
                  img.src = '/images/textile-editor/' + button.display;
         
     | 
| 
      
 130 
     | 
    
         
            +
                  theButton.appendChild(img);
         
     | 
| 
      
 131 
     | 
    
         
            +
                } else {
         
     | 
| 
      
 132 
     | 
    
         
            +
                  return button;
         
     | 
| 
      
 133 
     | 
    
         
            +
                } // end if !custom
         
     | 
| 
      
 134 
     | 
    
         
            +
             
     | 
| 
      
 135 
     | 
    
         
            +
                theButton.accessKey = button.access;
         
     | 
| 
      
 136 
     | 
    
         
            +
                theButton.title = button.title;
         
     | 
| 
      
 137 
     | 
    
         
            +
                return theButton; 
         
     | 
| 
      
 138 
     | 
    
         
            +
              }, // end prepareButton
         
     | 
| 
      
 139 
     | 
    
         
            +
              
         
     | 
| 
      
 140 
     | 
    
         
            +
              // if clicked, no selected text, tag not open highlight button
         
     | 
| 
      
 141 
     | 
    
         
            +
              // (edAddTag)
         
     | 
| 
      
 142 
     | 
    
         
            +
              addTag: function(button) {
         
     | 
| 
      
 143 
     | 
    
         
            +
                if (button.tagEnd != '') {
         
     | 
| 
      
 144 
     | 
    
         
            +
                  this.openTags[this.openTags.length] = button;
         
     | 
| 
      
 145 
     | 
    
         
            +
                  //var el = document.getElementById(button.id);
         
     | 
| 
      
 146 
     | 
    
         
            +
                  //el.className = 'selected';
         
     | 
| 
      
 147 
     | 
    
         
            +
                  button.className = 'selected';
         
     | 
| 
      
 148 
     | 
    
         
            +
                }
         
     | 
| 
      
 149 
     | 
    
         
            +
              }, // end addTag
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
      
 151 
     | 
    
         
            +
              // if clicked, no selected text, tag open lowlight button
         
     | 
| 
      
 152 
     | 
    
         
            +
              // (edRemoveTag)
         
     | 
| 
      
 153 
     | 
    
         
            +
              removeTag: function(button) {
         
     | 
| 
      
 154 
     | 
    
         
            +
                for (i = 0; i < this.openTags.length; i++) {
         
     | 
| 
      
 155 
     | 
    
         
            +
                  if (this.openTags[i] == button) {
         
     | 
| 
      
 156 
     | 
    
         
            +
                    this.openTags.splice(button, 1);
         
     | 
| 
      
 157 
     | 
    
         
            +
                    //var el = document.getElementById(button.id);
         
     | 
| 
      
 158 
     | 
    
         
            +
                    //el.className = 'unselected';
         
     | 
| 
      
 159 
     | 
    
         
            +
                    button.className = 'unselected';
         
     | 
| 
      
 160 
     | 
    
         
            +
                  }
         
     | 
| 
      
 161 
     | 
    
         
            +
                }
         
     | 
| 
      
 162 
     | 
    
         
            +
              }, // end removeTag
         
     | 
| 
      
 163 
     | 
    
         
            +
             
     | 
| 
      
 164 
     | 
    
         
            +
              // see if there are open tags. for the remove tag bit...
         
     | 
| 
      
 165 
     | 
    
         
            +
              // (edCheckOpenTags)
         
     | 
| 
      
 166 
     | 
    
         
            +
              checkOpenTags: function(button) {
         
     | 
| 
      
 167 
     | 
    
         
            +
                var tag = 0;
         
     | 
| 
      
 168 
     | 
    
         
            +
                for (i = 0; i < this.openTags.length; i++) {
         
     | 
| 
      
 169 
     | 
    
         
            +
                  if (this.openTags[i] == button) {
         
     | 
| 
      
 170 
     | 
    
         
            +
                    tag++;
         
     | 
| 
      
 171 
     | 
    
         
            +
                  }
         
     | 
| 
      
 172 
     | 
    
         
            +
                }
         
     | 
| 
      
 173 
     | 
    
         
            +
                if (tag > 0) {
         
     | 
| 
      
 174 
     | 
    
         
            +
                  return true; // tag found
         
     | 
| 
      
 175 
     | 
    
         
            +
                }
         
     | 
| 
      
 176 
     | 
    
         
            +
                else {
         
     | 
| 
      
 177 
     | 
    
         
            +
                  return false; // tag not found
         
     | 
| 
      
 178 
     | 
    
         
            +
                }
         
     | 
| 
      
 179 
     | 
    
         
            +
              }, // end checkOpenTags
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
              // insert the tag. this is the bulk of the code.
         
     | 
| 
      
 182 
     | 
    
         
            +
              // (edInsertTag)
         
     | 
| 
      
 183 
     | 
    
         
            +
              insertTag: function(button, tagStart, tagEnd) {
         
     | 
| 
      
 184 
     | 
    
         
            +
                // console.log(button);
         
     | 
| 
      
 185 
     | 
    
         
            +
                var myField = button.canvas;
         
     | 
| 
      
 186 
     | 
    
         
            +
                myField.focus();
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                if (tagStart) {
         
     | 
| 
      
 189 
     | 
    
         
            +
                  button.tagStart = tagStart;
         
     | 
| 
      
 190 
     | 
    
         
            +
                  button.tagEnd = tagEnd ? tagEnd : '\n';
         
     | 
| 
      
 191 
     | 
    
         
            +
                }
         
     | 
| 
      
 192 
     | 
    
         
            +
             
     | 
| 
      
 193 
     | 
    
         
            +
                var textSelected = false;
         
     | 
| 
      
 194 
     | 
    
         
            +
                var finalText = '';
         
     | 
| 
      
 195 
     | 
    
         
            +
                var FF = false;
         
     | 
| 
      
 196 
     | 
    
         
            +
             
     | 
| 
      
 197 
     | 
    
         
            +
                // grab the text that's going to be manipulated, by browser
         
     | 
| 
      
 198 
     | 
    
         
            +
                if (document.selection) { // IE support
         
     | 
| 
      
 199 
     | 
    
         
            +
                  sel = document.selection.createRange();
         
     | 
| 
      
 200 
     | 
    
         
            +
             
     | 
| 
      
 201 
     | 
    
         
            +
                  // set-up the text vars
         
     | 
| 
      
 202 
     | 
    
         
            +
                  var beginningText = '';
         
     | 
| 
      
 203 
     | 
    
         
            +
                  var followupText = '';
         
     | 
| 
      
 204 
     | 
    
         
            +
                  var selectedText = sel.text;
         
     | 
| 
      
 205 
     | 
    
         
            +
             
     | 
| 
      
 206 
     | 
    
         
            +
                  // check if text has been selected
         
     | 
| 
      
 207 
     | 
    
         
            +
                  if (sel.text.length > 0) {
         
     | 
| 
      
 208 
     | 
    
         
            +
                    textSelected = true;  
         
     | 
| 
      
 209 
     | 
    
         
            +
                  }
         
     | 
| 
      
 210 
     | 
    
         
            +
             
     | 
| 
      
 211 
     | 
    
         
            +
                  // set-up newline regex's so we can swap tags across multiple paragraphs
         
     | 
| 
      
 212 
     | 
    
         
            +
                  var newlineReplaceRegexClean = /\r\n\s\n/g;
         
     | 
| 
      
 213 
     | 
    
         
            +
                  var newlineReplaceRegexDirty = '\\r\\n\\s\\n';
         
     | 
| 
      
 214 
     | 
    
         
            +
                  var newlineReplaceClean = '\r\n\n';
         
     | 
| 
      
 215 
     | 
    
         
            +
                }
         
     | 
| 
      
 216 
     | 
    
         
            +
                else if (myField.selectionStart || myField.selectionStart == '0') { // MOZ/FF/NS/S support
         
     | 
| 
      
 217 
     | 
    
         
            +
             
     | 
| 
      
 218 
     | 
    
         
            +
                  // figure out cursor and selection positions
         
     | 
| 
      
 219 
     | 
    
         
            +
                  var startPos = myField.selectionStart;
         
     | 
| 
      
 220 
     | 
    
         
            +
                  var endPos = myField.selectionEnd;
         
     | 
| 
      
 221 
     | 
    
         
            +
                  var cursorPos = endPos;
         
     | 
| 
      
 222 
     | 
    
         
            +
                  var scrollTop = myField.scrollTop;
         
     | 
| 
      
 223 
     | 
    
         
            +
                  FF = true; // note that is is a FF/MOZ/NS/S browser
         
     | 
| 
      
 224 
     | 
    
         
            +
             
     | 
| 
      
 225 
     | 
    
         
            +
                  // set-up the text vars
         
     | 
| 
      
 226 
     | 
    
         
            +
                  var beginningText = myField.value.substring(0, startPos);
         
     | 
| 
      
 227 
     | 
    
         
            +
                  var followupText = myField.value.substring(endPos, myField.value.length);
         
     | 
| 
      
 228 
     | 
    
         
            +
             
     | 
| 
      
 229 
     | 
    
         
            +
                  // check if text has been selected
         
     | 
| 
      
 230 
     | 
    
         
            +
                  if (startPos != endPos) {
         
     | 
| 
      
 231 
     | 
    
         
            +
                    textSelected = true;
         
     | 
| 
      
 232 
     | 
    
         
            +
                    var selectedText = myField.value.substring(startPos, endPos); 
         
     | 
| 
      
 233 
     | 
    
         
            +
                  }
         
     | 
| 
      
 234 
     | 
    
         
            +
             
     | 
| 
      
 235 
     | 
    
         
            +
                  // set-up newline regex's so we can swap tags across multiple paragraphs
         
     | 
| 
      
 236 
     | 
    
         
            +
                  var newlineReplaceRegexClean = /\n\n/g;
         
     | 
| 
      
 237 
     | 
    
         
            +
                  var newlineReplaceRegexDirty = '\\n\\n';
         
     | 
| 
      
 238 
     | 
    
         
            +
                  var newlineReplaceClean = '\n\n';
         
     | 
| 
      
 239 
     | 
    
         
            +
                }
         
     | 
| 
      
 240 
     | 
    
         
            +
             
     | 
| 
      
 241 
     | 
    
         
            +
             
     | 
| 
      
 242 
     | 
    
         
            +
                // if there is text that has been highlighted...
         
     | 
| 
      
 243 
     | 
    
         
            +
                if (textSelected) {
         
     | 
| 
      
 244 
     | 
    
         
            +
             
     | 
| 
      
 245 
     | 
    
         
            +
                  // set-up some defaults for how to handle bad new line characters
         
     | 
| 
      
 246 
     | 
    
         
            +
                  var newlineStart = '';
         
     | 
| 
      
 247 
     | 
    
         
            +
                  var newlineStartPos = 0;
         
     | 
| 
      
 248 
     | 
    
         
            +
                  var newlineEnd = '';
         
     | 
| 
      
 249 
     | 
    
         
            +
                  var newlineEndPos = 0;
         
     | 
| 
      
 250 
     | 
    
         
            +
                  var newlineFollowup = '';
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                  // set-up some defaults for how to handle placing the beginning and end of selection
         
     | 
| 
      
 253 
     | 
    
         
            +
                  var posDiffPos = 0;
         
     | 
| 
      
 254 
     | 
    
         
            +
                  var posDiffNeg = 0;
         
     | 
| 
      
 255 
     | 
    
         
            +
                  var mplier = 1;
         
     | 
| 
      
 256 
     | 
    
         
            +
             
     | 
| 
      
 257 
     | 
    
         
            +
                  // remove newline from the beginning of the selectedText.
         
     | 
| 
      
 258 
     | 
    
         
            +
                  if (selectedText.match(/^\n/)) {
         
     | 
| 
      
 259 
     | 
    
         
            +
                    selectedText = selectedText.replace(/^\n/,'');
         
     | 
| 
      
 260 
     | 
    
         
            +
                    newlineStart = '\n';
         
     | 
| 
      
 261 
     | 
    
         
            +
                    newlineStartpos = 1;
         
     | 
| 
      
 262 
     | 
    
         
            +
                  }
         
     | 
| 
      
 263 
     | 
    
         
            +
             
     | 
| 
      
 264 
     | 
    
         
            +
                  // remove newline from the end of the selectedText.
         
     | 
| 
      
 265 
     | 
    
         
            +
                  if (selectedText.match(/\n$/g)) {
         
     | 
| 
      
 266 
     | 
    
         
            +
                    selectedText = selectedText.replace(/\n$/g,'');
         
     | 
| 
      
 267 
     | 
    
         
            +
                    newlineEnd = '\n';
         
     | 
| 
      
 268 
     | 
    
         
            +
                    newlineEndPos = 1;
         
     | 
| 
      
 269 
     | 
    
         
            +
                  }
         
     | 
| 
      
 270 
     | 
    
         
            +
             
     | 
| 
      
 271 
     | 
    
         
            +
                  // remove space from the end of the selectedText.
         
     | 
| 
      
 272 
     | 
    
         
            +
                  // Fixes a bug that causes any browser running under Microsoft Internet Explorer 
         
     | 
| 
      
 273 
     | 
    
         
            +
                  // to append an additional space before the closing element.
         
     | 
| 
      
 274 
     | 
    
         
            +
                  // *Bold text *here => *Bold text*
         
     | 
| 
      
 275 
     | 
    
         
            +
                  if (selectedText.match(/\s$/g)) {
         
     | 
| 
      
 276 
     | 
    
         
            +
                    selectedText = selectedText.replace(/\s$/g,'');
         
     | 
| 
      
 277 
     | 
    
         
            +
                    followupText = ' ';
         
     | 
| 
      
 278 
     | 
    
         
            +
                  }
         
     | 
| 
      
 279 
     | 
    
         
            +
                  
         
     | 
| 
      
 280 
     | 
    
         
            +
                  // no clue, i'm sure it made sense at the time i wrote it
         
     | 
| 
      
 281 
     | 
    
         
            +
                  if (followupText.match(/^\n/)) {
         
     | 
| 
      
 282 
     | 
    
         
            +
                    newlineFollowup = '';
         
     | 
| 
      
 283 
     | 
    
         
            +
                  }
         
     | 
| 
      
 284 
     | 
    
         
            +
                  else {
         
     | 
| 
      
 285 
     | 
    
         
            +
                    newlineFollowup = '\n\n';
         
     | 
| 
      
 286 
     | 
    
         
            +
                  }
         
     | 
| 
      
 287 
     | 
    
         
            +
             
     | 
| 
      
 288 
     | 
    
         
            +
                  // first off let's check if the user is trying to mess with lists
         
     | 
| 
      
 289 
     | 
    
         
            +
                  if ((button.tagStart == ' * ') || (button.tagStart == ' # ')) {
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                    listItems = 0; // sets up a default to be able to properly manipulate final selection
         
     | 
| 
      
 292 
     | 
    
         
            +
             
     | 
| 
      
 293 
     | 
    
         
            +
                    // set-up all of the regex's
         
     | 
| 
      
 294 
     | 
    
         
            +
                    re_start = new RegExp('^ (\\*|\\#) ','g');
         
     | 
| 
      
 295 
     | 
    
         
            +
                    if (button.tagStart == ' # ') {
         
     | 
| 
      
 296 
     | 
    
         
            +
                      re_tag = new RegExp(' \\# ','g'); // because of JS regex stupidity i need an if/else to properly set it up, could have done it with a regex replace though
         
     | 
| 
      
 297 
     | 
    
         
            +
                    }
         
     | 
| 
      
 298 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 299 
     | 
    
         
            +
                      re_tag = new RegExp(' \\* ','g');
         
     | 
| 
      
 300 
     | 
    
         
            +
                    }
         
     | 
| 
      
 301 
     | 
    
         
            +
                    re_replace = new RegExp(' (\\*|\\#) ','g');
         
     | 
| 
      
 302 
     | 
    
         
            +
             
     | 
| 
      
 303 
     | 
    
         
            +
                    // try to remove bullets in text copied from ms word **Mac Only!** 
         
     | 
| 
      
 304 
     | 
    
         
            +
                    re_word_bullet_m_s = new RegExp('• ','g'); // mac/safari
         
     | 
| 
      
 305 
     | 
    
         
            +
                    re_word_bullet_m_f = new RegExp('∑ ','g'); // mac/firefox
         
     | 
| 
      
 306 
     | 
    
         
            +
                    selectedText = selectedText.replace(re_word_bullet_m_s,'').replace(re_word_bullet_m_f,'');
         
     | 
| 
      
 307 
     | 
    
         
            +
             
     | 
| 
      
 308 
     | 
    
         
            +
                    // if the selected text starts with one of the tags we're working with...
         
     | 
| 
      
 309 
     | 
    
         
            +
                    if (selectedText.match(re_start)) {
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
      
 311 
     | 
    
         
            +
                      // if tag that begins the selection matches the one clicked, remove them all
         
     | 
| 
      
 312 
     | 
    
         
            +
                      if (selectedText.match(re_tag)) {
         
     | 
| 
      
 313 
     | 
    
         
            +
                        finalText = beginningText
         
     | 
| 
      
 314 
     | 
    
         
            +
                                + newlineStart
         
     | 
| 
      
 315 
     | 
    
         
            +
                                + selectedText.replace(re_replace,'')
         
     | 
| 
      
 316 
     | 
    
         
            +
                                + newlineEnd
         
     | 
| 
      
 317 
     | 
    
         
            +
                                + followupText;
         
     | 
| 
      
 318 
     | 
    
         
            +
                        if (matches = selectedText.match(/ (\*|\#) /g)) {
         
     | 
| 
      
 319 
     | 
    
         
            +
                          listItems = matches.length;
         
     | 
| 
      
 320 
     | 
    
         
            +
                        }
         
     | 
| 
      
 321 
     | 
    
         
            +
                        posDiffNeg = listItems*3; // how many list items were there because that's 3 spaces to remove from final selection
         
     | 
| 
      
 322 
     | 
    
         
            +
                      }
         
     | 
| 
      
 323 
     | 
    
         
            +
             
     | 
| 
      
 324 
     | 
    
         
            +
                      // else replace the current tag type with the selected tag type
         
     | 
| 
      
 325 
     | 
    
         
            +
                      else {
         
     | 
| 
      
 326 
     | 
    
         
            +
                        finalText = beginningText
         
     | 
| 
      
 327 
     | 
    
         
            +
                                + newlineStart
         
     | 
| 
      
 328 
     | 
    
         
            +
                                + selectedText.replace(re_replace,button.tagStart)
         
     | 
| 
      
 329 
     | 
    
         
            +
                                + newlineEnd
         
     | 
| 
      
 330 
     | 
    
         
            +
                                + followupText;
         
     | 
| 
      
 331 
     | 
    
         
            +
                      }
         
     | 
| 
      
 332 
     | 
    
         
            +
                    }
         
     | 
| 
      
 333 
     | 
    
         
            +
             
     | 
| 
      
 334 
     | 
    
         
            +
                    // else try to create the list type
         
     | 
| 
      
 335 
     | 
    
         
            +
                    // NOTE: the items in a list will only be replaced if a newline starts with some character, not a space
         
     | 
| 
      
 336 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 337 
     | 
    
         
            +
                      finalText = beginningText
         
     | 
| 
      
 338 
     | 
    
         
            +
                              + newlineStart
         
     | 
| 
      
 339 
     | 
    
         
            +
                                    + button.tagStart
         
     | 
| 
      
 340 
     | 
    
         
            +
                              + selectedText.replace(newlineReplaceRegexClean,newlineReplaceClean + button.tagStart).replace(/\n(\S)/g,'\n' + button.tagStart + '$1')
         
     | 
| 
      
 341 
     | 
    
         
            +
                              + newlineEnd
         
     | 
| 
      
 342 
     | 
    
         
            +
                              + followupText;
         
     | 
| 
      
 343 
     | 
    
         
            +
                      if (matches = selectedText.match(/\n(\S)/g)) {
         
     | 
| 
      
 344 
     | 
    
         
            +
                        listItems = matches.length;
         
     | 
| 
      
 345 
     | 
    
         
            +
                      }
         
     | 
| 
      
 346 
     | 
    
         
            +
                      posDiffPos = 3 + listItems*3;
         
     | 
| 
      
 347 
     | 
    
         
            +
                    } 
         
     | 
| 
      
 348 
     | 
    
         
            +
                  }
         
     | 
| 
      
 349 
     | 
    
         
            +
             
     | 
| 
      
 350 
     | 
    
         
            +
                  // now lets look and see if the user is trying to muck with a block or block modifier
         
     | 
| 
      
 351 
     | 
    
         
            +
                  else if (button.tagStart.match(/^(h1|h2|h3|h4|h5|h6|bq|p|\>|\<\>|\<|\=|\(|\))/g)) {
         
     | 
| 
      
 352 
     | 
    
         
            +
             
     | 
| 
      
 353 
     | 
    
         
            +
                    var insertTag = '';
         
     | 
| 
      
 354 
     | 
    
         
            +
                    var insertModifier = '';
         
     | 
| 
      
 355 
     | 
    
         
            +
                    var tagPartBlock = '';
         
     | 
| 
      
 356 
     | 
    
         
            +
                    var tagPartModifier = '';
         
     | 
| 
      
 357 
     | 
    
         
            +
                    var tagPartModifierOrig = ''; // ugly hack but it's late
         
     | 
| 
      
 358 
     | 
    
         
            +
                    var drawSwitch = '';
         
     | 
| 
      
 359 
     | 
    
         
            +
                    var captureIndentStart = false;
         
     | 
| 
      
 360 
     | 
    
         
            +
                    var captureListStart = false;
         
     | 
| 
      
 361 
     | 
    
         
            +
                    var periodAddition = '\\. ';
         
     | 
| 
      
 362 
     | 
    
         
            +
                    var periodAdditionClean = '. ';
         
     | 
| 
      
 363 
     | 
    
         
            +
                    var listItemsAddition = 0;
         
     | 
| 
      
 364 
     | 
    
         
            +
             
     | 
| 
      
 365 
     | 
    
         
            +
                    var re_list_items = new RegExp('(\\*+|\\#+)','g'); // need this regex later on when checking indentation of lists
         
     | 
| 
      
 366 
     | 
    
         
            +
             
     | 
| 
      
 367 
     | 
    
         
            +
                    var re_block_modifier = new RegExp('^(h1|h2|h3|h4|h5|h6|bq|p| [\\*]{1,} | [\\#]{1,} |)(\\>|\\<\\>|\\<|\\=|[\\(]{1,}|[\\)]{1,6}|)','g');
         
     | 
| 
      
 368 
     | 
    
         
            +
                    if (tagPartMatches = re_block_modifier.exec(selectedText)) {
         
     | 
| 
      
 369 
     | 
    
         
            +
                      tagPartBlock = tagPartMatches[1];
         
     | 
| 
      
 370 
     | 
    
         
            +
                      tagPartModifier = tagPartMatches[2];
         
     | 
| 
      
 371 
     | 
    
         
            +
                      tagPartModifierOrig = tagPartMatches[2];
         
     | 
| 
      
 372 
     | 
    
         
            +
                      tagPartModifierOrig = tagPartModifierOrig.replace(/\(/g,"\\(");
         
     | 
| 
      
 373 
     | 
    
         
            +
                    }
         
     | 
| 
      
 374 
     | 
    
         
            +
             
     | 
| 
      
 375 
     | 
    
         
            +
                    // if tag already up is the same as the tag provided replace the whole tag
         
     | 
| 
      
 376 
     | 
    
         
            +
                    if (tagPartBlock == button.tagStart) { 
         
     | 
| 
      
 377 
     | 
    
         
            +
                      insertTag  = tagPartBlock + tagPartModifierOrig; // use Orig because it's escaped for regex
         
     | 
| 
      
 378 
     | 
    
         
            +
                      drawSwitch = 0; 
         
     | 
| 
      
 379 
     | 
    
         
            +
                    }
         
     | 
| 
      
 380 
     | 
    
         
            +
                    // else if let's check to add/remove block modifier
         
     | 
| 
      
 381 
     | 
    
         
            +
                    else if ((tagPartModifier == button.tagStart) || (newm = tagPartModifier.match(/[\(]{2,}/g))) {
         
     | 
| 
      
 382 
     | 
    
         
            +
                      if ((button.tagStart == '(') || (button.tagStart == ')')) {
         
     | 
| 
      
 383 
     | 
    
         
            +
                        var indentLength = tagPartModifier.length;
         
     | 
| 
      
 384 
     | 
    
         
            +
                        if (button.tagStart == '(') {
         
     | 
| 
      
 385 
     | 
    
         
            +
                          indentLength = indentLength + 1;
         
     | 
| 
      
 386 
     | 
    
         
            +
                        }
         
     | 
| 
      
 387 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 388 
     | 
    
         
            +
                          indentLength = indentLength - 1;
         
     | 
| 
      
 389 
     | 
    
         
            +
                        }
         
     | 
| 
      
 390 
     | 
    
         
            +
                        for (var i = 0; i < indentLength; i++) {
         
     | 
| 
      
 391 
     | 
    
         
            +
                          insertModifier = insertModifier + '(';
         
     | 
| 
      
 392 
     | 
    
         
            +
                        }
         
     | 
| 
      
 393 
     | 
    
         
            +
                        insertTag = tagPartBlock + insertModifier;
         
     | 
| 
      
 394 
     | 
    
         
            +
                      }
         
     | 
| 
      
 395 
     | 
    
         
            +
                      else {
         
     | 
| 
      
 396 
     | 
    
         
            +
                        if (button.tagStart == tagPartModifier) {
         
     | 
| 
      
 397 
     | 
    
         
            +
                          insertTag =  tagPartBlock;
         
     | 
| 
      
 398 
     | 
    
         
            +
                          } // going to rely on the default empty insertModifier
         
     | 
| 
      
 399 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 400 
     | 
    
         
            +
             
     | 
| 
      
 401 
     | 
    
         
            +
                          if (button.tagStart.match(/(\>|\<\>|\<|\=)/g)) {
         
     | 
| 
      
 402 
     | 
    
         
            +
                            insertTag = tagPartBlock + button.tagStart;
         
     | 
| 
      
 403 
     | 
    
         
            +
                          }
         
     | 
| 
      
 404 
     | 
    
         
            +
                          else {
         
     | 
| 
      
 405 
     | 
    
         
            +
                            insertTag = button.tagStart + tagPartModifier;
         
     | 
| 
      
 406 
     | 
    
         
            +
                          }
         
     | 
| 
      
 407 
     | 
    
         
            +
                        }
         
     | 
| 
      
 408 
     | 
    
         
            +
             
     | 
| 
      
 409 
     | 
    
         
            +
                      }
         
     | 
| 
      
 410 
     | 
    
         
            +
                      drawSwitch = 1;
         
     | 
| 
      
 411 
     | 
    
         
            +
                    }
         
     | 
| 
      
 412 
     | 
    
         
            +
                    // indentation of list items
         
     | 
| 
      
 413 
     | 
    
         
            +
                    else if (listPartMatches = re_list_items.exec(tagPartBlock)) {
         
     | 
| 
      
 414 
     | 
    
         
            +
                        var listTypeMatch = listPartMatches[1];
         
     | 
| 
      
 415 
     | 
    
         
            +
                        var indentLength = tagPartBlock.length - 2;
         
     | 
| 
      
 416 
     | 
    
         
            +
                        var listInsert = '';
         
     | 
| 
      
 417 
     | 
    
         
            +
                        if (button.tagStart == '(') {
         
     | 
| 
      
 418 
     | 
    
         
            +
                          indentLength = indentLength + 1;
         
     | 
| 
      
 419 
     | 
    
         
            +
                        }
         
     | 
| 
      
 420 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 421 
     | 
    
         
            +
                          indentLength = indentLength - 1;
         
     | 
| 
      
 422 
     | 
    
         
            +
                        }
         
     | 
| 
      
 423 
     | 
    
         
            +
                        if (listTypeMatch.match(/[\*]{1,}/g)) {
         
     | 
| 
      
 424 
     | 
    
         
            +
                          var listType = '*';
         
     | 
| 
      
 425 
     | 
    
         
            +
                          var listReplace = '\\*';
         
     | 
| 
      
 426 
     | 
    
         
            +
                        }
         
     | 
| 
      
 427 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 428 
     | 
    
         
            +
                          var listType = '#';
         
     | 
| 
      
 429 
     | 
    
         
            +
                          var listReplace = '\\#';
         
     | 
| 
      
 430 
     | 
    
         
            +
                        }
         
     | 
| 
      
 431 
     | 
    
         
            +
                        for (var i = 0; i < indentLength; i++) {
         
     | 
| 
      
 432 
     | 
    
         
            +
                          listInsert = listInsert + listType;
         
     | 
| 
      
 433 
     | 
    
         
            +
                        }
         
     | 
| 
      
 434 
     | 
    
         
            +
                        if (listInsert != '') {
         
     | 
| 
      
 435 
     | 
    
         
            +
                          insertTag = ' ' + listInsert + ' ';
         
     | 
| 
      
 436 
     | 
    
         
            +
                        }
         
     | 
| 
      
 437 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 438 
     | 
    
         
            +
                          insertTag = '';
         
     | 
| 
      
 439 
     | 
    
         
            +
                        }
         
     | 
| 
      
 440 
     | 
    
         
            +
                        tagPartBlock = tagPartBlock.replace(/(\*|\#)/g,listReplace);
         
     | 
| 
      
 441 
     | 
    
         
            +
                        drawSwitch = 1;
         
     | 
| 
      
 442 
     | 
    
         
            +
                        captureListStart = true;
         
     | 
| 
      
 443 
     | 
    
         
            +
                        periodAddition = '';
         
     | 
| 
      
 444 
     | 
    
         
            +
                        periodAdditionClean = '';
         
     | 
| 
      
 445 
     | 
    
         
            +
                        if (matches = selectedText.match(/\n\s/g)) {
         
     | 
| 
      
 446 
     | 
    
         
            +
                          listItemsAddition = matches.length;
         
     | 
| 
      
 447 
     | 
    
         
            +
                        }
         
     | 
| 
      
 448 
     | 
    
         
            +
                    }
         
     | 
| 
      
 449 
     | 
    
         
            +
                    // must be a block modification e.g. p>. to p<.
         
     | 
| 
      
 450 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 451 
     | 
    
         
            +
             
     | 
| 
      
 452 
     | 
    
         
            +
                      // if this is a block modification/addition
         
     | 
| 
      
 453 
     | 
    
         
            +
                      if (button.tagStart.match(/(h1|h2|h3|h4|h5|h6|bq|p)/g)) { 
         
     | 
| 
      
 454 
     | 
    
         
            +
                        if (tagPartBlock == '') {
         
     | 
| 
      
 455 
     | 
    
         
            +
                          drawSwitch = 2;
         
     | 
| 
      
 456 
     | 
    
         
            +
                        }
         
     | 
| 
      
 457 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 458 
     | 
    
         
            +
                          drawSwitch = 1;
         
     | 
| 
      
 459 
     | 
    
         
            +
                        }
         
     | 
| 
      
 460 
     | 
    
         
            +
             
     | 
| 
      
 461 
     | 
    
         
            +
                        insertTag = button.tagStart + tagPartModifier;
         
     | 
| 
      
 462 
     | 
    
         
            +
                      }
         
     | 
| 
      
 463 
     | 
    
         
            +
             
     | 
| 
      
 464 
     | 
    
         
            +
                      // else this is a modifier modification/addition
         
     | 
| 
      
 465 
     | 
    
         
            +
                      else {
         
     | 
| 
      
 466 
     | 
    
         
            +
                        if ((tagPartModifier == '') && (tagPartBlock != '')) {
         
     | 
| 
      
 467 
     | 
    
         
            +
                          drawSwitch = 1;
         
     | 
| 
      
 468 
     | 
    
         
            +
                        }
         
     | 
| 
      
 469 
     | 
    
         
            +
                        else if (tagPartModifier == '') {
         
     | 
| 
      
 470 
     | 
    
         
            +
                          drawSwitch = 2;
         
     | 
| 
      
 471 
     | 
    
         
            +
                        }
         
     | 
| 
      
 472 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 473 
     | 
    
         
            +
                          drawSwitch = 1;
         
     | 
| 
      
 474 
     | 
    
         
            +
                        }
         
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
                        // if no tag part block but a modifier we need at least the p tag
         
     | 
| 
      
 477 
     | 
    
         
            +
                        if (tagPartBlock == '') {
         
     | 
| 
      
 478 
     | 
    
         
            +
                          tagPartBlock = 'p';
         
     | 
| 
      
 479 
     | 
    
         
            +
                        }
         
     | 
| 
      
 480 
     | 
    
         
            +
             
     | 
| 
      
 481 
     | 
    
         
            +
                        //make sure to swap out outdent
         
     | 
| 
      
 482 
     | 
    
         
            +
                        if (button.tagStart == ')') {
         
     | 
| 
      
 483 
     | 
    
         
            +
                          tagPartModifier = '';
         
     | 
| 
      
 484 
     | 
    
         
            +
                        }
         
     | 
| 
      
 485 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 486 
     | 
    
         
            +
                          tagPartModifier = button.tagStart;
         
     | 
| 
      
 487 
     | 
    
         
            +
                          captureIndentStart = true; // ugly hack to fix issue with proper selection handling
         
     | 
| 
      
 488 
     | 
    
         
            +
                        }
         
     | 
| 
      
 489 
     | 
    
         
            +
             
     | 
| 
      
 490 
     | 
    
         
            +
                        insertTag = tagPartBlock + tagPartModifier;
         
     | 
| 
      
 491 
     | 
    
         
            +
                      }
         
     | 
| 
      
 492 
     | 
    
         
            +
                    }
         
     | 
| 
      
 493 
     | 
    
         
            +
             
     | 
| 
      
 494 
     | 
    
         
            +
                    mplier = 0;
         
     | 
| 
      
 495 
     | 
    
         
            +
                    if (captureListStart || (tagPartModifier.match(/[\(\)]{1,}/g))) {
         
     | 
| 
      
 496 
     | 
    
         
            +
                      re_start = new RegExp(insertTag.escape + periodAddition,'g'); // for tags that mimic regex properties, parens + list tags
         
     | 
| 
      
 497 
     | 
    
         
            +
                    }
         
     | 
| 
      
 498 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 499 
     | 
    
         
            +
                      re_start = new RegExp(insertTag + periodAddition,'g'); // for tags that don't, why i can't just escape everything i have no clue
         
     | 
| 
      
 500 
     | 
    
         
            +
                    }
         
     | 
| 
      
 501 
     | 
    
         
            +
                    re_old = new RegExp(tagPartBlock + tagPartModifierOrig + periodAddition,'g');
         
     | 
| 
      
 502 
     | 
    
         
            +
                    re_middle = new RegExp(newlineReplaceRegexDirty + insertTag.escape + periodAddition.escape,'g');
         
     | 
| 
      
 503 
     | 
    
         
            +
                    re_tag = new RegExp(insertTag.escape + periodAddition.escape,'g');
         
     | 
| 
      
 504 
     | 
    
         
            +
             
     | 
| 
      
 505 
     | 
    
         
            +
                    // *************************************************************************************************************************
         
     | 
| 
      
 506 
     | 
    
         
            +
                    // this is where everything gets swapped around or inserted, bullets and single options have their own if/else statements
         
     | 
| 
      
 507 
     | 
    
         
            +
                    // *************************************************************************************************************************
         
     | 
| 
      
 508 
     | 
    
         
            +
                    if ((drawSwitch == 0) || (drawSwitch == 1)) {
         
     | 
| 
      
 509 
     | 
    
         
            +
                      if (drawSwitch == 0) { // completely removing a tag
         
     | 
| 
      
 510 
     | 
    
         
            +
                        finalText = beginningText
         
     | 
| 
      
 511 
     | 
    
         
            +
                                + newlineStart
         
     | 
| 
      
 512 
     | 
    
         
            +
                                + selectedText.replace(re_start,'').replace(re_middle,newlineReplaceClean)
         
     | 
| 
      
 513 
     | 
    
         
            +
                                + newlineEnd
         
     | 
| 
      
 514 
     | 
    
         
            +
                                + followupText;
         
     | 
| 
      
 515 
     | 
    
         
            +
                        if (matches = selectedText.match(newlineReplaceRegexClean)) {
         
     | 
| 
      
 516 
     | 
    
         
            +
                          mplier = mplier + matches.length;
         
     | 
| 
      
 517 
     | 
    
         
            +
                        }
         
     | 
| 
      
 518 
     | 
    
         
            +
                        posDiffNeg = insertTag.length + 2 + (mplier*4);
         
     | 
| 
      
 519 
     | 
    
         
            +
                      }
         
     | 
| 
      
 520 
     | 
    
         
            +
                      else { // modifying a tag, though we do delete bullets here
         
     | 
| 
      
 521 
     | 
    
         
            +
                        finalText = beginningText
         
     | 
| 
      
 522 
     | 
    
         
            +
                                + newlineStart
         
     | 
| 
      
 523 
     | 
    
         
            +
                                + selectedText.replace(re_old,insertTag + periodAdditionClean)
         
     | 
| 
      
 524 
     | 
    
         
            +
                                + newlineEnd
         
     | 
| 
      
 525 
     | 
    
         
            +
                                + followupText;
         
     | 
| 
      
 526 
     | 
    
         
            +
             
     | 
| 
      
 527 
     | 
    
         
            +
                        if (matches = selectedText.match(newlineReplaceRegexClean)) {
         
     | 
| 
      
 528 
     | 
    
         
            +
                          mplier = mplier + matches.length;
         
     | 
| 
      
 529 
     | 
    
         
            +
                        }
         
     | 
| 
      
 530 
     | 
    
         
            +
                        // figure out the length of various elements to modify the selection position
         
     | 
| 
      
 531 
     | 
    
         
            +
                        if (captureIndentStart) { // need to double-check that this wasn't the first indent
         
     | 
| 
      
 532 
     | 
    
         
            +
                          tagPreviousLength = tagPartBlock.length;
         
     | 
| 
      
 533 
     | 
    
         
            +
                          tagCurrentLength = insertTag.length;
         
     | 
| 
      
 534 
     | 
    
         
            +
                        }
         
     | 
| 
      
 535 
     | 
    
         
            +
                        else if (captureListStart) { // if this is a list we're manipulating
         
     | 
| 
      
 536 
     | 
    
         
            +
                          if (button.tagStart == '(') { // if indenting
         
     | 
| 
      
 537 
     | 
    
         
            +
                            tagPreviousLength = listTypeMatch.length + 2;
         
     | 
| 
      
 538 
     | 
    
         
            +
                            tagCurrentLength = insertTag.length + listItemsAddition;
         
     | 
| 
      
 539 
     | 
    
         
            +
                          }
         
     | 
| 
      
 540 
     | 
    
         
            +
                          else if (insertTag.match(/(\*|\#)/g)) { // if removing but still has bullets
         
     | 
| 
      
 541 
     | 
    
         
            +
                            tagPreviousLength = insertTag.length + listItemsAddition;
         
     | 
| 
      
 542 
     | 
    
         
            +
                            tagCurrentLength = listTypeMatch.length;
         
     | 
| 
      
 543 
     | 
    
         
            +
                          }
         
     | 
| 
      
 544 
     | 
    
         
            +
                          else {  // if removing last bullet
         
     | 
| 
      
 545 
     | 
    
         
            +
                            tagPreviousLength = insertTag.length + listItemsAddition;
         
     | 
| 
      
 546 
     | 
    
         
            +
                            tagCurrentLength = listTypeMatch.length - (3*listItemsAddition) - 1;
         
     | 
| 
      
 547 
     | 
    
         
            +
                          }
         
     | 
| 
      
 548 
     | 
    
         
            +
                        }
         
     | 
| 
      
 549 
     | 
    
         
            +
                        else { // everything else
         
     | 
| 
      
 550 
     | 
    
         
            +
                          tagPreviousLength = tagPartBlock.length + tagPartModifier.length;
         
     | 
| 
      
 551 
     | 
    
         
            +
                          tagCurrentLength = insertTag.length;
         
     | 
| 
      
 552 
     | 
    
         
            +
                        }
         
     | 
| 
      
 553 
     | 
    
         
            +
                        if (tagCurrentLength > tagPreviousLength) {
         
     | 
| 
      
 554 
     | 
    
         
            +
                          posDiffPos = (tagCurrentLength - tagPreviousLength) + (mplier*(tagCurrentLength - tagPreviousLength));
         
     | 
| 
      
 555 
     | 
    
         
            +
                        }
         
     | 
| 
      
 556 
     | 
    
         
            +
                        else {
         
     | 
| 
      
 557 
     | 
    
         
            +
                          posDiffNeg = (tagPreviousLength - tagCurrentLength) + (mplier*(tagPreviousLength - tagCurrentLength));
         
     | 
| 
      
 558 
     | 
    
         
            +
                        }
         
     | 
| 
      
 559 
     | 
    
         
            +
                      }
         
     | 
| 
      
 560 
     | 
    
         
            +
                    }
         
     | 
| 
      
 561 
     | 
    
         
            +
                    else { // for adding tags other then bullets (have their own statement)
         
     | 
| 
      
 562 
     | 
    
         
            +
                      finalText = beginningText
         
     | 
| 
      
 563 
     | 
    
         
            +
                              + newlineStart
         
     | 
| 
      
 564 
     | 
    
         
            +
                                    + insertTag + '. '
         
     | 
| 
      
 565 
     | 
    
         
            +
                              + selectedText.replace(newlineReplaceRegexClean,button.tagEnd + '\n' + insertTag + '. ')
         
     | 
| 
      
 566 
     | 
    
         
            +
                              + newlineFollowup
         
     | 
| 
      
 567 
     | 
    
         
            +
                              + newlineEnd
         
     | 
| 
      
 568 
     | 
    
         
            +
                              + followupText;
         
     | 
| 
      
 569 
     | 
    
         
            +
                      if (matches = selectedText.match(newlineReplaceRegexClean)) {
         
     | 
| 
      
 570 
     | 
    
         
            +
                        mplier = mplier + matches.length;
         
     | 
| 
      
 571 
     | 
    
         
            +
                      }
         
     | 
| 
      
 572 
     | 
    
         
            +
                      posDiffPos = insertTag.length + 2 + (mplier*4);
         
     | 
| 
      
 573 
     | 
    
         
            +
                    }       
         
     | 
| 
      
 574 
     | 
    
         
            +
                  }
         
     | 
| 
      
 575 
     | 
    
         
            +
             
     | 
| 
      
 576 
     | 
    
         
            +
                  // swap in and out the simple tags around a selection like bold
         
     | 
| 
      
 577 
     | 
    
         
            +
                  else {
         
     | 
| 
      
 578 
     | 
    
         
            +
             
     | 
| 
      
 579 
     | 
    
         
            +
                    mplier = 1; // the multiplier for the tag length
         
     | 
| 
      
 580 
     | 
    
         
            +
                    re_start = new RegExp('^\\' + button.tagStart,'g');
         
     | 
| 
      
 581 
     | 
    
         
            +
                    re_end =  new RegExp('\\' + button.tagEnd + '$','g');
         
     | 
| 
      
 582 
     | 
    
         
            +
                    re_middle = new RegExp('\\' + button.tagEnd + newlineReplaceRegexDirty + '\\' + button.tagStart,'g');
         
     | 
| 
      
 583 
     | 
    
         
            +
                    if (selectedText.match(re_start) && selectedText.match(re_end)) {
         
     | 
| 
      
 584 
     | 
    
         
            +
                      finalText = beginningText
         
     | 
| 
      
 585 
     | 
    
         
            +
                              + newlineStart
         
     | 
| 
      
 586 
     | 
    
         
            +
                              + selectedText.replace(re_start,'').replace(re_end,'').replace(re_middle,newlineReplaceClean)
         
     | 
| 
      
 587 
     | 
    
         
            +
                              + newlineEnd
         
     | 
| 
      
 588 
     | 
    
         
            +
                              + followupText;
         
     | 
| 
      
 589 
     | 
    
         
            +
                      if (matches = selectedText.match(newlineReplaceRegexClean)) {
         
     | 
| 
      
 590 
     | 
    
         
            +
                        mplier = mplier + matches.length;
         
     | 
| 
      
 591 
     | 
    
         
            +
                      }
         
     | 
| 
      
 592 
     | 
    
         
            +
                      posDiffNeg = button.tagStart.length*mplier + button.tagEnd.length*mplier;
         
     | 
| 
      
 593 
     | 
    
         
            +
                    }
         
     | 
| 
      
 594 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 595 
     | 
    
         
            +
                      finalText = beginningText
         
     | 
| 
      
 596 
     | 
    
         
            +
                              + newlineStart
         
     | 
| 
      
 597 
     | 
    
         
            +
                                    + button.tagStart
         
     | 
| 
      
 598 
     | 
    
         
            +
                              + selectedText.replace(newlineReplaceRegexClean,button.tagEnd + newlineReplaceClean + button.tagStart)
         
     | 
| 
      
 599 
     | 
    
         
            +
                              + button.tagEnd
         
     | 
| 
      
 600 
     | 
    
         
            +
                              + newlineEnd
         
     | 
| 
      
 601 
     | 
    
         
            +
                              + followupText;
         
     | 
| 
      
 602 
     | 
    
         
            +
                      if (matches = selectedText.match(newlineReplaceRegexClean)) {
         
     | 
| 
      
 603 
     | 
    
         
            +
                        mplier = mplier + matches.length;
         
     | 
| 
      
 604 
     | 
    
         
            +
                      }
         
     | 
| 
      
 605 
     | 
    
         
            +
                      posDiffPos = (button.tagStart.length*mplier) + (button.tagEnd.length*mplier);
         
     | 
| 
      
 606 
     | 
    
         
            +
                    }
         
     | 
| 
      
 607 
     | 
    
         
            +
                  }
         
     | 
| 
      
 608 
     | 
    
         
            +
             
     | 
| 
      
 609 
     | 
    
         
            +
                  cursorPos += button.tagStart.length + button.tagEnd.length;
         
     | 
| 
      
 610 
     | 
    
         
            +
             
     | 
| 
      
 611 
     | 
    
         
            +
                }
         
     | 
| 
      
 612 
     | 
    
         
            +
             
     | 
| 
      
 613 
     | 
    
         
            +
                // just swap in and out single values, e.g. someone clicks b they'll get a *
         
     | 
| 
      
 614 
     | 
    
         
            +
                else {
         
     | 
| 
      
 615 
     | 
    
         
            +
                  var buttonStart = '';
         
     | 
| 
      
 616 
     | 
    
         
            +
                  var buttonEnd = '';
         
     | 
| 
      
 617 
     | 
    
         
            +
                  var re_p = new RegExp('(\\<|\\>|\\=|\\<\\>|\\(|\\))','g');
         
     | 
| 
      
 618 
     | 
    
         
            +
                  var re_h = new RegExp('^(h1|h2|h3|h4|h5|h6|p|bq)','g');
         
     | 
| 
      
 619 
     | 
    
         
            +
                  if (!this.checkOpenTags(button) || button.tagEnd == '') { // opening tag
         
     | 
| 
      
 620 
     | 
    
         
            +
             
     | 
| 
      
 621 
     | 
    
         
            +
                    if (button.tagStart.match(re_h)) {
         
     | 
| 
      
 622 
     | 
    
         
            +
                      buttonStart = button.tagStart + '. ';
         
     | 
| 
      
 623 
     | 
    
         
            +
                    }
         
     | 
| 
      
 624 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 625 
     | 
    
         
            +
                      buttonStart = button.tagStart;
         
     | 
| 
      
 626 
     | 
    
         
            +
                    }
         
     | 
| 
      
 627 
     | 
    
         
            +
                    if (button.tagStart.match(re_p)) { // make sure that invoking block modifiers don't do anything
         
     | 
| 
      
 628 
     | 
    
         
            +
                      finalText = beginningText 
         
     | 
| 
      
 629 
     | 
    
         
            +
                                 + followupText;
         
     | 
| 
      
 630 
     | 
    
         
            +
                      cursorPos = startPos;
         
     | 
| 
      
 631 
     | 
    
         
            +
                    }
         
     | 
| 
      
 632 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 633 
     | 
    
         
            +
                      finalText = beginningText 
         
     | 
| 
      
 634 
     | 
    
         
            +
                                  + buttonStart
         
     | 
| 
      
 635 
     | 
    
         
            +
                                  + followupText;
         
     | 
| 
      
 636 
     | 
    
         
            +
                      this.addTag(button);
         
     | 
| 
      
 637 
     | 
    
         
            +
                      cursorPos = startPos + buttonStart.length;
         
     | 
| 
      
 638 
     | 
    
         
            +
                    }
         
     | 
| 
      
 639 
     | 
    
         
            +
             
     | 
| 
      
 640 
     | 
    
         
            +
                  }
         
     | 
| 
      
 641 
     | 
    
         
            +
                  else {  // closing tag
         
     | 
| 
      
 642 
     | 
    
         
            +
                    if (button.tagStart.match(re_p)) {
         
     | 
| 
      
 643 
     | 
    
         
            +
                      buttonEnd = '\n\n';
         
     | 
| 
      
 644 
     | 
    
         
            +
                    }
         
     | 
| 
      
 645 
     | 
    
         
            +
                    else if (button.tagStart.match(re_h)) {
         
     | 
| 
      
 646 
     | 
    
         
            +
                      buttonEnd = '\n\n';
         
     | 
| 
      
 647 
     | 
    
         
            +
                    }
         
     | 
| 
      
 648 
     | 
    
         
            +
                    else {
         
     | 
| 
      
 649 
     | 
    
         
            +
                      buttonEnd = button.tagEnd
         
     | 
| 
      
 650 
     | 
    
         
            +
                    }
         
     | 
| 
      
 651 
     | 
    
         
            +
                    finalText = beginningText 
         
     | 
| 
      
 652 
     | 
    
         
            +
                                + button.tagEnd
         
     | 
| 
      
 653 
     | 
    
         
            +
                                + followupText;
         
     | 
| 
      
 654 
     | 
    
         
            +
                    this.removeTag(button);
         
     | 
| 
      
 655 
     | 
    
         
            +
                    cursorPos = startPos + button.tagEnd.length;
         
     | 
| 
      
 656 
     | 
    
         
            +
                  }
         
     | 
| 
      
 657 
     | 
    
         
            +
                }
         
     | 
| 
      
 658 
     | 
    
         
            +
             
     | 
| 
      
 659 
     | 
    
         
            +
                // set the appropriate DOM value with the final text
         
     | 
| 
      
 660 
     | 
    
         
            +
                if (FF == true) {
         
     | 
| 
      
 661 
     | 
    
         
            +
                  myField.value = finalText;
         
     | 
| 
      
 662 
     | 
    
         
            +
                  myField.scrollTop = scrollTop;
         
     | 
| 
      
 663 
     | 
    
         
            +
                }
         
     | 
| 
      
 664 
     | 
    
         
            +
                else {
         
     | 
| 
      
 665 
     | 
    
         
            +
                  sel.text = finalText;
         
     | 
| 
      
 666 
     | 
    
         
            +
                }
         
     | 
| 
      
 667 
     | 
    
         
            +
             
     | 
| 
      
 668 
     | 
    
         
            +
                // build up the selection capture, doesn't work in IE
         
     | 
| 
      
 669 
     | 
    
         
            +
                if (textSelected) {
         
     | 
| 
      
 670 
     | 
    
         
            +
                  myField.selectionStart = startPos + newlineStartPos;
         
     | 
| 
      
 671 
     | 
    
         
            +
                  myField.selectionEnd = endPos + posDiffPos - posDiffNeg - newlineEndPos;
         
     | 
| 
      
 672 
     | 
    
         
            +
                  //alert('s: ' + myField.selectionStart + ' e: ' + myField.selectionEnd + ' sp: ' + startPos + ' ep: ' + endPos + ' pdp: ' + posDiffPos + ' pdn: ' + posDiffNeg)
         
     | 
| 
      
 673 
     | 
    
         
            +
                }
         
     | 
| 
      
 674 
     | 
    
         
            +
                else {
         
     | 
| 
      
 675 
     | 
    
         
            +
                  myField.selectionStart = cursorPos;
         
     | 
| 
      
 676 
     | 
    
         
            +
                  myField.selectionEnd = cursorPos;
         
     | 
| 
      
 677 
     | 
    
         
            +
                }
         
     | 
| 
      
 678 
     | 
    
         
            +
              } // end insertTag
         
     | 
| 
      
 679 
     | 
    
         
            +
            }; // end class
         
     | 
| 
      
 680 
     | 
    
         
            +
             
     | 
| 
      
 681 
     | 
    
         
            +
            // add class methods
         
     | 
| 
      
 682 
     | 
    
         
            +
            // Object.extend(TextileEditor, TextileEditor.Methods);
         
     | 
| 
      
 683 
     | 
    
         
            +
            destination = TextileEditor
         
     | 
| 
      
 684 
     | 
    
         
            +
            source = TextileEditor.Methods
         
     | 
| 
      
 685 
     | 
    
         
            +
            for(var property in source) destination[property] = source[property];
         
     | 
| 
      
 686 
     | 
    
         
            +
             
     | 
| 
      
 687 
     | 
    
         
            +
            document.write('<script src="/assets/textile-editor-config.js" type="text/javascript"></script>');
         
     |