@@ -11,7 +11,7 @@ jQuery.noConflict();
1111 , KEYCODE_SPACEBAR = 32
1212
1313 , DEFAULT_CLEAR_BUFFER_TIMEOUT = 750
14- , TIME_OUTLOOK_EDITOR_CHECK = 500
14+ , TIME_EDITOR_CHECK = 500
1515
1616 , DATE_MACRO_REGEX = / % d \( / g
1717 , DATE_MACRO_CLOSE_TAG = ')'
@@ -24,6 +24,7 @@ jQuery.noConflict();
2424 , GMAIL_DOMAIN_REGEX = / m a i l .g o o g l e .c o m /
2525 , INBOX_DOMAIN_REGEX = / i n b o x .g o o g l e .c o m /
2626 , OUTLOOK_DOMAIN_REGEX = / m a i l .l i v e .c o m /
27+ , MAILCHIMP_DOMAIN_REGEX = / a d m i n .m a i l c h i m p .c o m /
2728
2829 , EVENT_NAME_KEYPRESS = 'keypress.auto-expander'
2930 , EVENT_NAME_KEYUP = 'keyup.auto-expander'
@@ -36,9 +37,10 @@ jQuery.noConflict();
3637 , SELECTOR_INPUT = 'div[contenteditable=true],body[contenteditable=true],textarea,input'
3738 , SELECTOR_GMAIL_EDIT = 'div.aoI' // Class for Gmail's popup message composer
3839 , SELECTOR_INBOX_EDIT = 'div.aT' // Class for Inbox's inline reply container
39- , SELECTOR_OUTLOOK_EDIT = '#ComposeRteEditor_surface'
40- , SELECTOR_EVERNOTE_EDIT = 'gwt-debug-noteEditor'
41- , SELECTOR_BASECAMP_EDIT = 'iframe.wysihtml5-sandbox'
40+ , SELECTOR_MAILCHIMP_EDIT = 'iframe.cke_wysiwyg_frame' // Mailchimp web editor
41+ , SELECTOR_OUTLOOK_EDIT = '#ComposeRteEditor_surface' // Outlook web editor
42+ , SELECTOR_EVERNOTE_EDIT = 'gwt-debug-noteEditor' // Evernote web note editor
43+ , SELECTOR_BASECAMP_EDIT = 'iframe.wysihtml5-sandbox' // Basecamp message editor
4244 ;
4345
4446 var typingBuffer = [ ] ; // Keep track of what's been typed before timeout
@@ -213,6 +215,8 @@ jQuery.noConflict();
213215 replaceTextOutlook ( shortcut , autotext ) ;
214216 } else if ( EVERNOTE_DOMAIN_REGEX . test ( domain ) ) {
215217 replaceTextEvernote ( shortcut , autotext ) ;
218+ } else if ( MAILCHIMP_DOMAIN_REGEX . test ( domain ) ) {
219+ replaceTextMailchimp ( shortcut , autotext ) ;
216220 } else if ( BASECAMP_DOMAIN_REGEX . test ( domain ) ) {
217221 replaceTextBasecamp ( shortcut , autotext ) ;
218222 } else {
@@ -347,6 +351,21 @@ jQuery.noConflict();
347351 replaceTextContentEditable ( shortcut , autotext , node , iframeWindow ) ;
348352 }
349353
354+ // Specific handler for Mailchimp iframe replacements
355+ function replaceTextMailchimp ( shortcut , autotext )
356+ {
357+ debugLog ( "Domain: Mailchimp" ) ;
358+
359+ // Get the focused / selected text node
360+ var iframeWindow = document . querySelector ( SELECTOR_MAILCHIMP_EDIT )
361+ . contentWindow ;
362+ var node = findFocusedNode ( iframeWindow ) ;
363+ debugLog ( "node:" , node ) ;
364+
365+ // Pass onto editable iframe text handler
366+ replaceTextContentEditable ( shortcut , autotext , node , iframeWindow ) ;
367+ }
368+
350369 // Reusable handler for editable iframe text replacements
351370 function replaceTextContentEditable ( shortcut , autotext , node , win )
352371 {
@@ -738,8 +757,10 @@ jQuery.noConflict();
738757 return ; // Just return, otherwise will throw exception
739758 }
740759
741- $target . contents ( ) . on ( EVENT_NAME_KEYPRESS , SELECTOR_INPUT , keyPressHandler ) ;
742- $target . contents ( ) . on ( EVENT_NAME_KEYUP , SELECTOR_INPUT , keyUpHandler ) ;
760+ $target . contents ( ) . off ( EVENT_NAME_KEYPRESS )
761+ . on ( EVENT_NAME_KEYPRESS , SELECTOR_INPUT , keyPressHandler ) ;
762+ $target . contents ( )
763+ . on ( EVENT_NAME_KEYUP , SELECTOR_INPUT , keyUpHandler ) ;
743764 }
744765 catch ( exception ) {
745766 console . log ( exception ) ;
@@ -799,7 +820,7 @@ jQuery.noConflict();
799820 debugLog ( "Domain: Gmail" ) ;
800821 SELECTOR_INPUT += ',div.editable' ;
801822
802- // Annoying way to do this, but need to check for focus on div.aoI
823+ // Need to check for focus on div.aoI
803824 $document . on ( EVENT_NAME_FOCUS , SELECTOR_GMAIL_EDIT , function ( event )
804825 {
805826 debugLog ( 'focused on message editor' ) ;
@@ -818,28 +839,42 @@ jQuery.noConflict();
818839 debugLog ( "Domain: Google Inbox" ) ;
819840 SELECTOR_INPUT += ',' + SELECTOR_INBOX_EDIT ;
820841
821- // Annoying way to do this, but need to check for focus on editable elements
842+ // Need to check for focus on editable elements
822843 $document . on ( EVENT_NAME_FOCUS , SELECTOR_INPUT , function ( event )
823844 {
824845 debugLog ( 'focused on editable element:' , event . target ) ;
825846 refreshListenersOnElement ( $ ( event . target ) ) ;
826847 } ) ;
827848 }
828849
829-
830850 // Special case for Outlook.com
831851 if ( OUTLOOK_DOMAIN_REGEX . test ( domain ) )
832852 {
833853 debugLog ( "Domain: Outlook" ) ;
834854
835- // Super annoying way to do this , need to check for #ComposeRteEditor_surface
855+ // Annoying , need to check for existence of editor element
836856 var editorCheck = setInterval ( function ( ) {
837857 var $target = $ ( SELECTOR_OUTLOOK_EDIT ) ;
838858 if ( $target . length ) {
839859 clearInterval ( editorCheck ) ;
840860 addListenersToIframe ( $target ) ;
841861 }
842- } , TIME_OUTLOOK_EDITOR_CHECK ) ;
862+ } , TIME_EDITOR_CHECK ) ;
863+ }
864+
865+ // Special case for Mailchimp
866+ if ( MAILCHIMP_DOMAIN_REGEX . test ( domain ) )
867+ {
868+ debugLog ( "Domain: Mailchimp" ) ;
869+
870+ // SUPER annoying, need to continually check for existence of editor iframe
871+ // because the iframe gets recreated each time and starts with cross-origin
872+ var editorCheck = setInterval ( function ( ) {
873+ var $target = $ ( SELECTOR_MAILCHIMP_EDIT ) ;
874+ if ( $target . length ) {
875+ addListenersToIframe ( $target ) ;
876+ }
877+ } , TIME_EDITOR_CHECK ) ;
843878 }
844879
845880 // Attach to future iframes
0 commit comments