[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/mod/assign/feedback/editpdf/yui/src/editor/js/ -> comment.js (source)

   1  // This file is part of Moodle - http://moodle.org/
   2  //
   3  // Moodle is free software: you can redistribute it and/or modify
   4  // it under the terms of the GNU General Public License as published by
   5  // the Free Software Foundation, either version 3 of the License, or
   6  // (at your option) any later version.
   7  //
   8  // Moodle is distributed in the hope that it will be useful,
   9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  // GNU General Public License for more details.
  12  //
  13  // You should have received a copy of the GNU General Public License
  14  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  15  /* global SELECTOR, COMMENTCOLOUR, COMMENTTEXTCOLOUR */
  16  
  17  /**
  18   * Provides an in browser PDF editor.
  19   *
  20   * @module moodle-assignfeedback_editpdf-editor
  21   */
  22  
  23  /**
  24   * Class representing a list of comments.
  25   *
  26   * @namespace M.assignfeedback_editpdf
  27   * @class comment
  28   * @param M.assignfeedback_editpdf.editor editor
  29   * @param Int gradeid
  30   * @param Int pageno
  31   * @param Int x
  32   * @param Int y
  33   * @param Int width
  34   * @param String colour
  35   * @param String rawtext
  36   */
  37  var COMMENT = function(editor, gradeid, pageno, x, y, width, colour, rawtext) {
  38  
  39      /**
  40       * Reference to M.assignfeedback_editpdf.editor.
  41       * @property editor
  42       * @type M.assignfeedback_editpdf.editor
  43       * @public
  44       */
  45      this.editor = editor;
  46  
  47      /**
  48       * Grade id
  49       * @property gradeid
  50       * @type Int
  51       * @public
  52       */
  53      this.gradeid = gradeid || 0;
  54  
  55      /**
  56       * X position
  57       * @property x
  58       * @type Int
  59       * @public
  60       */
  61      this.x = parseInt(x, 10) || 0;
  62  
  63      /**
  64       * Y position
  65       * @property y
  66       * @type Int
  67       * @public
  68       */
  69      this.y = parseInt(y, 10) || 0;
  70  
  71      /**
  72       * Comment width
  73       * @property width
  74       * @type Int
  75       * @public
  76       */
  77      this.width = parseInt(width, 10) || 0;
  78  
  79      /**
  80       * Comment rawtext
  81       * @property rawtext
  82       * @type String
  83       * @public
  84       */
  85      this.rawtext = rawtext || '';
  86  
  87      /**
  88       * Comment page number
  89       * @property pageno
  90       * @type Int
  91       * @public
  92       */
  93      this.pageno = pageno || 0;
  94  
  95      /**
  96       * Comment background colour.
  97       * @property colour
  98       * @type String
  99       * @public
 100       */
 101      this.colour = colour || 'yellow';
 102  
 103      /**
 104       * Reference to M.assignfeedback_editpdf.drawable
 105       * @property drawable
 106       * @type M.assignfeedback_editpdf.drawable
 107       * @public
 108       */
 109      this.drawable = false;
 110  
 111      /**
 112       * Boolean used by a timeout to delete empty comments after a short delay.
 113       * @property deleteme
 114       * @type Boolean
 115       * @public
 116       */
 117      this.deleteme = false;
 118  
 119      /**
 120       * Reference to the link that opens the menu.
 121       * @property menulink
 122       * @type Y.Node
 123       * @public
 124       */
 125      this.menulink = null;
 126  
 127      /**
 128       * Reference to the dialogue that is the context menu.
 129       * @property menu
 130       * @type M.assignfeedback_editpdf.dropdown
 131       * @public
 132       */
 133      this.menu = null;
 134  
 135      /**
 136       * Clean a comment record, returning an oject with only fields that are valid.
 137       * @public
 138       * @method clean
 139       * @return {}
 140       */
 141      this.clean = function() {
 142          return {
 143              gradeid: this.gradeid,
 144              x: parseInt(this.x, 10),
 145              y: parseInt(this.y, 10),
 146              width: parseInt(this.width, 10),
 147              rawtext: this.rawtext,
 148              pageno: this.currentpage,
 149              colour: this.colour
 150          };
 151      };
 152  
 153      /**
 154       * Draw a comment.
 155       * @public
 156       * @method draw_comment
 157       * @param boolean focus - Set the keyboard focus to the new comment if true
 158       * @return M.assignfeedback_editpdf.drawable
 159       */
 160      this.draw = function(focus) {
 161          var drawable = new M.assignfeedback_editpdf.drawable(this.editor),
 162              node,
 163              drawingregion = this.editor.get_dialogue_element(SELECTOR.DRAWINGREGION),
 164              container,
 165              menu,
 166              position,
 167              scrollheight;
 168  
 169          // Lets add a contenteditable div.
 170          node = Y.Node.create('<textarea/>');
 171          container = Y.Node.create('<div class="commentdrawable"/>');
 172          menu = Y.Node.create('<a href="#"><img src="' + M.util.image_url('t/contextmenu', 'core') + '"/></a>');
 173  
 174          this.menulink = menu;
 175          container.append(node);
 176  
 177          if (!this.editor.get('readonly')) {
 178              container.append(menu);
 179          } else {
 180              node.setAttribute('readonly', 'readonly');
 181          }
 182          if (this.width < 100) {
 183              this.width = 100;
 184          }
 185  
 186          position = this.editor.get_window_coordinates(new M.assignfeedback_editpdf.point(this.x, this.y));
 187          node.setStyles({
 188              width: this.width + 'px',
 189              backgroundColor: COMMENTCOLOUR[this.colour],
 190              color: COMMENTTEXTCOLOUR
 191          });
 192  
 193          drawingregion.append(container);
 194          container.setStyle('position', 'absolute');
 195          container.setX(position.x);
 196          container.setY(position.y);
 197          drawable.store_position(container, position.x, position.y);
 198          drawable.nodes.push(container);
 199          node.set('value', this.rawtext);
 200          scrollheight = node.get('scrollHeight');
 201          node.setStyles({
 202              'height': scrollheight + 'px',
 203              'overflow': 'hidden'
 204          });
 205          if (!this.editor.get('readonly')) {
 206              this.attach_events(node, menu);
 207          }
 208          if (focus) {
 209              node.focus();
 210          }
 211          this.drawable = drawable;
 212  
 213  
 214          return drawable;
 215      };
 216  
 217      /**
 218       * Delete an empty comment if it's menu hasn't been opened in time.
 219       * @method delete_comment_later
 220       */
 221      this.delete_comment_later = function() {
 222          if (this.deleteme) {
 223              this.remove();
 224          }
 225      };
 226  
 227      /**
 228       * Comment nodes have a bunch of event handlers attached to them directly.
 229       * This is all done here for neatness.
 230       *
 231       * @protected
 232       * @method attach_comment_events
 233       * @param node - The Y.Node representing the comment.
 234       * @param menu - The Y.Node representing the menu.
 235       */
 236      this.attach_events = function(node, menu) {
 237          // Save the text on blur.
 238          node.on('blur', function() {
 239              // Save the changes back to the comment.
 240              this.rawtext = node.get('value');
 241              this.width = parseInt(node.getStyle('width'), 10);
 242  
 243              // Trim.
 244              if (this.rawtext.replace(/^\s+|\s+$/g, "") === '') {
 245                  // Delete empty comments.
 246                  this.deleteme = true;
 247                  Y.later(400, this, this.delete_comment_later);
 248              }
 249              this.editor.save_current_page();
 250              this.editor.editingcomment = false;
 251          }, this);
 252  
 253          // For delegated event handler.
 254          menu.setData('comment', this);
 255  
 256          node.on('keyup', function() {
 257              var scrollheight = node.get('scrollHeight'),
 258                  height = parseInt(node.getStyle('height'), 10);
 259  
 260              // Webkit scrollheight fix.
 261              if (scrollheight === height + 8) {
 262                  scrollheight -= 8;
 263              }
 264              node.setStyle('height', scrollheight + 'px');
 265  
 266          });
 267  
 268          node.on('gesturemovestart', function(e) {
 269              if (editor.currentedit.tool === 'select') {
 270                  e.preventDefault();
 271                  node.setData('dragging', true);
 272                  node.setData('offsetx', e.clientX - node.getX());
 273                  node.setData('offsety', e.clientY - node.getY());
 274              }
 275          });
 276          node.on('gesturemoveend', function() {
 277              if (editor.currentedit.tool === 'select') {
 278                  node.setData('dragging', false);
 279                  this.editor.save_current_page();
 280              }
 281          }, null, this);
 282          node.on('gesturemove', function(e) {
 283              if (editor.currentedit.tool === 'select') {
 284                  var x = e.clientX - node.getData('offsetx'),
 285                      y = e.clientY - node.getData('offsety'),
 286                      nodewidth,
 287                      nodeheight,
 288                      newlocation,
 289                      windowlocation,
 290                      bounds;
 291  
 292                  nodewidth = parseInt(node.getStyle('width'), 10);
 293                  nodeheight = parseInt(node.getStyle('height'), 10);
 294  
 295                  newlocation = this.editor.get_canvas_coordinates(new M.assignfeedback_editpdf.point(x, y));
 296                  bounds = this.editor.get_canvas_bounds(true);
 297                  bounds.x = 0;
 298                  bounds.y = 0;
 299  
 300                  bounds.width -= nodewidth + 42;
 301                  bounds.height -= nodeheight + 8;
 302                  // Clip to the window size - the comment size.
 303                  newlocation.clip(bounds);
 304  
 305                  this.x = newlocation.x;
 306                  this.y = newlocation.y;
 307  
 308                  windowlocation = this.editor.get_window_coordinates(newlocation);
 309                  node.ancestor().setX(windowlocation.x);
 310                  node.ancestor().setY(windowlocation.y);
 311                  this.drawable.store_position(node.ancestor(), windowlocation.x, windowlocation.y);
 312              }
 313          }, null, this);
 314  
 315          this.menu = new M.assignfeedback_editpdf.commentmenu({
 316              buttonNode: this.menulink,
 317              comment: this
 318          });
 319      };
 320  
 321      /**
 322       * Delete a comment.
 323       * @method remove
 324       */
 325      this.remove = function() {
 326          var i = 0;
 327          var comments;
 328  
 329          comments = this.editor.pages[this.editor.currentpage].comments;
 330          for (i = 0; i < comments.length; i++) {
 331              if (comments[i] === this) {
 332                  comments.splice(i, 1);
 333                  this.drawable.erase();
 334                  this.editor.save_current_page();
 335                  return;
 336              }
 337          }
 338      };
 339  
 340      /**
 341       * Event handler to remove a comment from the users quicklist.
 342       *
 343       * @protected
 344       * @method remove_from_quicklist
 345       */
 346      this.remove_from_quicklist = function(e, quickcomment) {
 347          e.preventDefault();
 348  
 349          this.menu.hide();
 350  
 351          this.editor.quicklist.remove(quickcomment);
 352      };
 353  
 354      /**
 355       * A quick comment was selected in the list, update the active comment and redraw the page.
 356       *
 357       * @param Event e
 358       * @protected
 359       * @method set_from_quick_comment
 360       */
 361      this.set_from_quick_comment = function(e, quickcomment) {
 362          e.preventDefault();
 363  
 364          this.menu.hide();
 365  
 366          this.rawtext = quickcomment.rawtext;
 367          this.width = quickcomment.width;
 368          this.colour = quickcomment.colour;
 369  
 370          this.editor.save_current_page();
 371  
 372          this.editor.redraw();
 373      };
 374  
 375      /**
 376       * Event handler to add a comment to the users quicklist.
 377       *
 378       * @protected
 379       * @method add_to_quicklist
 380       */
 381      this.add_to_quicklist = function(e) {
 382          e.preventDefault();
 383          this.menu.hide();
 384          this.editor.quicklist.add(this);
 385      };
 386  
 387      /**
 388       * Draw the in progress edit.
 389       *
 390       * @public
 391       * @method draw_current_edit
 392       * @param M.assignfeedback_editpdf.edit edit
 393       */
 394      this.draw_current_edit = function(edit) {
 395          var drawable = new M.assignfeedback_editpdf.drawable(this.editor),
 396              shape,
 397              bounds;
 398  
 399          bounds = new M.assignfeedback_editpdf.rect();
 400          bounds.bound([edit.start, edit.end]);
 401  
 402          // We will draw a box with the current background colour.
 403          shape = this.editor.graphic.addShape({
 404              type: Y.Rect,
 405              width: bounds.width,
 406              height: bounds.height,
 407              fill: {
 408                 color: COMMENTCOLOUR[edit.commentcolour]
 409              },
 410              x: bounds.x,
 411              y: bounds.y
 412          });
 413  
 414          drawable.shapes.push(shape);
 415  
 416          return drawable;
 417      };
 418  
 419      /**
 420       * Promote the current edit to a real comment.
 421       *
 422       * @public
 423       * @method init_from_edit
 424       * @param M.assignfeedback_editpdf.edit edit
 425       * @return bool true if comment bound is more than min width/height, else false.
 426       */
 427      this.init_from_edit = function(edit) {
 428          var bounds = new M.assignfeedback_editpdf.rect();
 429          bounds.bound([edit.start, edit.end]);
 430  
 431          // Minimum comment width.
 432          if (bounds.width < 100) {
 433              bounds.width = 100;
 434          }
 435  
 436          // Save the current edit to the server and the current page list.
 437  
 438          this.gradeid = this.editor.get('gradeid');
 439          this.pageno = this.editor.currentpage;
 440          this.x = bounds.x;
 441          this.y = bounds.y;
 442          this.width = bounds.width;
 443          this.colour = edit.commentcolour;
 444          this.rawtext = '';
 445  
 446          return (bounds.has_min_width() && bounds.has_min_height());
 447      };
 448  
 449  };
 450  
 451  M.assignfeedback_editpdf = M.assignfeedback_editpdf || {};
 452  M.assignfeedback_editpdf.comment = COMMENT;


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1