| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382 |
- (function() {
- var BlockRangeIterator = Trex.Class.create({
- initialize: function(processor, patterns, start, end) {
- this.processor = processor;
- this.start = start;
- this.end = end || this.start;
- this.current = this.start;
-
- this.wTranslator = $tom.translate(patterns).extract('%wrapper');
- this.pTranslator = $tom.translate(patterns).extract('%paragraph');
- },
- hasNext: function() {
- return !!this.current;
- },
- next: function() {
- var _current = this.current;
- _current = this.find(_current);
- var _next = _current;
- if ($tom.include(_current, this.end)) {
- _next = _NULL;
- } else {
- while(_next && !$tom.next(_next)) {
- _next = $tom.parent(_next);
- if($tom.isBody(_next)) {
- _next = _NULL;
- }
- }
- if(_next) {
- _next = $tom.next(_next);
- }
- }
- if (_next == this.end) {
- _next = _NULL;
- }
- this.current = _next;
- return _current;
- },
- find: function(node) {
- var _bNode;
- var _node = node;
-
- if(!$tom.hasContent(_node)) {
- return _node;
- }
-
- while(_node) {
- _bNode = _node;
- if($tom.isBody(_node)) {
- break;
- }
-
- if($tom.kindOf(_node, this.wTranslator.getExpression())) {
- return _node;
- }
-
- if($tom.kindOf(_node, '%wrapper,%outergroup')) {
- _node = $tom.descendant(_bNode, this.pTranslator.getExpression());
- if(_node) {
- return _node;
- }
- _node = $tom.descendant(_bNode, '%paragraph');
- if(_node) {
- _bNode = _node;
- break;
- }
- }
- if($tom.kindOf(_node, this.pTranslator.getExpression())) {
- return _node;
- }
- if(_node.nextSibling && _node.nodeType == 3) {
- // BlockIterator 이니까 TextNode 는 찾는 대상이 아님.
- _node = _node.nextSibling;
- } else {
- _node = _node.parentNode;
- }
- }
- var _innerName = $tom.paragraphOf($tom.getName(_bNode));
- var _wNode = this.processor.newNode(_innerName);
- var _pNodes = $tom.extract(_bNode, node, '%text,%inline,img,object,embed,hr');
- $tom.wrap(_wNode, _pNodes);
- this.processor.stuffNode(_wNode);
- return _wNode;
- }
- });
-
- Object.extend(Trex.I.Processor.Standard, /** @lends Trex.Canvas.Processor.prototype */{
- /**
- * @private
- * 선택한 영역안에 있는 노드 중에 패턴을 만족하는 블럭 노드들을 리턴한다.
- * @param {String} pattern - 수집할 노드 패턴 조건
- * @param {Element} start - 시작하는 노드(#tx_start_marker)
- * @param {Element} end - 끝나는 노드(#tx_end_marker)
- * @returns {Array} - 선택한 영역안에 있는 노드 중에 패턴을 만족하는 노드들
- * @example
- * processor.getBlockRangeIterator('div,p,li', node, node);
- */
- getBlockRangeIterator: function(pattern, start, end) {
- return new BlockRangeIterator(this, pattern, start, end);
- }
- });
- })();
- (function() {
- var InlineRangeIterator = Trex.Class.create({
- initialize: function(processor, patterns, start, end) {
- this.processor = processor;
- this.start = start;
- this.end = end || this.start;
- this.current = this.start;
-
- this.iTranslator = $tom.translate(patterns).extract('%inline');
- },
- hasNext: function() {
- return !!this.current;
- },
- next: function() {
- var _current = this.current;
- _current = this.find(_current);
-
- var _next = _current;
- if (_current == this.end) {
- _next = _NULL;
- } else {
- while(_next && !$tom.next(_next)) {
- _next = $tom.parent(_next);
- if($tom.isBody(_next)) {
- _next = _NULL;
- }
- }
- if(_next) {
- _next = $tom.next(_next);
- }
- }
- if ($tom.include(_next, this.end)) {
- _next = $tom.top(_next, _TRUE);
- }
- this.current = _next;
- return _current;
- },
- find: function(node) {
- var _node = node;
- if($tom.kindOf(_node, '%paragraph,%outergroup,%block') || $tom.isBody(_node)) {
- var _bNode = _node;
- _node = $tom.top(_bNode, _TRUE);
- if(!_node) {
- var _innerName = $tom.inlineOf();
- var _iNode = this.processor.create(_innerName);
- $tom.append(_bNode, _iNode);
- return _iNode;
- }
- }
-
- if($tom.kindOf(_node, 'br')) {
- return _node;
- } else if(!$tom.hasContent(_node)) {
- return _node;
- }
-
- if($tom.kindOf(_node, this.iTranslator.getExpression())) {
- return _node;
- }
-
- var _innerName = $tom.inlineOf();
- var _iNode = this.processor.create(_innerName);
- $tom.insertAt(_iNode, _node);
- if(_node) {
- $tom.append(_iNode, _node);
- }
- return _iNode;
- }
- });
-
- Object.extend(Trex.I.Processor.Standard, /** @lends Trex.Canvas.Processor.prototype */{
- /**
- * @private
- * 선택한 영역안에 있는 노드 중에 패턴을 만족하는 인라인 노드들을 리턴한다.
- * @param {String} pattern - 수집할 노드 패턴 조건
- * @param {Element} start - 시작하는 노드(#tx_start_marker)
- * @param {Element} end - 끝나는 노드(#tx_end_marker)
- * @returns {Array} - 선택한 영역안에 있는 노드 중에 패턴을 만족하는 노드들
- * @example
- * processor.getInlineRangeIterator('span,font,a', node, node);
- */
- getInlineRangeIterator: function(pattern, start, end) {
- return new InlineRangeIterator(this, pattern, start, end);
- }
- });
- })();
- (function() {
- var __CACHING_DOC = _NULL;
- var __CACHING_NODE = {};
- var __CACHING_PARAGRAPH = {};
- Object.extend(Trex.I.Processor.Standard, /** @lends Trex.Canvas.Processor.prototype */{
- /**
- * 노드를 생성하여 리턴한다. 캐싱을 사용하여 이미 생성했던 노드는 복사한다.
- * @private
- * @param {String} name - 노드명
- * @example
- * processor.newNode('div');
- */
- newNode: function(name) {
- if(__CACHING_DOC != this.doc) {
- __CACHING_NODE = {};
- __CACHING_DOC = this.doc;
- }
- if(!__CACHING_NODE[name]) {
- __CACHING_NODE[name] = this.win[name]();
- }
- return $tom.clone(__CACHING_NODE[name], _FALSE);
- },
- /**
- * 텍스트 노드를 생성한다.
- * @private
- * @param {String} text - 텍스트내용
- */
- newText: function(text) {
- return this.doc.createTextNode(text);
- },
- /**
- * 노드를 생성하여 리턴한다. 캐싱을 사용하여 이미 생성했던 노드는 복사한다.
- * @private
- * @param {String} name - 노드명
- * @example
- * processor.newParagraph('p');
- */
- newParagraph: function(name) {
- if(__CACHING_DOC != this.doc) {
- __CACHING_PARAGRAPH = {};
- __CACHING_DOC = this.doc;
- }
- if(!__CACHING_PARAGRAPH[name]) {
- __CACHING_PARAGRAPH[name] = this.stuffNode(this.newNode(name));
- }
- return $tom.clone(__CACHING_PARAGRAPH[name], _TRUE);
- }
- });
- })();
- (function() {
- var __CACHING_DOC = _NULL;
- var __CACHING_NODE = _NULL;
- var __HAS_DUMMY = _FALSE;
- var __TEXT_GC_LIST = [];
- Object.extend(Trex.I.Processor.Standard, /** @lends Trex.Canvas.Processor.prototype */{
- /**
- * 빈 텍스트 노드를 생성한다.
- * @private
- * @param {Boolean} keep - 계속 유지할 것인지 여부 optional
- */
- newDummy: function(keep) {
- if(__CACHING_DOC != this.doc) {
- __CACHING_NODE = _NULL;
- __TEXT_GC_LIST = [];
- __CACHING_DOC = this.doc;
- }
- if(!__CACHING_NODE) {
- __CACHING_NODE = this.doc.createTextNode(Trex.__WORD_JOINER);
- }
- var _dummy = $tom.clone(__CACHING_NODE);
- if(!keep) {
- __TEXT_GC_LIST.push(_dummy);
- __HAS_DUMMY = _TRUE;
- }
- // try {
- // throw new Error();
- // } catch (e) {
- // console.log((++newDummyCalled) + "\n" + e.stack);
- // }
- return _dummy;
- },
- /**
- * 생성된 빈 텍스트 노드들을 삭제한다.
- * @private
- */
- /* TODO
- * Bug : __TEXT_GC_LIST에 저장된 dummy를 splitText를 하면, reference가 사라지는 효과가 발생한다.
- * dummy를 넣기 위한 splitText 부분을 수정할 필요가 있다.
- * startConatiner를 지우면 (현재까지 확인된 바에 따르면) Chrome에서는 커서가 사라지고 더 이상 range를 가져오지 못하게 된다.
- */
- clearDummy: function() {
- if (!__HAS_DUMMY) {
- return;
- }
- var range, startNode;
- try {
- range = this.createGoogRange();
- startNode = range && range.getStartNode();
- } catch (ignore4ie678) {}
-
- var remained = _NULL;
- // console.log(__TEXT_GC_LIST.length);
- for (var i = 0, len = __TEXT_GC_LIST.length-1; i < len; i++) {
- try {
- var _dummy = __TEXT_GC_LIST.shift();
- // console.log(!!(_dummy && _dummy.nodeValue))
- if (_dummy && _dummy.nodeValue) {
- if (_dummy.nodeValue == Trex.__WORD_JOINER) {
- if (startNode != _dummy) {
- // console.log('remove');
- $tom.remove(_dummy);
- } else {
- remained = _dummy;
- }
- } else {
- // console.log('replace');
- _dummy.nodeValue = _dummy.nodeValue.replace(Trex.__WORD_JOINER_REGEXP, "");
- }
- } else {
- // console.log("this's not dummy");
- }
- } catch(e) {
- }
- }
- remained && __TEXT_GC_LIST.splice(0, 0, remained);
- __HAS_DUMMY = _FALSE;
- }
- });
- })();
- /**
- * Wysiwyg 영역의 컨텐츠를 조작하기 위해 사용되며, <br/>
- * browser와 newlinepolicy에 따라 필요한 함수들을 mixin한다. <br/>
- * 이 객체를 통해서 Bookmark, txSelection, Marker 객체에 접근한다. <br/>
- * canvas.getProcessor()를 통해서 얻거나 <br/>
- * canvas.execute(), canvas.query()를 통해서 processor를 얻어서 사용한다. <br/>
- *
- * @abstract
- * @class
- * @param {Object} win - Wysiwyg 영역의 window 객체
- * @param {Object} doc - Wysiwyg 영역의 document 객체
- *
- * @example
- * canvas.execute(function(processor) {
- * processor.pasteContent('<img />', _FALSE);
- * });
- *
- * var value = canvas.query(function(processor) {
- * return processor.getText();
- * });
- *
- * var _processor = canvas.getProcessor();
- * _processor.focusOnTop();
- */
- Trex.Canvas.Processor = Trex.Class.draft({
- /** @ignore */
- $mixins: [
- Trex.I.Processor.Standard,
- (($tx.msie_nonstd)? Trex.I.Processor.Trident: {}),
- (($tx.msie_std)? Trex.I.Processor.TridentStandard: {}),
- (($tx.gecko)? Trex.I.Processor.Gecko: {}),
- (($tx.webkit)? Trex.I.Processor.Webkit: {}),
- (($tx.presto)? Trex.I.Processor.Presto: {})
- ]
- });
- /**
- * newlinepolicy가 p인 Wysiwyg Processor
- * @class
- * @extends Trex.Canvas.Processor
- * @param {Object} win - Wysiwyg 영역의 window 객체
- * @param {Object} doc - Wysiwyg 영역의 document 객체
- */
- Trex.Canvas.ProcessorP = Trex.Class.create({
- /** ignore */
- $extend: Trex.Canvas.Processor,
- /** @ignore */
- $mixins: [
- Trex.I.Processor.StandardP,
- (($tx.msie_nonstd)? Trex.I.Processor.TridentP: {}),
- (($tx.msie_std)? Trex.I.Processor.TridentStandardP: {}),
- (($tx.gecko)? Trex.I.Processor.GeckoP: {}),
- (($tx.webkit)? Trex.I.Processor.WebkitP: {}),
- (($tx.presto)? Trex.I.Processor.PrestoP: {})
- ]
- });
|