},\r
\r
open : function(f, p) {\r
- var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u;\r
+ var t = this, id, opt = '', ed = t.editor, dw = 0, dh = 0, vp, po, mdf, clf, we, w, u, parentWindow;\r
\r
f = f || {};\r
p = p || {};\r
if (!f.inline)\r
return t.parent(f, p);\r
\r
+ parentWindow = t._frontWindow();\r
+ if (parentWindow && DOM.get(parentWindow.id + '_ifr')) {\r
+ parentWindow.focussedElement = DOM.get(parentWindow.id + '_ifr').contentWindow.document.activeElement;\r
+ }\r
+ \r
// Only store selection if the type is a normal window\r
if (!f.type)\r
t.bookmark = ed.selection.getBookmark(1);\r
\r
// Create DOM objects\r
t._addAll(DOM.doc.body, \r
- ['div', {id : id, 'class' : ed.settings.inlinepopups_skin || 'clearlooks2', style : 'width:100px;height:100px'}, \r
+ ['div', {id : id, role : 'dialog', 'aria-labelledby': f.type ? id + '_content' : id + '_title', 'class' : (ed.settings.inlinepopups_skin || 'clearlooks2') + (tinymce.isIE && window.getSelection ? ' ie9' : ''), style : 'width:100px;height:100px'}, \r
['div', {id : id + '_wrapper', 'class' : 'mceWrapper' + opt},\r
['div', {id : id + '_top', 'class' : 'mceTop'}, \r
['div', {'class' : 'mceLeft'}],\r
],\r
\r
['div', {id : id + '_middle', 'class' : 'mceMiddle'}, \r
- ['div', {id : id + '_left', 'class' : 'mceLeft'}],\r
+ ['div', {id : id + '_left', 'class' : 'mceLeft', tabindex : '0'}],\r
['span', {id : id + '_content'}],\r
- ['div', {id : id + '_right', 'class' : 'mceRight'}]\r
+ ['div', {id : id + '_right', 'class' : 'mceRight', tabindex : '0'}]\r
],\r
\r
['div', {id : id + '_bottom', 'class' : 'mceBottom'},\r
\r
DOM.add(id + '_middle', 'div', {'class' : 'mceIcon'});\r
DOM.setHTML(id + '_content', f.content.replace('\n', '<br />'));\r
+ \r
+ Event.add(id, 'keyup', function(evt) {\r
+ var VK_ESCAPE = 27;\r
+ if (evt.keyCode === VK_ESCAPE) {\r
+ f.button_func(false);\r
+ return Event.cancel(evt);\r
+ }\r
+ });\r
+\r
+ Event.add(id, 'keydown', function(evt) {\r
+ var cancelButton, VK_TAB = 9;\r
+ if (evt.keyCode === VK_TAB) {\r
+ cancelButton = DOM.select('a.mceCancel', id + '_wrapper')[0];\r
+ if (cancelButton && cancelButton !== evt.target) {\r
+ cancelButton.focus();\r
+ } else {\r
+ DOM.get(id + '_ok').focus();\r
+ }\r
+ return Event.cancel(evt);\r
+ }\r
+ });\r
}\r
\r
// Register events\r
}\r
}\r
});\r
-\r
+ \r
+ // Make sure the tab order loops within the dialog.\r
+ Event.add([id + '_left', id + '_right'], 'focus', function(evt) {\r
+ var iframe = DOM.get(id + '_ifr');\r
+ if (iframe) {\r
+ var body = iframe.contentWindow.document.body;\r
+ var focusable = DOM.select(':input:enabled,*[tabindex=0]', body);\r
+ if (evt.target.id === (id + '_left')) {\r
+ focusable[focusable.length - 1].focus();\r
+ } else {\r
+ focusable[0].focus();\r
+ }\r
+ } else {\r
+ DOM.get(id + '_ok').focus();\r
+ }\r
+ });\r
+ \r
// Add window\r
w = t.windows[id] = {\r
id : id,\r
});\r
\r
DOM.show('mceModalBlocker'); // Reduces flicker in IE\r
+ DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'true');\r
} else\r
DOM.setStyle('mceModalBlocker', 'z-index', t.zIndex - 1);\r
\r
if (tinymce.isIE6 || /Firefox\/2\./.test(navigator.userAgent) || (tinymce.isIE && !DOM.boxModel))\r
DOM.setStyles('mceModalBlocker', {position : 'absolute', left : vp.x, top : vp.y, width : vp.w - 2, height : vp.h - 2});\r
\r
+ DOM.setAttrib(id, 'aria-hidden', 'false');\r
t.focus(id);\r
t._fixIELayout(id, 1);\r
\r
// Focus ok button\r
if (DOM.get(id + '_ok'))\r
DOM.get(id + '_ok').focus();\r
-\r
t.count++;\r
\r
return w;\r
DOM.removeClass(t.lastId, 'mceFocus');\r
DOM.addClass(id, 'mceFocus');\r
t.lastId = id;\r
+ \r
+ if (w.focussedElement) {\r
+ w.focussedElement.focus();\r
+ } else if (DOM.get(id + '_ok')) {\r
+ DOM.get(w.id + '_ok').focus();\r
+ } else if (DOM.get(w.id + '_ifr')) {\r
+ DOM.get(w.id + '_ifr').focus();\r
+ }\r
}\r
},\r
\r
},\r
\r
close : function(win, id) {\r
- var t = this, w, d = DOM.doc, ix = 0, fw, id;\r
+ var t = this, w, d = DOM.doc, fw, id;\r
\r
id = t._findId(id || win);\r
\r
\r
t.count--;\r
\r
- if (t.count == 0)\r
+ if (t.count == 0) {\r
DOM.remove('mceModalBlocker');\r
+ DOM.setAttrib(DOM.doc.body, 'aria-hidden', 'false');\r
+ t.editor.focus();\r
+ }\r
\r
if (w = t.windows[id]) {\r
t.onClose.dispatch(t);\r
w.element.remove();\r
delete t.windows[id];\r
\r
- // Find front most window and focus that\r
- each (t.windows, function(w) {\r
- if (w.zIndex > ix) {\r
- fw = w;\r
- ix = w.zIndex;\r
- }\r
- });\r
+ fw = t._frontWindow();\r
\r
if (fw)\r
t.focus(fw.id);\r
}\r
},\r
+ \r
+ // Find front most window\r
+ _frontWindow : function() {\r
+ var fw, ix = 0;\r
+ // Find front most window and focus that\r
+ each (this.windows, function(w) {\r
+ if (w.zIndex > ix) {\r
+ fw = w;\r
+ ix = w.zIndex;\r
+ }\r
+ });\r
+ return fw;\r
+ },\r
\r
setTitle : function(w, ti) {\r
var e;\r