summernote-rails 0.2.1.4 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 9ee94f9fdfe922203de9d0b758f252d6ad6bd38d
4
- data.tar.gz: bc78ce03d54b494942a61a0c64b57d560beb5fc3
3
+ metadata.gz: 1f890a2cd92ec2c63e55cc5b0b300e8ab770a687
4
+ data.tar.gz: 8b75e63e1a5541143b78be480408ceaf5cc865d9
5
5
  SHA512:
6
- metadata.gz: cd84e5fa5e1df54218e1ae12769e58c3e4bdb6d9b1450d6bce770f697999065883fc369884af79c1cb85ea14f4426455a9709f65f8a828e08776d757ae92dabd
7
- data.tar.gz: ec63118f5a9056cf51f57085e4586066fb6adf2aadc124cb62c33bf7f25063b62b3ab1f642972bf2a7d4b7d1601779211eae1d86afa83411d69b8b9898559958
6
+ metadata.gz: 4a9cee9cffa95724a3fd5f3d55dd0c1e427580194cd0a1aa421a74220483b2fbb6ffc0a549df740e806345f0a272c536dbe9b720f70cb8f6d885268e5f99ceb1
7
+ data.tar.gz: 94181db624c6369b5e9e4c310d6e022bca36f338129e547a0bb6e6cf0fbf356bd09819d0471cef9606aa0b5fd68fc240ad45d65a81ec5ebbbe5a26d2007fc0d9
data/README.md CHANGED
@@ -126,6 +126,13 @@ That's it.
126
126
 
127
127
  ## Changelogs
128
128
 
129
+ - v0.3.0 : Added the resizing bar at the bottom of editor.
130
+ * Updated with `v0.3 Summernote, 2013-09-01` as the followings:
131
+ * `FIXED` bugs(image upload, fontsize, tab, recent color, ...)
132
+ * `ADDED` help dialog(keyboard shortcut)
133
+ * `ADDED` init options(event callbacks, custom toolbar)
134
+ * `ADDED` resize bar
135
+ * `ADDED` support IE8 Beta(some range bugs, can't insert Image)
129
136
  - v0.2.1.4 : Enable to customize Toolbar Collection
130
137
  - v0.2.1.3 : Added Help button in editor toolbox to popup Hot Key Table
131
138
  - v0.2.1.2 : Added InsertHorizontalRule(Cmd+Enter) in summernote editor /
@@ -1,5 +1,5 @@
1
1
  module Summernote
2
2
  module Rails
3
- VERSION = "0.2.1.4"
3
+ VERSION = "0.3.0"
4
4
  end
5
5
  end
@@ -14,12 +14,12 @@
14
14
  * func utils (for high-order func's arg)
15
15
  */
16
16
  var func = function() {
17
- var eq = function(nodeA) {
18
- return function(nodeB) { return nodeA === nodeB; };
19
- };
20
- var eq2 = function(nodeA, nodeB) { return nodeA === nodeB; };
17
+ var eq = function(elA) { return function(elB) { return elA === elB; }; };
18
+ var eq2 = function(elA, elB) { return elA === elB; };
21
19
  var fail = function() { return false; };
22
- return { eq: eq, eq2: eq2, fail: fail };
20
+ var not = function(f) { return function() { return !f.apply(f, arguments); }};
21
+ var self = function(a) { return a; }
22
+ return { eq: eq, eq2: eq2, fail: fail, not: not, self: self };
23
23
  }();
24
24
 
25
25
  /**
@@ -30,6 +30,21 @@
30
30
  var last = function(array) { return array[array.length - 1]; };
31
31
  var initial = function(array) { return array.slice(0, array.length - 1); };
32
32
  var tail = function(array) { return array.slice(1); };
33
+
34
+ var sum = function(array, fn) {
35
+ fn = fn || func.self;
36
+ return array.reduce(function(memo, v) {
37
+ return memo + fn(v);
38
+ }, 0);
39
+ };
40
+
41
+ var from = function(collection) {
42
+ var result = [], idx = -1, length = collection.length;
43
+ while (++idx < length) {
44
+ result[idx] = collection[idx];
45
+ }
46
+ return result;
47
+ };
33
48
 
34
49
  var clusterBy = function(array, fn) {
35
50
  if (array.length === 0) { return []; }
@@ -54,7 +69,7 @@
54
69
  };
55
70
 
56
71
  return { head: head, last: last, initial: initial, tail: tail,
57
- compact: compact, clusterBy: clusterBy };
72
+ sum: sum, from: from, compact: compact, clusterBy: clusterBy };
58
73
  }();
59
74
 
60
75
  /**
@@ -116,19 +131,35 @@
116
131
  // FIXME: nodeA and nodeB must be sorted, use comparePoints later.
117
132
  var listBetween = function(nodeA, nodeB) {
118
133
  var aNode = [];
119
- var elAncestor = commonAncestor(nodeA, nodeB);
120
- //TODO: IE8, createNodeIterator
121
- var iterator = document.createNodeIterator(elAncestor,
122
- NodeFilter.SHOW_ALL, null,
123
- false);
124
- var node, bStart = false;
125
- while (node = iterator.nextNode()) {
126
- if (nodeA === node) { bStart = true; }
127
- if (bStart) { aNode.push(node); }
128
- if (nodeB === node) { break; }
134
+
135
+ var bStart = false, bEnd = false;
136
+ var fnWalk = function(node) {
137
+ if (!node) { return; } // traverse fisnish
138
+ if (node === nodeA) { bStart = true; } // start point
139
+ if (bStart && !bEnd) { aNode.push(node) } // between
140
+ if (node === nodeB) { bEnd = true; return; } // end point
141
+
142
+ for (var idx = 0, sz=node.childNodes.length; idx < sz; idx++) {
143
+ fnWalk(node.childNodes[idx]);
144
+ }
129
145
  }
146
+
147
+ fnWalk(commonAncestor(nodeA, nodeB)); // DFS with commonAcestor.
130
148
  return aNode;
131
149
  };
150
+
151
+ // listPrev: listing prevSiblings (until predicate hit: optional)
152
+ var listPrev = function(node, pred) {
153
+ pred = pred || func.fail;
154
+
155
+ var aNext = [];
156
+ while (node) {
157
+ aNext.push(node);
158
+ if (pred(node)) { break; }
159
+ node = node.previousSibling;
160
+ };
161
+ return aNext;
162
+ };
132
163
 
133
164
  // listNext: listing nextSiblings (until predicate hit: optional)
134
165
  var listNext = function(node, pred) {
@@ -137,7 +168,7 @@
137
168
  var aNext = [];
138
169
  while (node) {
139
170
  aNext.push(node);
140
- if (node === pred) { break; }
171
+ if (pred(node)) { break; }
141
172
  node = node.nextSibling;
142
173
  };
143
174
  return aNext;
@@ -209,9 +240,7 @@
209
240
  // split: split dom tree by boundaryPoint(pivot and offset)
210
241
  var split = function(root, pivot, offset) {
211
242
  var aAncestor = listAncestor(pivot, func.eq(root));
212
- if (aAncestor.length === 1) {
213
- return splitData(pivot, offset);
214
- }
243
+ if (aAncestor.length === 1) { return splitData(pivot, offset); }
215
244
  return aAncestor.reduce(function(node, parent) {
216
245
  var clone = parent.cloneNode(false);
217
246
  insertAfter(clone, parent);
@@ -232,7 +261,8 @@
232
261
  isB: makePredByNodeName('B'), isU: makePredByNodeName('U'),
233
262
  isS: makePredByNodeName('S'), isI: makePredByNodeName('I'),
234
263
  isImg: makePredByNodeName('IMG'),
235
- ancestor: ancestor, listAncestor: listAncestor, listNext: listNext,
264
+ ancestor: ancestor, listAncestor: listAncestor,
265
+ listNext: listNext, listPrev: listPrev,
236
266
  commonAncestor: commonAncestor, listBetween: listBetween,
237
267
  insertAfter: insertAfter, position: position,
238
268
  makeOffsetPath: makeOffsetPath, fromOffsetPath: fromOffsetPath,
@@ -246,13 +276,101 @@
246
276
  * create Range Object From arguments or Browser Selection
247
277
  */
248
278
  var bW3CRangeSupport = !!document.createRange;
279
+
280
+ // return boundary point from TextRange(ie8)
281
+ // inspired by Andy Na's HuskyRange.js
282
+ var textRange2bp = function(textRange, bStart) {
283
+ var elCont = textRange.parentElement(), nOffset;
284
+
285
+ var tester = document.body.createTextRange(), elPrevCont;
286
+ var aChild = list.from(elCont.childNodes);
287
+ for (nOffset = 0; nOffset < aChild.length; nOffset++) {
288
+ if (dom.isText(aChild[nOffset])) { continue; }
289
+ tester.moveToElementText(aChild[nOffset]);
290
+ if (tester.compareEndPoints("StartToStart", textRange) >= 0) { break; }
291
+ elPrevCont = aChild[nOffset];
292
+ }
293
+
294
+ if (nOffset != 0 && dom.isText(aChild[nOffset - 1])) {
295
+ var textRangeStart = document.body.createTextRange(), elCurText = null;
296
+ textRangeStart.moveToElementText(elPrevCont || elCont);
297
+ textRangeStart.collapse(!elPrevCont);
298
+ elCurText = elPrevCont ? elPrevCont.nextSibling : elCont.firstChild;
299
+
300
+ var pointTester = textRange.duplicate();
301
+ pointTester.setEndPoint("StartToStart", textRangeStart);
302
+ var nTextCount = pointTester.text.replace(/[\r\n]/g, "").length;
303
+
304
+ while (nTextCount > elCurText.nodeValue.length && elCurText.nextSibling) {
305
+ nTextCount -= elCurText.nodeValue.length;
306
+ elCurText = elCurText.nextSibling;
307
+ }
308
+ var sDummy = elCurText.nodeValue; //enforce IE to re-reference elCurText
309
+
310
+ if (bStart && elCurText.nextSibling && dom.isText(elCurText.nextSibling) &&
311
+ nTextCount == elCurText.nodeValue.length) {
312
+ nTextCount -= elCurText.nodeValue.length;
313
+ elCurText = elCurText.nextSibling;
314
+ }
315
+
316
+ elCont = elCurText;
317
+ nOffset = nTextCount;
318
+ }
319
+
320
+ return {cont: elCont, offset: nOffset};
321
+ };
322
+
323
+ // return TextRange(ie8) from boundary point
324
+ // (inspired by google closure-library)
325
+ var bp2textRange = function(bp) {
326
+ var textRangeInfo = function(elCont, nOffset) {
327
+ var elNode, bCollapseToStart;
328
+
329
+ if (dom.isText(elCont)) {
330
+ var aPrevText = dom.listPrev(elCont, func.not(dom.isText));
331
+ var elPrevCont = list.last(aPrevText).previousSibling;
332
+ elNode = elPrevCont || elCont.parentNode;
333
+ nOffset += list.sum(list.tail(aPrevText), dom.length);
334
+ bCollapseToStart = !elPrevCont;
335
+ } else {
336
+ elNode = elCont.childNodes[nOffset] || elCont;
337
+ if (dom.isText(elNode)) {
338
+ return textRangeInfo(elNode, nOffset);
339
+ }
340
+
341
+ nOffset = 0;
342
+ bCollapseToStart = false;
343
+ }
344
+
345
+ return {cont: elNode, collapseToStart: bCollapseToStart, offset: nOffset};
346
+ }
347
+
348
+ var textRange = document.body.createTextRange();
349
+ var info = textRangeInfo(bp.cont, bp.offset);
350
+
351
+ textRange.moveToElementText(info.cont);
352
+ textRange.collapse(info.collapseToStart);
353
+ textRange.moveStart("character", info.offset);
354
+ return textRange;
355
+ };
356
+
249
357
  var Range = function(sc, so, ec, eo) {
250
358
  if (arguments.length === 0) { // from Browser Selection
251
- if (document.getSelection) { // webkit, firefox
359
+ if (bW3CRangeSupport) { // webkit, firefox
252
360
  var nativeRng = document.getSelection().getRangeAt(0);
253
361
  sc = nativeRng.startContainer, so = nativeRng.startOffset,
254
362
  ec = nativeRng.endContainer, eo = nativeRng.endOffset;
255
- } // TODO: handle IE8+ TextRange
363
+ } else { //TextRange
364
+ var textRange = document.selection.createRange();
365
+ var textRangeEnd = textRange.duplicate(); textRangeEnd.collapse(false);
366
+ var textRangeStart = textRange; textRangeStart.collapse(true);
367
+
368
+ var bpStart = textRange2bp(textRangeStart, true),
369
+ bpEnd = textRange2bp(textRangeEnd, false);
370
+
371
+ sc = bpStart.cont, so = bpStart.offset;
372
+ ec = bpEnd.cont, eo = bpEnd.offset;
373
+ }
256
374
  }
257
375
 
258
376
  this.sc = sc; this.so = so;
@@ -265,7 +383,11 @@
265
383
  range.setStart(sc, so);
266
384
  range.setEnd(ec, eo);
267
385
  return range;
268
- } // TODO: handle IE8+ TextRange
386
+ } else {
387
+ var textRange = bp2textRange({cont:sc, offset:so});
388
+ textRange.setEndPoint('EndToEnd', bp2textRange({cont:ec, offset:eo}));
389
+ return textRange;
390
+ }
269
391
  };
270
392
 
271
393
  // select: update visible range
@@ -275,7 +397,9 @@
275
397
  var selection = document.getSelection();
276
398
  if (selection.rangeCount > 0) { selection.removeAllRanges(); }
277
399
  selection.addRange(nativeRng);
278
- } // TODO: handle IE8+ TextRange
400
+ } else {
401
+ nativeRng.select();
402
+ }
279
403
  };
280
404
 
281
405
  // listPara: listing paragraphs on range
@@ -309,25 +433,18 @@
309
433
  var nativeRng = nativeRange();
310
434
  if (bW3CRangeSupport) {
311
435
  nativeRng.insertNode(node);
312
- } // TODO: IE8
313
- };
314
-
315
- // surroundContents
316
- this.surroundContents = function(sNodeName) {
317
- var node = $('<' + sNodeName + ' />')[0];
318
- var nativeRng = nativeRange();
319
- if (bW3CRangeSupport) {
320
- nativeRng.surroundContents(node);
321
- } // TODO: IE8
322
-
323
- return node;
436
+ } else {
437
+ nativeRng.pasteHTML(node.outerHTML); // NOTE: missing node reference.
438
+ }
324
439
  };
325
440
 
326
441
  this.toString = function() {
327
442
  var nativeRng = nativeRange();
328
443
  if (bW3CRangeSupport) {
329
444
  return nativeRng.toString();
330
- } // TODO: IE8
445
+ } else {
446
+ return nativeRng.text;
447
+ }
331
448
  };
332
449
 
333
450
  //bookmark: offsetPath bookmark
@@ -351,16 +468,6 @@
351
468
  * Style
352
469
  */
353
470
  var Style = function() {
354
- // font level style
355
- this.styleFont = function(rng, oStyle) {
356
- //TODO: complete styleFont later only works for webkit
357
- //rng.splitInline();
358
- var elSpan = rng.surroundContents('span');
359
- $.each(oStyle, function(sKey, sValue) {
360
- elSpan.style[sKey] = sValue;
361
- });
362
- };
363
-
364
471
  // para level style
365
472
  this.stylePara = function(rng, oStyle) {
366
473
  var aPara = rng.listPara();
@@ -374,16 +481,15 @@
374
481
  // get current style, elTarget: target element on event.
375
482
  this.current = function(rng, elTarget) {
376
483
  var welCont = $(dom.isText(rng.sc) ? rng.sc.parentNode : rng.sc);
377
- var oStyle = welCont.css(['font-size', 'font-weight', 'font-style',
378
- 'text-decoration', 'text-align',
484
+ var oStyle = welCont.css(['font-size', 'text-align',
379
485
  'list-style-type', 'line-height']) || {};
380
-
486
+
381
487
  oStyle['font-size'] = parseInt(oStyle['font-size']);
382
488
 
383
- // FF font-weight patch(number to 'bold' or 'normal')
384
- if (!isNaN(parseInt(oStyle['font-weight']))) {
385
- oStyle['font-weight'] = oStyle['font-weight'] > 400 ? 'bold' : 'normal';
386
- }
489
+ // document.queryCommandState for toggle state
490
+ oStyle['font-bold'] = document.queryCommandState('bold') ? 'bold' : 'normal';
491
+ oStyle['font-italic'] = document.queryCommandState('italic') ? 'italic' : 'normal';
492
+ oStyle['font-underline'] = document.queryCommandState('underline') ? 'underline' : 'normal';
387
493
 
388
494
  // list-style-type to list-style(unordered, ordered)
389
495
  if (!rng.isOnList()) {
@@ -453,7 +559,7 @@
453
559
  //currentStyle
454
560
  var style = new Style();
455
561
  this.currentStyle = function(elTarget) {
456
- if (document.getSelection().rangeCount == 0) { return null; }
562
+ if (document.getSelection && document.getSelection().rangeCount == 0) { return null; }
457
563
  return style.current((new Range()), elTarget);
458
564
  };
459
565
 
@@ -473,11 +579,11 @@
473
579
  };
474
580
 
475
581
  // native commands(with execCommand)
476
- var aCmd = ['bold', 'italic', 'underline', 'justifyLeft', 'justifyCenter',
477
- 'justifyRight', 'justifyFull', 'insertOrderedList',
478
- 'insertUnorderedList', 'indent', 'outdent', 'formatBlock',
479
- 'removeFormat', 'backColor', 'foreColor', 'insertImage',
480
- 'insertHorizontalRule'];
582
+ var aCmd = ['bold', 'italic', 'underline', 'strikethrough',
583
+ 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull',
584
+ 'insertOrderedList', 'insertUnorderedList',
585
+ 'indent', 'outdent', 'formatBlock', 'removeFormat',
586
+ 'backColor', 'foreColor', 'insertImage', 'insertHorizontalRule'];
481
587
 
482
588
  for (var idx = 0, len=aCmd.length; idx < len; idx ++) {
483
589
  this[aCmd[idx]] = function(sCmd) {
@@ -488,11 +594,9 @@
488
594
  }(aCmd[idx]);
489
595
  }
490
596
 
491
- this.tab = function(welEditable) {
492
- var rng = new Range();
493
- if (rng.isOnList() || !rng.isCollapsed()) {
494
- return this.indent(welEditable); // return is hack.
495
- }
597
+ this.formatBlock = function(welEditable, sValue) {
598
+ sValue = bMSIE ? "<" + sValue + ">" : sValue;
599
+ document.execCommand("FormatBlock", false, sValue);
496
600
  };
497
601
 
498
602
  this.fontSize = function(welEditable, sValue) {
@@ -530,12 +634,21 @@
530
634
  text: rng.toString(),
531
635
  url: rng.isOnAnchor() ? dom.ancestor(rng.sc, dom.isAnchor).href : ""
532
636
  }, function(sLinkUrl) {
533
- rng.select();
534
- recordUndo(welEditable);
535
- if (sLinkUrl.toLowerCase().indexOf("http://") !== 0) {
536
- sLinkUrl = "http://" + sLinkUrl;
637
+ rng.select(); recordUndo(welEditable);
638
+
639
+ var bProtocol = sLinkUrl.toLowerCase().indexOf("://") !== -1;
640
+ var sLinkUrlWithProtocol = bProtocol ? sLinkUrl : "http://" + sLinkUrl;
641
+
642
+ //IE: createLink when range collapsed.
643
+ if (bMSIE && rng.isCollapsed()) {
644
+ rng.insertNode($('<A id="linkAnchor">' + sLinkUrl + '</A>')[0]);
645
+ var welAnchor = $('#linkAnchor').removeAttr("id")
646
+ .attr('href', sLinkUrlWithProtocol);
647
+ rng = new Range(welAnchor[0], 0, welAnchor[0], 1);
648
+ rng.select();
649
+ } else {
650
+ document.execCommand('createlink', false, sLinkUrlWithProtocol);
537
651
  }
538
- document.execCommand('createlink', false, sLinkUrl);
539
652
  });
540
653
  };
541
654
 
@@ -612,13 +725,13 @@
612
725
  };
613
726
 
614
727
  btnState('button[data-event="bold"]', function() {
615
- return oStyle['font-weight'] === 'bold';
728
+ return oStyle['font-bold'] === 'bold';
616
729
  });
617
730
  btnState('button[data-event="italic"]', function() {
618
- return oStyle['font-style'] === 'italic';
731
+ return oStyle['font-italic'] === 'italic';
619
732
  });
620
733
  btnState('button[data-event="underline"]', function() {
621
- return oStyle['text-decoration'] === 'underline';
734
+ return oStyle['font-underline'] === 'underline';
622
735
  });
623
736
  btnState('button[data-event="justifyLeft"]', function() {
624
737
  return oStyle['text-align'] === 'left' || oStyle['text-align'] === 'start';
@@ -725,7 +838,7 @@
725
838
  var welDropzone = welDialog.find('.note-dropzone'),
726
839
  welImageInput = welDialog.find('.note-image-input');
727
840
 
728
- welImageDialog.on('shown', function(e) {
841
+ welImageDialog.on('shown.bs.modal', function(e) {
729
842
  welDropzone.on('dragenter dragover dragleave', false);
730
843
  welDropzone.on('drop', function(e) {
731
844
  hDropImage(e); welImageDialog.modal('hide');
@@ -734,7 +847,7 @@
734
847
  fnInsertImages(this.files); $(this).val('');
735
848
  welImageDialog.modal('hide');
736
849
  });
737
- }).on('hidden', function(e) {
850
+ }).on('hidden.bs.modal', function(e) {
738
851
  welDropzone.off('dragenter dragover dragleave drop');
739
852
  welImageInput.off('change');
740
853
  }).modal('show');
@@ -746,7 +859,7 @@
746
859
  welLinkUrl = welLinkDialog.find('.note-link-url'),
747
860
  welLinkBtn = welLinkDialog.find('.note-link-btn');
748
861
 
749
- welLinkDialog.on('shown', function(e) {
862
+ welLinkDialog.on('shown.bs.modal', function(e) {
750
863
  welLinkText.html(linkInfo.text);
751
864
  welLinkUrl.val(linkInfo.url).keyup(function(event) {
752
865
  if (welLinkUrl.val()) {
@@ -762,9 +875,9 @@
762
875
  callback(welLinkUrl.val());
763
876
  event.preventDefault();
764
877
  });
765
- }).on('hidden', function(e) {
878
+ }).on('hidden.bs.modal', function(e) {
766
879
  welLinkUrl.off('keyup');
767
- welLinkDialog.off('shown hidden');
880
+ welLinkDialog.off('shown.bs.modal hidden.bs.modal');
768
881
  welLinkBtn.off('click');
769
882
  }).modal('show');
770
883
  };
@@ -786,16 +899,18 @@
786
899
 
787
900
  var key = { BACKSPACE: 8, TAB: 9, ENTER: 13, SPACE: 32,
788
901
  NUM0: 48, NUM1: 49, NUM6: 54, NUM7: 55, NUM8: 56,
789
- B: 66, E: 69, I: 73, J: 74, K: 75, L: 76, R: 82,
790
- U: 85, Y: 89, Z: 90, BACKSLACH: 220 };
902
+ B: 66, E: 69, I: 73, J: 74, K: 75, L: 76, R: 82, S: 83, U: 85,
903
+ Y: 89, Z: 90, SLASH: 191,
904
+ LEFTBRACKET: 219, BACKSLACH: 220, RIGHTBRACKET: 221 };
791
905
 
792
906
  // makeLayoutInfo from editor's descendant node.
793
907
  var makeLayoutInfo = function(descendant) {
794
908
  var welEditor = $(descendant).closest('.note-editor');
795
909
  return {
796
910
  editor: function() { return welEditor; },
797
- editable: function() { return welEditor.find('.note-editable'); },
798
911
  toolbar: function() { return welEditor.find('.note-toolbar'); },
912
+ editable: function() { return welEditor.find('.note-editable'); },
913
+ statusbar: function() { return welEditor.find('.note-statusbar'); },
799
914
  popover: function() { return welEditor.find('.note-popover'); },
800
915
  handle: function() { return welEditor.find('.note-handle'); },
801
916
  dialog: function() { return welEditor.find('.note-dialog'); }
@@ -820,12 +935,16 @@
820
935
  editor.italic(oLayoutInfo.editable());
821
936
  } else if (bCmd && keyCode === key.U) {
822
937
  editor.underline(oLayoutInfo.editable());
938
+ } else if (bCmd && bShift && keyCode === key.S) {
939
+ editor.strikethrough(oLayoutInfo.editable());
823
940
  } else if (bCmd && keyCode === key.BACKSLACH) {
824
941
  editor.removeFormat(oLayoutInfo.editable());
825
942
  } else if (bCmd && keyCode === key.K) {
826
943
  editor.setLinkDialog(oLayoutInfo.editable(), function(linkInfo, cb) {
827
944
  dialog.showLinkDialog(oLayoutInfo.dialog(), linkInfo, cb);
828
945
  });
946
+ } else if (bCmd && keyCode === key.SLASH) {
947
+ dialog.showHelpDialog(oLayoutInfo.dialog());
829
948
  } else if (bCmd && bShift && keyCode === key.L) {
830
949
  editor.justifyLeft(oLayoutInfo.editable());
831
950
  } else if (bCmd && bShift && keyCode === key.E) {
@@ -838,10 +957,10 @@
838
957
  editor.insertUnorderedList(oLayoutInfo.editable());
839
958
  } else if (bCmd && bShift && keyCode === key.NUM8) {
840
959
  editor.insertOrderedList(oLayoutInfo.editable());
841
- } else if (bShift && keyCode === key.TAB) { // shift + tab
960
+ } else if (bCmd && keyCode === key.LEFTBRACKET) {
842
961
  editor.outdent(oLayoutInfo.editable());
843
- } else if (keyCode === key.TAB) { // tab
844
- editor.tab(oLayoutInfo.editable());
962
+ } else if (bCmd && keyCode === key.RIGHTBRACKET) {
963
+ editor.indent(oLayoutInfo.editable());
845
964
  } else if (bCmd && keyCode === key.NUM0) { // formatBlock Paragraph
846
965
  editor.formatBlock(oLayoutInfo.editable(), 'P');
847
966
  } else if (bCmd && (key.NUM1 <= keyCode && keyCode <= key.NUM6)) {
@@ -860,6 +979,7 @@
860
979
  };
861
980
 
862
981
  var insertImages = function(welEditable, files) {
982
+ welEditable.trigger('focus');
863
983
  $.each(files, function(idx, file) {
864
984
  var fileReader = new FileReader;
865
985
  fileReader.onload = function(event) {
@@ -973,6 +1093,23 @@
973
1093
  hToolbarAndPopoverUpdate(event);
974
1094
  }
975
1095
  };
1096
+
1097
+ var EDITABLE_PADDING = 24;
1098
+ var hStatusbarMousedown = function(event) {
1099
+ var welDocument = $(document);
1100
+ var welEditable = makeLayoutInfo(event.target).editable();
1101
+
1102
+ var nEditableTop = welEditable.offset().top - welDocument.scrollTop();
1103
+ var hMousemove = function(event) {
1104
+ welEditable.height(event.clientY - (nEditableTop + EDITABLE_PADDING));
1105
+ };
1106
+ var hMouseup = function() {
1107
+ welDocument.unbind('mousemove', hMousemove)
1108
+ .unbind('mouseup', hMouseup);
1109
+ }
1110
+ welDocument.mousemove(hMousemove).mouseup(hMouseup);
1111
+ event.stopPropagation(); event.preventDefault();
1112
+ };
976
1113
 
977
1114
  var PX_PER_EM = 18;
978
1115
  var hDimensionPickerMove = function(event) {
@@ -997,11 +1134,11 @@
997
1134
  welHighlighted.css({ width: dim.c +'em', height: dim.r + 'em' });
998
1135
  welCatcher.attr('data-value', dim.c + 'x' + dim.r);
999
1136
 
1000
- if (3 < dim.c && dim.c < 20) { // 5~20
1137
+ if (3 < dim.c && dim.c < 10) { // 5~10
1001
1138
  welUnhighlighted.css({ width: dim.c + 1 + 'em'});
1002
1139
  }
1003
1140
 
1004
- if (3 < dim.r && dim.r < 20) { // 5~20
1141
+ if (3 < dim.r && dim.r < 10) { // 5~10
1005
1142
  welUnhighlighted.css({ height: dim.r + 1 + 'em'});
1006
1143
  }
1007
1144
 
@@ -1023,6 +1160,8 @@
1023
1160
  oLayoutInfo.popover.on('click', hToolbarAndPopoverClick);
1024
1161
  oLayoutInfo.toolbar.on('mousedown', hToolbarAndPopoverMousedown);
1025
1162
  oLayoutInfo.popover.on('mousedown', hToolbarAndPopoverMousedown);
1163
+
1164
+ oLayoutInfo.statusbar.on('mousedown', hStatusbarMousedown);
1026
1165
 
1027
1166
  //toolbar table dimension
1028
1167
  var welToolbar = oLayoutInfo.toolbar;
@@ -1061,11 +1200,11 @@
1061
1200
  var Renderer = function() {
1062
1201
  var aToolbarItem = {
1063
1202
  picture:
1064
- '<button type="button" class="btn btn-small" title="Picture" data-event="showImageDialog" tabindex="-1"><i class="icon-picture"></i></button>',
1203
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Picture" data-event="showImageDialog" tabindex="-1"><i class="icon-picture"></i></button>',
1065
1204
  link:
1066
- '<button type="button" class="btn btn-small" title="Link" data-event="showLinkDialog" data-shortcut="Ctrl+K" data-mac-shortcut="⌘+K" tabindex="-1"><i class="icon-link"></i></button>',
1205
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Link" data-event="showLinkDialog" data-shortcut="Ctrl+K" data-mac-shortcut="⌘+K" tabindex="-1"><i class="icon-link"></i></button>',
1067
1206
  table:
1068
- '<button type="button" class="btn btn-small dropdown-toggle" title="Table" data-toggle="dropdown" tabindex="-1"><i class="icon-table"></i> <span class="caret"></span></button>' +
1207
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" title="Table" data-toggle="dropdown" tabindex="-1"><i class="icon-table"></i> <span class="caret"></span></button>' +
1069
1208
  '<ul class="dropdown-menu">' +
1070
1209
  '<div class="note-dimension-picker">' +
1071
1210
  '<div class="note-dimension-picker-mousecatcher" data-event="insertTable" data-value="1x1"></div>' +
@@ -1075,7 +1214,7 @@
1075
1214
  '<div class="note-dimension-display"> 1 x 1 </div>' +
1076
1215
  '</ul>',
1077
1216
  style:
1078
- '<button type="button" class="btn btn-small dropdown-toggle" title="Style" data-toggle="dropdown" tabindex="-1"><i class="icon-magic"></i> <span class="caret"></span></button>' +
1217
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" title="Style" data-toggle="dropdown" tabindex="-1"><i class="icon-magic"></i> <span class="caret"></span></button>' +
1079
1218
  '<ul class="dropdown-menu">' +
1080
1219
  '<li><a data-event="formatBlock" data-value="p">Normal</a></li>' +
1081
1220
  '<li><a data-event="formatBlock" data-value="blockquote"><blockquote>Quote</blockquote></a></li>' +
@@ -1088,7 +1227,7 @@
1088
1227
  '<li><a data-event="formatBlock" data-value="h6"><h6>Header 6</h6></a></li>' +
1089
1228
  '</ul>',
1090
1229
  fontsize:
1091
- '<button type="button" class="btn btn-small dropdown-toggle" data-toggle="dropdown" title="Font Size" tabindex="-1"><span class="note-current-fontsize">11</span> <b class="caret"></b></button>' +
1230
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" data-toggle="dropdown" title="Font Size" tabindex="-1"><span class="note-current-fontsize">11</span> <b class="caret"></b></button>' +
1092
1231
  '<ul class="dropdown-menu">' +
1093
1232
  '<li><a data-event="fontSize" data-value="8"><i class="icon-ok"></i> 8</a></li>' +
1094
1233
  '<li><a data-event="fontSize" data-value="9"><i class="icon-ok"></i> 9</a></li>' +
@@ -1101,8 +1240,8 @@
1101
1240
  '<li><a data-event="fontSize" data-value="36"><i class="icon-ok"></i> 36</a></li>' +
1102
1241
  '</ul>',
1103
1242
  color:
1104
- '<button type="button" class="btn btn-small note-recent-color" title="Recent Color" data-event="color" data-value=\'{"foreColor":"black","backColor":"yellow"}\' tabindex="-1"><i class="icon-font" style="color:black;background-color:yellow;"></i></button>' +
1105
- '<button type="button" class="btn btn-small dropdown-toggle" title="More Color" data-toggle="dropdown" tabindex="-1">' +
1243
+ '<button type="button" class="btn btn-default btn-sm btn-small note-recent-color" title="Recent Color" data-event="color" data-value=\'{"foreColor":"black","backColor":"yellow"}\' tabindex="-1"><i class="icon-font" style="color:black;background-color:yellow;"></i></button>' +
1244
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" title="More Color" data-toggle="dropdown" tabindex="-1">' +
1106
1245
  '<span class="caret"></span>' +
1107
1246
  '</button>' +
1108
1247
  '<ul class="dropdown-menu">' +
@@ -1118,37 +1257,37 @@
1118
1257
  '</li>' +
1119
1258
  '</ul>',
1120
1259
  bold:
1121
- '<button type="button" class="btn btn-small" title="Bold" data-shortcut="Ctrl+B" data-mac-shortcut="⌘+B" data-event="bold" tabindex="-1"><i class="icon-bold"></i></button>',
1260
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Bold" data-shortcut="Ctrl+B" data-mac-shortcut="⌘+B" data-event="bold" tabindex="-1"><i class="icon-bold"></i></button>',
1122
1261
  italic:
1123
- '<button type="button" class="btn btn-small" title="Italic" data-shortcut="Ctrl+I" data-mac-shortcut="⌘+I" data-event="italic" tabindex="-1"><i class="icon-italic"></i></button>',
1262
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Italic" data-shortcut="Ctrl+I" data-mac-shortcut="⌘+I" data-event="italic" tabindex="-1"><i class="icon-italic"></i></button>',
1124
1263
  underline:
1125
- '<button type="button" class="btn btn-small" title="Underline" data-shortcut="Ctrl+U" data-mac-shortcut="⌘+U" data-event="underline" tabindex="-1"><i class="icon-underline"></i></button>',
1264
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Underline" data-shortcut="Ctrl+U" data-mac-shortcut="⌘+U" data-event="underline" tabindex="-1"><i class="icon-underline"></i></button>',
1126
1265
  clear:
1127
- '<button type="button" class="btn btn-small" title="Remove Font Style" data-shortcut="Ctrl+\\" data-mac-shortcut="⌘+\\" data-event="removeFormat" tabindex="-1"><i class="icon-eraser"></i></button>',
1266
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Remove Font Style" data-shortcut="Ctrl+\\" data-mac-shortcut="⌘+\\" data-event="removeFormat" tabindex="-1"><i class="icon-eraser"></i></button>',
1128
1267
  ul:
1129
- '<button type="button" class="btn btn-small" title="Unordered list" data-shortcut="Ctrl+Shift+8" data-mac-shortcut="⌘+⇧+7" data-event="insertUnorderedList" tabindex="-1"><i class="icon-list-ul"></i></button>',
1268
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Unordered list" data-shortcut="Ctrl+Shift+8" data-mac-shortcut="⌘+⇧+7" data-event="insertUnorderedList" tabindex="-1"><i class="icon-list-ul"></i></button>',
1130
1269
  ol:
1131
- '<button type="button" class="btn btn-small" title="Ordered list" data-shortcut="Ctrl+Shift+7" data-mac-shortcut="⌘+⇧+8" data-event="insertOrderedList" tabindex="-1"><i class="icon-list-ol"></i></button>',
1270
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Ordered list" data-shortcut="Ctrl+Shift+7" data-mac-shortcut="⌘+⇧+8" data-event="insertOrderedList" tabindex="-1"><i class="icon-list-ol"></i></button>',
1132
1271
  paragraph:
1133
- '<button type="button" class="btn btn-small dropdown-toggle" title="Paragraph" data-toggle="dropdown" tabindex="-1"><i class="icon-align-left"></i> <span class="caret"></span></button>' +
1134
- '<ul class="dropdown-menu right">' +
1272
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" title="Paragraph" data-toggle="dropdown" tabindex="-1"><i class="icon-align-left"></i> <span class="caret"></span></button>' +
1273
+ '<ul class="dropdown-menu">' +
1135
1274
  '<li>' +
1136
1275
  '<div class="note-align btn-group">' +
1137
- '<button type="button" class="btn btn-small" title="Align left" data-shortcut="Ctrl+Shift+L" data-mac-shortcut="⌘+⇧+L" data-event="justifyLeft" tabindex="-1"><i class="icon-align-left"></i></button>' +
1138
- '<button type="button" class="btn btn-small" title="Align center" data-shortcut="Ctrl+Shift+E" data-mac-shortcut="⌘+⇧+E" data-event="justifyCenter" tabindex="-1"><i class="icon-align-center"></i></button>' +
1139
- '<button type="button" class="btn btn-small" title="Align right" data-shortcut="Ctrl+Shift+R" data-mac-shortcut="⌘+⇧+R" data-event="justifyRight" tabindex="-1"><i class="icon-align-right"></i></button>' +
1140
- '<button type="button" class="btn btn-small" title="Justify full" data-shortcut="Ctrl+Shift+J" data-mac-shortcut="⌘+⇧+J" data-event="justifyFull" tabindex="-1"><i class="icon-align-justify"></i></button>' +
1276
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Align left" data-shortcut="Ctrl+Shift+L" data-mac-shortcut="⌘+⇧+L" data-event="justifyLeft" tabindex="-1"><i class="icon-align-left"></i></button>' +
1277
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Align center" data-shortcut="Ctrl+Shift+E" data-mac-shortcut="⌘+⇧+E" data-event="justifyCenter" tabindex="-1"><i class="icon-align-center"></i></button>' +
1278
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Align right" data-shortcut="Ctrl+Shift+R" data-mac-shortcut="⌘+⇧+R" data-event="justifyRight" tabindex="-1"><i class="icon-align-right"></i></button>' +
1279
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Justify full" data-shortcut="Ctrl+Shift+J" data-mac-shortcut="⌘+⇧+J" data-event="justifyFull" tabindex="-1"><i class="icon-align-justify"></i></button>' +
1141
1280
  '</div>' +
1142
1281
  '</li>' +
1143
1282
  '<li>' +
1144
1283
  '<div class="note-list btn-group">' +
1145
- '<button type="button" class="btn btn-small" title="Outdent" data-shortcut="Shift+TAB" data-mac-shortcut="⇧+TAB" data-event="outdent" tabindex="-1"><i class="icon-indent-left"></i></button>' +
1146
- '<button type="button" class="btn btn-small" title="Indent" data-shortcut="TAB" data-mac-shortcut="TAB" data-event="indent" tabindex="-1"><i class="icon-indent-right"></i></button>' +
1284
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Outdent" data-shortcut="Ctrl+[" data-mac-shortcut="⌘+[" data-event="outdent" tabindex="-1"><i class="icon-indent-left"></i></button>' +
1285
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Indent" data-shortcut="Ctrl+]" data-mac-shortcut="⌘+]" data-event="indent" tabindex="-1"><i class="icon-indent-right"></i></button>' +
1147
1286
  '</li>' +
1148
1287
  '</ul>',
1149
1288
  height:
1150
- '<button type="button" class="btn btn-small dropdown-toggle" data-toggle="dropdown" title="Line Height" tabindex="-1"><i class="icon-text-height"></i>&nbsp; <b class="caret"></b></button>' +
1151
- '<ul class="dropdown-menu right">' +
1289
+ '<button type="button" class="btn btn-default btn-sm btn-small dropdown-toggle" data-toggle="dropdown" title="Line Height" tabindex="-1"><i class="icon-text-height"></i>&nbsp; <b class="caret"></b></button>' +
1290
+ '<ul class="dropdown-menu">' +
1152
1291
  '<li><a data-event="lineHeight" data-value="1.0"><i class="icon-ok"></i> 1.0</a></li>' +
1153
1292
  '<li><a data-event="lineHeight" data-value="1.2"><i class="icon-ok"></i> 1.2</a></li>' +
1154
1293
  '<li><a data-event="lineHeight" data-value="1.4"><i class="icon-ok"></i> 1.4</a></li>' +
@@ -1159,7 +1298,7 @@
1159
1298
  '<li><a data-event="lineHeight" data-value="3.0"><i class="icon-ok"></i> 3.0</a></li>' +
1160
1299
  '</ul>',
1161
1300
  help:
1162
- '<button type="button" class="btn btn-small" title="Help" data-event="showHelpDialog" tabindex="-1"><i class="icon-question"></i></button>'
1301
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Help" data-shortcut="Ctrl+/" data-mac-shortcut="⌘+/" data-event="showHelpDialog" tabindex="-1"><i class="icon-question"></i></button>'
1163
1302
  };
1164
1303
  var sPopover = '<div class="note-popover">' +
1165
1304
  '<div class="note-link-popover popover fade bottom in" style="display: none;">' +
@@ -1167,8 +1306,8 @@
1167
1306
  '<div class="popover-content note-link-content">' +
1168
1307
  '<a href="http://www.google.com" target="_blank">www.google.com</a>&nbsp;&nbsp;' +
1169
1308
  '<div class="note-insert btn-group">' +
1170
- '<button type="button" class="btn btn-small" title="Edit" data-event="showLinkDialog" tabindex="-1"><i class="icon-edit"></i></button>' +
1171
- '<button type="button" class="btn btn-small" title="Unlink" data-event="unlink" tabindex="-1"><i class="icon-unlink"></i></button>' +
1309
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Edit" data-event="showLinkDialog" tabindex="-1"><i class="icon-edit"></i></button>' +
1310
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Unlink" data-event="unlink" tabindex="-1"><i class="icon-unlink"></i></button>' +
1172
1311
  '</div>' +
1173
1312
  '</div>' +
1174
1313
  '</div>' +
@@ -1176,15 +1315,15 @@
1176
1315
  '<div class="arrow"></div>' +
1177
1316
  '<div class="popover-content note-image-content">' +
1178
1317
  '<div class="btn-group">' +
1179
- '<button type="button" class="btn btn-small" title="Resize Full" data-event="resize" data-value="1" tabindex="-1"><i class="icon-resize-full"></i></button>' +
1180
- '<button type="button" class="btn btn-small" title="Resize Half" data-event="resize" data-value="0.5" tabindex="-1">½</button>' +
1181
- '<button type="button" class="btn btn-small" title="Resize Thrid" data-event="resize" data-value="0.33" tabindex="-1">⅓</button>' +
1182
- '<button type="button" class="btn btn-small" title="Resize Quarter" data-event="resize" data-value="0.25" tabindex="-1">¼</button>' +
1318
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Resize Full" data-event="resize" data-value="1" tabindex="-1"><i class="icon-resize-full"></i></button>' +
1319
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Resize Half" data-event="resize" data-value="0.5" tabindex="-1">½</button>' +
1320
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Resize Thrid" data-event="resize" data-value="0.33" tabindex="-1">⅓</button>' +
1321
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Resize Quarter" data-event="resize" data-value="0.25" tabindex="-1">¼</button>' +
1183
1322
  '</div>' +
1184
1323
  '<div class="btn-group">' +
1185
- '<button type="button" class="btn btn-small" title="Float Left" data-event="float" data-value="left" tabindex="-1"><i class="icon-align-left"></i></button>' +
1186
- '<button type="button" class="btn btn-small" title="Float Right" data-event="float" data-value="right" tabindex="-1"><i class="icon-align-right"></i></button>' +
1187
- '<button type="button" class="btn btn-small" title="Float None" data-event="float" data-value="none" tabindex="-1"><i class="icon-reorder"></i></button>' +
1324
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Float Left" data-event="float" data-value="left" tabindex="-1"><i class="icon-align-left"></i></button>' +
1325
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Float Right" data-event="float" data-value="right" tabindex="-1"><i class="icon-align-right"></i></button>' +
1326
+ '<button type="button" class="btn btn-default btn-sm btn-small" title="Float None" data-event="float" data-value="none" tabindex="-1"><i class="icon-reorder"></i></button>' +
1188
1327
  '</div>' +
1189
1328
  '</div>' +
1190
1329
  '</div>' +
@@ -1203,192 +1342,123 @@
1203
1342
 
1204
1343
  var sShortcutText = '<table class="note-shortcut">' +
1205
1344
  '<thead>' +
1206
- '<tr>' +
1207
- '<th></th>' +
1208
- '<th>Text formatting</th>' +
1209
- '</tr>' +
1345
+ '<tr><th></th><th>Text formatting</th></tr>' +
1210
1346
  '</thead>' +
1211
1347
  '<tbody>' +
1212
- '<tr>' +
1213
- '<td>⌘ + B</td>' +
1214
- '<td>Bold</td>' +
1215
- '</tr>' +
1216
- '<tr>' +
1217
- '<td>⌘ + I</td>' +
1218
- '<td>Italic</td>' +
1219
- '</tr>' +
1220
- '<tr>' +
1221
- '<td>⌘ + U</td>' +
1222
- '<td>Underline</td>' +
1223
- '</tr>' +
1224
- '<tr>' +
1225
- '<td>⌘ + \\</td>' +
1226
- '<td>Remove Font Style</td>' +
1227
- '</tr>' +
1348
+ '<tr><td>⌘ + B</td><td>Toggle Bold</td></tr>' +
1349
+ '<tr><td>⌘ + I</td><td>Toggle Italic</td></tr>' +
1350
+ '<tr><td>⌘ + U</td><td>Toggle Underline</td></tr>' +
1351
+ '<tr><td>⌘ + ⇧ + S</td><td>Toggle Strike</td></tr>' +
1352
+ '<tr><td>⌘ + \\</td><td>Remove Font Style</td></tr>' +
1228
1353
  '</tr>' +
1229
1354
  '</tbody>' +
1230
1355
  '</table>';
1231
1356
 
1232
1357
  var sShortcutAction = '<table class="note-shortcut">' +
1233
1358
  '<thead>' +
1234
- '<tr>' +
1235
- '<th></th>' +
1236
- '<th>Action</th>' +
1237
- '</tr>' +
1359
+ '<tr><th></th><th>Action</th></tr>' +
1238
1360
  '</thead>' +
1239
1361
  '<tbody>' +
1240
- '<tr>' +
1241
- '<td>⌘ + Z</td>' +
1242
- '<td>Undo</td>' +
1243
- '</tr>' +
1244
- '<tr>' +
1245
- '<td>⌘ + + Z</td>' +
1246
- '<td>Redo</td>' +
1247
- '</tr>' +
1248
- '<tr>' +
1249
- '<td>Tab</td>' +
1250
- '<td>Indent</td>' +
1251
- '</tr>' +
1252
- '<tr>' +
1253
- '<td>⇧ + Tab</td>' +
1254
- '<td>Outdent</td>' +
1255
- '</tr>' +
1256
- '<tr>' +
1257
- '<td>⌘ + K</td>' +
1258
- '<td>Insert Link</td>' +
1259
- '</tr>' +
1260
- '<tr>' +
1261
- '<td>⌘ + ENTER</td>' +
1262
- '<td>Insert Horizontal Rule</td>' +
1263
- '</tr>' +
1362
+ '<tr><td>⌘ + Z</td><td>Undo</td></tr>' +
1363
+ '<tr><td>⌘ + ⇧ + Z</td><td>Redo</td></tr>' +
1364
+ '<tr><td>⌘ + ]</td><td>Indent</td></tr>' +
1365
+ '<tr><td>⌘ + [</td><td>Outdent</td></tr>' +
1366
+ '<tr><td>⌘ + K</td><td>Insert Link</td></tr>' +
1367
+ '<tr><td>⌘ + ENTER</td><td>Insert Horizontal Rule</td></tr>' +
1264
1368
  '</tbody>' +
1265
1369
  '</table>';
1266
1370
 
1267
1371
  var sShortcutPara = '<table class="note-shortcut">' +
1268
1372
  '<thead>' +
1269
- '<tr>' +
1270
- '<th></th>' +
1271
- '<th>Paragraph formatting</th>' +
1272
- '</tr>' +
1373
+ '<tr><th></th><th>Paragraph formatting</th></tr>' +
1273
1374
  '</thead>' +
1274
1375
  '<tbody>' +
1275
- '<tr>' +
1276
- '<td>⌘ + ⇧ + L</td>' +
1277
- '<td>Align Left</td>' +
1278
- '</tr>' +
1279
- '<tr>' +
1280
- '<td>⌘ + ⇧ + E</td>' +
1281
- '<td>Align Center</td>' +
1282
- '</tr>' +
1283
- '<tr>' +
1284
- '<td>⌘ + ⇧ + R</td>' +
1285
- '<td>Align Right</td>' +
1286
- '</tr>' +
1287
- '<tr>' +
1288
- '<td>⌘ + ⇧ + J</td>' +
1289
- '<td>Justify Full</td>' +
1290
- '</tr>' +
1291
- '<tr>' +
1292
- '<td>⌘ + ⇧ + NUM7</td>' +
1293
- '<td>Ordered List</td>' +
1294
- '</tr>' +
1295
- '<tr>' +
1296
- '<td>⌘ + ⇧ + NUM8</td>' +
1297
- '<td>Unordered List</td>' +
1298
- '</tr>' +
1376
+ '<tr><td>⌘ + ⇧ + L</td><td>Align Left</td></tr>' +
1377
+ '<tr><td>⌘ + ⇧ + E</td><td>Align Center</td></tr>' +
1378
+ '<tr><td>⌘ + ⇧ + R</td><td>Align Right</td></tr>' +
1379
+ '<tr><td>⌘ + ⇧ + J</td><td>Justify Full</td></tr>' +
1380
+ '<tr><td>⌘ + ⇧ + NUM7</td><td>Ordered List</td></tr>' +
1381
+ '<tr><td>⌘ + ⇧ + NUM8</td><td>Unordered List</td></tr>' +
1299
1382
  '</tbody>' +
1300
1383
  '</table>';
1301
1384
 
1302
1385
  var sShortcutStyle = '<table class="note-shortcut">' +
1303
1386
  '<thead>' +
1304
- '<tr>' +
1305
- '<th></th>' +
1306
- '<th>Document Style</th>' +
1307
- '</tr>' +
1387
+ '<tr><th></th><th>Document Style</th></tr>' +
1308
1388
  '</thead>' +
1309
1389
  '<tbody>' +
1310
- '<tr>' +
1311
- '<td>⌘ + NUM0</td>' +
1312
- '<td>Normal Text</td>' +
1313
- '</tr>' +
1314
- '<tr>' +
1315
- '<td>⌘ + NUM1</td>' +
1316
- '<td>Heading 1</td>' +
1317
- '</tr>' +
1318
- '<tr>' +
1319
- '<td>⌘ + NUM2</td>' +
1320
- '<td>Heading 2</td>' +
1321
- '</tr>' +
1322
- '<tr>' +
1323
- '<td>⌘ + NUM3</td>' +
1324
- '<td>Heading 3</td>' +
1325
- '</tr>' +
1326
- '<tr>' +
1327
- '<td>⌘ + NUM4</td>' +
1328
- '<td>Heading 4</td>' +
1329
- '</tr>' +
1330
- '<tr>' +
1331
- '<td>⌘ + NUM5</td>' +
1332
- '<td>Heading 5</td>' +
1333
- '</tr>' +
1334
- '<tr>' +
1335
- '<td>⌘ + NUM6</td>' +
1336
- '<td>Heading 6</td>' +
1337
- '</tr>' +
1338
-
1390
+ '<tr><td>⌘ + NUM0</td><td>Normal Text</td></tr>' +
1391
+ '<tr><td>⌘ + NUM1</td><td>Heading 1</td></tr>' +
1392
+ '<tr><td>⌘ + NUM2</td><td>Heading 2</td></tr>' +
1393
+ '<tr><td>⌘ + NUM3</td><td>Heading 3</td></tr>' +
1394
+ '<tr><td>⌘ + NUM4</td><td>Heading 4</td></tr>' +
1395
+ '<tr><td>⌘ + NUM5</td><td>Heading 5</td></tr>' +
1396
+ '<tr><td>⌘ + NUM6</td><td>Heading 6</td></tr>' +
1339
1397
  '</tbody>' +
1340
1398
  '</table>';
1399
+
1341
1400
  var sShortcutTable = '<table class="note-shortcut-layout">' +
1342
1401
  '<tbody>' +
1343
- '<tr>' +
1344
- '<td>' + sShortcutAction +'</td>' +
1345
- '<td>' + sShortcutText +'</td>' +
1346
- '</tr>' +
1347
- '<tr>' +
1348
- '<td>' + sShortcutStyle +'</td>' +
1349
- '<td>' + sShortcutPara +'</td>' +
1350
- '</tr>' +
1402
+ '<tr><td>' + sShortcutAction +'</td><td>' + sShortcutText +'</td></tr>' +
1403
+ '<tr><td>' + sShortcutStyle +'</td><td>' + sShortcutPara +'</td></tr>' +
1351
1404
  '</tbody>' +
1352
1405
  '</table>';
1353
1406
 
1354
1407
  var sDialog = '<div class="note-dialog">' +
1355
- '<div class="note-image-dialog modal hide in" aria-hidden="false">' +
1356
- '<div class="modal-header">' +
1357
- '<button type="button" class="close" data-dismiss="modal" aria-hidden="true" tabindex="-1">×</button>' +
1358
- '<h4>Insert Image</h4>' +
1359
- '</div>' +
1360
- '<div class="modal-body">' +
1361
- '<div class="row-fluid">' +
1362
- '<div class="note-dropzone span12">Drag an image here</div>' +
1363
- '<div>or if you prefer...</div>' +
1364
- '<input class="note-image-input" type="file" class="note-link-url" type="text" />' +
1408
+ '<div class="note-image-dialog modal" aria-hidden="false">' +
1409
+ '<div class="modal-dialog">' +
1410
+ '<div class="modal-content">' +
1411
+ '<div class="modal-header">' +
1412
+ '<button type="button" class="close" data-dismiss="modal" aria-hidden="true" tabindex="-1">×</button>' +
1413
+ '<h4>Insert Image</h4>' +
1414
+ '</div>' +
1415
+ '<div class="modal-body">' +
1416
+ '<div class="row-fluid">' +
1417
+ '<div class="note-dropzone span12">Drag an image here</div>' +
1418
+ '<div>or if you prefer...</div>' +
1419
+ '<input class="note-image-input" type="file" class="note-link-url" type="text" />' +
1420
+ '</div>' +
1421
+ '</div>' +
1365
1422
  '</div>' +
1366
1423
  '</div>' +
1367
1424
  '</div>' +
1368
- '<div class="note-link-dialog modal hide in" aria-hidden="false">' +
1369
- '<div class="modal-header">' +
1370
- '<button type="button" class="close" data-dismiss="modal" aria-hidden="true" tabindex="-1">×</button>' +
1371
- '<h4>Edit Link</h4>' +
1372
- '</div>' +
1373
- '<div class="modal-body">' +
1374
- '<div class="row-fluid">' +
1375
- '<label>Text to display</label>' +
1376
- '<span class="note-link-text input-xlarge uneditable-input" />' +
1377
- '<label>To what URL should this link go?</label>' +
1378
- '<input class="note-link-url span12" type="text" />' +
1425
+ '<div class="note-link-dialog modal" aria-hidden="false">' +
1426
+ '<div class="modal-dialog">' +
1427
+ '<div class="modal-content">' +
1428
+ '<div class="modal-header">' +
1429
+ '<button type="button" class="close" data-dismiss="modal" aria-hidden="true" tabindex="-1">×</button>' +
1430
+ '<h4>Edit Link</h4>' +
1431
+ '</div>' +
1432
+ '<div class="modal-body">' +
1433
+ '<div class="row-fluid">' +
1434
+
1435
+ '<div class="form-group">' +
1436
+ '<label>Text to display</label>' +
1437
+ '<span class="note-link-text form-control input-xlarge uneditable-input" />' +
1438
+ '</div>' +
1439
+ '<div class="form-group">' +
1440
+ '<label>To what URL should this link go?</label>' +
1441
+ '<input class="note-link-url form-control span12" type="text" />' +
1442
+ '</div>' +
1443
+ '</div>' +
1444
+ '</div>' +
1445
+ '<div class="modal-footer">' +
1446
+ '<a href="#" class="btn disabled note-link-btn" disabled="disabled">Link</a>' +
1447
+ '</div>' +
1379
1448
  '</div>' +
1380
1449
  '</div>' +
1381
- '<div class="modal-footer">' +
1382
- '<a href="#" class="btn disabled note-link-btn" disabled="disabled">Link</a>' +
1383
- '</div>' +
1384
1450
  '</div>' +
1385
- '<div class="note-help-dialog modal hide in" aria-hidden="false">' +
1386
- '<div class="modal-body">' +
1387
- '<div class="modal-background">' +
1388
- '<a class="modal-close pull-right" data-dismiss="modal" aria-hidden="true" tabindex="-1">Close</a>' +
1389
- '<div class="title">Keyboard shortcuts</div>' +
1390
- sShortcutTable +
1391
- '<p class="text-center"><a href="//hackerwins.github.io/summernote/" target="_blank">Summernote v0.2</a> · <a href="//github.com/HackerWins/summernote" target="_blank">Project</a> · <a href="//github.com/HackerWins/summernote/issues" target="_blank">Issues</a></p>' +
1451
+ '<div class="note-help-dialog modal fade" aria-hidden="false">' +
1452
+ '<div class="modal-dialog">' +
1453
+ '<div class="modal-content">' +
1454
+ '<div class="modal-body">' +
1455
+ '<div class="modal-background">' +
1456
+ '<a class="modal-close pull-right" data-dismiss="modal" aria-hidden="true" tabindex="-1">Close</a>' +
1457
+ '<div class="title">Keyboard shortcuts</div>' +
1458
+ sShortcutTable +
1459
+ '<p class="text-center"><a href="//hackerwins.github.io/summernote/" target="_blank">Summernote v0.3</a> · <a href="//github.com/HackerWins/summernote" target="_blank">Project</a> · <a href="//github.com/HackerWins/summernote/issues" target="_blank">Issues</a></p>' +
1460
+ '</div>' +
1461
+ '</div>' +
1392
1462
  '</div>' +
1393
1463
  '</div>' +
1394
1464
  '</div>';
@@ -1447,7 +1517,12 @@
1447
1517
  //01. create Editor
1448
1518
  var welEditor = $('<div class="note-editor"></div>');
1449
1519
 
1450
- //02. create Editable
1520
+ //02. statusbar
1521
+ if (nHeight > 0) {
1522
+ var welStatusbar = $('<div class="note-statusbar"><div class="note-resizebar"><div class="note-icon-bar"></div><div class="note-icon-bar"></div><div class="note-icon-bar"></div></div></div>').prependTo(welEditor);
1523
+ }
1524
+
1525
+ //03. create Editable
1451
1526
  var welEditable = $('<div class="note-editable" contentEditable="true"></div>').prependTo(welEditor);
1452
1527
  if (nTabIndex) { welEditable.attr('tabIndex', nTabIndex); }
1453
1528
  if (nHeight) { welEditable.height(nHeight); }
@@ -1455,12 +1530,12 @@
1455
1530
  welEditable.html(welHolder.html());
1456
1531
  welEditable.data('NoteHistory', new History());
1457
1532
 
1458
- //03. create Toolbar
1533
+ //04. create Toolbar
1459
1534
  var sToolbar = '';
1460
- for (var idx in aToolbarSetting) {
1535
+ for (var idx = 0, sz = aToolbarSetting.length; idx < sz; idx ++) {
1461
1536
  var group = aToolbarSetting[idx];
1462
1537
  sToolbar += '<div class="note-' + group[0] + ' btn-group">';
1463
- for (var i in group[1]) {
1538
+ for (var i = 0, szGroup = group[1].length; i < szGroup; i++) {
1464
1539
  sToolbar += aToolbarItem[group[1][i]];
1465
1540
  }
1466
1541
  sToolbar += '</div>';
@@ -1472,17 +1547,17 @@
1472
1547
  createPalette(welToolbar);
1473
1548
  createTooltip(welToolbar, 'bottom');
1474
1549
 
1475
- //04. create Popover
1550
+ //05. create Popover
1476
1551
  var welPopover = $(sPopover).prependTo(welEditor);
1477
1552
  createTooltip(welPopover);
1478
1553
 
1479
- //05. handle(control selection, ...)
1554
+ //06. handle(control selection, ...)
1480
1555
  $(sHandle).prependTo(welEditor);
1481
1556
 
1482
- //06. create Dialog
1557
+ //07. create Dialog
1483
1558
  $(sDialog).prependTo(welEditor);
1484
1559
 
1485
- //05. Editor/Holder switch
1560
+ //08. Editor/Holder switch
1486
1561
  welEditor.insertAfter(welHolder);
1487
1562
  welHolder.hide();
1488
1563
  };
@@ -1494,8 +1569,9 @@
1494
1569
 
1495
1570
  return {
1496
1571
  editor: welEditor,
1497
- editable: welEditor.find('.note-editable'),
1498
1572
  toolbar: welEditor.find('.note-toolbar'),
1573
+ editable: welEditor.find('.note-editable'),
1574
+ statusbar: welEditor.find('.note-statusbar'),
1499
1575
  popover: welEditor.find('.note-popover'),
1500
1576
  handle: welEditor.find('.note-handle'),
1501
1577
  dialog: welEditor.find('.note-dialog')
@@ -1523,18 +1599,18 @@
1523
1599
  // create Editor Layout and attach Key and Mouse Event
1524
1600
  summernote: function(options) {
1525
1601
  options = $.extend({
1526
- toolbar: [
1527
- ['insert', ['picture', 'link']],
1528
- ['table', ['table']],
1529
- ['style', ['style']],
1530
- ['fontsize', ['fontsize']],
1531
- ['color', ['color']],
1532
- ['style', ['bold', 'italic', 'underline', 'clear']],
1533
- ['para', ['ul', 'ol', 'paragraph']],
1534
- ['height', ['height']],
1535
- ['help', ['help']]
1536
- ]
1537
- }, options );
1602
+ toolbar: [
1603
+ ['style', ['style']],
1604
+ ['font', ['bold', 'italic', 'underline', 'clear']],
1605
+ ['fontsize', ['fontsize']],
1606
+ ['color', ['color']],
1607
+ ['para', ['ul', 'ol', 'paragraph']],
1608
+ ['height', ['height']],
1609
+ ['table', ['table']],
1610
+ ['insert', ['link', 'picture']],
1611
+ ['help', ['help']]
1612
+ ]
1613
+ }, options );
1538
1614
 
1539
1615
  this.each(function(idx, elHolder) {
1540
1616
  var welHolder = $(elHolder);
@@ -1587,4 +1663,27 @@
1587
1663
  return { dom: dom, list: list, func: func, Range: Range };
1588
1664
  }
1589
1665
  });
1590
- })(jQuery); // jQuery
1666
+ })(jQuery); // jQuery
1667
+
1668
+ //Array.prototype.reduce fallback
1669
+ //https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/Reduce
1670
+ if ('function' !== typeof Array.prototype.reduce) {
1671
+ Array.prototype.reduce = function(callback, opt_initialValue) {
1672
+ 'use strict';
1673
+ var idx, value, length = this.length >>> 0, isValueSet = false;
1674
+ if (1 < arguments.length) { value = opt_initialValue, isValueSet = true; }
1675
+ for (idx = 0; length > idx; ++idx) {
1676
+ if (this.hasOwnProperty(idx)) {
1677
+ if (isValueSet) {
1678
+ value = callback(value, this[idx], idx, this);
1679
+ } else {
1680
+ value = this[idx], isValueSet = true;
1681
+ }
1682
+ }
1683
+ }
1684
+ if (!isValueSet) {
1685
+ throw new TypeError('Reduce of empty array with no initial value');
1686
+ }
1687
+ return value;
1688
+ };
1689
+ }