You are reading a single comment by @branwen and its replies. Click here to read the full conversation.
  • Quoting is still broken

    The failure to quote links?

    I think I have a solution to that having looked at the code yesterday.

    It is doing this:

        comments.prototype.getWindowSelectedText = function(){
    
          var selection     = window.getSelection();
    
          if (selection && typeof selection.toString == 'function') {
            return selection.toString().replace(/\n/g, "\n> ");
          }
    
          return false;
        };
    

    Note the .toString() in there.

    It would be better if it copied the HTML fragment.

    Perhaps something along the lines of:

    comments.prototype.getWindowSelectedHTML = function(){
      var selection = window.getSelection();
      
      if (selection && typeof selection.getRangeAt == 'function') {
        // Pull a balanced tree HTML fragment from the DOM for the given selection
        var range = selection.getRangeAt(0);
        var fragment = range.cloneContents();
    
        // We only want core HTML and link attributes, almost every other attribute
        // can be jettisoned
        var walk = function(node,func) {
            func(node);
            node = node.firstChild;
            while(node) {
                walk(node,func);
                node = node.nextSibling;
            }
        };
        var stripAttrs = function(node) {
          if (node.attributes) {
            var names = [];
            for (var i = 0; i < node.attributes.length; i++) {
              switch (node.attributes[i].name) {
                case "href":
                  break;
                case "title":
                  break;
                case "alt":
                  break;
                default:
                  name[names.length] = node.attributes[i].name;
              }
            }
            for (var i = 0; i < names.length; i++) {
              node.removeAttribute(names[i]);
            }
          }
        } 
        walk(fragment, stripAttrs);
    
        return fragment;
      }
      
      return false;
    };
    

    I wrote that blind... I've no idea whether it would work. I'm just guessing. I wish I had a JS developer around.

  • That's OK.

    I wrote a working version of that idea...

    var getWindowSelectedHTML = function() {
      var selection = window.getSelection();
      
      if (selection && typeof selection.getRangeAt == 'function') {
        // Pull a balanced tree HTML fragment from the DOM for the given selection
        var range = selection.getRangeAt(0);
        var fragment = range.cloneContents();
    
        // We only want core HTML and link attributes, almost every other attribute
        // can be jettisoned
        var walk = function(node,f) {
          f(node);
          var child = node.firstChild;
          while(child) {
            walk(child,f);
            child = (child.nextSibling) ? child.nextSibling : false;
          }
          return node;
        };
        var stripAttrs = function(node) {
          if (typeof node.hasAttributes == 'function' && node.hasAttributes()) {
            var names = [];
            for (var i = 0; i < node.attributes.length; i++) {
              switch (node.attributes[i].name) {
                case "href":
                  break;
                case "title":
                  break;
                case "alt":
                  break;
                default:
                  names[names.length] = node.attributes[i].name;
              }
            }
            for (var i = 0; i < names.length; i++) {
              node.removeAttribute(names[i]);
            }
          }
        }
        fragment = walk(fragment, stripAttrs);
    
        // Now we have a clean fragment we need to get the HTML as text but a
        // DocumentFragment does not have an innerHTML so we need to attach it to
        // the DOM and ask that for the innerHTML.
        var scratch = document.getElementById('scratchpad');
        if (scratch) {
          while (scratch.firstChild) {
            scratch.removeChild(scratch.firstChild);
          }
        } else {
          scratch = document.createElement("div");
          scratch.id = "scratchpad";
          scratch.style = "display: none;";
          scratch.hidden = true;
          document.body.appendChild(scratch)
        }
        scratch.appendChild(fragment);
        return scratch.innerHTML;
      }
      
      return false;
    };
    

    I'm not sure whether I'll use it, because HTML scares people. But the idea is nice.

    It returns the HTML of the selected text, and so would preserve links, formatting, etc... whilst ensuring that the HTML is not broken.

    The only downside is that in the text box that people type their reply, the HTML would show.

About

Avatar for branwen @branwen started