Ticket #11460: getDropPositionUsingCustomSrcipt.html

File getDropPositionUsingCustomSrcipt.html, 8.1 KB (added by Piotr Jasiun, 6 years ago)

Get drop position using custom script based on elementFromPoint and getClientRects

Line 
1<!DOCTYPE html>
2<html>
3<head>
4        <meta charset="utf-8">
5        <script src="http://ckeditor.dev/ckeditor.js"></script>
6        <link href="http://ckeditor.dev/samples/sample.css" rel="stylesheet"/>
7</head>
8<body>
9        <textarea cols="100" id="editor1" name="editor1" rows="10">
10&lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;http://ckeditor.dev/samples/assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
11        </textarea>
12
13        <script>
14                var editor = CKEDITOR.replace( 'editor1' );
15
16                editor.on( 'contentDom', function() {
17                        var editable = editor.editable(),
18                                dropTarget = ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) ? editable : editor.document;
19
20                        editable.attachListener( dropTarget, 'drop', function( evt ) {
21                                try {
22                                        var range = positionFromPoint( editor, evt.data.$.clientX, evt.data.$.clientY );
23
24                                        if ( !range )
25                                                throw "Range is null!"
26
27                                        editor.getSelection().getRanges()
28                                        range.select();
29
30                                        editor.insertText( '!!!' );
31
32                                        setTimeout( function() {
33                                                editor.insertText( '???' );
34                                        }, 1 );
35
36                                } catch( err ) {
37                                        console.log( err );
38                                }
39                                evt.data.preventDefault();
40                        } );
41
42
43                } );
44
45        function getNodeIndex( node ) {
46                var i = 0;
47                while ( ( node = node.previousSibling ) ) {
48                        i++;
49                }
50                return i;
51        }
52
53        function getLastRangeRect( range ) {
54                var rects = range.getClientRects();
55                return ( rects.length > 0 ) ? rects[ rects.length - 1 ] : null;
56        }
57
58        function pointIsInOrAboveRect( x, y, rect ) {
59                return y < rect.bottom && x >= rect.left && x <= rect.right;
60        }
61
62        function positionFromPoint( editor, x, y, favourPrecedingPosition ) {
63                var doc = editor.document.$,
64                        body = editor.document.getBody().$;
65
66                var el = doc.elementFromPoint( x, y );
67
68                var range = doc.createRange(); // IE9+
69                range.selectNodeContents( el ); // IE9+
70
71                range.collapse( true );
72
73                var offsetNode = el.firstChild, offset, position, rect;
74
75                if ( !offsetNode ) {
76                        offsetNode = el.parentNode;
77                        offset = getNodeIndex( el );
78                        if ( !favourPrecedingPosition )
79                                ++offset;
80
81                } else {
82                        var textLen;
83                        // Search through the text node children of el
84                        main: while ( offsetNode ) {
85                                if ( offsetNode.nodeType == 3 ) {
86                                        // Go through the text node character by character
87                                        for ( offset = 0, textLen = offsetNode.length; offset <= textLen; ++offset ) {
88                                                range.setEnd( offsetNode, offset );
89                                                rect = getLastRangeRect( range );
90                                                if ( rect && pointIsInOrAboveRect( x, y, rect ) ) {
91                                                        // We've gone past the point. Now we check which side (left or right) of the character the point is nearer to
92                                                        if ( rect.right - x > x - rect.left )
93                                                                --offset;
94
95                                                        break main;
96                                                }
97                                        }
98                                } else {
99                                        // Handle elements
100                                        range.setEndAfter( offsetNode );
101                                        // IF IE8
102                                                // offsetNode.setEndPoint( 'EndToEnd', range );
103
104                                        rect = getLastRangeRect( range );
105                                        if ( rect && pointIsInOrAboveRect( x, y, rect ) ) {
106                                                offset = getNodeIndex( offsetNode );
107                                                offsetNode = el.parentNode;
108                                                if ( !favourPrecedingPosition )
109                                                        ++offset;
110
111                                                break main;
112                                        }
113                                }
114
115                                offsetNode = offsetNode.nextSibling;
116                        }
117                        if ( !offsetNode ) {
118                                offsetNode = el;
119                                offset = el.childNodes.length;
120                        }
121                }
122
123                var range = editor.createRange();
124                range.setStart( CKEDITOR.dom.node( offsetNode ), offset );
125                range.collapse( true );
126
127                return range;
128        }
129
130        </script>
131
132</body>
133</html>
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy