| //////////////////////////////////////////////////////////////////////////////// |
| // |
| // Licensed to the Apache Software Foundation (ASF) under one or more |
| // contributor license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright ownership. |
| // The ASF licenses this file to You under the Apache License, Version 2.0 |
| // (the "License"); you may not use this file except in compliance with |
| // the License. You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| // |
| //////////////////////////////////////////////////////////////////////////////// |
| |
| package com.adobe.linguistics.spelling.ui |
| { |
| import com.adobe.linguistics.utils.ITokenizer; |
| import com.adobe.linguistics.utils.TextTokenizer; |
| import com.adobe.linguistics.utils.Token; |
| |
| import flashx.textLayout.edit.SelectionManager; |
| import flashx.textLayout.tlf_internal; |
| |
| import spark.components.RichEditableText; |
| |
| use namespace tlf_internal; |
| |
| public class SparkWordProcessor implements IWordProcessor |
| { |
| private var mTextField:RichEditableText; |
| |
| public function SparkWordProcessor(textField:RichEditableText) |
| { |
| if (textField == null ) throw new Error("illegal argument."); |
| mTextField = textField; |
| } |
| |
| |
| public function replaceText(startIndex:int, endIndex:int, replacement:String):void { |
| var ta:RichEditableText = mTextField; |
| var end:int = getValidLastWordIndex(); |
| |
| if ( replacement == null ) return; |
| |
| if (mTextField.text.length<endIndex || startIndex<0) { |
| return; |
| } |
| |
| var _misspellStart:int = startIndex; |
| var _misspellEnd:int = endIndex; |
| |
| // Workaround for Spark: changes in inactive components will trigger strange behavior |
| ta.setFocus(); |
| ta.text = ta.text.substr(0, _misspellStart) + replacement + ta.text.substr(_misspellEnd); |
| ta.textFlow; |
| ta.selectRange(_misspellStart + replacement.length, _misspellStart + replacement.length); |
| |
| // Workaround for unexpected jump |
| ta.scrollToRange(end, end); |
| } |
| |
| public function getWordAtPoint(x:uint, y:uint, externalTokenizer:ITokenizer=null):Token |
| { |
| // TODO: use a better alternative than _misspellStart, end |
| var ta:RichEditableText = mTextField; |
| var index:int = SelectionManager.computeSelectionIndex(ta.textFlow, ta, ta, x, y); |
| |
| if (index >= ta.text.length) return null; |
| |
| var tmpToken:Token = new Token(index,index); |
| var tokenizer:ITokenizer; |
| if ( externalTokenizer == null ) { |
| tokenizer = new TextTokenizer(mTextField.text); |
| }else { |
| tokenizer = externalTokenizer; |
| } |
| |
| var result:Token = new Token(0,0); |
| var preToken:Token = tokenizer.getPreviousToken(tmpToken); |
| var nextToken:Token = tokenizer.getNextToken(tmpToken); |
| if ( preToken.last == nextToken.first ) { |
| result.first = preToken.first; |
| result.last = nextToken.last; |
| return result; |
| }else { |
| return null; |
| } |
| |
| } |
| |
| // TODO: workaround for unexpected jump when word replaced, to be refactored for code sharing |
| private function getValidLastWordIndex():int{ |
| var index:int = SelectionManager.computeSelectionIndex(mTextField.textFlow, mTextField, mTextField, mTextField.width+mTextField.horizontalScrollPosition, mTextField.height+mTextField.verticalScrollPosition); |
| return index; |
| } |
| |
| |
| } |
| } |