From 86a484baeada34324e245055f08d8079310b319e Mon Sep 17 00:00:00 2001 From: Chris Klimas <1405578+klembot@users.noreply.github.com> Date: Sun, 12 Apr 2015 19:22:49 -0400 Subject: [PATCH] Merge --- .hgignore | 20 +- Gruntfile.js | 59 ++- README.md | 8 +- app.html | 5 + css/storyeditview.css | 13 +- img/logo-osx.svg | 137 +++++ img/logo.icns | Bin 0 -> 113543 bytes img/logo.ico | Bin 0 -> 31076 bytes js/app.js | 17 +- js/collections/passagecollection.js | 2 +- js/collections/storycollection.js | 2 +- js/eventedlocalstorage.js | 32 ++ js/models/passage.js | 2 +- js/models/story.js | 18 +- js/models/storyformat.js | 14 +- js/nwui.js | 479 ++++++++++++++++++ js/router.js | 106 ++-- js/views/storyeditview/passageeditor.js | 68 ++- js/views/storyeditview/statsmodal.js | 141 ++++++ js/views/storyeditview/storyeditview.js | 27 +- js/views/storyeditview/toolbar.js | 28 +- js/views/storyitemview.js | 2 +- js/views/storylistview/storylistview.js | 6 + lib/codemirror/css/codemirror.css | 4 + .../js/addon/display/placeholder.js | 58 +++ lib/uuid.js | 24 + package.json | 17 +- storyformats/Snowman/format.js | 2 +- templates/storyeditview/passageeditmodal.html | 2 +- templates/storyeditview/statsmodal.html | 63 +++ templates/storyeditview/storyeditview.html | 1 + templates/storyeditview/toolbar.html | 6 +- .../Adds passages that are newly linked.test | 12 +- tests/selenium/storyeditview/All.suite | 7 +- ...assage with the Create Passage button.test | 2 +- ...oard shortcuts when editing a passage.test | 2 +- ... IFIDs meet Treaty of Babel standards.test | 101 ++++ .../IFIDs remain stable for a story.test | 121 +++++ .../Saves changes to passage text.test | 8 +- .../Story statistics are accurate.test | 130 +++++ ...vigating away while editing a passage.test | 8 +- 41 files changed, 1629 insertions(+), 125 deletions(-) create mode 100644 img/logo-osx.svg create mode 100644 img/logo.icns create mode 100644 img/logo.ico create mode 100644 js/eventedlocalstorage.js create mode 100644 js/nwui.js create mode 100644 js/views/storyeditview/statsmodal.js create mode 100644 lib/codemirror/js/addon/display/placeholder.js create mode 100644 lib/uuid.js create mode 100644 templates/storyeditview/statsmodal.html create mode 100644 tests/selenium/storyeditview/Generated IFIDs meet Treaty of Babel standards.test create mode 100644 tests/selenium/storyeditview/IFIDs remain stable for a story.test create mode 100644 tests/selenium/storyeditview/Story statistics are accurate.test diff --git a/.hgignore b/.hgignore index d0a05a365..6e6811a81 100644 --- a/.hgignore +++ b/.hgignore @@ -1,9 +1,11 @@ -syntax: glob -*.swp -index.html -node_modules/* -dist/* -doc/* -.tmp/* -*.DS_Store -.idea +syntax: glob +*.swp +index.html +node_modules/* +dist/* +doc/* +.tmp/* +*.DS_Store +.idea +cache +dist-apps \ No newline at end of file diff --git a/Gruntfile.js b/Gruntfile.js index 7e8797826..41e8eb963 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -5,7 +5,7 @@ module.exports = function (grunt) pkg: grunt.file.readJSON('package.json'), jshint: { - all: ['js/**'], + all: ['js/**/*.js'], options: { globals: { // Libraries @@ -18,9 +18,16 @@ module.exports = function (grunt) saveAs: true, SVG: true, JSZip: true, + UUID: true, + XDate: true, // Misc. app: true, + global: true, + nwui: true, + process: true, + require: true, ui: true, + EventedLocalStorage: true, TransRegion: true, TwineRouter: true, // Collections @@ -128,7 +135,7 @@ module.exports = function (grunt) { files: [ - { expand: true, src: ['index.html'], dest: 'dist/' } + { expand: true, src: ['index.html'], dest: 'dist/html/' } ] }, @@ -136,12 +143,12 @@ module.exports = function (grunt) { files: [ - { expand: true, src: ['img/*.ico'], dest: 'dist/rsrc/' }, - { expand: true, src: ['img/*.png'], dest: 'dist/rsrc/' }, - { expand: true, src: ['img/*.svg'], dest: 'dist/rsrc/' }, - { expand: true, cwd: 'fonts', src: ['*'], dest: 'dist/rsrc/fonts/' }, - { expand: true, cwd: 'storyformats', src: ['**'], dest: 'dist/storyformats' }, - { expand: true, cwd: 'lib/fontawesome/fonts', src: ['*'], dest: 'dist/rsrc/fonts/' } + { expand: true, src: ['img/*.ico'], dest: 'dist/html/rsrc/' }, + { expand: true, src: ['img/*.png'], dest: 'dist/html/rsrc/' }, + { expand: true, src: ['img/*.svg'], dest: 'dist/html/rsrc/' }, + { expand: true, cwd: 'fonts', src: ['*'], dest: 'dist/html/rsrc/fonts/' }, + { expand: true, cwd: 'storyformats', src: ['**'], dest: 'dist/html/storyformats' }, + { expand: true, cwd: 'lib/fontawesome/fonts', src: ['*'], dest: 'dist/html/rsrc/fonts/' } ] }, @@ -149,11 +156,34 @@ module.exports = function (grunt) { files: [ - { expand: true, src: ['LICENSE'], dest: 'dist/' } + { expand: true, src: ['LICENSE'], dest: 'dist/html/' } + ] + }, + + package: + { + files: + [ + { expand: true, src: ['package.json'], dest: 'dist/html/' } ] } }, + nodewebkit: + { + src: + ['dist/**/*'], + options: + { + buildDir: 'dist/apps/', + buildType: 'versioned', + 'chromium-args': '--enable-threaded-compositing', + macIcns: 'img/logo.icns', + platforms: ['win', 'osx', 'linux'], + winIco: 'img/logo.ico' + }, + }, + replace: { blockUseminCdn: @@ -181,12 +211,12 @@ module.exports = function (grunt) useminPrepare: { html: 'index.html', - options: { dest: 'dist' } + options: { dest: 'dist/html/' } }, usemin: { - html: 'dist/index.html' + html: 'dist/html/index.html' }, watch: @@ -226,9 +256,10 @@ module.exports = function (grunt) grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-yuidoc'); + grunt.loadNpmTasks('grunt-node-webkit-builder'); grunt.loadNpmTasks('grunt-replace'); grunt.loadNpmTasks('grunt-usemin'); - grunt.registerTask('default', ['bake']); + grunt.registerTask('default', ['jshint', 'bake']); grunt.registerTask('release', [ 'clean', 'jshint', 'bake', 'yuidoc', 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'usemin' @@ -241,5 +272,9 @@ module.exports = function (grunt) [ 'bake', 'jshint', 'cdnify' ]); + grunt.registerTask('release-nw', + [ + 'clean', 'jshint', 'bake', 'yuidoc', 'copy', 'useminPrepare', 'concat', 'uglify', 'cssmin', 'usemin', 'nodewebkit' + ]); grunt.registerTask('server', ['connect']); }; diff --git a/README.md b/README.md index 532b072ad..be98abf80 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,13 @@ You need [Grunt](http://gruntjs.com) to continue. Run `npm install -g grunt-cli` Run `grunt` to perform a basic build, including creating documentation in doc/; `grunt watch` will perform the same tasks whenever you make changes to the source code. `grunt release` will minify everything to as few files as possible -into dist/. +into dist/html/. + +To build executable versions of Twine with [NW.js](http://nwjs.io/), run `grunt +release-nw`, which will publish the files to dist/apps/. In order to build +Windows apps on OS X or Linux, you will need to have +[Wine](https://www.winehq.org/) installed. **nb. NW.js builds are currently +considered experimental, and have not been well-tested or documented.** ### TESTING diff --git a/app.html b/app.html index d4043d2ab..7d8f90849 100644 --- a/app.html +++ b/app.html @@ -76,6 +76,7 @@ + @@ -83,13 +84,16 @@ + + + @@ -117,6 +121,7 @@ + diff --git a/css/storyeditview.css b/css/storyeditview.css index 54468e191..203a779d6 100644 --- a/css/storyeditview.css +++ b/css/storyeditview.css @@ -388,7 +388,6 @@ body.iOS .editModal width: 100%; padding-bottom: 0.1em; font-size: 125%; - line-height: 100%; } #passageEditModal .error @@ -559,6 +558,18 @@ body.iOS .editModal font-size: 90%; } +#statsModal table +{ + margin: 0 auto; + font-size: 120%; +} + +#statsModal td:first-child +{ + text-align: right; + font-weight: bold; +} + .CodeMirror { height: auto; diff --git a/img/logo-osx.svg b/img/logo-osx.svg new file mode 100644 index 000000000..646e02766 --- /dev/null +++ b/img/logo-osx.svg @@ -0,0 +1,137 @@ + + + + + + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + + + diff --git a/img/logo.icns b/img/logo.icns new file mode 100644 index 0000000000000000000000000000000000000000..8930a33c24cba73209c00dd0da04637ba1c3769a GIT binary patch literal 113543 zcmeEv1zc21)c7SuK{vp}K*jFDcy=dtA!!E&CcA*#-KD#`J0t|8ySqccLKH<|7qFB6 znY)1KL*3_le&6@|{XGio%$zyr%!!$~b7y8x9XWRi<4e##b!pyQ4C8xZj`2|`I2EJl zV@xVWVqzGD0iT4)1IZ*3nasd&DnErvW{~($0uyHdYIlOlpkUo4d{ip_B{hIbr9dqb zi9(WKV!~7kB*|nwObBIDsQU1MN+wgteSSa%lmWJwIVMEYpwl&Qz@pP>bht1iw9>%c#dWC|*$OkD zT7k3UR3-&{*9z08V&eK3zbJ*Qi$0T?m;jkVqA(zdQJ8=wh*2P|3uzXGLFFS+4B?|L zm5)L-CU6)K4t!*a5lWC56d^LWJcWdk45~1Ergo(UP^eUK5|nkNF$f%C2sH|cOknp% zMNk>=5n+CD3K^$>EM$rvS&)i?QWqLQ#mNGQ0*ed+m|#!|NRkm5CfN)VlYlZr1(6zL zfr)a92p(ihOc=2rL?+>6zClARu>mLv+>s1c*nmMjDGH_Gf7y~2F z=}a1?fzv_nbWGg}6QI**8caH$2IT0_1t8cp^)P|XmoHy{y6FfLQ)gfzot*X#6uWJ@ z7*6MhP5`I(qtP&SJG+g8w+V2F5`G$8Lx(OL#D)%`S2iEQ76mqjQ4avIcM%4x2Wa`E zW`A2iMq<%*BhoT*8osSV!!^Y8Vv^Id@*jRvgwqG=L?xwX<`gu3Q$mLBEF>W%JuCO` zMKqdQLUL+mZhpz*Z)#E1nbAq9>Dl>3B~9ESPCMSl$KmK=6q zt?1;8oSeea(#j{C_I8dLHqbmVJv%qQsI;O6ayrd1QJ>VTyn>?git5^@97{|zA}hbJ zxU{n7cHPsb;1KaS1;wT1Rkv&JG=d8x_N1yImC=(bgH%dSs_-ABl9DpAv+_%dOUp`- zLtq>|HpYQ~Y}H}&x3XJ-7N?cyLZKIJvw{v*0QILh^snF-_(5eQh%!{?IRg_otEjBN zR0L%}FAIGx;IW@!$CVVI>tsQ;7|P)OkCcZl7$b5KCxJVG7oa9LLzKfo^;?qct<`#E zqM8qaoNO)6^<-ioN56YMPWIO3Uou63^CLf3M_WtNvptxiz&O;^+0M$$SoKRLo0IP0 zVsC9>VtD3DX8RLwH%D7@QzP9|3Ob5{3QBUy%BV?c?vD0QT~Ftff}*05q9U>{+t0

p+G41~G%Chai9txPk3s0` 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%0AZY3$bl1 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 NQv#r66Z*UH{{d6>!>RxP literal 0 HcmV?d00001 diff --git a/img/logo.ico b/img/logo.ico new file mode 100644 index 0000000000000000000000000000000000000000..a7727f8c0e29442dfb097fe34ee884a26b287019 GIT binary patch literal 31076 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 literal 0 HcmV?d00001 diff --git a/js/app.js b/js/app.js index de0d2436e..688d243b8 100644 --- a/js/app.js +++ b/js/app.js @@ -25,7 +25,7 @@ var TwineApp = Backbone.Marionette.Application.extend( @property version **/ - version: '2.0.3', + version: '2.0.4', /** Saves data to a file. This appears to the user as if they had clicked @@ -169,9 +169,10 @@ var TwineApp = Backbone.Marionette.Application.extend( @method importFile @param {String} data Contents of the file to be imported. + @param {Date} lastUpdate If passed, overrides the last updated date of the stories. **/ - importFile: function (data) + importFile: function (data, lastUpdate) { var selectors = this.selectors; @@ -201,7 +202,8 @@ var TwineApp = Backbone.Marionette.Application.extend( var story = allStories.create( { name: $story.attr('name'), - storyFormat: $story.attr('format') + storyFormat: $story.attr('format'), + ifid: $story.attr('ifid') }, { wait: true }); // and child passages @@ -226,7 +228,7 @@ var TwineApp = Backbone.Marionette.Application.extend( }, { wait: true }); if (id == startPassageId) - story.save({ startPassage: passage.id }); + story.save({ startPassage: passage.id }, { wait: true }); }); // for now, glom all style nodes into the stylesheet property @@ -249,6 +251,11 @@ var TwineApp = Backbone.Marionette.Application.extend( if (stylesheet != '' || script != '') story.save({ stylesheet: stylesheet, script: script }); + + // override update date if requested + + if (lastUpdate) + story.save({ lastUpdate: lastUpdate }); count++; }); @@ -320,6 +327,8 @@ window.app = new TwineApp(); window.app.addInitializer(function () { + if (nwui.active) + nwui.init(); /** Build number of the app. diff --git a/js/collections/passagecollection.js b/js/collections/passagecollection.js index 7786527cf..f3c7279dd 100644 --- a/js/collections/passagecollection.js +++ b/js/collections/passagecollection.js @@ -10,7 +10,7 @@ var PassageCollection = Backbone.Collection.extend( { model: Passage, - localStorage: new Backbone.LocalStorage('twine-passages') + localStorage: new EventedLocalStorage('twine-passages') }); /** diff --git a/js/collections/storycollection.js b/js/collections/storycollection.js index 1ee213d8e..3499a8dcd 100644 --- a/js/collections/storycollection.js +++ b/js/collections/storycollection.js @@ -10,7 +10,7 @@ var StoryCollection = Backbone.Collection.extend( { model: Story, - localStorage: new Backbone.LocalStorage('twine-stories'), + localStorage: new EventedLocalStorage('twine-stories'), order: 'name', reverseOrder: false, diff --git a/js/eventedlocalstorage.js b/js/eventedlocalstorage.js new file mode 100644 index 000000000..154011a8b --- /dev/null +++ b/js/eventedlocalstorage.js @@ -0,0 +1,32 @@ +/** + A thin wrapper over Backbone.LocalStorage that emits an event after + a model is successfully saved. + + @class EventedLocalStorage +**/ + +'use strict'; + +function EventedLocalStorage (name, serializer) +{ + return Backbone.LocalStorage.call(this, name, serializer); +}; + +EventedLocalStorage.prototype = new Backbone.LocalStorage(); + +_.extend(EventedLocalStorage.prototype, +{ + update: function (model) + { + var result = Backbone.LocalStorage.prototype.update.call(this, model); + + /** + Triggered after a successful update. + + @event update + **/ + + model.trigger('update'); + return result; + } +}); diff --git a/js/models/passage.js b/js/models/passage.js index 65d4d2265..91eb0d320 100644 --- a/js/models/passage.js +++ b/js/models/passage.js @@ -38,7 +38,7 @@ var Passage = Backbone.Model.extend( { // update parent's last update date - this.fetchStory().set('lastUpdate', new Date()); + this.fetchStory().save('lastUpdate', new Date()); // clamp our position to positive coordinates diff --git a/js/models/story.js b/js/models/story.js index e1109474f..0fae0eabc 100644 --- a/js/models/story.js +++ b/js/models/story.js @@ -20,13 +20,14 @@ var Story = Backbone.Model.extend( stylesheet: '', script: '', storyFormat: AppPref.withName('defaultFormat').get('value') || 'Harlowe', - lastUpdate: new Date() + lastUpdate: new Date(), + ifid: UUID().toUpperCase() }; }, template: _.template('' + '' + '' + @@ -38,7 +39,10 @@ var Story = Backbone.Model.extend( { // delete all child passages - this.fetchPassages().invoke('destroy'); + var passages = this.fetchPassages(); + + while (passages.length > 0) + passages.at(0).destroy(); }, this); this.on('sync', function() @@ -54,7 +58,10 @@ var Story = Backbone.Model.extend( this.on('change', function() { - this.set('lastUpdate', new Date()); + // if we're manually setting our last update, don't override that + + if (this.changedAttributes().lastUpdate === undefined) + this.set('lastUpdate', new Date()); }, this); }, @@ -122,7 +129,8 @@ var Story = Backbone.Model.extend( stylesheet: this.get('stylesheet'), script: this.get('script'), options: (options) ? options.join(' ') : null, - storyFormat: this.get('storyFormat') + storyFormat: this.get('storyFormat'), + ifid: this.get('ifid') }); } }); diff --git a/js/models/storyformat.js b/js/models/storyformat.js index 9eac10d10..ba1ea91d1 100644 --- a/js/models/storyformat.js +++ b/js/models/storyformat.js @@ -66,11 +66,23 @@ var StoryFormat = Backbone.Model.extend( return; }; + var prevStoryFormatFn = window.storyFormat || null; + window.storyFormat = _.bind(function (properties) { this.properties = properties; this.loaded = true; - window.storyFormat = null; + + // The lexer is a stringified JS function. When eval()ed, it adds + // a TwineMarkup object to this, and its lex() method takes + // string source and returns a syntax tree. + + if (this.properties.setup) + { + this.properties.setup.call(this); + } + + window.storyFormat = prevStoryFormatFn; if (callback) callback(); diff --git a/js/nwui.js b/js/nwui.js new file mode 100644 index 000000000..e0d09efbb --- /dev/null +++ b/js/nwui.js @@ -0,0 +1,479 @@ +/** + A singleton that adapts the Twine interface for NW.js, + adding menus and syncing changes to the filesystem. + This takes the approach of patching existing classes + instead of creating a separate set of classes just for + NW.js, to try to keep things as similar as possible. + + @class nwui +**/ + +'use strict'; + +var nwui = +{ + /** + Whether Twine is running in a NW.js environment. + @property active + @static + @const + **/ + + active: + (typeof process !== "undefined" && + typeof require !== "undefined" && + typeof require('nw.gui') !== 'undefined'), + + /** + Whether changes to a story should be saved to the filesystem. + This is mainly so that internal nwui methods can do their work + without tripping over each other. + @property syncFs + @static + **/ + + syncFs: true, + + /** + While the app is open, we lock story files in the filesystem so + that the user can't make changes outside of Twine. This indexes + the locks we maintain on these files so we can lift one when + deleting a file. + **/ + + fileLocks: {}, + + /** + Performs one-time initialization, e.g. setting up menus. + This should be called as early in the app initialization process + as possible. + + @method init + **/ + + init: function() + { + /** + An instance of the nw.gui module, for manipulating the native UI. + @property gui + **/ + + nwui.gui = require('nw.gui'); + + var win = nwui.gui.Window.get(); + var nativeMenuBar = new nwui.gui.Menu({ type: 'menubar' }); + var mainMenu; + + if (process.platform == 'darwin') + { + // create Mac menus + + nativeMenuBar.createMacBuiltin(window.app.name); + mainMenu = _.findWhere(nativeMenuBar.items, { label: '' }); + + // add fullscreen item + // only on OS X for now -- hard to reverse on other platforms + // if you don't remember the keyboard shortcut + + mainMenu.submenu.insert(new nwui.gui.MenuItem({ + label: 'Toggle Fullscreen', + key: 'f', + modifiers: 'cmd-shift', + click: function() + { + nwui.gui.Window.get().toggleFullscreen(); + } + }), 0); + } + else + { + // create a basic menu on other platforms + + mainMenu = new nwui.gui.MenuItem({ + label: window.app.name, + submenu: new nwui.gui.Menu() + }); + + mainMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Quit', + key: 'q', + modifiers: 'ctrl', + click: function() + { + nwui.gui.App.closeAllWindows(); + } + })); + + mainMenu.submenu.insert(new nwui.gui.MenuItem({ type: 'separator' }), 0); + nativeMenuBar.append(mainMenu); + + // and a stand-in Edit menu + + var editMenu = new nwui.gui.MenuItem({ + label: 'Edit', + submenu: new nwui.gui.Menu() + }); + + editMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Undo', + key: 'z', + modifiers: 'ctrl', + click: function() + { + document.execCommand('undo'); + } + })); + + editMenu.submenu.append(new nwui.gui.MenuItem({ type: 'separator' })); + + editMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Cut', + key: 'x', + modifiers: 'ctrl', + click: function() + { + document.execCommand('cut'); + } + })); + + editMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Copy', + key: 'c', + modifiers: 'ctrl', + click: function() + { + document.execCommand('copy'); + } + })); + + editMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Paste', + key: 'v', + modifiers: 'ctrl', + click: function() + { + document.execCommand('paste'); + } + })); + + editMenu.submenu.append(new nwui.gui.MenuItem({ + label: 'Delete', + click: function() + { + document.execCommand('delete'); + } + })); + + nativeMenuBar.append(editMenu); + }; + + // add item to show story library + + /** + An instance of the node path module. + @property path + **/ + + nwui.path = require('path'); + + mainMenu.submenu.insert(new nwui.gui.MenuItem({ + label: 'Show Library', + click: function() + { + nwui.gui.Shell.openItem(nwui.path.resolve(nwui.filePath.replace(/\//g, nwui.path.sep))); + } + }), 0); + + win.menu = nativeMenuBar; + + // create ~/Documents/Twine if it doesn't exist + + /** + An instance of the fs modules, for working with the native filesystem. + @property fs + **/ + + nwui.fs = require('fs'); + + /** + The path that stories will be saved to in the filesystem. + @property filePath + **/ + + var homePath = process.env.HOME || process.env.HOMEPATH || process.env.USERPROFILE; + + // if the user doesn't have a Documents folder, + // check for "My Documents" instead (thanks Windows) + + var docPath = homePath + '/Documents'; + + if (! nwui.fs.existsSync(docPath)) + { + if (nwui.fs.existsSync(homePath + '/My\\ Documents')) + docPath = homePath + '/My\\ Documents'; + else + nwui.fs.mkdirSync(docPath); + }; + + nwui.filePath = docPath + '/Twine/Stories/'; + + if (! nwui.fs.existsSync(nwui.filePath)) + { + var twinePath = docPath + '/Twine'; + + if (! nwui.fs.existsSync(twinePath)) + nwui.fs.mkdirSync(twinePath); + + nwui.fs.mkdirSync(nwui.filePath); + }; + + // do a file sync if we're just starting up + // we have to stuff this in the global scope; + // otherwise, each new window will think it's starting afresh + // and screw up our model IDs + + if (! global.nwuiFirstRun) + { + nwui.syncStoryFiles(); + nwui.lockStoryDirectory(); + global.nwuiFirstRun = true; + }; + + // open external links outside the app + + $('body').on('click', 'a', function (e) + { + var url = $(this).attr('href'); + + if (url.match(/^https?:/)) + { + nwui.gui.Shell.openExternal(url); + e.preventDefault(); + }; + }); + + // when quitting, unlock the story directory + + process.on('exit', function() + { + nwui.unlockStoryDirectory(); + }); + + // monkey patch Story to save to a file + // under ~/Documents/Twine whenever the model changes, + // or delete it when it is destroyed + + var oldStoryInit = Story.prototype.initialize; + + Story.prototype.initialize = function() + { + oldStoryInit.call(this); + + this.on('change', _.debounce(function() + { + // if the only thing that is changing is last modified date, + // then skip it + + if (! _.some(_.keys(this.changedAttributes), function (key) + { + return (key != 'lastUpdated'); + })) + return; + + // if we aren't syncing changes or the story has no passages, + // give up early + + if (! nwui.syncFs || this.fetchPassages().length == 0) + return; + + nwui.saveStoryFile(this); + }, 100), this); + + this.on('destroy', function() + { + if (! nwui.syncFs) + return; + + nwui.deleteStoryFile(this); + }, this); + }; + + // monkey patch Passage to save its parent story whenever + // it is changed or destroyed + + var oldPassageInit = Passage.prototype.initialize; + + Passage.prototype.initialize = function() + { + oldPassageInit.call(this); + + this.on('change destroy', _.debounce(function() + { + if (! nwui.syncFs) + return; + + // if we have no parent, skip it + // (this happens during an import, for example) + + var parent = this.fetchStory(); + + if (parent) + nwui.saveStoryFile(parent); + }, 100), this); + }; + + // monkey patch StorageQuota to hide itself, since we + // don't have to sweat quota ourselves + + StoryListView.StorageQuota.prototype.render = function() + { + this.$el.css('display', 'none'); + }; + }, + + /** + Saves a story model to the file system. If a problem occurs, + then a notification is shown to the user. + + @method saveStoryFile + @param {Story} story Story model to save + **/ + + saveStoryFile: function (story) + { + try + { + nwui.unlockStoryDirectory(); + var fd = nwui.fs.openSync(nwui.filePath + story.get('name') + '.html', 'w'); + nwui.fs.writeSync(fd, story.publish()); + nwui.fs.closeSync(fd); + } + catch (e) + { + ui.notify('An error occurred while saving your story (' + e.message + ').', 'danger'); + throw e; + } + finally + { + nwui.lockStoryDirectory(); + }; + }, + + /** + Deletes a story file from the file system. If a problem occurs, + then a notification is shown to the user. + + @method deleteStoryFile + @param {Story} story Story model to delete + **/ + + deleteStoryFile: function (story) + { + try + { + nwui.unlockStoryDirectory(); + nwui.fs.unlinkSync(nwui.filePath + this.get('name') + '.html'); + } + catch (e) + { + ui.notify('An error occurred while deleting your story (' + e.message + ').', 'danger'); + } + finally + { + nwui.lockStoryDirectory(); + }; + }, + + /** + Syncs local storage with the file system, obliterating + any stories that happen to be saved to local storage only. + + @method syncStoryFiles + **/ + + syncStoryFiles: function() + { + nwui.syncFs = false; + + // clear all existing stories and passages + + var allStories = StoryCollection.all(); + + while (allStories.length > 0) + allStories.at(0).destroy(); + + // read from files + + nwui.unlockStoryDirectory(); + var fileStories = nwui.fs.readdirSync(nwui.filePath); + + _.each(fileStories, function (filename) + { + if (filename.match(/\.html$/)) + { + var stats = nwui.fs.statSync(nwui.filePath + filename); + window.app.importFile(nwui.fs.readFileSync(nwui.filePath + filename, { encoding: 'utf-8' }), + new Date(Date.parse(stats.mtime))); + }; + }); + + nwui.unlockStoryDirectory(); + nwui.syncFs = true; + }, + + /** + Locks the story directory to prevent the user from changing it + outside of Twine. The init() method must be called first. + + @method lockStoryDirectory + **/ + + lockStoryDirectory: function() + { + try + { + if (process.platform == 'win32') + _.each(nwui.fs.readdirSync(nwui.filePath), function (filename) + { + nwui.fs.chmodSync(nwui.filePath + filename, 292); // a-w, 0444 + }); + else + { + var stat = nwui.fs.statSync(nwui.filePath); + nwui.fs.chmodSync(nwui.filePath, stat.mode ^ 128); // u-w + }; + } + catch (e) + { + ui.notify('An error occurred while locking your library (' + e.message + ').', 'danger'); + }; + }, + + /** + Unlocks the story directory. The init() method must be called + first. + + @method lockStoryDirectory + **/ + + unlockStoryDirectory: function() + { + try + { + if (process.platform == 'win32') + _.each(nwui.fs.readdirSync(nwui.filePath), function (filename) + { + nwui.fs.chmodSync(nwui.filePath + filename, 438); // a+w, 0666 + }); + else + { + var stat = nwui.fs.statSync(nwui.filePath); + nwui.fs.chmodSync(nwui.filePath, stat.mode | 128); // u+w + }; + } + catch (e) + { + ui.notify('An error occurred while unlocking your library (' + e.message + ').', 'danger'); + }; + }, +}; diff --git a/js/router.js b/js/router.js index 13be6cfe4..af27e9f64 100644 --- a/js/router.js +++ b/js/router.js @@ -16,72 +16,74 @@ var TwineRouter = Backbone.Router.extend( { - routes: + welcome: function() { - 'welcome': function() - { - window.app.mainRegion.show(new WelcomeView()); - }, + window.app.mainRegion.show(new WelcomeView()); + }, - 'stories': function() - { - // list of all stories + listStories: function() + { + // list of all stories - window.app.mainRegion.show(new StoryListView({ collection: StoryCollection.all() })); - }, + window.app.mainRegion.show(new StoryListView({ collection: StoryCollection.all() })); + }, - 'stories/:id': function (id) - { - // edit a specific story + editStory: function (id) + { + // edit a specific story - window.app.mainRegion.show(new StoryEditView({ model: Story.withId(id) })); - }, + window.app.mainRegion.show(new StoryEditView({ model: Story.withId(id) })); + }, - 'stories/:id/play': function (id) - { - // play a story + playStory: function (id) + { + // play a story - window.app.publishStory(Story.withId(id)); - }, + window.app.publishStory(Story.withId(id)); + }, - 'stories/:id/test': function (id) + testStory: function (storyId, passageId) + { + // test a story from a particular passage + + window.app.publishStory(Story.withId(storyId), null, { - // test a story from the beginning + formatOptions: ['debug'], + startPassageId: passageId + }); + }, - window.app.publishStory(Story.withId(id), null, { formatOptions: ['debug'] }); - }, + proofStory: function (id) + { + // proof a story - 'stories/:storyId/test/:passageId': function (storyId, passageId) - { - // test a story from a particular passage - - window.app.publishStory(Story.withId(storyId), null, - { - formatOptions: ['debug'], - startPassageId: passageId - }); - }, - - 'stories/:id/proof': function (id) - { - // proof a story + var story = Story.withId(id); + var format = StoryFormat.withName(AppPref.withName('proofingFormat').get('value')); + + window.app.publishStory(story, null, { format: format }); + }, - var story = Story.withId(id); - var format = StoryFormat.withName(AppPref.withName('proofingFormat').get('value')); - - window.app.publishStory(story, null, { format: format }); - }, + startup: function() + { + // default route -- show welcome if the user hasn't already seen it - '*path': function() - { - // default route -- show welcome if the user hasn't already seen it + var welcomePref = AppPref.withName('welcomeSeen', false); - var welcomePref = AppPref.withName('welcomeSeen', false); + if (welcomePref.get('value') === true) + window.location.hash = '#stories'; + else + window.location.hash = '#welcome'; + }, - if (welcomePref.get('value') === true) - window.location.hash = '#stories'; - else - window.location.hash = '#welcome'; - } + routes: + { + 'welcome': 'welcome', + 'stories': 'listStories', + 'stories/:id': 'editStory', + 'stories/:id/play': 'playStory', + 'stories/:id/test': 'testStory', + 'stories/:storyId/test/:passageId': 'testStory', + 'stories/:id/proof': 'proofStory', + '*path': 'startup' } }); diff --git a/js/views/storyeditview/passageeditor.js b/js/views/storyeditview/passageeditor.js index bc9fcb493..82ea70117 100644 --- a/js/views/storyeditview/passageeditor.js +++ b/js/views/storyeditview/passageeditor.js @@ -12,12 +12,26 @@ StoryEditView.PassageEditor = Backbone.View.extend( tagTemplate: '<%- name %>', - initialize: function() + initialize: function(options) { this.tagContainer = this.$('.tags'); this.tagTemplate = _.template(this.tagTemplate); + // Required to identify the current story format + this.story = options.parent.model; - this.$el.on('modalhide', _.bind(this.restoreTitle, this)); + this.cm = CodeMirror.fromTextArea(this.$('.passageText')[0], + { + lineWrapping: true, + lineNumbers: false, + mode: 'text', + }); + + this.$el.on('modalhide', _.bind(this.restoreTitle, this)); + this.$el.on('modalshown', function() { + setTimeout(this.cm.refresh.bind(this.cm), + // This must equal the animation time of @keyframes appear in app.css + 400); + }.bind(this)); this.$el.on('click', '.showNewTag', _.bind(this.showNewTag, this)); this.$el.on('click', '.hideNewTag', _.bind(this.hideNewTag, this)); this.$el.on('submit', _.bind(function (e) @@ -27,7 +41,7 @@ StoryEditView.PassageEditor = Backbone.View.extend( // don't add duplicate tags if (this.model.get('tags').indexOf(name) == -1) - this.addTag(name); + this.addTag(name); this.hideNewTag(); e.preventDefault(); @@ -40,7 +54,7 @@ StoryEditView.PassageEditor = Backbone.View.extend( this.$el.data('blockModalHide', _.bind(function() { - var worked = this.save(); + var worked = this.save(); if (worked) window.onbeforeunload = null; @@ -64,8 +78,50 @@ StoryEditView.PassageEditor = Backbone.View.extend( this.$('.passageId').val(this.model.id); this.$('.passageName').val(this.model.get('name')); + + /* + Load the story format, which may install a CodeMirror mode named after itself. + We use that mode if it is found to exist after loading. + */ + var storyFormatName = this.story.get('storyFormat'); + StoryFormat.withName(storyFormatName).load(function(err) + { + var modeName = storyFormatName.toLowerCase(); + + if (!err && modeName in CodeMirror.modes) + { + /* + This is a small hack to allow modes such as Harlowe to access the + full text of the textarea, permitting its lexer to grow + a syntax tree by itself. + */ + CodeMirror.modes[modeName].cm = this.cm; + /* + Now that's done, we can assign the mode and trigger a re-render. + */ + this.cm.setOption('mode', modeName); + } + }.bind(this)); + + /* + Set the mode to the default, 'text'. The above callback will reset it if it fires. + */ + this.cm.setOption('mode', 'text'); var text = this.model.get('text'); - this.$('.passageText').val((text == Passage.prototype.defaults.text) ? '' : text); + /* + Reset the placeholder, which may have been modified by a prior story format. + */ + this.cm.setOption('placeholder', "Enter the body text of your passage here."); + /* + swapDoc resets all of the attached events, undo history, etc. of the document. + */ + this.cm.swapDoc(CodeMirror.Doc('')); + /* + These lines must be used (instead of passing the text to the above constructor) + to work around a bug in the CodeMirror placeholder code. + */ + this.cm.setValue(text || ''); + this.cm.clearHistory(); // sync tags @@ -117,7 +173,7 @@ StoryEditView.PassageEditor = Backbone.View.extend( if (this.model.save({ name: this.$('.passageName').val(), - text: this.$('.passageText').val(), + text: this.cm.doc.getValue(), tags: tags })) { diff --git a/js/views/storyeditview/statsmodal.js b/js/views/storyeditview/statsmodal.js new file mode 100644 index 000000000..9d245795c --- /dev/null +++ b/js/views/storyeditview/statsmodal.js @@ -0,0 +1,141 @@ +/** + Shows statistics about the story being edited. + + @class StatsModal + @extends Backbone.View +**/ + +'use strict'; + +StoryEditView.StatsModal = Backbone.View.extend( +{ + initialize: function (options) + { + this.parent = options.parent; + }, + + /** + Opens the modal dialog. + + @method open + **/ + + open: function() + { + // format the date + + this.$('.lastUpdate').text(new XDate(this.parent.model.get('lastUpdate')).toString('h:mm tt, d MMMM yyyy')); + + // calculate counts + + var charCount = 0; + var wordCount = 0; + var passageCount = 0; + var linkCount = 0; + var brokenLinkCount = 0; + var passageLinks = {}; + var passageNames = []; + + _.each(this.parent.collection.models, function (passage) + { + passageCount++; + var text = passage.get('text'); + charCount += text.length; + wordCount += text.split(/\s+/).length; + var links = passage.links(); + linkCount += links.length; + passageNames.push(passage.get('name')); + + _.each(links, function (link) + { + passageLinks[link] = (passageLinks[link] || 0) + 1; + }); + }); + + // we calculate broken links now that we have + // a complete list of names + + _.each(passageLinks, function (count, name) + { + if (passageNames.indexOf(name) == -1) + brokenLinkCount += count; + }); + + this.$('.charCount').text(charCount.toLocaleString()); + this.$('.wordCount').text(wordCount.toLocaleString()); + this.$('.passageCount').text(passageCount.toLocaleString()); + this.$('.linkCount').text(linkCount.toLocaleString()); + this.$('.brokenLinkCount').text(brokenLinkCount.toLocaleString()); + + // adjust visibility of singular/plural nouns + + if (charCount != 1) + { + this.$('.charDesc .singular').addClass('hide'); + this.$('.charDesc .plural').removeClass('hide'); + } + else + { + this.$('.charDesc .singular').removeClass('hide'); + this.$('.charDesc .plural').addClass('hide'); + }; + + if (wordCount != 1) + { + this.$('.wordDesc .singular').addClass('hide'); + this.$('.wordDesc .plural').removeClass('hide'); + } + else + { + this.$('.wordDesc .singular').removeClass('hide'); + this.$('.wordDesc .plural').addClass('hide'); + }; + + if (passageCount != 1) + { + this.$('.passageDesc .singular').addClass('hide'); + this.$('.passageDesc .plural').removeClass('hide'); + } + else + { + this.$('.passageDesc .singular').removeClass('hide'); + this.$('.passageDesc .plural').addClass('hide'); + }; + + if (linkCount != 1) + { + this.$('.linkDesc .singular').addClass('hide'); + this.$('.linkDesc .plural').removeClass('hide'); + } + else + { + this.$('.linkDesc .singular').removeClass('hide'); + this.$('.linkDesc .plural').addClass('hide'); + }; + + if (brokenLinkCount != 1) + { + this.$('.brokenLinkDesc .singular').addClass('hide'); + this.$('.brokenLinkDesc .plural').removeClass('hide'); + } + else + { + this.$('.brokenLinkDesc .singular').removeClass('hide'); + this.$('.brokenLinkDesc .plural').addClass('hide'); + }; + + this.$el.data('modal').trigger('show'); + }, + + /** + Closes the modal dialog. + + @method close + **/ + + close: function() + { + this.$el.data('modal').trigger('hide'); + }, + +}); diff --git a/js/views/storyeditview/storyeditview.js b/js/views/storyeditview/storyeditview.js index d25e4e75c..e646f60ff 100755 --- a/js/views/storyeditview/storyeditview.js +++ b/js/views/storyeditview/storyeditview.js @@ -33,10 +33,15 @@ var StoryEditView = Marionette.CompositeView.extend( childViewOptions: function() { return { parentView: this }; }, template: '#templates .storyEditView', - initialize: function () + initialize: function() { - this.listenTo(this.model, 'change:zoom', this.syncZoom); - this.listenTo(this.model, 'change:name', this.syncName); + this.listenTo(this.model, 'change:zoom', this.syncZoom) + .listenTo(this.model, 'change:name', this.syncName) + .listenTo(this.model, 'error', function (model, resp, options) + { + ui.notify('A problem occurred while saving your changes (' + resp + ').', 'danger'); + }); + this.collection = this.model.fetchPassages(); this.listenTo(this.collection, 'change:top change:left', this.resize) .listenTo(this.collection, 'add', function (p) @@ -45,6 +50,10 @@ var StoryEditView = Marionette.CompositeView.extend( if (this.collection.length == 1) this.model.save({ startPassage: p.cid }); + }) + .listenTo(this.collection, 'error', function (model, resp, options) + { + ui.notify('A problem occurred while saving your changes (' + resp + ').', 'danger'); }); }, @@ -161,6 +170,7 @@ var StoryEditView = Marionette.CompositeView.extend( this.searchModal = new StoryEditView.SearchModal({ el: this.$('#searchModal'), parent: this }); this.renameModal = new StoryEditView.RenameStoryModal({ el: this.$('#renameStoryModal'), parent: this }); this.storyFormatModal = new StoryEditView.StoryFormatModal({ el: this.$('#storyFormatModal'), parent: this }); + this.statsModal = new StoryEditView.StatsModal({ el: this.$('#statsModal'), parent: this }); if (! window.app.hasPrimaryTouchUI()) this.marquee = new StoryEditView.Marquee({ el: this.$('.passages'), parent: this }); @@ -561,6 +571,17 @@ var StoryEditView = Marionette.CompositeView.extend( document.title = 'Editing \u201c' + this.model.get('name') + '\u201d'; }, + updateSaved: function() + { + this.$('.saveIndicator').addClass('active fadeOut slow').one('animationend', function() + { + $(this).removeClass('active fadeOut'); + }); + + this.$('.storyName').attr('title', 'Last saved at ' + new XDate().toString('h:mm TT, M/d/yyyy')); + this.$('.storyName').powerTip(); + }, + events: { 'drag .passage': function (e) diff --git a/js/views/storyeditview/toolbar.js b/js/views/storyeditview/toolbar.js index 824b62b05..890684274 100644 --- a/js/views/storyeditview/toolbar.js +++ b/js/views/storyeditview/toolbar.js @@ -13,8 +13,11 @@ StoryEditView.Toolbar = Backbone.View.extend( { this.parent = options.parent; this.syncZoomButtons(); - this.parent.model.on('change:zoom', this.syncZoomButtons, this); - this.parent.model.on('change:name', this.syncStoryName, this); + this.syncStorySaved(); + this.listenTo(this.parent.model, 'change:zoom', this.syncZoomButtons); + this.listenTo(this.parent.model, 'change:name', this.syncStoryName); + this.listenTo(this.parent.model, 'update', this.syncStorySaved); + this.listenTo(this.parent.collection, 'update', this.syncStorySaved); }, /** @@ -73,6 +76,23 @@ StoryEditView.Toolbar = Backbone.View.extend( menu.removeClass('checked'); }, + /** + Sets the tooltip of the story menu to indicate that a save has + just occurred. + + @method syncStorySaved + @param {Date} forceDate If passed, uses this date instead of the current one + **/ + + syncStorySaved: function (forceDate) + { + var $sn = this.$('.storyName'); + var date = (forceDate) ? new XDate(forceDate) : new XDate(); + + $sn.attr('title', $sn.data('datetext').replace('%', date.toString($sn.data('dateformat')))); + $sn.powerTip(); + }, + events: { 'click .editScript': function (e) @@ -115,9 +135,9 @@ StoryEditView.Toolbar = Backbone.View.extend( this.parent.publish(); }, - 'click .storyProperties': function (e) + 'click .storyStats': function (e) { - this.parent.properties.open(); + this.parent.statsModal.open(); }, 'click .changeFormat': function (e) diff --git a/js/views/storyitemview.js b/js/views/storyitemview.js index 7d2b38115..d18ad6532 100644 --- a/js/views/storyitemview.js +++ b/js/views/storyitemview.js @@ -68,7 +68,7 @@ var StoryItemView = Marionette.ItemView.extend( if (Passage.withId(this.model.get('startPassage')) === undefined) ui.notify('This story does not have a starting point. Edit this story and use the icon on a passage to set this.', 'danger'); else - window.open('#stories/' + this.model.id + '/play', 'twinestory_' + this.model.id); + window.open('#stories/' + this.model.id + '/play', 'twinestory_play_' + this.model.id); }, /** diff --git a/js/views/storylistview/storylistview.js b/js/views/storylistview/storylistview.js index eadf739d1..8b678d760 100644 --- a/js/views/storylistview/storylistview.js +++ b/js/views/storylistview/storylistview.js @@ -131,6 +131,12 @@ var StoryListView = Backbone.Marionette.CompositeView.extend( // is there a new update to Twine? var lastUpdateSeenPref = AppPref.withName('lastUpdateSeen', window.app.buildNumber); + + // force last update to be at least the current app version + + if (lastUpdateSeenPref.get('value') < window.app.buildNumber) + lastUpdateSeenPref.save({ value: window.app.buildNumber }); + var lastUpdateCheckPref = AppPref.withName('lastUpdateCheckTime', new Date().getTime()); if (new Date().getTime() > lastUpdateCheckPref.get('value') + this.UPDATE_CHECK_DELAY) diff --git a/lib/codemirror/css/codemirror.css b/lib/codemirror/css/codemirror.css index c56510e99..e28dfcc43 100644 --- a/lib/codemirror/css/codemirror.css +++ b/lib/codemirror/css/codemirror.css @@ -307,3 +307,7 @@ div.CodeMirror-cursors { /* Help users use markselection to safely style text background */ span.CodeMirror-selectedtext { background: none; } + +/* Placeholder addon */ +.CodeMirror pre.CodeMirror-placeholder { color: #999; } + diff --git a/lib/codemirror/js/addon/display/placeholder.js b/lib/codemirror/js/addon/display/placeholder.js new file mode 100644 index 000000000..bb0c3931e --- /dev/null +++ b/lib/codemirror/js/addon/display/placeholder.js @@ -0,0 +1,58 @@ +// CodeMirror, copyright (c) by Marijn Haverbeke and others +// Distributed under an MIT license: http://codemirror.net/LICENSE + +(function(mod) { + if (typeof exports == "object" && typeof module == "object") // CommonJS + mod(require("../../lib/codemirror")); + else if (typeof define == "function" && define.amd) // AMD + define(["../../lib/codemirror"], mod); + else // Plain browser env + mod(CodeMirror); +})(function(CodeMirror) { + CodeMirror.defineOption("placeholder", "", function(cm, val, old) { + var prev = old && old != CodeMirror.Init; + if (val && !prev) { + cm.on("blur", onBlur); + cm.on("change", onChange); + onChange(cm); + } else if (!val && prev) { + cm.off("blur", onBlur); + cm.off("change", onChange); + clearPlaceholder(cm); + var wrapper = cm.getWrapperElement(); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", ""); + } + + if (val && !cm.hasFocus()) onBlur(cm); + }); + + function clearPlaceholder(cm) { + if (cm.state.placeholder) { + cm.state.placeholder.parentNode.removeChild(cm.state.placeholder); + cm.state.placeholder = null; + } + } + function setPlaceholder(cm) { + clearPlaceholder(cm); + var elt = cm.state.placeholder = document.createElement("pre"); + elt.style.cssText = "height: 0; overflow: visible"; + elt.className = "CodeMirror-placeholder"; + elt.appendChild(document.createTextNode(cm.getOption("placeholder"))); + cm.display.lineSpace.insertBefore(elt, cm.display.lineSpace.firstChild); + } + + function onBlur(cm) { + if (isEmpty(cm)) setPlaceholder(cm); + } + function onChange(cm) { + var wrapper = cm.getWrapperElement(), empty = isEmpty(cm); + wrapper.className = wrapper.className.replace(" CodeMirror-empty", "") + (empty ? " CodeMirror-empty" : ""); + + if (empty) setPlaceholder(cm); + else clearPlaceholder(cm); + } + + function isEmpty(cm) { + return (cm.lineCount() === 1) && (cm.getLine(0) === ""); + } +}); diff --git a/lib/uuid.js b/lib/uuid.js new file mode 100644 index 000000000..563c414ac --- /dev/null +++ b/lib/uuid.js @@ -0,0 +1,24 @@ +// An incredibly short and scary method of generating UUIDs +// https://gist.github.com/LeverOne/1308368 + +var UUID = function b( + a // placeholder +){ + return a // if the placeholder was passed, return + ? ( // a random number from 0 to 15 + a ^ // unless b is 8, + Math.random() // in which case + * 16 // a random number from + >> a/4 // 8 to 11 + ).toString(16) // in hexadecimal + : ( // or otherwise a concatenated string: + [1e7] + // 10000000 + + -1e3 + // -1000 + + -4e3 + // -4000 + + -8e3 + // -80000000 + + -1e11 // -100000000000, + ).replace( // replacing + /[018]/g, // zeroes, ones, and eights with + b // random hex digits + ) +} diff --git a/package.json b/package.json index d32ac7408..e7b06f1eb 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,21 @@ { - "name": "twine", - "version": "2.0.0", - "author": "Chris Klimas ", + "name": "Twine", + "version": "2.0.4", + "author": "Chris Klimas ", "description": "a GUI for creating nonlinear stories", "license": "GPL v3", "repository": { "type": "hg", "url": "https://bitbucket.org/klembot/twinejs" }, + "main": "index.html", + "window": + { + "toolbar": false, + "width": 1024, + "height": 600, + "icon": "rsrc/img/logo.ico" + }, "dependencies": { "grunt": "*", "grunt-bake": "*", @@ -21,8 +29,9 @@ "grunt-contrib-uglify": "*", "grunt-contrib-watch": "*", "grunt-contrib-yuidoc": "*", + "grunt-node-webkit-builder": "*", "grunt-replace": "*", - "grunt-usemin": "*", + "grunt-usemin": "2.0.x", "require": "*" } } diff --git a/storyformats/Snowman/format.js b/storyformats/Snowman/format.js index 03cffb4a8..65bb0af8e 100644 --- a/storyformats/Snowman/format.js +++ b/storyformats/Snowman/format.js @@ -1 +1 @@ -window.storyFormat({"name":"Snowman","version":"1.0","description":"A minimal story format for authors experienced with HTML, CSS, and JavaScript.","author":"Chris Klimas","image":"icon.svg","url":"http://bitbucket.org/klembot/snowman","license":"MIT License","proofing":false,"source":"\n\n\n{{STORY_NAME}}\n\n\r\n\n\n\n

{{STORY_DATA}}\n\r\n\n\n\n"}); \ No newline at end of file +window.storyFormat({"name":"Snowman","version":"1.0","description":"A minimal story format for authors experienced with HTML, CSS, and JavaScript.","author":"Chris Klimas","image":"icon.svg","url":"http://bitbucket.org/klembot/snowman","license":"MIT License","proofing":false,"source":"\n\n\n{{STORY_NAME}}\n\n\r\n\n\n\n
{{STORY_DATA}}\n\r\n\n\n\n"}); \ No newline at end of file diff --git a/templates/storyeditview/passageeditmodal.html b/templates/storyeditview/passageeditmodal.html index 1fe57de14..4e4af7dda 100644 --- a/templates/storyeditview/passageeditmodal.html +++ b/templates/storyeditview/passageeditmodal.html @@ -28,7 +28,7 @@
- +
diff --git a/templates/storyeditview/statsmodal.html b/templates/storyeditview/statsmodal.html new file mode 100644 index 000000000..25109ac53 --- /dev/null +++ b/templates/storyeditview/statsmodal.html @@ -0,0 +1,63 @@ +
diff --git a/templates/storyeditview/storyeditview.html b/templates/storyeditview/storyeditview.html index e15bdddc5..3589dc2cc 100644 --- a/templates/storyeditview/storyeditview.html +++ b/templates/storyeditview/storyeditview.html @@ -12,6 +12,7 @@ + diff --git a/templates/storyeditview/toolbar.html b/templates/storyeditview/toolbar.html index e291355f3..b9c265f3f 100644 --- a/templates/storyeditview/toolbar.html +++ b/templates/storyeditview/toolbar.html @@ -6,7 +6,7 @@
- @@ -35,6 +35,10 @@ +
  • + +
  • +
  • diff --git a/tests/selenium/storyeditview/Adds passages that are newly linked.test b/tests/selenium/storyeditview/Adds passages that are newly linked.test index 7c81c94e1..cee3b983b 100644 --- a/tests/selenium/storyeditview/Adds passages that are newly linked.test +++ b/tests/selenium/storyeditview/Adds passages that are newly linked.test @@ -49,15 +49,20 @@ *hide* - type - css=#passageEditModal textarea.passageText - [[a new passage]] + storeEval + window.$('#passageEditModal .CodeMirror')[0].CodeMirror.setValue('[[a new passage]]') + click css=#passageEditModal > .save + + pause + 150 + + refresh @@ -68,7 +73,6 @@ css=div.passage:last .title a new passage - diff --git a/tests/selenium/storyeditview/All.suite b/tests/selenium/storyeditview/All.suite index 03e99a296..e168cdd50 100644 --- a/tests/selenium/storyeditview/All.suite +++ b/tests/selenium/storyeditview/All.suite @@ -8,8 +8,8 @@ - - + + @@ -30,6 +30,9 @@ + + +
    Test Suite
    Setup
    Create story
    Setup
    Create story
    Displays story title
    Returns to the story list with the home button
    Creates a passage with the Create Passage button
    Disables keyboard shortcuts when editing a passage
    Numbers new passages to avoid name conflicts
    Warns the user before navigating away while editing a passage
    Story statistics are accurate
    Generated IFIDs meet Treaty of Babel standards
    IFIDs remain stable for a story
    diff --git a/tests/selenium/storyeditview/Creates a passage with the Create Passage button.test b/tests/selenium/storyeditview/Creates a passage with the Create Passage button.test index 39702d019..7ec02fd3c 100644 --- a/tests/selenium/storyeditview/Creates a passage with the Create Passage button.test +++ b/tests/selenium/storyeditview/Creates a passage with the Create Passage button.test @@ -55,7 +55,7 @@ pause - 10 + 100, diff --git a/tests/selenium/storyeditview/Disables keyboard shortcuts when editing a passage.test b/tests/selenium/storyeditview/Disables keyboard shortcuts when editing a passage.test index 7a5ae8a74..58973e2c7 100644 --- a/tests/selenium/storyeditview/Disables keyboard shortcuts when editing a passage.test +++ b/tests/selenium/storyeditview/Disables keyboard shortcuts when editing a passage.test @@ -65,7 +65,7 @@ sendKeys - css=#passageEditModal textarea.passageText + css=#passageEditModal ${KEY_DELETE} diff --git a/tests/selenium/storyeditview/Generated IFIDs meet Treaty of Babel standards.test b/tests/selenium/storyeditview/Generated IFIDs meet Treaty of Babel standards.test new file mode 100644 index 000000000..22451db27 --- /dev/null +++ b/tests/selenium/storyeditview/Generated IFIDs meet Treaty of Babel standards.test @@ -0,0 +1,101 @@ + + + + + + +Generated IFIDs meet Treaty of Babel standards + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Generated IFIDs meet Treaty of Babel standards
    open${baseURL}/tests/selenium/resetLocalStorage.html
    clickcss=#deleteAll
    waitForTextcss=#resultAll data deleted.
    open${baseURL}
    storeEvalwindow.location.hash = 'stories';
    waitForElementPresentcss=.addStory
    clickcss=.addStory
    typecss=input.newName.block${shortUni}
    clickcss=button.add.create
    waitForElementPresentcss=div.frame
    clickcss=button.storyName.subtle
    clickcss=button.storyStats
    waitForTextcss=td.passageCount1
    storeTextcss=.ifidifid
    assertEvalstoredVars.ifid.length > 7 && storedVars.ifid.length < 64true
    assertEval/[^0-9A-Z\-]/.test(storedVars.ifid)false
    + + diff --git a/tests/selenium/storyeditview/IFIDs remain stable for a story.test b/tests/selenium/storyeditview/IFIDs remain stable for a story.test new file mode 100644 index 000000000..04d8dabba --- /dev/null +++ b/tests/selenium/storyeditview/IFIDs remain stable for a story.test @@ -0,0 +1,121 @@ + + + + + + +IFIDs remain stable for a story + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    IFIDs remain stable for a story
    open${baseURL}/tests/selenium/resetLocalStorage.html
    clickcss=#deleteAll
    waitForTextcss=#resultAll data deleted.
    open${baseURL}
    storeEvalwindow.location.hash = 'stories';
    waitForElementPresentcss=.addStory
    clickcss=.addStory
    typecss=input.newName.block${shortUni}
    clickcss=button.add.create
    waitForElementPresentcss=div.frame
    clickcss=button.storyName.subtle
    clickcss=button.storyStats
    waitForTextcss=td.passageCount1
    storeTextcss=.ifidifid
    refresh
    pause500
    clickcss=button.storyName.subtle
    clickcss=button.storyStats
    waitForTextcss=td.passageCount1
    assertTextcss=.ifid${ifid}
    + + diff --git a/tests/selenium/storyeditview/Saves changes to passage text.test b/tests/selenium/storyeditview/Saves changes to passage text.test index e0c240eb5..d367fa1cd 100644 --- a/tests/selenium/storyeditview/Saves changes to passage text.test +++ b/tests/selenium/storyeditview/Saves changes to passage text.test @@ -44,9 +44,9 @@ - type - css=#passageEditModal textarea.passageText - ${longUni} + storeEval + window.$('#passageEditModal .CodeMirror')[0].CodeMirror.setValue(storedVars.longUni) + click @@ -75,7 +75,7 @@ assertEval - window.$('#passageEditModal textarea').val() + window.$('#passageEditModal .CodeMirror')[0].CodeMirror.getValue() ${longUni} diff --git a/tests/selenium/storyeditview/Story statistics are accurate.test b/tests/selenium/storyeditview/Story statistics are accurate.test new file mode 100644 index 000000000..674d0fd8d --- /dev/null +++ b/tests/selenium/storyeditview/Story statistics are accurate.test @@ -0,0 +1,130 @@ + + + + + + +Story statistics are accurate + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Story statistics are accurate
    open${baseURL}/tests/selenium/resetLocalStorage.html
    clickcss=#deleteAll
    waitForTextcss=#resultAll data deleted.
    open${baseURL}
    storeEvalwindow.location.hash = 'stories';
    waitForElementPresentcss=.addStory
    clickcss=.addStory
    typecss=input.newName.block${shortUni}
    clickcss=button.add.create
    waitForElementPresentcss=div.frame
    clickcss=button.edit.subtle
    typecss=textarea.passageText[[red]] [[green]] [[blue]] The quick brown fox jumps over the lazy dog.
    storeEvalwindow.$('#passageEditModal .CodeMirror')[0].CodeMirror.setValue("[[red]] [[green]] [[blue]] The quick brown fox jumps over the lazy dog.")
    click//div[@id='passageEditModal']/button
    click//div[@id='storyEditView']/div[2]/div/div[2]/div/div[2]/div/button
    pause500
    clickcss=button.storyName.subtle
    clickcss=button.storyStats
    waitForTextcss=td.charCount145
    assertTextcss=td.wordCount24
    assertTextcss=td.passageCount3
    assertTextcss=td.brokenLinkCount1
    + + diff --git a/tests/selenium/storyeditview/Warns the user before navigating away while editing a passage.test b/tests/selenium/storyeditview/Warns the user before navigating away while editing a passage.test index 4463187ea..277234963 100644 --- a/tests/selenium/storyeditview/Warns the user before navigating away while editing a passage.test +++ b/tests/selenium/storyeditview/Warns the user before navigating away while editing a passage.test @@ -44,13 +44,13 @@ - click - css=button.edit.subtle + pause + 500 - pause - 500 + click + css=button.edit.subtle