summernote-rails 0.2.1.4 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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
+ }