summaryrefslogtreecommitdiff
path: root/platform/www/lib/scripts/edit.js
diff options
context:
space:
mode:
Diffstat (limited to 'platform/www/lib/scripts/edit.js')
-rw-r--r--platform/www/lib/scripts/edit.js307
1 files changed, 307 insertions, 0 deletions
diff --git a/platform/www/lib/scripts/edit.js b/platform/www/lib/scripts/edit.js
new file mode 100644
index 0000000..f53a6d4
--- /dev/null
+++ b/platform/www/lib/scripts/edit.js
@@ -0,0 +1,307 @@
+/**
+ * Functions for text editing (toolbar stuff)
+ *
+ * @todo most of the stuff in here should be revamped and then moved to toolbar.js
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+
+/**
+ * Creates a toolbar button through the DOM
+ * Called for each entry of toolbar definition array (built by inc/toolbar.php and extended via js)
+ *
+ * Style the buttons through the toolbutton class
+ *
+ * @param {string} icon image filename, relative to folder lib/images/toolbar/
+ * @param {string} label title of button, show on mouseover
+ * @param {string} key hint in title of button for access key
+ * @param {string} id id of button, and '<id>_ico' of icon
+ * @param {string} classname for styling buttons
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ * @author Michal Rezler <m.rezler@centrum.cz>
+ */
+function createToolButton(icon,label,key,id,classname){
+ var $btn = jQuery(document.createElement('button')),
+ $ico = jQuery(document.createElement('img'));
+
+ // prepare the basic button stuff
+ $btn.addClass('toolbutton');
+ if(classname){
+ $btn.addClass(classname);
+ }
+
+ $btn.attr('title', label).attr('aria-controls', 'wiki__text');
+ if(key){
+ $btn.attr('title', label + ' ['+key.toUpperCase()+']')
+ .attr('accessKey', key);
+ }
+
+ // set IDs if given
+ if(id){
+ $btn.attr('id', id);
+ $ico.attr('id', id+'_ico');
+ }
+
+ // create the icon and add it to the button
+ if(icon.substr(0,1) !== '/'){
+ icon = DOKU_BASE + 'lib/images/toolbar/' + icon;
+ }
+ $ico.attr('src', icon);
+ $ico.attr('alt', '');
+ $ico.attr('width', 16);
+ $ico.attr('height', 16);
+ $btn.append($ico);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $btn[0];
+}
+
+/**
+ * Creates a picker window for inserting text
+ *
+ * The given list can be an associative array with text,icon pairs
+ * or a simple list of text. Style the picker window through the picker
+ * class or the picker buttons with the pickerbutton class. Picker
+ * windows are appended to the body and created invisible.
+ *
+ * @param {string} id the ID to assign to the picker
+ * @param {Array} props the properties for the picker
+ * @param {string} edid the ID of the textarea
+ * @return DOMobject the created picker
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function createPicker(id,props,edid){
+ // create the wrapping div
+ var $picker = jQuery(document.createElement('div'));
+
+ $picker.addClass('picker a11y');
+ if(props['class']){
+ $picker.addClass(props['class']);
+ }
+
+ $picker.attr('id', id).css('position', 'absolute');
+
+ function $makebutton(title) {
+ var $btn = jQuery(document.createElement('button'))
+ .addClass('pickerbutton').attr('title', title)
+ .attr('aria-controls', edid)
+ .on('click', bind(pickerInsert, title, edid))
+ .appendTo($picker);
+ return $btn;
+ }
+
+ jQuery.each(props.list, function (key, item) {
+ if (!props.list.hasOwnProperty(key)) {
+ return;
+ }
+
+ if(isNaN(key)){
+ // associative array -> treat as text => image pairs
+ if (item.substr(0,1) !== '/') {
+ item = DOKU_BASE+'lib/images/'+props.icobase+'/'+item;
+ }
+ jQuery(document.createElement('img'))
+ .attr('src', item)
+ .attr('alt', '')
+ .appendTo($makebutton(key));
+ }else if (typeof item == 'string'){
+ // a list of text -> treat as text picker
+ $makebutton(item).text(item);
+ }else{
+ // a list of lists -> treat it as subtoolbar
+ initToolbar($picker,edid,props.list);
+ return false; // all buttons handled already
+ }
+
+ });
+ jQuery('body').append($picker);
+
+ // we have to return a DOM object (for compatibility reasons)
+ return $picker[0];
+}
+
+/**
+ * Called by picker buttons to insert Text and close the picker again
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function pickerInsert(text,edid){
+ insertAtCarret(edid,text);
+ pickerClose();
+}
+
+/**
+ * Add button action for signature button
+ *
+ * @param {jQuery} $btn Button element to add the action to
+ * @param {Array} props Associative array of button properties
+ * @param {string} edid ID of the editor textarea
+ * @return {string} picker id for aria-controls attribute
+ * @author Gabriel Birke <birke@d-scribe.de>
+ */
+function addBtnActionSignature($btn, props, edid) {
+ if(typeof SIG != 'undefined' && SIG != ''){
+ $btn.on('click', function (e) {
+ insertAtCarret(edid,SIG);
+ e.preventDefault();
+ });
+ return edid;
+ }
+ return '';
+}
+
+/**
+ * Determine the current section level while editing
+ *
+ * @param {string} textboxId ID of the text field
+ *
+ * @author Andreas Gohr <gohr@cosmocode.de>
+ */
+function currentHeadlineLevel(textboxId){
+ var field = jQuery('#' + textboxId)[0],
+ s = false,
+ opts = [field.value.substr(0,DWgetSelection(field).start)];
+ if (field.form && field.form.prefix) {
+ // we need to look in prefix context
+ opts.push(field.form.prefix.value);
+ }
+
+ jQuery.each(opts, function (_, opt) {
+ // Check whether there is a headline in the given string
+ var str = "\n" + opt,
+ lasthl = str.lastIndexOf("\n==");
+ if (lasthl !== -1) {
+ s = str.substr(lasthl+1,6);
+ return false;
+ }
+ });
+ if (s === false) {
+ return 0;
+ }
+ return 7 - s.match(/^={2,6}/)[0].length;
+}
+
+
+/**
+ * global var used for not saved yet warning
+ */
+window.textChanged = false;
+
+/**
+ * global var which stores original editor content
+ */
+window.doku_edit_text_content = '';
+/**
+ * Delete the draft before leaving the page
+ */
+function deleteDraft() {
+ if (is_opera || window.keepDraft) {
+ return;
+ }
+
+ var $dwform = jQuery('#dw__editform');
+
+ if($dwform.length === 0) {
+ return;
+ }
+
+ // remove a possibly saved draft using ajax
+ jQuery.post(DOKU_BASE + 'lib/exe/ajax.php',
+ {
+ call: 'draftdel',
+ id: $dwform.find('input[name=id]').val()
+ }
+ );
+}
+
+/**
+ * Activate "not saved" dialog, add draft deletion to page unload,
+ * add handlers to monitor changes
+ * Note: textChanged could be set by e.g. html_edit() as well
+ *
+ * Sets focus to the editbox as well
+ */
+jQuery(function () {
+ var $editform = jQuery('#dw__editform');
+ if ($editform.length == 0) {
+ return;
+ }
+
+ var $edit_text = jQuery('#wiki__text');
+ if ($edit_text.length > 0) {
+ if($edit_text.attr('readOnly')) {
+ return;
+ }
+
+ // set focus and place cursor at the start
+ var sel = DWgetSelection($edit_text[0]);
+ sel.start = 0;
+ sel.end = 0;
+ DWsetSelection(sel);
+ $edit_text.trigger('focus');
+
+ doku_edit_text_content = $edit_text.val();
+ }
+
+ var changeHandler = function() {
+ doku_hasTextBeenModified();
+
+ doku_summaryCheck();
+ };
+
+ $editform.change(changeHandler);
+ $editform.keydown(changeHandler);
+
+ window.onbeforeunload = function(){
+ if(window.textChanged) {
+ return LANG.notsavedyet;
+ }
+ };
+ window.onunload = deleteDraft;
+
+ // reset change memory var on submit
+ jQuery('#edbtn__save').on('click',
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ }
+ );
+ jQuery('#edbtn__preview').on('click',
+ function() {
+ window.onbeforeunload = '';
+ textChanged = false;
+ window.keepDraft = true; // needed to keep draft on page unload
+ }
+ );
+
+ var $summary = jQuery('#edit__summary');
+ $summary.on('change keyup', doku_summaryCheck);
+
+ if (textChanged) doku_summaryCheck();
+});
+
+/**
+ * Updates textChanged variable if content of the editor has been modified
+ */
+function doku_hasTextBeenModified() {
+ if (!textChanged) {
+ var $edit_text = jQuery('#wiki__text');
+
+ if ($edit_text.length > 0) {
+ textChanged = doku_edit_text_content != $edit_text.val();
+ } else {
+ textChanged = true;
+ }
+ }
+}
+
+/**
+ * Checks if a summary was entered - if not the style is changed
+ *
+ * @author Andreas Gohr <andi@splitbrain.org>
+ */
+function doku_summaryCheck(){
+ var $sum = jQuery('#edit__summary'),
+ missing = $sum.val() === '';
+ $sum.toggleClass('missing', missing).toggleClass('edit', !missing);
+}