csledit.js (8419B)
1 /* 2 ***** BEGIN LICENSE BLOCK ***** 3 4 Copyright © 2009 Center for History and New Media 5 George Mason University, Fairfax, Virginia, USA 6 http://zotero.org 7 8 This file is part of Zotero. 9 10 Zotero is free software: you can redistribute it and/or modify 11 it under the terms of the GNU Affero General Public License as published by 12 the Free Software Foundation, either version 3 of the License, or 13 (at your option) any later version. 14 15 Zotero is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU Affero General Public License for more details. 19 20 You should have received a copy of the GNU Affero General Public License 21 along with Zotero. If not, see <http://www.gnu.org/licenses/>. 22 23 ***** END LICENSE BLOCK ***** 24 */ 25 26 var Zotero_CSL_Editor = new function() { 27 this.init = init; 28 this.handleKeyPress = handleKeyPress; 29 this.loadCSL = loadCSL; 30 function init() { 31 Zotero.Styles.populateLocaleList(document.getElementById("locale-menu")); 32 33 var cslList = document.getElementById('zotero-csl-list'); 34 cslList.removeAllItems(); 35 36 var lastStyle = Zotero.Prefs.get('export.lastStyle'); 37 38 var styles = Zotero.Styles.getVisible(); 39 var currentStyle = null; 40 for (let style of styles) { 41 if (style.source) { 42 continue; 43 } 44 var item = cslList.appendItem(style.title, style.styleID); 45 if (!currentStyle && lastStyle == style.styleID) { 46 currentStyle = style; 47 cslList.selectedItem = item; 48 } 49 } 50 51 if (currentStyle) { 52 // Call asynchronously, see note in Zotero.Styles 53 window.setTimeout(this.onStyleSelected.bind(this, currentStyle.styleID), 1); 54 } 55 56 var pageList = document.getElementById('zotero-csl-page-type'); 57 var locators = Zotero.Cite.labels; 58 for (let type of locators) { 59 var locator = type; 60 locator = Zotero.getString('citation.locator.'+locator.replace(/\s/g,'')); 61 pageList.appendItem(locator, type); 62 } 63 64 pageList.selectedIndex = 0; 65 } 66 67 this.onStyleSelected = function(styleID) { 68 Zotero.Prefs.set('export.lastStyle', styleID); 69 let style = Zotero.Styles.get(styleID); 70 Zotero.Styles.updateLocaleList( 71 document.getElementById("locale-menu"), 72 style, 73 Zotero.Prefs.get('export.lastLocale') 74 ); 75 76 loadCSL(style.styleID); 77 this.refresh(); 78 } 79 80 this.refresh = function() { 81 this.generateBibliography(this.loadStyleFromEditor()); 82 } 83 84 this.save = function() { 85 var editor = document.getElementById('zotero-csl-editor'); 86 var style = editor.value; 87 const nsIFilePicker = Components.interfaces.nsIFilePicker; 88 var fp = Components.classes["@mozilla.org/filepicker;1"] 89 .createInstance(nsIFilePicker); 90 fp.init(window, Zotero.getString('styles.editor.save'), nsIFilePicker.modeSave); 91 fp.appendFilter("Citation Style Language", "*.csl"); 92 //get the filename from the id; we could consider doing even more here like creating the id from filename. 93 var parser = new DOMParser(); 94 var doc = parser.parseFromString(style, 'text/xml'); 95 var filename = doc.getElementsByTagName("id"); 96 if (filename) { 97 filename = filename[0].textContent; 98 fp.defaultString = filename.replace(/.+\//, "") + ".csl"; 99 } 100 else { 101 fp.defaultString = "untitled.csl"; 102 } 103 var rv = fp.show(); 104 if (rv == nsIFilePicker.returnOK || rv == nsIFilePicker.returnReplace) { 105 var outputFile = fp.file; 106 Zotero.File.putContents(outputFile, style); 107 } 108 }; 109 110 function handleKeyPress(event) { 111 if (event.keyCode == 9 && 112 (!event.shiftKey && !event.metaKey && !event.altKey && !event.ctrlKey)) { 113 _insertText("\t"); 114 event.preventDefault(); 115 } 116 } 117 118 119 function loadCSL(cslID) { 120 var editor = document.getElementById('zotero-csl-editor'); 121 var style = Zotero.Styles.get(cslID); 122 editor.value = style.getXML(); 123 editor.cslID = cslID; 124 editor.doCommand(); 125 document.getElementById('zotero-csl-list').value = cslID; 126 } 127 128 this.loadStyleFromEditor = function() { 129 var styleObject; 130 try { 131 styleObject = new Zotero.Style( 132 document.getElementById('zotero-csl-editor').value 133 ); 134 } catch(e) { 135 document.getElementById('zotero-csl-preview-box') 136 .contentDocument.documentElement.innerHTML = '<div>' 137 + Zotero.getString('styles.editor.warning.parseError') 138 + '</div><div>' + e + '</div>'; 139 throw e; 140 } 141 142 return styleObject; 143 } 144 145 this.onStyleModified = function(str) { 146 document.getElementById('zotero-csl-list').selectedIndex = -1; 147 148 let styleObject = this.loadStyleFromEditor(); 149 150 Zotero.Styles.updateLocaleList( 151 document.getElementById("locale-menu"), 152 styleObject, 153 Zotero.Prefs.get('export.lastLocale') 154 ); 155 Zotero_CSL_Editor.generateBibliography(styleObject); 156 } 157 158 this.generateBibliography = function(style) { 159 var iframe = document.getElementById('zotero-csl-preview-box'); 160 var editor = document.getElementById('zotero-csl-editor'); 161 162 var items = Zotero.getActiveZoteroPane().getSelectedItems(); 163 if (items.length == 0) { 164 iframe.contentDocument.documentElement.innerHTML = 165 '<html><head><title></title></head><body><p style="color: red">' 166 + Zotero.getString('styles.editor.warning.noItems') 167 + '</p></body></html>'; 168 return; 169 } 170 171 var selectedLocale = document.getElementById("locale-menu").value; 172 var styleEngine; 173 try { 174 styleEngine = style.getCiteProc(style.locale || selectedLocale); 175 } catch(e) { 176 iframe.contentDocument.documentElement.innerHTML = '<div>' + Zotero.getString('styles.editor.warning.parseError') + '</div><div>'+e+'</div>'; 177 throw e; 178 } 179 180 var itemIds = items.map(item => item.id); 181 182 styleEngine.updateItems(itemIds); 183 184 // Generate multiple citations 185 var citation = {}; 186 citation.citationItems = []; 187 citation.properties = {}; 188 citation.properties.noteIndex = 1; 189 for (var i = 0, ilen = items.length; i < ilen; i += 1) { 190 citation.citationItems.push({id:itemIds[i]}); 191 } 192 193 // Generate single citations 194 var author = document.getElementById("preview-suppress-author").checked; 195 var search = document.getElementById('preview-pages'); 196 var loc = document.getElementById('zotero-csl-page-type'); 197 var pos = document.getElementById('zotero-ref-position').selectedItem.value; 198 var citations = '<h3>' + Zotero.getString('styles.editor.output.individualCitations') + '</h3>'; 199 for (var i=0; i<citation.citationItems.length; i++) { 200 citation.citationItems[i]['suppress-author'] = author; 201 if (search.value !== '') { 202 citation.citationItems[i].locator = search.value; 203 citation.citationItems[i].label = loc.selectedItem.value; 204 } 205 if (pos == 4) { 206 //near note is a subsequent citation with near note set to true; 207 citation.citationItems[i].position = 1; 208 citation.citationItems[i]["near-note"] = true; 209 } 210 else { 211 citation.citationItems[i].position = parseInt(pos, 10); 212 } 213 var subcitation = [citation.citationItems[i]]; 214 citations += styleEngine.makeCitationCluster(subcitation) + '<br />'; 215 } 216 217 try { 218 var multCitations = '<hr><h3>' + Zotero.getString('styles.editor.output.singleCitation') + '</h3>' + 219 styleEngine.previewCitationCluster(citation, [], [], "html"); 220 221 // Generate bibliography 222 styleEngine.updateItems(itemIds); 223 var bibliography = '<hr/><h3>' + Zotero.getString('styles.bibliography') + '</h3>' + 224 Zotero.Cite.makeFormattedBibliography(styleEngine, "html"); 225 226 iframe.contentDocument.documentElement.innerHTML = 227 '<div>' + citations + multCitations + bibliography + '</div>'; 228 } catch(e) { 229 iframe.contentDocument.documentElement.innerHTML = '<div>' + Zotero.getString('styles.editor.warning.renderError') + '</div><div>'+e+'</div>'; 230 throw e; 231 } 232 editor.styleEngine = styleEngine; 233 } 234 235 236 // From http://kb.mozillazine.org/Inserting_text_at_cursor 237 function _insertText(text) { 238 var command = "cmd_insertText"; 239 var controller = document.commandDispatcher.getControllerForCommand(command); 240 if (controller && controller.isCommandEnabled(command)) { 241 controller = controller.QueryInterface(Components.interfaces.nsICommandController); 242 var params = Components.classes["@mozilla.org/embedcomp/command-params;1"]; 243 params = params.createInstance(Components.interfaces.nsICommandParams); 244 params.setStringValue("state_data", "\t"); 245 controller.doCommandWithParams(command, params); 246 } 247 } 248 }();