X-Git-Url: https://git.donarmstrong.com/?a=blobdiff_plain;f=program%2Fjs%2Fgoogiespell.js;h=3618fe10a3c99e12da6542b720cdfb22995a504e;hb=76507f7c63a660742e76889ad6e3919f3dde3bb0;hp=abd3462ecd267cb9f0b143529369631f14150460;hpb=b68022ca3782d5eb5a1a7ef6f8cf7abe1dc15bd6;p=roundcube.git diff --git a/program/js/googiespell.js b/program/js/googiespell.js index abd3462..3618fe1 100644 --- a/program/js/googiespell.js +++ b/program/js/googiespell.js @@ -1,1006 +1,39 @@ -/* - SpellCheck - jQuery'fied spell checker based on GoogieSpell 4.0 - Copyright Amir Salihefendic 2006 - Copyright Aleksander Machniak 2009 - LICENSE - GPL - AUTHORS - 4mir Salihefendic (http://amix.dk) - amix@amix.dk - Aleksander Machniak - alec [at] alec.pl -*/ - -var SPELL_CUR_LANG = null; -var GOOGIE_DEFAULT_LANG = 'en'; - -function GoogieSpell(img_dir, server_url) { - var ref = this; - - this.array_keys = function(arr) { - var res = []; - for (var key in arr) { res.push([key]); } - return res; - } - - var cookie_value = getCookie('language'); - GOOGIE_CUR_LANG = cookie_value != null ? cookie_value : GOOGIE_DEFAULT_LANG; - - this.img_dir = img_dir; - this.server_url = server_url; - - this.org_lang_to_word = { - "da": "Dansk", "de": "Deutsch", "en": "English", - "es": "Español", "fr": "Français", "it": "Italiano", - "nl": "Nederlands", "pl": "Polski", "pt": "Português", - "fi": "Suomi", "sv": "Svenska" - }; - this.lang_to_word = this.org_lang_to_word; - this.langlist_codes = this.array_keys(this.lang_to_word); - this.show_change_lang_pic = true; - this.change_lang_pic_placement = 'right'; - this.report_state_change = true; - - this.ta_scroll_top = 0; - this.el_scroll_top = 0; - - this.lang_chck_spell = "Check spelling"; - this.lang_revert = "Revert to"; - this.lang_close = "Close"; - this.lang_rsm_edt = "Resume editing"; - this.lang_no_error_found = "No spelling errors found"; - this.lang_no_suggestions = "No suggestions"; - - this.show_spell_img = false; // roundcube mod. - this.decoration = true; - this.use_close_btn = true; - this.edit_layer_dbl_click = true; - this.report_ta_not_found = true; - - //Extensions - this.custom_ajax_error = null; - this.custom_no_spelling_error = null; - this.custom_menu_builder = []; //Should take an eval function and a build menu function - this.custom_item_evaulator = null; //Should take an eval function and a build menu function - this.extra_menu_items = []; - this.custom_spellcheck_starter = null; - this.main_controller = true; - - //Observers - this.lang_state_observer = null; - this.spelling_state_observer = null; - this.show_menu_observer = null; - this.all_errors_fixed_observer = null; - - //Focus links - used to give the text box focus - this.use_focus = false; - this.focus_link_t = null; - this.focus_link_b = null; - - //Counters - this.cnt_errors = 0; - this.cnt_errors_fixed = 0; - - //Set document on click to hide the language and error menu - $(document).bind('click', function(e) { - if($(e.target).attr('googie_action_btn') != '1' && ref.isLangWindowShown()) - ref.hideLangWindow(); - if($(e.target).attr('googie_action_btn') != '1' && ref.isErrorWindowShown()) - ref.hideErrorWindow(); - }); - - -this.decorateTextarea = function(id) { - this.text_area = typeof(id) == 'string' ? document.getElementById(id) : id; - - if (this.text_area) { - if (!this.spell_container && this.decoration) { - var table = document.createElement('table'); - var tbody = document.createElement('tbody'); - var tr = document.createElement('tr'); - var spell_container = document.createElement('td'); - - var r_width = this.isDefined(this.force_width) ? this.force_width : this.text_area.offsetWidth; - var r_height = this.isDefined(this.force_height) ? this.force_height : 16; - - tr.appendChild(spell_container); - tbody.appendChild(tr); - $(table).append(tbody).insertBefore(this.text_area).width('100%').height(r_height); - $(spell_container).height(r_height).width(r_width).css('text-align', 'right'); - - this.spell_container = spell_container; - } - - this.checkSpellingState(); - } - else - if (this.report_ta_not_found) - alert('Text area not found'); -} - -////// -// API Functions (the ones that you can call) -///// -this.setSpellContainer = function(id) { - this.spell_container = typeof(id) == 'string' ? document.getElementById(id) : id; - -} - -this.setLanguages = function(lang_dict) { - this.lang_to_word = lang_dict; - this.langlist_codes = this.array_keys(lang_dict); -} - -this.setCurrentLanguage = function(lan_code) { - GOOGIE_CUR_LANG = lan_code; - - //Set cookie - var now = new Date(); - now.setTime(now.getTime() + 365 * 24 * 60 * 60 * 1000); - setCookie('language', lan_code, now); -} - -this.setForceWidthHeight = function(width, height) { - // Set to null if you want to use one of them - this.force_width = width; - this.force_height = height; -} - -this.setDecoration = function(bool) { - this.decoration = bool; -} - -this.dontUseCloseButtons = function() { - this.use_close_btn = false; -} - -this.appendNewMenuItem = function(name, call_back_fn, checker) { - this.extra_menu_items.push([name, call_back_fn, checker]); -} - -this.appendCustomMenuBuilder = function(eval, builder) { - this.custom_menu_builder.push([eval, builder]); -} - -this.setFocus = function() { - try { - this.focus_link_b.focus(); - this.focus_link_t.focus(); - return true; - } - catch(e) { - return false; - } -} - - -////// -// Set functions (internal) -///// -this.setStateChanged = function(current_state) { - this.state = current_state; - if (this.spelling_state_observer != null && this.report_state_change) - this.spelling_state_observer(current_state, this); -} - -this.setReportStateChange = function(bool) { - this.report_state_change = bool; -} - - -////// -// Request functions -///// -this.getUrl = function() { - return this.server_url + GOOGIE_CUR_LANG; -} - -this.escapeSpecial = function(val) { - return val.replace(/&/g, "&").replace(//g, ">"); -} - -this.createXMLReq = function (text) { - return '' - + '' - + '' + text + ''; -} - -this.spellCheck = function(ignore) { - this.cnt_errors_fixed = 0; - this.cnt_errors = 0; - this.setStateChanged('checking_spell'); - - if (this.main_controller) - this.appendIndicator(this.spell_span); - - this.error_links = []; - this.ta_scroll_top = this.text_area.scrollTop; - this.ignore = ignore; - this.hideLangWindow(); - - if ($(this.text_area).val() == '' || ignore) { - if (!this.custom_no_spelling_error) - this.flashNoSpellingErrorState(); - else - this.custom_no_spelling_error(this); - this.removeIndicator(); - return; - } - - this.createEditLayer(this.text_area.offsetWidth, this.text_area.offsetHeight); - this.createErrorWindow(); - $('body').append(this.error_window); - - try { netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead"); } - catch (e) { } - - if (this.main_controller) - $(this.spell_span).unbind('click'); - - this.orginal_text = $(this.text_area).val(); - var req_text = this.escapeSpecial(this.orginal_text); - var ref = this; - - $.ajax({ type: 'POST', url: this.getUrl(), - data: this.createXMLReq(req_text), dataType: 'text', - error: function(o) { - if (ref.custom_ajax_error) - ref.custom_ajax_error(ref); - else - alert('An error was encountered on the server. Please try again later.'); - if (ref.main_controller) { - $(ref.spell_span).remove(); - ref.removeIndicator(); - } - ref.checkSpellingState(); - }, - success: function(data) { - var r_text = data; - ref.results = ref.parseResult(r_text); - if (r_text.match(//) != null) { - //Before parsing be sure that errors were found - ref.showErrorsInIframe(); - ref.resumeEditingState(); - } else { - if (!ref.custom_no_spelling_error) - ref.flashNoSpellingErrorState(); - else - ref.custom_no_spelling_error(ref); - } - ref.removeIndicator(); - } - }); -} - - -////// -// Spell checking functions -///// -this.parseResult = function(r_text) { - // Returns an array: result[item] -> ['attrs'], ['suggestions'] - var re_split_attr_c = /\w+="(\d+|true)"/g; - var re_split_text = /\t/g; - - var matched_c = r_text.match(/]*>[^<]*<\/c>/g); - var results = new Array(); - - if (matched_c == null) - return results; - - for (var i=0; i < matched_c.length; i++) { - var item = new Array(); - this.errorFound(); - - //Get attributes - item['attrs'] = new Array(); - var split_c = matched_c[i].match(re_split_attr_c); - for (var j=0; j < split_c.length; j++) { - var c_attr = split_c[j].split(/=/); - var val = c_attr[1].replace(/"/g, ''); - item['attrs'][c_attr[0]] = val != 'true' ? parseInt(val) : val; - } - - //Get suggestions - item['suggestions'] = new Array(); - var only_text = matched_c[i].replace(/<[^>]*>/g, ''); - var split_t = only_text.split(re_split_text); - for (var k=0; k < split_t.length; k++) { - if(split_t[k] != '') - item['suggestions'].push(split_t[k]); - } - results.push(item); - } - return results; -} - - -////// -// Error menu functions -///// -this.createErrorWindow = function() { - this.error_window = document.createElement('div'); - $(this.error_window).addClass('googie_window').attr('googie_action_btn', '1'); -} - -this.isErrorWindowShown = function() { - return $(this.error_window).is(':visible'); -} - -this.hideErrorWindow = function() { - $(this.error_window).css('visibility', 'hidden'); - $(this.error_window_iframe).css('visibility', 'hidden'); -} - -this.updateOrginalText = function(offset, old_value, new_value, id) { - var part_1 = this.orginal_text.substring(0, offset); - var part_2 = this.orginal_text.substring(offset+old_value.length); - this.orginal_text = part_1 + new_value + part_2; - $(this.text_area).val(this.orginal_text); - var add_2_offset = new_value.length - old_value.length; - for (var j=0; j < this.results.length; j++) { - //Don't edit the offset of the current item - if (j != id && j > id) - this.results[j]['attrs']['o'] += add_2_offset; - } -} - -this.saveOldValue = function(elm, old_value) { - elm.is_changed = true; - elm.old_value = old_value; -} - -this.createListSeparator = function() { - var td = document.createElement('td'); - var tr = document.createElement('tr'); - - $(td).html(' ').attr('googie_action_btn', '1') - .css({'cursor': 'default', 'font-size': '3px', 'border-top': '1px solid #ccc', 'padding-top': '3px'}); - tr.appendChild(td); - - return tr; -} - -this.correctError = function(id, elm, l_elm, rm_pre_space) { - var old_value = elm.innerHTML; - var new_value = l_elm.nodeType == 3 ? l_elm.nodeValue : l_elm.innerHTML; - var offset = this.results[id]['attrs']['o']; - - if (rm_pre_space) { - var pre_length = elm.previousSibling.innerHTML; - elm.previousSibling.innerHTML = pre_length.slice(0, pre_length.length-1); - old_value = " " + old_value; - offset--; - } - - this.hideErrorWindow(); - this.updateOrginalText(offset, old_value, new_value, id); - - $(elm).html(new_value).css('color', 'green').attr('is_corrected', true); - - this.results[id]['attrs']['l'] = new_value.length; - - if (!this.isDefined(elm.old_value)) - this.saveOldValue(elm, old_value); - - this.errorFixed(); -} - -this.showErrorWindow = function(elm, id) { - if (this.show_menu_observer) - this.show_menu_observer(this); - - var ref = this; - var pos = $(elm).offset(); - pos.top -= this.edit_layer.scrollTop; - - $(this.error_window).css({'visibility': 'visible', - 'top': (pos.top+20)+'px', 'left': (pos.left)+'px'}).html(''); - - var table = document.createElement('table'); - var list = document.createElement('tbody'); - - $(table).addClass('googie_list').attr('googie_action_btn', '1'); - - //Check if we should use custom menu builder, if not we use the default - var changed = false; - if (this.custom_menu_builder != []) { - for (var k=0; k 0) - list.appendChild(this.createListSeparator()); - - var loop = function(i) { - if (i < ref.extra_menu_items.length) { - var e_elm = ref.extra_menu_items[i]; - - if (!e_elm[2] || e_elm[2](elm, ref)) { - var e_row = document.createElement('tr'); - var e_col = document.createElement('td'); - - $(e_col).html(e_elm[0]) - .bind('mouseover', ref.item_onmouseover) - .bind('mouseout', ref.item_onmouseout) - .bind('click', function() { return e_elm[1](elm, ref) }); - - e_row.appendChild(e_col); - list.appendChild(e_row); - } - loop(i+1); - } - } - - loop(0); - loop = null; - - //Close button - if (this.use_close_btn) { - list.appendChild(this.createCloseButton(this.hideErrorWindow)); - } - } - - table.appendChild(list); - this.error_window.appendChild(table); - - //Dummy for IE - dropdown bug fix - if ($.browser.msie) { - if (!this.error_window_iframe) { - var iframe = $('