Merge pull request #2566 from ether/editbar-accessibility
Accessibility
This commit is contained in:
commit
a5345524e1
|
@ -38,7 +38,24 @@
|
|||
"pad.settings.rtlcheck": "Read content from right to left?",
|
||||
"pad.settings.fontType": "Font type:",
|
||||
"pad.settings.fontType.normal": "Normal",
|
||||
"pad.settings.fontType.opendyslexic": "Open Dyslexic",
|
||||
"pad.settings.fontType.monospaced": "Monospace",
|
||||
"pad.settings.fontType.comicsans": "Comic Sans",
|
||||
"pad.settings.fontType.couriernew": "Courier New",
|
||||
"pad.settings.fontType.georgia": "Georgia",
|
||||
"pad.settings.fontType.impact": "Impact",
|
||||
"pad.settings.fontType.lucida": "Lucida",
|
||||
"pad.settings.fontType.lucidasans": "Lucida Sans",
|
||||
"pad.settings.fontType.palatino": "Palatino",
|
||||
"pad.settings.fontType.tahoma": "Tahoma",
|
||||
"pad.settings.fontType.timesnewroman": "Times New Roman",
|
||||
"pad.settings.fontType.trebuchet": "Trebuchet",
|
||||
"pad.settings.fontType.verdana": "Verdana",
|
||||
"pad.settings.fontType.symbol": "Symbol",
|
||||
"pad.settings.fontType.webdings": "Webdings",
|
||||
"pad.settings.fontType.wingdings": "Wingdings",
|
||||
"pad.settings.fontType.sansserif": "Sans Serif",
|
||||
"pad.settings.fontType.serif": "Serif",
|
||||
"pad.settings.globalView": "Global View",
|
||||
"pad.settings.language": "Language:",
|
||||
|
||||
|
@ -105,6 +122,10 @@
|
|||
"timeslider.version": "Version {{version}}",
|
||||
"timeslider.saved": "Saved {{month}} {{day}}, {{year}}",
|
||||
|
||||
"timeslider.playPause": "Playback / Pause Pad Contents",
|
||||
"timeslider.backRevision":"Go back a revision in this Pad",
|
||||
"timeslider.forwardRevision":"Go forward a revision in this Pad",
|
||||
|
||||
"timeslider.dateformat": "{{month}}/{{day}}/{{year}} {{hours}}:{{minutes}}:{{seconds}}",
|
||||
"timeslider.month.january": "January",
|
||||
"timeslider.month.february": "February",
|
||||
|
|
|
@ -148,6 +148,9 @@ exports.doImport = function(req, res, padId)
|
|||
if(!importHandledByPlugin || !directDatabaseAccess){
|
||||
var fileEnding = path.extname(srcFile).toLowerCase();
|
||||
var fileIsHTML = (fileEnding === ".html" || fileEnding === ".htm");
|
||||
var fileIsTXT = (fileEnding === ".txt");
|
||||
if (fileIsTXT) abiword = false; // Don't use abiword for text files
|
||||
// See https://github.com/ether/etherpad-lite/issues/2572
|
||||
if (abiword && !fileIsHTML) {
|
||||
abiword.convertFile(srcFile, destFile, "htm", function(err) {
|
||||
//catch convert errors
|
||||
|
@ -213,7 +216,7 @@ exports.doImport = function(req, res, padId)
|
|||
// Title needs to be stripped out else it appends it to the pad..
|
||||
text = text.replace("<title>", "<!-- <title>");
|
||||
text = text.replace("</title>","</title>-->");
|
||||
|
||||
|
||||
//node on windows has a delay on releasing of the file lock.
|
||||
//We add a 100ms delay to work around this
|
||||
if(os.type().indexOf("Windows") > -1){
|
||||
|
@ -245,7 +248,6 @@ exports.doImport = function(req, res, padId)
|
|||
padManager.getPad(padId, function(err, _pad){
|
||||
var pad = _pad;
|
||||
padManager.unloadPad(padId);
|
||||
|
||||
// direct Database Access means a pad user should perform a switchToPad
|
||||
// and not attempt to recieve updated pad data..
|
||||
if(!directDatabaseAccess){
|
||||
|
|
|
@ -100,7 +100,7 @@ exports.toolbar = {
|
|||
["showusers"]
|
||||
],
|
||||
timeslider: [
|
||||
["timeslider_export", "timeslider_returnToPad"]
|
||||
["timeslider_export", "timeslider_settings", "timeslider_returnToPad"]
|
||||
]
|
||||
}
|
||||
|
||||
|
|
|
@ -99,12 +99,14 @@ _.extend(Button.prototype, {
|
|||
};
|
||||
return tag("li", liAttributes,
|
||||
tag("a", { "class": this.grouping, "data-l10n-id": this.attributes.localizationId },
|
||||
tag("span", { "class": " "+ this.attributes.class })
|
||||
tag("button", { "class": " "+ this.attributes.class, "data-l10n-id": this.attributes.localizationId })
|
||||
)
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
||||
SelectButton = function (attributes) {
|
||||
this.attributes = attributes;
|
||||
this.options = [];
|
||||
|
@ -208,6 +210,12 @@ module.exports = {
|
|||
class: "buttonicon buttonicon-import_export"
|
||||
},
|
||||
|
||||
timeslider_settings: {
|
||||
command: "settings",
|
||||
localizationId: "pad.toolbar.settings.title",
|
||||
class: "buttonicon buttonicon-settings"
|
||||
},
|
||||
|
||||
timeslider_returnToPad: {
|
||||
command: "timeslider_returnToPad",
|
||||
localizationId: "timeslider.toolbar.returnbutton",
|
||||
|
|
|
@ -70,10 +70,6 @@ a img {
|
|||
.toolbar ul li {
|
||||
float: left;
|
||||
margin-left: 2px;
|
||||
-webkit-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
height:32px;
|
||||
}
|
||||
.toolbar ul li.separator {
|
||||
|
@ -141,9 +137,24 @@ a img {
|
|||
top: 1px;
|
||||
}
|
||||
.toolbar ul li a .buttontext {
|
||||
color: #222;
|
||||
color: #666;
|
||||
font-size: 14px;
|
||||
border:none;
|
||||
background:none;
|
||||
margin-top:1px;
|
||||
color:#666;
|
||||
}
|
||||
|
||||
.buttontext::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
.buttontext:focus{
|
||||
/* Not sure why important is required here but it is */
|
||||
border: 1px solid #666 !important;
|
||||
}
|
||||
|
||||
.toolbar ul li a.grouped-left {
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
@ -197,6 +208,7 @@ li[data-key=showusers] > a #online_count {
|
|||
#editbar{
|
||||
display:none;
|
||||
}
|
||||
|
||||
#editorcontainer {
|
||||
position: absolute;
|
||||
top: 37px; /* + 1px border */
|
||||
|
@ -742,12 +754,24 @@ table#otheruserstable {
|
|||
height: 16px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
|
||||
border: none;
|
||||
padding: 0;
|
||||
background: none;
|
||||
font-family: "fontawesome-etherpad";
|
||||
font-size: 15px;
|
||||
font-style: normal;
|
||||
font-weight: normal;
|
||||
color: #666;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.buttonicon::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0
|
||||
}
|
||||
|
||||
.buttonicon:focus{
|
||||
border: 1px solid #666;
|
||||
}
|
||||
.buttonicon-bold:before {
|
||||
content: "\e81c";
|
||||
|
@ -1216,6 +1240,11 @@ input[type=checkbox] {
|
|||
}
|
||||
/* End of gritter stuff */
|
||||
|
||||
@font-face {
|
||||
font-family: opendyslexic;
|
||||
src: url("../../static/font/opendyslexic.otf") format("opentype");
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: "fontawesome-etherpad";
|
||||
src:url("../font/fontawesome-etherpad.eot");
|
||||
|
@ -1254,3 +1283,11 @@ input[type=checkbox] {
|
|||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
.hideControlsEditor{
|
||||
top:0px !important;
|
||||
}
|
||||
.hideControlsEditbar{
|
||||
display:none !important;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -78,6 +78,7 @@
|
|||
width: 44px;
|
||||
text-align:center;
|
||||
vertical-align:middle;
|
||||
background:none;
|
||||
}
|
||||
#playpause_button {
|
||||
right: 77px;
|
||||
|
@ -125,7 +126,7 @@
|
|||
font-family: fontawesome-etherpad;
|
||||
border-radius:2px;
|
||||
border: #666 solid 1px;
|
||||
line-height:18px;
|
||||
/* line-height:18px; */
|
||||
text-align:center;
|
||||
height:22px;
|
||||
color:#666;
|
||||
|
@ -204,12 +205,9 @@ stepper:active{
|
|||
float:right;
|
||||
height:30px;
|
||||
}
|
||||
#settings,
|
||||
#import_export,
|
||||
#embed,
|
||||
#connectivity,
|
||||
#users {
|
||||
top: 62px;
|
||||
#import_export, #settings{
|
||||
top: 115px;
|
||||
position: fixed;
|
||||
}
|
||||
#import_export .popup {
|
||||
width: 183px;
|
||||
|
@ -218,9 +216,7 @@ stepper:active{
|
|||
border-radius: 0 0 0 6px;
|
||||
}
|
||||
#import_export {
|
||||
top: 115px;
|
||||
width: 185px;
|
||||
position: fixed;
|
||||
}
|
||||
.timeslider-bar {
|
||||
background: #f7f7f7;
|
||||
|
@ -236,7 +232,7 @@ stepper:active{
|
|||
.timeslider-bar #editbar {
|
||||
border-bottom: none;
|
||||
float: right;
|
||||
width: 170px;
|
||||
width: 180px;
|
||||
}
|
||||
.timeslider-bar h1 {
|
||||
margin: 5px
|
||||
|
@ -337,3 +333,19 @@ OL {
|
|||
.list-number6 {
|
||||
list-style-type: lower-roman
|
||||
}
|
||||
|
||||
button{
|
||||
margin:0;
|
||||
padding:0;
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
button::-moz-focus-inner {
|
||||
padding: 0;
|
||||
border: 0
|
||||
}
|
||||
|
||||
button:focus{
|
||||
border: 1px solid #666;
|
||||
}
|
||||
|
||||
|
|
Binary file not shown.
|
@ -265,7 +265,7 @@ plugins.ensure(function () {\n\
|
|||
iframeHTML: iframeHTML
|
||||
});
|
||||
|
||||
iframeHTML.push('</head><body id="innerdocbody" class="syntax" spellcheck="false"> </body></html>');
|
||||
iframeHTML.push('</head><body id="innerdocbody" role="application" class="syntax" spellcheck="false"> </body></html>');
|
||||
|
||||
// Expose myself to global for my child frame.
|
||||
var thisFunctionsName = "ChildAccessibleAce2Editor";
|
||||
|
@ -279,6 +279,7 @@ window.onload = function () {\n\
|
|||
setTimeout(function () {\n\
|
||||
var iframe = document.createElement("IFRAME");\n\
|
||||
iframe.name = "ace_inner";\n\
|
||||
iframe.title = "pad";\n\
|
||||
iframe.scrolling = "no";\n\
|
||||
var outerdocbody = document.getElementById("outerdocbody");\n\
|
||||
iframe.frameBorder = 0;\n\
|
||||
|
@ -319,6 +320,7 @@ window.onload = function () {\n\
|
|||
var outerFrame = document.createElement("IFRAME");
|
||||
outerFrame.name = "ace_outer";
|
||||
outerFrame.frameBorder = 0; // for IE
|
||||
outerFrame.title = "Ether";
|
||||
info.frame = outerFrame;
|
||||
document.getElementById(containerId).appendChild(outerFrame);
|
||||
|
||||
|
|
|
@ -3618,6 +3618,8 @@ function Ace2Inner(){
|
|||
var charCode = evt.charCode;
|
||||
var keyCode = evt.keyCode;
|
||||
var which = evt.which;
|
||||
var altKey = evt.altKey;
|
||||
var shiftKey = evt.shiftKey;
|
||||
|
||||
// prevent ESC key
|
||||
if (keyCode == 27)
|
||||
|
@ -3658,7 +3660,6 @@ function Ace2Inner(){
|
|||
if (keyCode == 13 && browser.opera && (type == "keypress")){
|
||||
return; // This stops double enters in Opera but double Tabs still show on single tab keypress, adding keyCode == 9 to this doesn't help as the event is fired twice
|
||||
}
|
||||
|
||||
var specialHandled = false;
|
||||
var isTypeForSpecialKey = ((browser.msie || browser.safari || browser.chrome) ? (type == "keydown") : (type == "keypress"));
|
||||
var isTypeForCmdKey = ((browser.msie || browser.safari || browser.chrome) ? (type == "keydown") : (type == "keypress"));
|
||||
|
@ -3689,6 +3690,101 @@ function Ace2Inner(){
|
|||
evt:evt
|
||||
});
|
||||
specialHandled = (specialHandledInHook&&specialHandledInHook.length>0)?specialHandledInHook[0]:specialHandled;
|
||||
if ((!specialHandled) && altKey && isTypeForSpecialKey && keyCode == 120){
|
||||
// Alt F9 focuses on the File Menu and/or editbar.
|
||||
// Note that while most editors use Alt F10 this is not desirable
|
||||
// As ubuntu cannot use Alt F10....
|
||||
// Focus on the editbar. -- TODO: Move Focus back to previous state (we know it so we can use it)
|
||||
var firstEditbarElement = parent.parent.$('#editbar').children("ul").first().children().first().children().first().children().first();
|
||||
$(this).blur();
|
||||
firstEditbarElement.focus();
|
||||
evt.preventDefault();
|
||||
}
|
||||
if ((!specialHandled) && altKey && keyCode == 67){
|
||||
// Alt c focuses on the Chat window
|
||||
$(this).blur();
|
||||
parent.parent.chat.show();
|
||||
parent.parent.chat.focus();
|
||||
evt.preventDefault();
|
||||
}
|
||||
if ((!specialHandled) && evt.ctrlKey && shiftKey && keyCode == 50 && type === "keydown"){
|
||||
// Control-Shift-2 shows a gritter popup showing a line author
|
||||
var lineNumber = rep.selEnd[0];
|
||||
var alineAttrs = rep.alines[lineNumber];
|
||||
var apool = rep.apool;
|
||||
|
||||
// TODO: support selection ranges
|
||||
// TODO: Still work when authorship colors have been cleared
|
||||
// TODO: i18n
|
||||
// TODO: There appears to be a race condition or so.
|
||||
|
||||
var author = null;
|
||||
if (alineAttrs) {
|
||||
var authors = [];
|
||||
var authorNames = [];
|
||||
var opIter = Changeset.opIterator(alineAttrs);
|
||||
|
||||
while (opIter.hasNext()){
|
||||
var op = opIter.next();
|
||||
authorId = Changeset.opAttributeValue(op, 'author', apool);
|
||||
|
||||
// Only push unique authors and ones with values
|
||||
if(authors.indexOf(authorId) === -1 && authorId !== ""){
|
||||
authors.push(authorId);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// No author information is available IE on a new pad.
|
||||
if(authors.length === 0){
|
||||
var authorString = "No author information is available";
|
||||
}
|
||||
else{
|
||||
// Known authors info, both current and historical
|
||||
var padAuthors = parent.parent.pad.userList();
|
||||
var authorObj = {};
|
||||
authors.forEach(function(authorId){
|
||||
padAuthors.forEach(function(padAuthor){
|
||||
// If the person doing the lookup is the author..
|
||||
if(padAuthor.userId === authorId){
|
||||
if(parent.parent.clientVars.userId === authorId){
|
||||
authorObj = {
|
||||
name: "Me"
|
||||
}
|
||||
}else{
|
||||
authorObj = padAuthor;
|
||||
}
|
||||
}
|
||||
});
|
||||
if(!authorObj){
|
||||
author = "Unknown";
|
||||
return;
|
||||
}
|
||||
author = authorObj.name;
|
||||
if(!author) author = "Unknown";
|
||||
authorNames.push(author);
|
||||
})
|
||||
}
|
||||
if(authors.length === 1){
|
||||
var authorString = "The author of this line is " + authorNames;
|
||||
}
|
||||
if(authors.length > 1){
|
||||
var authorString = "The authors of this line are " + authorNames.join(" & ");
|
||||
}
|
||||
|
||||
parent.parent.$.gritter.add({
|
||||
// (string | mandatory) the heading of the notification
|
||||
title: 'Line Authors',
|
||||
// (string | mandatory) the text inside the notification
|
||||
text: authorString,
|
||||
// (bool | optional) if you want it to fade out on its own or just sit there
|
||||
sticky: false,
|
||||
// (int | optional) the time you want it to be alive for before fading out
|
||||
time: '4000'
|
||||
});
|
||||
}
|
||||
if ((!specialHandled) && isTypeForSpecialKey && keyCode == 8)
|
||||
{
|
||||
// "delete" key; in mozilla, if we're at the beginning of a line, normalize now,
|
||||
|
|
|
@ -290,6 +290,11 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
|||
|
||||
$(document).keyup(function(e)
|
||||
{
|
||||
// If focus is on editbar, don't do anything
|
||||
var target = $(':focus');
|
||||
if($(target).parents(".toolbar").length === 1){
|
||||
return;
|
||||
}
|
||||
var code = -1;
|
||||
if (!e) var e = window.event;
|
||||
if (e.keyCode) code = e.keyCode;
|
||||
|
@ -330,7 +335,6 @@ function loadBroadcastSliderJS(fireWhenAllScriptsAreLoaded)
|
|||
}
|
||||
}
|
||||
else if (code == 32) playpause();
|
||||
|
||||
});
|
||||
|
||||
$(window).resize(function()
|
||||
|
|
|
@ -18,6 +18,7 @@ var padutils = require('./pad_utils').padutils;
|
|||
var padcookie = require('./pad_cookie').padcookie;
|
||||
var Tinycon = require('tinycon/tinycon');
|
||||
var hooks = require('./pluginfw/hooks');
|
||||
var padeditor = require('./pad_editor').padeditor;
|
||||
|
||||
var chat = (function()
|
||||
{
|
||||
|
@ -36,6 +37,14 @@ var chat = (function()
|
|||
chatMentions = 0;
|
||||
Tinycon.setBubble(0);
|
||||
},
|
||||
focus: function ()
|
||||
{
|
||||
// I'm not sure why we need a setTimeout here but without it we don't get focus...
|
||||
// Animation maybe?
|
||||
setTimeout(function(){
|
||||
$("#chatinput").focus();
|
||||
},100);
|
||||
},
|
||||
stickToScreen: function(fromInitialCall) // Make chat stick to right hand side of screen
|
||||
{
|
||||
chat.show();
|
||||
|
@ -205,8 +214,28 @@ var chat = (function()
|
|||
init: function(pad)
|
||||
{
|
||||
this._pad = pad;
|
||||
$("#chatinput").keypress(function(evt)
|
||||
$("#chatinput").keyup(function(evt)
|
||||
{
|
||||
// If the event is Alt C or Escape & we're already in the chat menu
|
||||
// Send the users focus back to the pad
|
||||
if((evt.altKey == true && evt.which === 67) || evt.which === 27){
|
||||
// If we're in chat already..
|
||||
$(':focus').blur(); // required to do not try to remove!
|
||||
padeditor.ace.focus(); // Sends focus back to pad
|
||||
}
|
||||
});
|
||||
|
||||
$('body:not(#chatinput)').on("keydown", function(evt){
|
||||
if (evt.altKey && evt.which == 67){
|
||||
// Alt c focuses on the Chat window
|
||||
$(this).blur();
|
||||
parent.parent.chat.show();
|
||||
parent.parent.chat.focus();
|
||||
evt.preventDefault();
|
||||
}
|
||||
});
|
||||
|
||||
$("#chatinput").keypress(function(evt){
|
||||
//if the user typed enter, fire the send
|
||||
if(evt.which == 13 || evt.which == 10)
|
||||
{
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
_tpl_close: '<div class="gritter-close"></div>',
|
||||
_tpl_title: '<span class="gritter-title">[[title]]</span>',
|
||||
_tpl_item: '<div id="gritter-item-[[number]]" class="gritter-item-wrapper [[item_class]]" style="display:none"><div class="gritter-top"></div><div class="gritter-item">[[close]][[image]]<div class="[[class_name]]">[[title]]<p>[[text]]</p></div><div style="clear:both"></div></div><div class="gritter-bottom"></div></div>',
|
||||
_tpl_wrap: '<div id="gritter-notice-wrapper"></div>',
|
||||
_tpl_wrap: '<div id="gritter-notice-wrapper" aria-live="polite" aria-atomic="false" aria-relevant="additions" role="log"></div>',
|
||||
|
||||
/**
|
||||
* Add a gritter notification to the screen
|
||||
|
|
|
@ -110,7 +110,7 @@ function randomString()
|
|||
// callback: the function to call when all above succeeds, `val` is the value supplied by the user
|
||||
var getParameters = [
|
||||
{ name: "noColors", checkVal: "true", callback: function(val) { settings.noColors = true; $('#clearAuthorship').hide(); } },
|
||||
{ name: "showControls", checkVal: "false", callback: function(val) { $('#editbar').hide(); $('#editorcontainer').css({"top":"0px"}); } },
|
||||
{ name: "showControls", checkVal: "false", callback: function(val) { $('#editbar').addClass('hideControlsEditbar'); $('#editorcontainer').addClass('hideControlsEditor'); } },
|
||||
{ name: "showChat", checkVal: "false", callback: function(val) { $('#chaticon').hide(); } },
|
||||
{ name: "showLineNumbers", checkVal: "false", callback: function(val) { settings.LineNumbersDisabled = true; } },
|
||||
{ name: "useMonospaceFont", checkVal: "true", callback: function(val) { settings.useMonospaceFontGlobal = true; } },
|
||||
|
@ -433,6 +433,10 @@ var pad = {
|
|||
{
|
||||
return pad.myUserInfo.name;
|
||||
},
|
||||
userList: function()
|
||||
{
|
||||
return paduserlist.users();
|
||||
},
|
||||
sendClientReady: function(isReconnect, messageType)
|
||||
{
|
||||
messageType = typeof messageType !== 'undefined' ? messageType : 'CLIENT_READY';
|
||||
|
@ -576,9 +580,18 @@ var pad = {
|
|||
if(padcookie.getPref("rtlIsTrue") == true){
|
||||
pad.changeViewOption('rtlIsTrue', true);
|
||||
}
|
||||
if(padcookie.getPref("useMonospaceFont") == true){
|
||||
pad.changeViewOption('useMonospaceFont', true);
|
||||
}
|
||||
|
||||
var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont',
|
||||
'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont',
|
||||
'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont',
|
||||
'useSerifFont'];
|
||||
|
||||
$.each(fonts, function(i, font){
|
||||
if(padcookie.getPref(font) == true){
|
||||
pad.changeViewOption(font, true);
|
||||
}
|
||||
})
|
||||
|
||||
hooks.aCallAll("postAceInit", {ace: padeditor.ace, pad: pad});
|
||||
}
|
||||
},
|
||||
|
|
|
@ -63,6 +63,7 @@ ToolbarItem.prototype.bind = function (callback) {
|
|||
|
||||
if (self.isButton()) {
|
||||
self.$el.click(function (event) {
|
||||
$(':focus').blur();
|
||||
callback(self.getCommand(), self);
|
||||
event.preventDefault();
|
||||
});
|
||||
|
@ -155,6 +156,10 @@ var padeditbar = (function()
|
|||
});
|
||||
});
|
||||
|
||||
$('body:not(#editorcontainerbox)').on("keydown", function(evt){
|
||||
bodyKeyEvent(evt);
|
||||
});
|
||||
|
||||
$('#editbar').show();
|
||||
|
||||
this.redrawHeight();
|
||||
|
@ -300,6 +305,72 @@ var padeditbar = (function()
|
|||
}
|
||||
};
|
||||
|
||||
var editbarPosition = 0;
|
||||
|
||||
function bodyKeyEvent(evt){
|
||||
|
||||
// If the event is Alt F9 or Escape & we're already in the editbar menu
|
||||
// Send the users focus back to the pad
|
||||
if((evt.keyCode === 120 && evt.altKey) || evt.keyCode === 27){
|
||||
if($(':focus').parents(".toolbar").length === 1){
|
||||
// If we're in the editbar already..
|
||||
// Close any dropdowns we have open..
|
||||
padeditbar.toggleDropDown("none");
|
||||
// Check we're on a pad and not on the timeslider
|
||||
// Or some other window I haven't thought about!
|
||||
if(typeof pad === 'undefined'){
|
||||
// Timeslider probably..
|
||||
// Shift focus away from any drop downs
|
||||
$(':focus').blur(); // required to do not try to remove!
|
||||
$('#padmain').focus(); // Focus back onto the pad
|
||||
}else{
|
||||
// Shift focus away from any drop downs
|
||||
$(':focus').blur(); // required to do not try to remove!
|
||||
padeditor.ace.focus(); // Sends focus back to pad
|
||||
// The above focus doesn't always work in FF, you have to hit enter afterwards
|
||||
evt.preventDefault();
|
||||
}
|
||||
}else{
|
||||
// Focus on the editbar :)
|
||||
var firstEditbarElement = parent.parent.$('#editbar').children("ul").first().children().first().children().first().children().first();
|
||||
$(this).blur();
|
||||
firstEditbarElement.focus();
|
||||
evt.preventDefault();
|
||||
}
|
||||
}
|
||||
// Are we in the toolbar??
|
||||
if($(':focus').parents(".toolbar").length === 1){
|
||||
// On arrow keys go to next/previous button item in editbar
|
||||
if(evt.keyCode !== 39 && evt.keyCode !== 37) return;
|
||||
|
||||
// Get all the focusable items in the editbar
|
||||
var focusItems = $('#editbar').find('button, select');
|
||||
|
||||
// On left arrow move to next button in editbar
|
||||
if(evt.keyCode === 37){
|
||||
// If a dropdown is visible or we're in an input don't move to the next button
|
||||
if($('.popup').is(":visible") || evt.target.localName === "input") return;
|
||||
|
||||
editbarPosition--;
|
||||
// Allow focus to shift back to end of row and start of row
|
||||
if(editbarPosition === -1) editbarPosition = focusItems.length -1;
|
||||
$(focusItems[editbarPosition]).focus()
|
||||
}
|
||||
|
||||
// On right arrow move to next button in editbar
|
||||
if(evt.keyCode === 39){
|
||||
// If a dropdown is visible or we're in an input don't move to the next button
|
||||
if($('.popup').is(":visible") || evt.target.localName === "input") return;
|
||||
|
||||
editbarPosition++;
|
||||
// Allow focus to shift back to end of row and start of row
|
||||
if(editbarPosition >= focusItems.length) editbarPosition = 0;
|
||||
$(focusItems[editbarPosition]).focus();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function aceAttributeCommand(cmd, ace) {
|
||||
ace.ace_toggleAttributeOnSelection(cmd);
|
||||
}
|
||||
|
@ -311,10 +382,36 @@ var padeditbar = (function()
|
|||
toolbar.registerDropdownCommand("import_export");
|
||||
toolbar.registerDropdownCommand("embed");
|
||||
|
||||
toolbar.registerCommand("settings", function () {
|
||||
toolbar.toggleDropDown("settings", function(){
|
||||
$('#options-stickychat').focus();
|
||||
});
|
||||
});
|
||||
|
||||
toolbar.registerCommand("import_export", function () {
|
||||
toolbar.toggleDropDown("import_export", function(){
|
||||
// If Import file input exists then focus on it..
|
||||
if($('#importfileinput').length !== 0){
|
||||
setTimeout(function(){
|
||||
$('#importfileinput').focus();
|
||||
}, 100);
|
||||
}else{
|
||||
$('.exportlink').first().focus();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
toolbar.registerCommand("showusers", function () {
|
||||
toolbar.toggleDropDown("users", function(){
|
||||
$('#myusernameedit').focus();
|
||||
});
|
||||
});
|
||||
|
||||
toolbar.registerCommand("embed", function () {
|
||||
toolbar.setEmbedLinks();
|
||||
$('#linkinput').focus().select();
|
||||
toolbar.toggleDropDown("embed");
|
||||
toolbar.toggleDropDown("embed", function(){
|
||||
$('#linkinput').focus().select();
|
||||
});
|
||||
});
|
||||
|
||||
toolbar.registerCommand("savedRevision", function () {
|
||||
|
|
|
@ -28,6 +28,13 @@ var padeditor = (function()
|
|||
var Ace2Editor = undefined;
|
||||
var pad = undefined;
|
||||
var settings = undefined;
|
||||
|
||||
// Array of available fonts
|
||||
var fonts = ['useMonospaceFont', 'useOpenDyslexicFont', 'useComicSansFont', 'useCourierNewFont', 'useGeorgiaFont', 'useImpactFont',
|
||||
'useLucidaFont', 'useLucidaSansFont', 'usePalatinoFont', 'useTahomaFont', 'useTimesNewRomanFont',
|
||||
'useTrebuchetFont', 'useVerdanaFont', 'useSymbolFont', 'useWebdingsFont', 'useWingDingsFont', 'useSansSerifFont',
|
||||
'useSerifFont'];
|
||||
|
||||
var self = {
|
||||
ace: null,
|
||||
// this is accessed directly from other files
|
||||
|
@ -85,10 +92,15 @@ var padeditor = (function()
|
|||
padutils.setCheckbox($("#options-rtlcheck"), ('rtl' == html10n.getDirection()));
|
||||
})
|
||||
|
||||
// font face
|
||||
// font family change
|
||||
$("#viewfontmenu").change(function()
|
||||
{
|
||||
pad.changeViewOption('useMonospaceFont', $("#viewfontmenu").val() == 'monospace');
|
||||
$.each(fonts, function(i, font){
|
||||
var sfont = font.replace("use","");
|
||||
sfont = sfont.replace("Font","");
|
||||
sfont = sfont.toLowerCase();
|
||||
pad.changeViewOption(font, $("#viewfontmenu").val() == sfont);
|
||||
});
|
||||
});
|
||||
|
||||
// Language
|
||||
|
@ -98,12 +110,12 @@ var padeditor = (function()
|
|||
// this does not interfere with html10n's normal value-setting because html10n just ingores <input>s
|
||||
// also, a value which has been set by the user will be not overwritten since a user-edited <input>
|
||||
// does *not* have the editempty-class
|
||||
$('input[data-l10n-id]').each(function(key, input)
|
||||
{
|
||||
input = $(input);
|
||||
if(input.hasClass("editempty"))
|
||||
input.val(html10n.get(input.attr("data-l10n-id")));
|
||||
});
|
||||
$('input[data-l10n-id]').each(function(key, input){
|
||||
input = $(input);
|
||||
if(input.hasClass("editempty")){
|
||||
input.val(html10n.get(input.attr("data-l10n-id")));
|
||||
}
|
||||
});
|
||||
})
|
||||
$("#languagemenu").val(html10n.getLanguage());
|
||||
$("#languagemenu").change(function() {
|
||||
|
@ -136,13 +148,49 @@ var padeditor = (function()
|
|||
v = getOption('showAuthorColors', true);
|
||||
self.ace.setProperty("showsauthorcolors", v);
|
||||
padutils.setCheckbox($("#options-colorscheck"), v);
|
||||
// Override from parameters if true
|
||||
if (settings.noColors !== false)
|
||||
self.ace.setProperty("showsauthorcolors", !settings.noColors);
|
||||
|
||||
v = getOption('useMonospaceFont', false);
|
||||
self.ace.setProperty("textface", (v ? "monospace" : "Arial, sans-serif"));
|
||||
$("#viewfontmenu").val(v ? "monospace" : "normal");
|
||||
// Override from parameters if true
|
||||
if (settings.noColors !== false){
|
||||
self.ace.setProperty("showsauthorcolors", !settings.noColors);
|
||||
}
|
||||
|
||||
var normalFont = true;
|
||||
// Go through each font and see if the option is set..
|
||||
$.each(fonts, function(i, font){
|
||||
var isEnabled = getOption(font, false);
|
||||
if(isEnabled){
|
||||
font = font.replace("use","");
|
||||
font = font.replace("Font","");
|
||||
font = font.toLowerCase();
|
||||
if(font === "monospace") self.ace.setProperty("textface", "Courier new");
|
||||
if(font === "opendyslexic") self.ace.setProperty("textface", "OpenDyslexic");
|
||||
if(font === "comicsans") self.ace.setProperty("textface", "Comic Sans MS");
|
||||
if(font === "georgia") self.ace.setProperty("textface", "Georgia");
|
||||
if(font === "impact") self.ace.setProperty("textface", "Impact");
|
||||
if(font === "lucida") self.ace.setProperty("textface", "Lucida");
|
||||
if(font === "lucidasans") self.ace.setProperty("textface", "Lucida Sans Unicode");
|
||||
if(font === "palatino") self.ace.setProperty("textface", "Palatino Linotype");
|
||||
if(font === "tahoma") self.ace.setProperty("textface", "Tahoma");
|
||||
if(font === "timesnewroman") self.ace.setProperty("textface", "Times New Roman");
|
||||
if(font === "trebuchet") self.ace.setProperty("textface", "Trebuchet MS");
|
||||
if(font === "verdana") self.ace.setProperty("textface", "Verdana");
|
||||
if(font === "symbol") self.ace.setProperty("textface", "Symbol");
|
||||
if(font === "webdings") self.ace.setProperty("textface", "Webdings");
|
||||
if(font === "wingdings") self.ace.setProperty("textface", "Wingdings");
|
||||
if(font === "sansserif") self.ace.setProperty("textface", "MS Sans Serif");
|
||||
if(font === "serif") self.ace.setProperty("textface", "MS Serif");
|
||||
|
||||
// $("#viewfontmenu").val(font);
|
||||
normalFont = false;
|
||||
}
|
||||
});
|
||||
|
||||
// No font has been previously selected so use the Normal font
|
||||
if(normalFont){
|
||||
self.ace.setProperty("textface", "Arial, sans-serif");
|
||||
// $("#viewfontmenu").val("normal");
|
||||
}
|
||||
|
||||
},
|
||||
dispose: function()
|
||||
{
|
||||
|
|
|
@ -508,6 +508,30 @@ var paduserlist = (function()
|
|||
});
|
||||
//
|
||||
},
|
||||
users: function(){
|
||||
// Returns an object of users who have been on this pad
|
||||
// Firstly we have to get live data..
|
||||
var userList = otherUsersInfo;
|
||||
// Now we need to add ourselves..
|
||||
userList.push(myUserInfo);
|
||||
// Now we add historical authors
|
||||
var historical = clientVars.collab_client_vars.historicalAuthorData;
|
||||
for (var key in historical){
|
||||
var userId = historical[key].userId;
|
||||
// Check we don't already have this author in our array
|
||||
var exists = false;
|
||||
|
||||
userList.forEach(function(user){
|
||||
if(user.userId === userId) exists = true;
|
||||
});
|
||||
|
||||
if(exists === false){
|
||||
userList.push(historical[key]);
|
||||
}
|
||||
|
||||
}
|
||||
return userList;
|
||||
},
|
||||
setMyUserInfo: function(info)
|
||||
{
|
||||
//translate the colorId
|
||||
|
|
|
@ -157,6 +157,38 @@ function handleClientVars(message)
|
|||
fireWhenAllScriptsAreLoaded[i]();
|
||||
}
|
||||
$("#ui-slider-handle").css('left', $("#ui-slider-bar").width() - 2);
|
||||
|
||||
// Translate some strings where we only want to set the title not the actual values
|
||||
$('#playpause_button_icon').attr("title", html10n.get("timeslider.playPause"));
|
||||
$('#leftstep').attr("title", html10n.get("timeslider.backRevision"));
|
||||
$('#rightstep').attr("title", html10n.get("timeslider.forwardRevision"));
|
||||
|
||||
// font family change
|
||||
$("#viewfontmenu").change(function(){
|
||||
var font = $("#viewfontmenu").val();
|
||||
if(font === "monospace") setFont("Courier new");
|
||||
if(font === "opendyslexic") setFont("OpenDyslexic");
|
||||
if(font === "comicsans") setFont("Comic Sans MS");
|
||||
if(font === "georgia") setFont("Georgia");
|
||||
if(font === "impact") setFont("Impact");
|
||||
if(font === "lucida") setFont("Lucida");
|
||||
if(font === "lucidasans") setFont("Lucida Sans Unicode");
|
||||
if(font === "palatino") setFont("Palatino Linotype");
|
||||
if(font === "tahoma") setFont("Tahoma");
|
||||
if(font === "timesnewroman") setFont("Times New Roman");
|
||||
if(font === "trebuchet") setFont("Trebuchet MS");
|
||||
if(font === "verdana") setFont("Verdana");
|
||||
if(font === "symbol") setFont("Symbol");
|
||||
if(font === "webdings") setFont("Webdings");
|
||||
if(font === "wingdings") setFont("Wingdings");
|
||||
if(font === "sansserif") setFont("MS Sans Serif");
|
||||
if(font === "serif") setFont("MS Serif");
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function setFont(font){
|
||||
$('#padcontent').css("font-family", font);
|
||||
}
|
||||
|
||||
exports.baseURL = '';
|
||||
|
|
|
@ -70,9 +70,10 @@
|
|||
}
|
||||
#button {
|
||||
margin: 0 auto;
|
||||
border-radius: 3px;
|
||||
text-align: center;
|
||||
font: 36px verdana,arial,sans-serif;
|
||||
width:300px;
|
||||
border:none;
|
||||
color: white;
|
||||
text-shadow: 0 -1px 0 rgba(0,0,0,.8);
|
||||
height: 70px;
|
||||
|
@ -100,6 +101,7 @@
|
|||
text-align: left;
|
||||
text-shadow: 0 1px 1px #fff;
|
||||
margin: 16px auto 0;
|
||||
display:block;
|
||||
}
|
||||
#padname{
|
||||
height:38px;
|
||||
|
@ -158,8 +160,8 @@
|
|||
<div id="wrapper">
|
||||
<% e.begin_block("indexWrapper"); %>
|
||||
<div id="inner">
|
||||
<div id="button" onclick="go2Random()" data-l10n-id="index.newPad"></div>
|
||||
<div id="label" data-l10n-id="index.createOpenPad"></div>
|
||||
<buttOn id="button" onclick="go2Random()" data-l10n-id="index.newPad"></button>
|
||||
<label id="label" for="padname" data-l10n-id="index.createOpenPad"></label>
|
||||
<form action="#" onsubmit="go2Name();return false;">
|
||||
<input type="text" id="padname" autofocus x-webkit-speech>
|
||||
<button type="submit">OK</button>
|
||||
|
|
|
@ -56,17 +56,17 @@
|
|||
<!-- head and body had been removed intentionally -->
|
||||
|
||||
<% e.begin_block("body"); %>
|
||||
<div id="editbar" class="toolbar">
|
||||
<div id="editbar" class="toolbar" title="Toolbar (Alt F9)">
|
||||
<div id="overlay">
|
||||
<div id="overlay-inner"></div>
|
||||
</div>
|
||||
|
||||
<ul class="menu_left">
|
||||
<ul class="menu_left" role="toolbar">
|
||||
<% e.begin_block("editbarMenuLeft"); %>
|
||||
<%- toolbar.menu(settings.toolbar.left) %>
|
||||
<% e.end_block(); %>
|
||||
</ul>
|
||||
<ul class="menu_right">
|
||||
<ul class="menu_right" role="toolbar">
|
||||
<% e.begin_block("editbarMenuRight"); %>
|
||||
<%- toolbar.menu(settings.toolbar.right) %>
|
||||
<% e.end_block(); %>
|
||||
|
@ -88,7 +88,7 @@
|
|||
<div id="myusernameform"><input type="text" id="myusernameedit" disabled="disabled" data-l10n-id="pad.userlist.entername"></div>
|
||||
<div id="mystatusform"><input type="text" id="mystatusedit" disabled="disabled"></div>
|
||||
</div>
|
||||
<div id="otherusers">
|
||||
<div id="otherusers" aria-role="document">
|
||||
<div id="guestprompts"></div>
|
||||
<table id="otheruserstable" cellspacing="0" cellpadding="0" border="0">
|
||||
<tr><td></td></tr>
|
||||
|
@ -160,6 +160,22 @@
|
|||
<select id="viewfontmenu">
|
||||
<option value="normal" data-l10n-id="pad.settings.fontType.normal"></option>
|
||||
<option value="monospace" data-l10n-id="pad.settings.fontType.monospaced"></option>
|
||||
<option value="opendyslexic" data-l10n-id="pad.settings.fontType.opendyslexic"></option>
|
||||
<option value="comicsans" data-l10n-id="pad.settings.fontType.comicsans"></option>
|
||||
<option value="georgia" data-l10n-id="pad.settings.fontType.georgia"></option>
|
||||
<option value="impact" data-l10n-id="pad.settings.fontType.impact"></option>
|
||||
<option value="lucida" data-l10n-id="pad.settings.fontType.lucida"></option>
|
||||
<option value="lucidasans" data-l10n-id="pad.settings.fontType.lucidasans"></option>
|
||||
<option value="palatino" data-l10n-id="pad.settings.fontType.palatino"></option>
|
||||
<option value="tahoma" data-l10n-id="pad.settings.fontType.tahoma"></option>
|
||||
<option value="timesnewroman" data-l10n-id="pad.settings.fontType.timesnewroman"></option>
|
||||
<option value="trebuchet" data-l10n-id="pad.settings.fontType.trebuchet"></option>
|
||||
<option value="verdana" data-l10n-id="pad.settings.fontType.verdana"></option>
|
||||
<option value="symbol" data-l10n-id="pad.settings.fontType.symbol"></option>
|
||||
<option value="webdings" data-l10n-id="pad.settings.fontType.webdings"></option>
|
||||
<option value="wingdings" data-l10n-id="pad.settings.fontType.wingdings"></option>
|
||||
<option value="sansserif" data-l10n-id="pad.settings.fontType.sansserif"></option>
|
||||
<option value="serif" data-l10n-id="pad.settings.fontType.serif"></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
|
@ -306,7 +322,7 @@
|
|||
<% e.end_block(); %>
|
||||
</div>
|
||||
|
||||
<div id="chaticon" onclick="chat.show();return false;">
|
||||
<div id="chaticon" onclick="chat.show();return false;" title="Chat (Alt C)">
|
||||
<span id="chatlabel" data-l10n-id="pad.chat"></span>
|
||||
<span class="buttonicon buttonicon-chat"></span>
|
||||
<span id="chatcounter">0</span>
|
||||
|
@ -317,7 +333,7 @@
|
|||
<a id="titlecross" onClick="chat.hide();return false;">- </a>
|
||||
<a id="titlesticky" onClick="chat.stickToScreen(true);$('#options-stickychat').prop('checked', true);return false;" title="Stick chat to screen">█ </a>
|
||||
</div>
|
||||
<div id="chattext" class="authorColors">
|
||||
<div id="chattext" class="authorColors" aria-live="polite" aria-relevant="additions removals text" role="log" aria-atomic="false">
|
||||
<div alt="loading.." id="chatloadmessagesball" class="chatloadmessages loadingAnimation" align="top"></div>
|
||||
<button id="chatloadmessagesbutton" class="chatloadmessages" data-l10n-id="pad.chat.loadmessages"></button>
|
||||
</div>
|
||||
|
|
|
@ -61,11 +61,11 @@
|
|||
<div id="ui-slider-bar"></div>
|
||||
</div>
|
||||
<div id="playpause_button">
|
||||
<div id="playpause_button_icon" class=""></div>
|
||||
<button id="playpause_button_icon" class=""></button>
|
||||
</div>
|
||||
<div id="steppers">
|
||||
<div class="stepper" id="leftstep"></div>
|
||||
<div class="stepper" id="rightstep"></div>
|
||||
<button class="stepper" id="leftstep"></button>
|
||||
<button class="stepper" id="rightstep"></button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
@ -176,11 +176,41 @@
|
|||
<% e.end_block(); %>
|
||||
</div>
|
||||
|
||||
<div class="popup" id="settings">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="viewfontmenu" data-l10n-id="pad.settings.fontType">Font type:</label>
|
||||
</td>
|
||||
<td>
|
||||
<select id="viewfontmenu">
|
||||
<option value="normal" data-l10n-id="pad.settings.fontType.normal"></option>
|
||||
<option value="monospace" data-l10n-id="pad.settings.fontType.monospaced"></option>
|
||||
<option value="opendyslexic" data-l10n-id="pad.settings.fontType.opendyslexic"></option>
|
||||
<option value="comicsans" data-l10n-id="pad.settings.fontType.comicsans"></option>
|
||||
<option value="georgia" data-l10n-id="pad.settings.fontType.georgia"></option>
|
||||
<option value="impact" data-l10n-id="pad.settings.fontType.impact"></option>
|
||||
<option value="lucida" data-l10n-id="pad.settings.fontType.lucida"></option>
|
||||
<option value="lucidasans" data-l10n-id="pad.settings.fontType.lucidasans"></option>
|
||||
<option value="palatino" data-l10n-id="pad.settings.fontType.palatino"></option>
|
||||
<option value="tahoma" data-l10n-id="pad.settings.fontType.tahoma"></option>
|
||||
<option value="timesnewroman" data-l10n-id="pad.settings.fontType.timesnewroman"></option>
|
||||
<option value="trebuchet" data-l10n-id="pad.settings.fontType.trebuchet"></option>
|
||||
<option value="verdana" data-l10n-id="pad.settings.fontType.verdana"></option>
|
||||
<option value="symbol" data-l10n-id="pad.settings.fontType.symbol"></option>
|
||||
<option value="webdings" data-l10n-id="pad.settings.fontType.webdings"></option>
|
||||
<option value="wingdings" data-l10n-id="pad.settings.fontType.wingdings"></option>
|
||||
<option value="sansserif" data-l10n-id="pad.settings.fontType.sansserif"></option>
|
||||
<option value="serif" data-l10n-id="pad.settings.fontType.serif"></option>
|
||||
</select>
|
||||
</td>
|
||||
</tr>
|
||||
</div>
|
||||
|
||||
<!-- export code -->
|
||||
<div id="import_export">
|
||||
|
||||
<div id="export" class="popup">
|
||||
<p data-l10n-id="timeslider.exportCurrent"></p>
|
||||
<a id="exportetherpada" target="_blank" class="exportlink"><div class="exporttype" id="exportetherpad" data-l10n-id="pad.importExport.exportetherpad"></div></a>
|
||||
<a id="exporthtmla" target="_blank" class="exportlink"><div class="exporttype" id="exporthtml" data-l10n-id="pad.importExport.exporthtml"></div></a>
|
||||
<a id="exportplaina" target="_blank" class="exportlink"><div class="exporttype" id="exportplain" data-l10n-id="pad.importExport.exportplain"></div></a>
|
||||
<a id="exportworda" target="_blank" class="exportlink"><div class="exporttype" id="exportword" data-l10n-id="pad.importExport.exportword"></div></a>
|
||||
|
|
|
@ -24,7 +24,7 @@ describe("font select", function(){
|
|||
|
||||
//check if font changed to monospace
|
||||
var fontFamily = inner$("body").css("font-family").toLowerCase();
|
||||
expect(fontFamily).to.be("monospace");
|
||||
expect(fontFamily).to.be("courier new");
|
||||
|
||||
done();
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue