PageSourceSearch

https://bermuda-e96c4.firebaseapp.com/static/share/javascripts/external/sortablelist.js?v=0230479a0d90

js bermuda-e96c4.firebaseapp.com collected 2026-10-03 14:05:09 UTC 10,627 bytes, 281 lines download raw bytes

1/**
2 * jackykim: Original Source: https://codepen.io/rainner/pen/YGrzpv
3*/
4(function( name, factory ) {
5    if( typeof window === "object" ) {
6        // add to window 
7        window[ name ] = factory();
8    }
9})( "Sortable", function() {
10   
11    var _w = window,
12        _b = document.body,
13        _d = document.documentElement;
14   
15    // get position of mouse/touch in relation to viewport 
16    var getPoint = function( e )
17    {
18        if (e && e.touches) {
19            e = e.touches[0];
20        }
21        var scrollX = Math.max( 0, _w.pageXOffset || _d.scrollLeft || _b.scrollLeft || 0 ) - ( _d.clientLeft || 0 ), 
22            scrollY = Math.max( 0, _w.pageYOffset || _d.scrollTop || _b.scrollTop || 0 ) - ( _d.clientTop || 0 ), 
23            pointX  = e ? ( Math.max( 0, e.pageX || e.clientX || 0 ) - scrollX ) : 0,
24            pointY  = e ? ( Math.max( 0, e.pageY || e.clientY || 0 ) - scrollY ) : 0; 
25        
26        return { x: pointX, y: pointY }; 
27    };
28
29    // class constructor
30    var Factory = function( container, options )
31    {
32        if( container && container instanceof Element )
33        {
34            this._container = container; 
35            this._options   = options || {}; /* nothing atm */
36            this._clickItem = null;
37            this._dragItem  = null;
38            this._hovItem   = null;
39            this._sortLists = [];
40            this._click     = {};
41            this._dragging  = false;
42            this._changed   = false;
43
44            // jackkykim - onMove()에서 subItem이 handleClass를 포함하는 경우에만 swap하기 위해서 RegExp를 생성해 둠.
45            if (this._options.hasOwnProperty('handleClass')) {
46                this._options.handleClassRegExp = new RegExp('(^|\\W)' + this._options.handleClass + '($|\\W)', 'i');
47            }
48            
49            this._container.setAttribute( "data-is-sortable", 1 );
50            // Safari에서 position: static 잔상남는 버그 있음 (relative로 변경)
51            this._container.style["position"] = "relative";     // "static";
52
53            container.addEventListener( "touchstart", this._onPress.bind( this ), true );
54            container.addEventListener( "touchend", this._onRelease.bind( this ), true ); 
55            container.addEventListener( "touchmove", this._onMove.bind( this ), true );
56        }
57    };
58   
59    // class prototype
60    Factory.prototype = {
61        constructor: Factory,
62        
63        // serialize order into array list 
64        toArray: function( attr )
65        {
66            attr = attr || "id";
67            
68            var data = [], 
69                item = null, 
70                uniq = ""; 
71            
72            for( var i = 0; i < this._container.children.length; ++i )
73            {
74                item = this._container.children[ i ], 
75                uniq = item.getAttribute( attr ) || "";
76                uniq = uniq.replace( /[^0-9]+/gi, "" );
77                data.push( uniq );
78            }
79            return data;
80        }, 
81        
82        // serialize order array into a string 
83        toString: function( attr, delimiter )
84        {
85            delimiter = delimiter || ":"; 
86            return this.toArray( attr ).join( delimiter );
87        }, 
88        
89        // checks if mouse x/y is on top of an item 
90        _isOnTop: function( item, x, y )
91        {
92            var box = item.getBoundingClientRect(),
93                isx = ( x > box.left && x < ( box.left + box.width ) ), 
94                isy = ( y > box.top && y < ( box.top + box.height ) ); 
95            return ( isx && isy );
96        },
97        
98        // manipulate the className of an item (for browsers that lack classList support)
99        _itemClass: function( item, task, cls )
100        {
101            var list  = item.className.split( /\s+/ ), 
102                index = list.indexOf( cls );
103            
104            if( task === "add" && index == -1 )
105            { 
106                list.push( cls ); 
107                item.className = list.join( " " ); 
108            }
109            else if( task === "remove" && index != -1 )
110            {
111                list.splice( index, 1 ); 
112                item.className = list.join( " " ); 
113            }
114        }, 
115        
116        // swap position of two item in sortable list container 
117        _swapItems: function( item1, item2 )
118        {
119            var parent1 = item1.parentNode, 
120                parent2 = item2.parentNode;
121            
122            if( parent1 !== parent2 ) 
123            {
124                // move to new list 
125                parent2.insertBefore( item1, item2 );
126            }
127            else { 
128                // sort is same list 
129                var temp = document.createElement( "div" ); 
130                parent1.insertBefore( temp, item1 );
131                parent2.insertBefore( item1, item2 );
132                parent1.insertBefore( item2, temp );
133                parent1.removeChild( temp );
134            }
135            this._changed = true;
136        },
137        
138        // update item position 
139        _moveItem: function( item, x, y )
140        {
141            item.style["-webkit-transform"] = "translateX( "+ x +"px ) translateY( "+ y +"px )";
142            item.style["-moz-transform"] = "translateX( "+ x +"px ) translateY( "+ y +"px )";
143            item.style["-ms-transform"] = "translateX( "+ x +"px ) translateY( "+ y +"px )";
144            item.style["transform"] = "translateX( "+ x +"px ) translateY( "+ y +"px )";
145        },
146        
147        // make a temp fake item for dragging and add to container 
148        _makeDragItem: function( item )
149        {
150            this._trashDragItem(); 
151            this._sortLists = document.querySelectorAll( "[data-is-sortable]" );
152            
153            this._clickItem = item; 
154            this._itemClass( this._clickItem, "add", "active" ); 
155
156            this._dragItem = document.createElement( item.tagName );
157            this._dragItem.className = "dragging"; 
158            this._dragItem.innerHTML = item.innerHTML; 
159            this._dragItem.style["position"] = "absolute";
160            this._dragItem.style["z-index"] = "999";
161            this._dragItem.style["left"] = ( item.offsetLeft || 0 ) + "px";
162            this._dragItem.style["top"] = ( item.offsetTop || 0 ) + "px";
163            this._dragItem.style["width"] = ( item.offsetWidth || 0 ) + "px";
164            
165            this._container.appendChild( this._dragItem ); 
166        }, 
167        
168        // remove drag item that was added to container 
169        _trashDragItem: function()
170        {
171            if( this._dragItem && this._clickItem )
172            {
173                this._itemClass( this._clickItem, "remove", "active" ); 
174                this._clickItem = null; 
175                
176                this._container.removeChild( this._dragItem ); 
177                this._dragItem = null; 
178            }
179        }, 
180        
181        // on item press/drag 
182        _onPress: function( e )
183        {
184            var target = e.target;
185            if (target == this._container) {
186                return;
187            }
188
189            var handlePressed = false;
190            while (target && target.parentNode != this._container) {
191                if (!this._options.hasOwnProperty('handleClass') || target.classList.contains(this._options.handleClass)) {
192                    handlePressed = true;
193                }
194                target = target.parentNode;
195            }
196
197            if( handlePressed && target && target.parentNode === this._container )
198            {
199                e.preventDefault();
200                e.stopPropagation();
201                
202                this._dragging = true;
203                this._click = getPoint( e ); 
204                this._makeDragItem( target ); 
205                this._onMove( e );
206            }
207            this._changed = false;
208        },
209        
210        // on item release/drop 
211        _onRelease: function( e )
212        {
213            this._dragging = false;
214            this._trashDragItem(); 
215
216            // jackkykim - Swap이 되어서 순서 바뀔 가능성이 있는 경우 callback
217            if (this._changed && this._options.hasOwnProperty('orderChangedCallback')) {
218                this._options.orderChangedCallback();
219            }
220        },
221        
222        // on item drag/move
223        _onMove: function( e )
224        {
225            if( this._dragItem && this._dragging ) 
226            {
227                //e.preventDefault();
228                e.stopPropagation();
229
230                var point     = getPoint( e );
231                var container = this._container;
232
233                // drag fake item 
234                this._moveItem( this._dragItem, ( point.x - this._click.x ), ( point.y - this._click.y ) ); 
235                
236                // keep an eye for other sortable lists and switch over to it on hover 
237                for( var a = 0; a < this._sortLists.length; ++a )
238                {
239                    var subContainer = this._sortLists[ a ]; 
240                    
241                    if( this._isOnTop( subContainer, point.x, point.y ) ) 
242                    {
243                        container = subContainer;
244                    }
245                }
246                
247                // container is empty, move clicked item over to it on hover 
248                if( this._isOnTop( container, point.x, point.y ) && container.children.length === 0 ) 
249                {
250                    container.appendChild( this._clickItem ); 
251                    return; 
252                }
253                
254                // check if current drag item is over another item and swap places 
255                for( var b = 0; b < container.children.length; ++b )
256                {
257                    var subItem = container.children[ b ]; 
258                    
259                    if( subItem === this._clickItem || subItem === this._dragItem )
260                    {
261                        continue; 
262                    }
263                    if( this._isOnTop( subItem, point.x, point.y ) ) 
264                    {
265                        // jackkykim - handleClass가 있는 item인 경우만 SWAP
266                        if (this._options.hasOwnProperty('handleClassRegExp') && this._options.handleClassRegExp.test(subItem.innerHTML) == false) {
267                            //console.log(subItem.innerHTML);
268                        } else {
269                            this._hovItem = subItem; 
270                            this._swapItems( this._clickItem, subItem ); 
271                        }
272                    }
273                }
274            }
275        },
276        
277    };
278
279    // export
280    return Factory;
281});

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.