Commit c1a9ec901fbaffa802c29f5986f28de8a34ed094

Authored by Mukul Rajput
1 parent 6ae22fe0

this is solution for the bug touch with labex

400-SOURCECODE/AIAHTML5.Web/app/controllers/LabExercController.js
... ... @@ -401,7 +401,7 @@ function ($scope, $rootScope, pages, log, $http,$timeout, DataService, $filter,
401 401  
402 402 this.style.opacity = '0.4';
403 403 var $ua = navigator.userAgent;
404   - if ($.browser.msie || ($ua.match(/(iPod|iPhone|iPad|android)/i))) {
  404 + if ($.browser.msie) {
405 405 localStorage.setItem("text", this.innerHTML);
406 406 }
407 407 else
... ... @@ -471,7 +471,7 @@ function ($scope, $rootScope, pages, log, $http,$timeout, DataService, $filter,
471 471  
472 472 var keywords = $location.search();
473 473 var $ua = navigator.userAgent;
474   - if ($.browser.msie || ($ua.match(/(iPod|iPhone|iPad|android)/i))) {
  474 + if ($.browser.msie) {
475 475 dataText = localStorage.getItem("text");
476 476 localStorage.setItem("text", '');
477 477 }
... ... @@ -1051,9 +1051,6 @@ AIA.directive('draggable', function () {
1051 1051 link: function ($scope, element, attrs) {
1052 1052 element[0].addEventListener('dragstart', $scope.handleDragStart, false);
1053 1053 element[0].addEventListener('dragend', $scope.handleDragEnd, false);
1054   -
1055   - element[0].addEventListener('touchstart', $scope.handleDragStart, false);
1056   - element[0].addEventListener('touchend', $scope.handleDragEnd, false);
1057 1054 }
1058 1055 }
1059 1056 });
... ... @@ -1063,9 +1060,6 @@ AIA.directive('droppable', function () {
1063 1060 link: function ($scope, element, attrs) {
1064 1061 element[0].addEventListener('drop', $scope.handleDrop, false);
1065 1062 element[0].addEventListener('dragover', $scope.handleDragOver, false);
1066   -
1067   - element[0].addEventListener('touchmove', $scope.handleDragOver, false);
1068   - element[0].addEventListener('touchend', $scope.handleDrop, false);
1069 1063 }
1070 1064 }
1071 1065 });
... ...
400-SOURCECODE/AIAHTML5.Web/app/views/LabExerc/LabExerc-view.html
... ... @@ -122,3 +122,4 @@
122 122  
123 123  
124 124 </div>
  125 +<script src="../../../libs/DragDropTouch.js"></script>
125 126 \ No newline at end of file
... ...
400-SOURCECODE/AIAHTML5.Web/libs/DragDropTouch.js 0 → 100644
  1 +var DragDropTouch;
  2 +(function (DragDropTouch_1) {
  3 + 'use strict';
  4 + /**
  5 + * Object used to hold the data that is being dragged during drag and drop operations.
  6 + *
  7 + * It may hold one or more data items of different types. For more information about
  8 + * drag and drop operations and data transfer objects, see
  9 + * <a href="https://developer.mozilla.org/en-US/docs/Web/API/DataTransfer">HTML Drag and Drop API</a>.
  10 + *
  11 + * This object is created automatically by the @see:DragDropTouch singleton and is
  12 + * accessible through the @see:dataTransfer property of all drag events.
  13 + */
  14 + var DataTransfer = (function () {
  15 + function DataTransfer() {
  16 + this._dropEffect = 'move';
  17 + this._effectAllowed = 'all';
  18 + this._data = {};
  19 + }
  20 + Object.defineProperty(DataTransfer.prototype, "dropEffect", {
  21 + /**
  22 + * Gets or sets the type of drag-and-drop operation currently selected.
  23 + * The value must be 'none', 'copy', 'link', or 'move'.
  24 + */
  25 + get: function () {
  26 + return this._dropEffect;
  27 + },
  28 + set: function (value) {
  29 + this._dropEffect = value;
  30 + },
  31 + enumerable: true,
  32 + configurable: true
  33 + });
  34 + Object.defineProperty(DataTransfer.prototype, "effectAllowed", {
  35 + /**
  36 + * Gets or sets the types of operations that are possible.
  37 + * Must be one of 'none', 'copy', 'copyLink', 'copyMove', 'link',
  38 + * 'linkMove', 'move', 'all' or 'uninitialized'.
  39 + */
  40 + get: function () {
  41 + return this._effectAllowed;
  42 + },
  43 + set: function (value) {
  44 + this._effectAllowed = value;
  45 + },
  46 + enumerable: true,
  47 + configurable: true
  48 + });
  49 + Object.defineProperty(DataTransfer.prototype, "types", {
  50 + /**
  51 + * Gets an array of strings giving the formats that were set in the @see:dragstart event.
  52 + */
  53 + get: function () {
  54 + return Object.keys(this._data);
  55 + },
  56 + enumerable: true,
  57 + configurable: true
  58 + });
  59 + /**
  60 + * Removes the data associated with a given type.
  61 + *
  62 + * The type argument is optional. If the type is empty or not specified, the data
  63 + * associated with all types is removed. If data for the specified type does not exist,
  64 + * or the data transfer contains no data, this method will have no effect.
  65 + *
  66 + * @param type Type of data to remove.
  67 + */
  68 + DataTransfer.prototype.clearData = function (type) {
  69 + if (type != null) {
  70 + delete this._data[type];
  71 + }
  72 + else {
  73 + this._data = null;
  74 + }
  75 + };
  76 + /**
  77 + * Retrieves the data for a given type, or an empty string if data for that type does
  78 + * not exist or the data transfer contains no data.
  79 + *
  80 + * @param type Type of data to retrieve.
  81 + */
  82 + DataTransfer.prototype.getData = function (type) {
  83 + return this._data[type] || '';
  84 + };
  85 + /**
  86 + * Set the data for a given type.
  87 + *
  88 + * For a list of recommended drag types, please see
  89 + * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Recommended_Drag_Types.
  90 + *
  91 + * @param type Type of data to add.
  92 + * @param value Data to add.
  93 + */
  94 + DataTransfer.prototype.setData = function (type, value) {
  95 + this._data[type] = value;
  96 + };
  97 + /**
  98 + * Set the image to be used for dragging if a custom one is desired.
  99 + *
  100 + * @param img An image element to use as the drag feedback image.
  101 + * @param offsetX The horizontal offset within the image.
  102 + * @param offsetY The vertical offset within the image.
  103 + */
  104 + DataTransfer.prototype.setDragImage = function (img, offsetX, offsetY) {
  105 + var ddt = DragDropTouch._instance;
  106 + ddt._imgCustom = img;
  107 + ddt._imgOffset = { x: offsetX, y: offsetY };
  108 + };
  109 + return DataTransfer;
  110 + }());
  111 + DragDropTouch_1.DataTransfer = DataTransfer;
  112 + /**
  113 + * Defines a class that adds support for touch-based HTML5 drag/drop operations.
  114 + *
  115 + * The @see:DragDropTouch class listens to touch events and raises the
  116 + * appropriate HTML5 drag/drop events as if the events had been caused
  117 + * by mouse actions.
  118 + *
  119 + * The purpose of this class is to enable using existing, standard HTML5
  120 + * drag/drop code on mobile devices running IOS or Android.
  121 + *
  122 + * To use, include the DragDropTouch.js file on the page. The class will
  123 + * automatically start monitoring touch events and will raise the HTML5
  124 + * drag drop events (dragstart, dragenter, dragleave, drop, dragend) which
  125 + * should be handled by the application.
  126 + *
  127 + * For details and examples on HTML drag and drop, see
  128 + * https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Drag_operations.
  129 + */
  130 + var DragDropTouch = (function () {
  131 + /**
  132 + * Initializes the single instance of the @see:DragDropTouch class.
  133 + */
  134 + function DragDropTouch() {
  135 + this._lastClick = 0;
  136 + // enforce singleton pattern
  137 + if (DragDropTouch._instance) {
  138 + throw 'DragDropTouch instance already created.';
  139 + }
  140 + // detect passive event support
  141 + // https://github.com/Modernizr/Modernizr/issues/1894
  142 + var supportsPassive = false;
  143 + document.addEventListener('test', function () { }, {
  144 + get passive() {
  145 + supportsPassive = true;
  146 + return true;
  147 + }
  148 + });
  149 + // listen to touch events
  150 + if ('ontouchstart' in document) {
  151 + var d = document, ts = this._touchstart.bind(this), tm = this._touchmove.bind(this), te = this._touchend.bind(this), opt = supportsPassive ? { passive: false, capture: false } : false;
  152 + d.addEventListener('touchstart', ts, opt);
  153 + d.addEventListener('touchmove', tm, opt);
  154 + d.addEventListener('touchend', te);
  155 + d.addEventListener('touchcancel', te);
  156 + }
  157 + }
  158 + /**
  159 + * Gets a reference to the @see:DragDropTouch singleton.
  160 + */
  161 + DragDropTouch.getInstance = function () {
  162 + return DragDropTouch._instance;
  163 + };
  164 + // ** event handlers
  165 + DragDropTouch.prototype._touchstart = function (e) {
  166 + var _this = this;
  167 + if (this._shouldHandle(e)) {
  168 + // raise double-click and prevent zooming
  169 + if (Date.now() - this._lastClick < DragDropTouch._DBLCLICK) {
  170 + if (this._dispatchEvent(e, 'dblclick', e.target)) {
  171 + e.preventDefault();
  172 + this._reset();
  173 + return;
  174 + }
  175 + }
  176 + // clear all variables
  177 + this._reset();
  178 + // get nearest draggable element
  179 + var src = this._closestDraggable(e.target);
  180 + if (src) {
  181 + // give caller a chance to handle the hover/move events
  182 + if (!this._dispatchEvent(e, 'mousemove', e.target) &&
  183 + !this._dispatchEvent(e, 'mousedown', e.target)) {
  184 + // get ready to start dragging
  185 + this._dragSource = src;
  186 + this._ptDown = this._getPoint(e);
  187 + this._lastTouch = e;
  188 + e.preventDefault();
  189 + // show context menu if the user hasn't started dragging after a while
  190 + setTimeout(function () {
  191 + if (_this._dragSource == src && _this._img == null) {
  192 + if (_this._dispatchEvent(e, 'contextmenu', src)) {
  193 + _this._reset();
  194 + }
  195 + }
  196 + }, DragDropTouch._CTXMENU);
  197 + }
  198 + }
  199 + }
  200 + };
  201 + DragDropTouch.prototype._touchmove = function (e) {
  202 + if (this._shouldHandle(e)) {
  203 + // see if target wants to handle move
  204 + var target = this._getTarget(e);
  205 + if (this._dispatchEvent(e, 'mousemove', target)) {
  206 + this._lastTouch = e;
  207 + e.preventDefault();
  208 + return;
  209 + }
  210 + // start dragging
  211 + if (this._dragSource && !this._img) {
  212 + var delta = this._getDelta(e);
  213 + if (delta > DragDropTouch._THRESHOLD) {
  214 + this._dispatchEvent(e, 'dragstart', this._dragSource);
  215 + this._createImage(e);
  216 + this._dispatchEvent(e, 'dragenter', target);
  217 + }
  218 + }
  219 + // continue dragging
  220 + if (this._img) {
  221 + this._lastTouch = e;
  222 + e.preventDefault(); // prevent scrolling
  223 + if (target != this._lastTarget) {
  224 + this._dispatchEvent(this._lastTouch, 'dragleave', this._lastTarget);
  225 + this._dispatchEvent(e, 'dragenter', target);
  226 + this._lastTarget = target;
  227 + }
  228 + this._moveImage(e);
  229 + this._dispatchEvent(e, 'dragover', target);
  230 + }
  231 + }
  232 + };
  233 + DragDropTouch.prototype._touchend = function (e) {
  234 + if (this._shouldHandle(e)) {
  235 + // see if target wants to handle up
  236 + if (this._dispatchEvent(this._lastTouch, 'mouseup', e.target)) {
  237 + e.preventDefault();
  238 + return;
  239 + }
  240 + // user clicked the element but didn't drag, so clear the source and simulate a click
  241 + if (!this._img) {
  242 + this._dragSource = null;
  243 + this._dispatchEvent(this._lastTouch, 'click', e.target);
  244 + this._lastClick = Date.now();
  245 + }
  246 + // finish dragging
  247 + this._destroyImage();
  248 + if (this._dragSource) {
  249 + if (e.type.indexOf('cancel') < 0) {
  250 + this._dispatchEvent(this._lastTouch, 'drop', this._lastTarget);
  251 + }
  252 + this._dispatchEvent(this._lastTouch, 'dragend', this._dragSource);
  253 + this._reset();
  254 + }
  255 + }
  256 + };
  257 + // ** utilities
  258 + // ignore events that have been handled or that involve more than one touch
  259 + DragDropTouch.prototype._shouldHandle = function (e) {
  260 + return e &&
  261 + !e.defaultPrevented &&
  262 + e.touches && e.touches.length < 2;
  263 + };
  264 + // clear all members
  265 + DragDropTouch.prototype._reset = function () {
  266 + this._destroyImage();
  267 + this._dragSource = null;
  268 + this._lastTouch = null;
  269 + this._lastTarget = null;
  270 + this._ptDown = null;
  271 + this._dataTransfer = new DataTransfer();
  272 + };
  273 + // get point for a touch event
  274 + DragDropTouch.prototype._getPoint = function (e, page) {
  275 + if (e && e.touches) {
  276 + e = e.touches[0];
  277 + }
  278 + return { x: page ? e.pageX : e.clientX, y: page ? e.pageY : e.clientY };
  279 + };
  280 + // get distance between the current touch event and the first one
  281 + DragDropTouch.prototype._getDelta = function (e) {
  282 + var p = this._getPoint(e);
  283 + return Math.abs(p.x - this._ptDown.x) + Math.abs(p.y - this._ptDown.y);
  284 + };
  285 + // get the element at a given touch event
  286 + DragDropTouch.prototype._getTarget = function (e) {
  287 + var pt = this._getPoint(e), el = document.elementFromPoint(pt.x, pt.y);
  288 + while (el && getComputedStyle(el).pointerEvents == 'none') {
  289 + el = el.parentElement;
  290 + }
  291 + return el;
  292 + };
  293 + // create drag image from source element
  294 + DragDropTouch.prototype._createImage = function (e) {
  295 + // just in case...
  296 + if (this._img) {
  297 + this._destroyImage();
  298 + }
  299 + // create drag image from custom element or drag source
  300 + var src = this._imgCustom || this._dragSource;
  301 + this._img = src.cloneNode(true);
  302 + this._copyStyle(src, this._img);
  303 + this._img.style.top = this._img.style.left = '-9999px';
  304 + // if creating from drag source, apply offset and opacity
  305 + if (!this._imgCustom) {
  306 + var rc = src.getBoundingClientRect(), pt = this._getPoint(e);
  307 + this._imgOffset = { x: pt.x - rc.left, y: pt.y - rc.top };
  308 + this._img.style.opacity = DragDropTouch._OPACITY.toString();
  309 + }
  310 + // add image to document
  311 + this._moveImage(e);
  312 + document.body.appendChild(this._img);
  313 + };
  314 + // dispose of drag image element
  315 + DragDropTouch.prototype._destroyImage = function () {
  316 + if (this._img && this._img.parentElement) {
  317 + this._img.parentElement.removeChild(this._img);
  318 + }
  319 + this._img = null;
  320 + this._imgCustom = null;
  321 + };
  322 + // move the drag image element
  323 + DragDropTouch.prototype._moveImage = function (e) {
  324 + var _this = this;
  325 + if (this._img) {
  326 + requestAnimationFrame(function () {
  327 + var pt = _this._getPoint(e, true), s = _this._img.style;
  328 + s.position = 'absolute';
  329 + s.pointerEvents = 'none';
  330 + s.zIndex = '999999';
  331 + s.left = Math.round(pt.x - _this._imgOffset.x) + 'px';
  332 + s.top = Math.round(pt.y - _this._imgOffset.y) + 'px';
  333 + });
  334 + }
  335 + };
  336 + // copy properties from an object to another
  337 + DragDropTouch.prototype._copyProps = function (dst, src, props) {
  338 + for (var i = 0; i < props.length; i++) {
  339 + var p = props[i];
  340 + dst[p] = src[p];
  341 + }
  342 + };
  343 + DragDropTouch.prototype._copyStyle = function (src, dst) {
  344 + // remove potentially troublesome attributes
  345 + DragDropTouch._rmvAtts.forEach(function (att) {
  346 + dst.removeAttribute(att);
  347 + });
  348 + // copy canvas content
  349 + if (src instanceof HTMLCanvasElement) {
  350 + var cSrc = src, cDst = dst;
  351 + cDst.width = cSrc.width;
  352 + cDst.height = cSrc.height;
  353 + cDst.getContext('2d').drawImage(cSrc, 0, 0);
  354 + }
  355 + // copy style (without transitions)
  356 + var cs = getComputedStyle(src);
  357 + for (var i = 0; i < cs.length; i++) {
  358 + var key = cs[i];
  359 + if (key.indexOf('transition') < 0) {
  360 + dst.style[key] = cs[key];
  361 + }
  362 + }
  363 + dst.style.pointerEvents = 'none';
  364 + // and repeat for all children
  365 + for (var i = 0; i < src.children.length; i++) {
  366 + this._copyStyle(src.children[i], dst.children[i]);
  367 + }
  368 + };
  369 + DragDropTouch.prototype._dispatchEvent = function (e, type, target) {
  370 + if (e && target) {
  371 + var evt = document.createEvent('Event'), t = e.touches ? e.touches[0] : e;
  372 + evt.initEvent(type, true, true);
  373 + evt.button = 0;
  374 + evt.which = evt.buttons = 1;
  375 + this._copyProps(evt, e, DragDropTouch._kbdProps);
  376 + this._copyProps(evt, t, DragDropTouch._ptProps);
  377 + evt.dataTransfer = this._dataTransfer;
  378 + target.dispatchEvent(evt);
  379 + return evt.defaultPrevented;
  380 + }
  381 + return false;
  382 + };
  383 + // gets an element's closest draggable ancestor
  384 + DragDropTouch.prototype._closestDraggable = function (e) {
  385 + for (; e; e = e.parentElement) {
  386 + if (e.hasAttribute('draggable') && e.draggable) {
  387 + return e;
  388 + }
  389 + }
  390 + return null;
  391 + };
  392 + return DragDropTouch;
  393 + }());
  394 + /*private*/ DragDropTouch._instance = new DragDropTouch(); // singleton
  395 + // constants
  396 + DragDropTouch._THRESHOLD = 5; // pixels to move before drag starts
  397 + DragDropTouch._OPACITY = 0.5; // drag image opacity
  398 + DragDropTouch._DBLCLICK = 500; // max ms between clicks in a double click
  399 + DragDropTouch._CTXMENU = 900; // ms to hold before raising 'contextmenu' event
  400 + // copy styles/attributes from drag source to drag image element
  401 + DragDropTouch._rmvAtts = 'id,class,style,draggable'.split(',');
  402 + // synthesize and dispatch an event
  403 + // returns true if the event has been handled (e.preventDefault == true)
  404 + DragDropTouch._kbdProps = 'altKey,ctrlKey,metaKey,shiftKey'.split(',');
  405 + DragDropTouch._ptProps = 'pageX,pageY,clientX,clientY,screenX,screenY'.split(',');
  406 + DragDropTouch_1.DragDropTouch = DragDropTouch;
  407 +})(DragDropTouch || (DragDropTouch = {}));
0 408 \ No newline at end of file
... ...