_fontSettingChanged: function() { var fontSize = settings.get('fontsize'); var fontFace = settings.get('fontface'); this._font = fontSize + 'px ' + fontFace; // Recompute the layouts. this.layoutManager._recalculateMaximumWidth(); this._layoutManagerSizeChanged(this.layoutManager.size); this.textView.invalidate(); },
set: function(key, value) { if (util.none(key)) { throw new Error('setSetting(): key must be supplied'); } if (util.none(value)) { throw new Error('setSetting(): value must be supplied'); } settings.set(key, value); },
this.elementAppended.add(function() { // Set the font property. var fontSize = settings.get('fontsize'); var fontFace = settings.get('fontface'); this._font = fontSize + 'px ' + fontFace; // Repaint when the theme changes. catalog.registerExtension('themeChange', { pointer: this._themeVariableChange.bind(this) }); // When the font changes, set our local font property, and repaint. catalog.registerExtension('settingChange', { match: "font[size|face]", pointer: this._fontSettingChanged.bind(this) }); // Likewise when the dimensions change. catalog.registerExtension('dimensionsChanged', { pointer: this.dimensionsChanged.bind(this) }); // Allow the layout to be recomputed. this._dontRecomputeLayout = false; this._recomputeLayout(); var wheelEvent = util.isMozilla ? 'DOMMouseScroll' : 'mousewheel'; container.addEventListener(wheelEvent, this._onMouseWheel.bind(this), false); verticalScroller.valueChanged.add(function(value) { this.scrollOffset = { y: value }; }.bind(this)); horizontalScroller.valueChanged.add(function(value) { this.scrollOffset = { x: value }; }.bind(this)); this.scrollOffsetChanged.add(function(offset) { this._updateScrollOffsetChanged(offset); }.bind(this)); }.bind(this));
_customKeymappingChanged: function() { var ckc = this._customKeymappingCache = JSON.parse(settings.get('customKeymapping')); ckc.states = ckc.states || {}; for (state in ckc.states) { this._buildBindingsRegex(ckc.states[state]); } ckc._convertedRegExp = true; }
var computeFontDimension = function() { var fontSize = settings.get('fontsize'); var fontFace = settings.get('fontface'); var font = fontSize + 'px ' + fontFace; var canvas = m_scratchcanvas.get(); // Measure a large string to work around the fact that width and height // are truncated to the nearest integer in the canvas API. var str = ''; for (var i = 0; i < 100; i++) { str += 'M'; } var width = canvas.measureStringWidth(font, str) / 100; fontDimension.characterWidth = width; fontDimension.lineHeight = Math.floor(fontSize * 1.6); fontDimension.lineAscent = Math.floor(fontSize * 1.3); };
exports.setCommand = function(args, request) { var html; if (!args.setting) { var settingsList = settings._list(); html = ''; // first sort the settingsList based on the key settingsList.sort(function(a, b) { if (a.key < b.key) { return -1; } else if (a.key == b.key) { return 0; } else { return 1; } }); settingsList.forEach(function(setting) { html += '<a class="setting" href="https://wiki.mozilla.org/Labs/Skywriter/Settings#' + setting.key + '" title="View external documentation on setting: ' + setting.key + '" target="_blank">' + setting.key + '</a> = ' + setting.value + '<br/>'; }); } else { if (args.value === undefined) { html = '<strong>' + args.setting + '</strong> = ' + settings.get(args.setting); } else { html = 'Setting: <strong>' + args.setting + '</strong> = ' + args.value; settings.set(args.setting, args.value); } } request.done(html); };
view.groupChanges(function() { var tabstop = settings.get('tabstop'); var selection = view.getSelectedRange(); var str = ''; if (m_range.isZeroLength(selection)){ var line = env.model.lines[selection.start.row]; var trailspaces = line.substring(selection.start.col). match(/^\s*/)[0].length; var count = tabstop - (selection.start.col + trailspaces) % tabstop; for (var i = 0; i < count; i++) { str += ' '; } view.replaceCharacters({ start: selection.start, end: selection.start }, str); view.moveCursorTo({ col: selection.start.col + count + trailspaces, row: selection.end.row }); } else { for (var i = 0; i < tabstop; i++) { str += ' '; } var startCol; var row = selection.start.row - 1; while (row++ < selection.end.row) { startCol = row == selection.start.row ? selection.start.col : 0; view.replaceCharacters({ start: { row: row, col: startCol}, end: { row: row, col: startCol} }, str); } view.setSelection({ start: selection.start, end: { col: selection.end.col + tabstop, row: selection.end.row } }); } }.bind(this));
view.groupChanges(function() { var tabstop = settings.get('tabstop'); var selection = view.getSelectedRange(); var lines = env.model.lines; var count = 0; if (m_range.isZeroLength(selection)){ count = Math.min( lines[selection.start.row].substring(0, selection.start.col). match(/\s*$/)[0].length, (selection.start.col - tabstop) % tabstop || tabstop); view.replaceCharacters({ start: { col: selection.start.col - count, row: selection.start.row }, end: selection.start }, ''); view.moveCursorTo({ row: selection.start.row, col: selection.end.col - count }); } else { var startCol; var row = selection.start.row - 1; while (row++ < selection.end.row) { startCol = row == selection.start.row ? selection.start.col : 0; count = Math.min( lines[row].substring(startCol).match(/^\s*/)[0].length, tabstop); view.replaceCharacters({ start: { row: row, col: startCol}, end: { row: row, col: startCol + count} }, ''); } view.setSelection({ start: { row: selection.start.row, col: selection.start.col}, end: { row: selection.end.row, col: selection.end.col - count} }); } }.bind(this));
get: function(key) { if (util.none(key)) { throw new Error('getSetting(): key must be supplied'); } return settings.get(key); }
exports.detabCommand = function(args, request) { tabstop = settings.get('tabstop'); withSelection(function(selected) { return selected.replace('\t', new Array(tabstop + 1).join(' ')); }); };
exports.entabCommand = function(args, request) { tabstop = settings.get('tabstop'); withSelection(function(selected) { return selected.replace(' {' + tabstop + '}', '\t'); }); };
$(this.fontsizeSelector).change(function(evt) { var newSize = $(evt.target).val(); settings.set('fontsize', parseInt(newSize, 10)); env.editor.focus = true; });
this._syntaxInfo.settings.forEach(function(name) { var value = settings.get(name); this._worker.send('setSyntaxSetting', [ name, value ]); }, this);
exports.launch = function(config) { var launchPromise = new Promise(); // Remove the "Loading..." hint. $('#_bespin_loading').remove(); // This will hold the require function to get the catalog. var require; // Is this the fist Bespin? if (firstBespin) { // Use the global require. require = bespin.tiki.require; firstBespin = false; } else { // Otherwise create a new tiki-bespin sandbox and a new require function. var sandbox = new (bespin.tiki.require('bespin:sandbox').Sandbox); require = sandbox.createRequire({ id: 'index', ownerPackage: bespin.tiki.loader.anonymousPackage }); } // Here we go: Require the catalog that is used for this Bespin instance. var catalog = require('bespin:plugins').catalog; // Launch Bespin! config = config || {}; exports.normalizeConfig(catalog, config); var objects = config.objects; for (var key in objects) { catalog.registerObject(key, objects[key]); } for (var setting in config.settings) { settings.set(setting, config.settings[setting]); } // Resolve the launchPromise and pass the env variable along. var resolveLaunchPromise = function() { var env = require("environment").env; var editor = env.editor; if (editor) { if (config.lineNumber) { editor.setLineNumber(config.lineNumber); } if (config.stealFocus) { editor.focus = true; } if (config.readOnly) { editor.readOnly = config.readOnly; } if (config.syntax) { editor.syntax = config.syntax; } } var commandLine = catalog.getObject('commandLine'); if (commandLine) { env.commandLine = commandLine; } catalog.publish(this, 'appLaunched'); launchPromise.resolve(env); }.bind(this); var themeLoadingPromise = new Promise(); themeLoadingPromise.then(function() { if (objects.loginController) { catalog.createObject("loginController").then( function(loginController) { var pr = loginController.showLogin(); pr.then(function(username) { // Add the username as constructor argument. config.objects.session.arguments.push(username); exports.launchEditor(catalog, config).then(resolveLaunchPromise, launchPromise.reject.bind(launchPromise)); }); }); } else { exports.launchEditor(catalog, config).then(resolveLaunchPromise, launchPromise.reject.bind(launchPromise)); } }, function(error) { launchPromise.reject(error); }); // If the themeManager plugin is there, then check for theme configuration. if (catalog.plugins.theme_manager) { bespin.tiki.require.ensurePackage('::theme_manager', function() { var themeManager = require('theme_manager'); if (config.theme.basePlugin) { themeManager.setBasePlugin(config.theme.basePlugin); } if (config.theme.standard) { themeManager.setStandardTheme(config.theme.standard); } themeManager.startParsing().then(function() { themeLoadingPromise.resolve(); }, function(error) { themeLoadingPromise.reject(error); }); }); } else { themeLoadingPromise.resolve(); } return launchPromise; };
performBackspaceOrDelete: function(isBackspace) { if (this._isReadOnly()) { return false; } var model = this.editor.layoutManager.textStorage; var lines = model.lines; var line = '', count = 0; var tabstop = settings.get('tabstop'); var range = this.getSelectedRange(); if (Range.isZeroLength(range)) { if (isBackspace) { var start = range.start; line = lines[start.row]; var preWhitespaces = line.substring(0, start.col). match(/\s*$/)[0].length; // If there are less then n-tabstop whitespaces in front, OR // the current cursor position is not n times tabstop, THEN // delete only 1 character. if (preWhitespaces < tabstop || (start.col - tabstop) % tabstop != 0) { count = 1; } else { // Otherwise delete tabstop whitespaces. count = tabstop; } range = { start: model.displacePosition(start, count * -1), end: range.end }; } else { var end = range.end; line = lines[end.row]; var trailingWhitespaces = line.substring(end.col). match(/^\s*/)[0].length; // If there are less then n-tabstop whitespaces after the cursor // position, then delete only 1 character. Otherwise delete // tabstop whitespaces. if (trailingWhitespaces < tabstop) { count = 1; } else { count = tabstop; } range = { start: range.start, end: model.displacePosition(range.end, count) }; } } this.groupChanges(function() { this.replaceCharacters(range, ''); // Position the insertion point at the start of all the ranges that // were just deleted. this.moveCursorTo(range.start); }.bind(this)); return true; },
exports.unsetCommand = function(args, request) { settings.resetValue(args.setting); request.done('Reset ' + args.setting + ' to default: ' + settings.get(args.setting)); };
$(this.themeSelector).change(function(evt) { var newTheme = $(evt.target).val(); settings.set('theme', newTheme); env.editor.focus = true; });