├── .gitignore ├── .travis.yml ├── CHANGES.md ├── Gruntfile.coffee ├── LICENSE ├── README.md ├── bower.json ├── design ├── hallo-toolbar.bmml ├── hallo-toolbar.png ├── logo-200x59.png ├── logo.eps └── logo.png ├── dist └── hallo.js ├── examples ├── annotate.css ├── fixed.html ├── fontawesome │ ├── README.md │ ├── css │ │ ├── font-awesome-ie7.css │ │ └── font-awesome.css │ └── fonts │ │ ├── FontAwesome.otf │ │ ├── fontawesome-webfont.eot │ │ ├── fontawesome-webfont.svg │ │ ├── fontawesome-webfont.svgz │ │ ├── fontawesome-webfont.ttf │ │ └── fontawesome-webfont.woff ├── hallo.css ├── image.css ├── images │ ├── arrow.png │ ├── divider.png │ ├── drop_left.png │ ├── pager_arrows.png │ ├── tabicon_search.png │ ├── tabicon_suggestions.png │ ├── tabicon_upload.png │ └── trash.png ├── jquery-ui-bootstrap │ └── css │ │ └── custom-theme │ │ ├── images │ │ ├── ui-bg_flat_0_aaaaaa_40x100.png │ │ ├── ui-bg_glass_55_fbf9ee_1x400.png │ │ ├── ui-bg_glass_65_ffffff_1x400.png │ │ ├── ui-bg_glass_75_dadada_1x400.png │ │ ├── ui-bg_glass_75_e6e6e6_1x400.png │ │ ├── ui-bg_glass_75_ffffff_1x400.png │ │ ├── ui-bg_highlight-soft_75_cccccc_1x100.png │ │ ├── ui-bg_inset-soft_95_fef1ec_1x100.png │ │ ├── ui-icons_222222_256x240.png │ │ ├── ui-icons_2e83ff_256x240.png │ │ ├── ui-icons_454545_256x240.png │ │ ├── ui-icons_888888_256x240.png │ │ ├── ui-icons_cd0a0a_256x240.png │ │ └── ui-icons_f6cf3b_256x240.png │ │ ├── jquery-ui-1.8.16.custom.css │ │ └── jquery.ui.1.8.16.ie.css ├── overlay.css ├── test-annotate.html ├── test.html └── whitelist.html ├── package.json ├── src ├── hallo.coffee ├── plugins │ ├── annotate.coffee │ ├── blacklist.coffee │ ├── block.coffee │ ├── cleanhtml.coffee │ ├── halloformat.coffee │ ├── headings.coffee │ ├── html.coffee │ ├── image.coffee │ ├── image │ │ ├── current.coffee │ │ ├── search.coffee │ │ ├── suggestions.coffee │ │ └── upload.coffee │ ├── image_insert_edit.coffee │ ├── indicator.coffee │ ├── justify.coffee │ ├── link.coffee │ ├── lists.coffee │ ├── overlay.coffee │ ├── reundo.coffee │ └── toolbarlinebreak.coffee ├── toolbar │ ├── contextual.coffee │ ├── fixed.coffee │ └── instant.coffee └── widgets │ ├── button.coffee │ └── dropdownbutton.coffee └── test ├── hallo.coffee ├── index.html └── qunit ├── coffee-script.js ├── qunit.css ├── qunit.js └── run.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | docs/ 3 | node_modules/ 4 | docs_tmp/ 5 | _site/ 6 | dist/hallo-min.js 7 | bower_components/ 8 | .DS_Store 9 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '4.6' 4 | before_script: 5 | - npm install -g grunt-cli 6 | script: 7 | - grunt crossbrowser 8 | env: 9 | global: 10 | - secure: a7gNmuvehYer8OKmSYxF93A0kNqsgE7YWh4ml0Kme/ywZqal6LnkM8hX6ldmO3Wbzh703IiS1imY8MbQRsrA5xSl/HwaXiYOzan7RVHbSujcc4TxgYE4tKgdhM9ozWtX4XomJJ2E9kRTIShwEJkmC8sOh1uQ2IxxP3/MhxRtDNk= 11 | - secure: Xqhsriuk54lMsiWiN8Axz3z0fVNv6pyK2LhNptDbzDXkgpdp1O8Sqk4LaqSLpOwO3gM0X6PUnqF9hDbIbp7t4JB636NYPigMCJAPt46CBw4N3B3Apysn35ENI7/sdVK8iKuqYRexUpRIP2Ylok2DmFdnXVywEfS01fXqhv+CRcI= 12 | deploy: 13 | provider: npm 14 | email: henri.bergius@iki.fi 15 | api_key: 16 | secure: h4RC9wynsPCjDEP5aBV2A8OSbf191U+tFlzSO/S6w3zJul04874LcITp5iJBq4PZaCBgMhbFht/ZcyHTTtYgXTb2U1OHUYQFQTmt72Lko2OWMRE/35Kl5Xr7kZK+OqEdmbGRRguc3mU7fkIOMc5n2CAUWdgf8GvyUGHJ57l3BWE= 17 | on: 18 | tags: true 19 | repo: bergie/hallo 20 | -------------------------------------------------------------------------------- /CHANGES.md: -------------------------------------------------------------------------------- 1 | Hallo Editor ChangeLog 2 | ====================== 3 | 4 | ## 1.1.1 (January 21st 2015) 5 | 6 | * Switch everything to use dependencies installed via Bower instead of in-repository 7 | 8 | ## 1.1.0 (January 21st 2015) 9 | 10 | * Compatibility with Font Awesome 4.x 11 | 12 | ## 1.0.4 (September 10th 2013) 13 | 14 | * Plugin instance fetching is now more robust and gives better errors on plugins not compatible with jQuery 1.10 15 | 16 | ## 1.0.3 (September 10th 2013) 17 | 18 | * Ported the build environment to [Grunt](http://gruntjs.com) 19 | * Updated Bower packaging, and moved built Hallo version to `dist` 20 | 21 | ## 1.0.2 (February 18th 2013) 22 | 23 | Improved compatibility with [jQuery 1.9](http://jquery.com/upgrade-guide/1.9/) by removing the deprecated `jQuery.browser` calls. 24 | 25 | ## 1.0.1 (February 18th 2013) 26 | 27 | User interface: 28 | 29 | * Fixed Hallo toolbars now stay on the top of the screen when scrolling longer content elements [135](https://github.com/bergie/hallo/pull/135) 30 | * Contextual toolbar positioning is now more accurate [120](https://github.com/bergie/hallo/pull/120) & [121](https://github.com/bergie/hallo/pull/121) 31 | * Link plugin now prepends a `http://` to links if no protocol is defined [101](https://github.com/bergie/hallo/pull/101) 32 | * [New Hallo logo](https://raw.github.com/bergie/hallo/49c3236e59f900d82450eb41e628bf47a19aa6d1/design/logo.png) from the contest: 33 | 34 | ![Hallo Editor](https://raw.github.com/bergie/hallo/49c3236e59f900d82450eb41e628bf47a19aa6d1/design/logo-200x59.png) 35 | 36 | Plugins: 37 | 38 | * New [blacklist plugin](https://github.com/bergie/hallo/commit/627462b9738325030be46e2ba673e430780e0493) for removing unwanted DOM elements 39 | * Headings plugin uses the button class [126](https://github.com/bergie/hallo/pull/126) 40 | * Drag-and-drop behavior with the image widget was improved [115](https://github.com/bergie/hallo/pull/115) 41 | 42 | Internals: 43 | 44 | * Whitespace no longer prevents Hallo placeholder content from showing up [140](https://github.com/bergie/hallo/pull/140) 45 | * jQuery UI 1.10 compatibility [138](https://github.com/bergie/hallo/pull/138) 46 | * Several Internet Explorer fixes were included 47 | * Switched to jQuery 1.7+ `on`/`off` instead of `bind`/`unbind` 48 | * Switched selection handling to use the [Rangy](http://code.google.com/p/rangy/) library 49 | 50 | Development: 51 | 52 | * [CoffeeScript coding standards](https://github.com/polarmobile/coffeescript-style-guide) are now enforced by CoffeeLint 53 | * Unit tests and continuous integration run with the PhantomJS headless browser 54 | -------------------------------------------------------------------------------- /Gruntfile.coffee: -------------------------------------------------------------------------------- 1 | module.exports = -> 2 | banner = """/* Hallo <%= pkg.version %> - rich text editor for jQuery UI 3 | * by Henri Bergius and contributors. Available under the MIT license. 4 | * See http://hallojs.org for more information 5 | */""" 6 | 7 | # Project configuration 8 | @initConfig 9 | pkg: @file.readJSON 'package.json' 10 | 11 | # Install dependencies 12 | 'bower-install-simple': 13 | deps: 14 | options: 15 | interactive: false 16 | forceLatest: false 17 | directory: 'bower_components' 18 | 19 | # CoffeeScript complication 20 | coffee: 21 | core: 22 | expand: true 23 | src: ['**.coffee'] 24 | dest: 'tmp' 25 | cwd: 'src' 26 | ext: '.js' 27 | toolbar: 28 | expand: true 29 | src: ['**.coffee'] 30 | dest: 'tmp/toolbar' 31 | cwd: 'src/toolbar' 32 | ext: '.js' 33 | widgets: 34 | expand: true 35 | src: ['**.coffee'] 36 | dest: 'tmp/widgets' 37 | cwd: 'src/widgets' 38 | ext: '.js' 39 | plugins: 40 | expand: true 41 | src: ['**.coffee'] 42 | dest: 'tmp/plugins' 43 | cwd: 'src/plugins' 44 | ext: '.js' 45 | plugins_image: 46 | expand: true 47 | src: ['**.coffee'] 48 | dest: 'tmp/plugins/image' 49 | cwd: 'src/plugins/image' 50 | ext: '.js' 51 | 52 | # Build setup: concatenate source files 53 | concat: 54 | options: 55 | stripBanners: true 56 | banner: banner 57 | full: 58 | src: [ 59 | 'tmp/*.js' 60 | 'tmp/**/*.js' 61 | 'tmp/**/**/*.js' 62 | ] 63 | dest: 'dist/hallo.js' 64 | 65 | # Remove tmp directory once builds are complete 66 | clean: ['tmp'] 67 | 68 | # JavaScript minification 69 | uglify: 70 | options: 71 | banner: banner 72 | report: 'min' 73 | full: 74 | files: 75 | 'dist/hallo-min.js': ['dist/hallo.js'] 76 | 77 | # Coding standards verification 78 | coffeelint: 79 | full: [ 80 | 'src/*.coffee' 81 | 'src/**/*.coffee' 82 | ] 83 | options: 84 | 'max_line_length': 85 | 'level': 'ignore' 86 | 87 | # Unit tests 88 | qunit: 89 | all: ['test/*.html'] 90 | 91 | # Cross-browser testing 92 | connect: 93 | server: 94 | options: 95 | base: '' 96 | port: 9999 97 | 98 | 'saucelabs-qunit': 99 | all: 100 | options: 101 | urls: ['http://127.0.0.1:9999/test/index.html'] 102 | browsers: [ 103 | browserName: 'chrome' 104 | , 105 | browserName: 'safari' 106 | platform: 'OS X 10.9' 107 | version: '7' 108 | ] 109 | build: process.env.TRAVIS_JOB_ID 110 | testname: 'hallo.js cross-browser tests' 111 | tunnelTimeout: 5 112 | concurrency: 3 113 | detailedError: true 114 | 115 | # Dependency installation 116 | @loadNpmTasks 'grunt-bower-install-simple' 117 | 118 | # Build dependencies 119 | @loadNpmTasks 'grunt-contrib-coffee' 120 | @loadNpmTasks 'grunt-contrib-concat' 121 | @loadNpmTasks 'grunt-contrib-clean' 122 | @loadNpmTasks 'grunt-contrib-uglify' 123 | 124 | # Testing dependencies 125 | @loadNpmTasks 'grunt-coffeelint' 126 | @loadNpmTasks 'grunt-contrib-jshint' 127 | @loadNpmTasks 'grunt-contrib-qunit' 128 | 129 | # Cross-browser testing 130 | @loadNpmTasks 'grunt-contrib-connect' 131 | @loadNpmTasks 'grunt-saucelabs' 132 | 133 | # Local tasks 134 | @registerTask 'build', ['bower-install-simple', 'coffee', 'concat', 'clean', 'uglify'] 135 | @registerTask 'test', ['coffeelint', 'build', 'qunit'] 136 | @registerTask 'crossbrowser', ['test', 'connect', 'saucelabs-qunit'] 137 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2011-2013 Henri Bergius, The Midgard Project 2 | 3 | Permission is hereby granted, free of charge, to any person 4 | obtaining a copy of this software and associated documentation 5 | files (the "Software"), to deal in the Software without 6 | restriction, including without limitation the rights to use, 7 | copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following 10 | conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 17 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT 19 | HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 20 | WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 22 | OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Hallo - contentEditable for jQuery UI [![Build Status](https://secure.travis-ci.org/bergie/hallo.png)](http://travis-ci.org/bergie/hallo) [![Greenkeeper badge](https://badges.greenkeeper.io/bergie/hallo.svg)](https://greenkeeper.io/) 2 | ===================================== 3 | 4 | ![Hallo Editor logo](https://raw.github.com/bergie/hallo/master/design/logo-200x59.png) 5 | 6 | [![Cross-browser testing status](https://saucelabs.com/browser-matrix/hallo-js.svg)](https://saucelabs.com/u/hallo-js) 7 | 8 | Hallo is a very simple in-place rich text editor for web pages. It uses jQuery UI and the [HTML5 contentEditable functionality](https://developer.mozilla.org/en/rich-text_editing_in_mozilla) to edit web content. 9 | 10 | The widget has been written as a simple and liberally licensed editor. It doesn't aim to replace popular editors like [Aloha](http://aloha-editor.org), but instead to provide a simpler and more reusable option. 11 | 12 | Read the [introductory blog post](http://bergie.iki.fi/blog/hallo-editor/) for more information. 13 | 14 | ## Using the editor 15 | 16 | You need jQuery, jQuery UI (1.10+), and [Rangy](https://code.google.com/p/rangy/) loaded. An easy way to do this is to use Google's JS service: 17 | 18 | ```html 19 | 20 | 21 | 22 | ``` 23 | 24 | The editor toolbar is using jQuery UI theming, so you'll probably also want to [grab a theme](http://jqueryui.com/themeroller/) that fits your needs. Toolbar pluggins use icons from [Font Awesome](http://fortawesome.github.com/Font-Awesome/). Check these [integration instructions](http://fortawesome.github.com/Font-Awesome/#integration) for the right way to include Font Awesome depending on if/how you use Twitter Bootstrap. To style the toolbar as it appears in the demo, you'll also want to add some CSS (like background and border) to the class `hallotoolbar`. 25 | 26 | ```html 27 | 28 | 29 | ``` 30 | 31 | Then include Hallo itself: 32 | 33 | ```html 34 | 35 | ``` 36 | 37 | Editor activation is easy: 38 | 39 | ```javascript 40 | jQuery('p').hallo(); 41 | ``` 42 | 43 | You can also deactivate the editor: 44 | 45 | ```javascript 46 | jQuery('p').hallo({editable: false}); 47 | ``` 48 | 49 | Hallo itself only makes the selected DOM elements editable and doesn't provide any formatting tools. Formatting is accomplished by loading plugins when initializing Hallo. Even simple things like *bold* and *italic* are plugins: 50 | 51 | ```javascript 52 | jQuery('.editable').hallo({ 53 | plugins: { 54 | 'halloformat': {} 55 | } 56 | }); 57 | ``` 58 | 59 | This example would enable the simple formatting plugin that provides functionality like _bold_ and _italic_. You can include as many Hallo plugins as you want, and if necessary pass them options. 60 | 61 | Hallo has got more options you set when instantiating. See the [hallo.coffee](https://github.com/bergie/hallo/blob/master/src/hallo.coffee) file for further documentation. 62 | 63 | ### Events 64 | 65 | Hallo provides some events that are useful for integration. You can use [jQuery bind](http://api.jquery.com/bind/) to subscribe to them: 66 | 67 | * `halloenabled`: Triggered when an editable is enabled (`editable` set to `true`) 68 | * `hallodisabled`: Triggered when an editable is disabled (`editable` set to `false`) 69 | * `hallomodified`: Triggered whenever user has changed the contents being edited. Event data key `content` contains the HTML 70 | * `halloactivated`: Triggered when user activates an editable area (usually by clicking it) 71 | * `hallodeactivated`: Triggered when user deactivates an editable area 72 | 73 | ## Plugins 74 | 75 | * halloformat - Adds Bold, Italic, StrikeThrough and Underline support to the toolbar. (Enable/Disable with options: "formattings": {"bold": true, "italic": true, "strikethrough": true, "underline": false}) 76 | * halloheadings - Adds support for H1, H2, H3. You can pass a headings option key to specify what is going to be displayed (e.g. "formatBlocks":["p", "h2","h3"]) 77 | * hallojustify - Adds align left, center, right support 78 | * hallolists - Adds support for ordered and unordered lists (Pick with options: "lists": {"ordered": false, "unordered": true}) 79 | * halloreundo - Adds support for undo and redo 80 | * hallolink - Adds support to add links to a selection (currently not working) 81 | * halloimage - Image uploading, searching, suggestions 82 | * halloblacklist - Filtering unwanted tags from the content 83 | 84 | ## Licensing 85 | 86 | Hallo is free software available under the [MIT license](http://en.wikipedia.org/wiki/MIT_License). 87 | 88 | ## Contributing 89 | 90 | Hallo is written in [CoffeeScript](http://jashkenas.github.com/coffee-script/), a simple language that compiles into JavaScript. You'll need Node.js to to build it. All build dependencies can be installed with: 91 | 92 | $ npm install 93 | 94 | To generate the JavaScript code to `dist/hallo.js` from Hallo sources, run [Grunt](http://gruntjs.com): 95 | 96 | $ grunt build 97 | 98 | Hallo development is coordinated using Git. Just fork the [Hallo repository on GitHub](https://github.com/bergie/hallo) and [send pull requests](http://help.github.com/pull-requests/). 99 | 100 | ### Unit tests 101 | 102 | We use the Travis continuous integration service for testing Hallo. Currently we run two types of tests: 103 | 104 | * [CoffeeLint](http://www.coffeelint.org/) for ensuring compliance with [coding standards](https://github.com/polarmobile/coffeescript-style-guide) 105 | * Some [QUnit](http://qunitjs.com/) tests 106 | 107 | You can run the unit tests locally by opening `test/index.html` in your browser, or with [PhantomJS](http://phantomjs.org/) by running: 108 | 109 | $ grunt test 110 | 111 | or: 112 | 113 | $ npm test 114 | 115 | ### Writing plugins 116 | 117 | Hallo plugins are written as regular [jQuery UI widgets](http://semantic-interaction.org/blog/2011/03/01/jquery-ui-widget-factory/). 118 | 119 | When Hallo is loaded it will also load all the enabled plugins for the element, and pass them some additional options: 120 | 121 | * `editable`: The main Hallo widget instance 122 | * `uuid`: unique identifier of the Hallo instance, can be used for element IDs 123 | 124 | A simplistic plugin would look like the following: 125 | 126 | ```coffeescript 127 | # Formatting plugin for Hallo 128 | # (c) 2011 Henri Bergius, IKS Consortium 129 | # Hallo may be freely distributed under the MIT license 130 | ((jQuery) -> 131 | jQuery.widget "IKS.halloformat", 132 | boldElement: null 133 | 134 | options: 135 | uuid: '' 136 | editable: null 137 | 138 | _create: -> 139 | # Add any actions you want to run on plugin initialization 140 | # here 141 | 142 | populateToolbar: (toolbar) -> 143 | # Create an element for holding the button 144 | @boldElement = jQuery '' 145 | 146 | # Use Hallo Button 147 | @boldElement.hallobutton 148 | uuid: @options.uuid 149 | editable: @options.editable 150 | label: 'Bold' 151 | # Icons come from Font Awesome 152 | icon: 'icon-bold' 153 | # Commands are used for execCommand and queryCommandState 154 | command: 'bold' 155 | 156 | # Append the button to toolbar 157 | toolbar.append @boldElement 158 | 159 | cleanupContentClone: (element) -> 160 | # Perform content clean-ups before HTML is sent out 161 | 162 | )(jQuery) 163 | ``` 164 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hallo", 3 | "main": "./dist/hallo.js", 4 | "license": "MIT", 5 | "ignore": [ 6 | "**/.*", 7 | "node_modules", 8 | "components" 9 | ], 10 | "dependencies": { 11 | "jquery": "1.9.x", 12 | "jquery-ui": "1.10.x", 13 | "jquery-htmlclean": "1.3.x", 14 | "rangy-official": "1.3.x", 15 | "font-awesome": "~4.2.0" 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /design/hallo-toolbar.bmml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | A%20Web%20Page%0Ahttp%3A// 6 | 7 | 8 | 9 | 10 | A%20paragraph%20of%20text.%0AA%20_second_%20%5Brow%5D%20of%20*text*. 11 | 12 | 13 | 14 | 15 | B%2C%20I%2C%20H2%2C%20+ 16 | 17 | 18 | 19 | 20 | When%20there%20is%20a%20selection%20we%20show%20a%20%22popover%22%20toolbar.%0A%20%0AToolbar%20only%20has%20the%20actions%20you%20can%20apply%20to%20the%20selected%20area%2C%20and%20a%20+%20for%20insertions 21 | 22 | 23 | 24 | 25 | A%20Web%20Page%0Ahttp%3A// 26 | 27 | 28 | 29 | 30 | A%20paragraph%20of%20text.%0AA%20_second_%20%5Brow%5D%20of%20*text*. 31 | 32 | 33 | 34 | 35 | P%2C%20PRE%2C%20H1%2C%20H2 36 | 37 | 38 | 39 | 40 | Clicking%20the%20block%20formatting%20button%20%28which%20shows%20current%20blocklevel%20element%20%5Bh2%5D%29%20changes%20toolbar%20contents%20to%20blocklevel%20element%20selection 41 | 42 | 43 | 44 | 45 | A%20Web%20Page%0Ahttp%3A// 46 | 47 | 48 | 49 | 50 | A%20paragraph%20of%20text.%0AA%20_second_%20%5Brow%5D%20of%20*text*. 51 | 52 | 53 | 54 | 55 | Link%2C%20Image%2C%20Person 56 | 57 | 58 | 59 | 60 | 13369344 61 | bottom 62 | false 63 | 64 | 65 | 66 | 67 | 68 | Clicking%20the%20+%20button%20changes%20toolbar%20to%20show%20different%20things%20you%20can%20insert%20to%20the%20page 69 | 70 | 71 | 72 | 73 | 13369344 74 | false 75 | 76 | 77 | 78 | 79 | 80 | A%20Web%20Page%0Ahttp%3A// 81 | 82 | 83 | 84 | 85 | A%20paragraph%20of%20text.%0AA%20_second_%20row%20of%20*text*.%20%7C 86 | 87 | 88 | 89 | 90 | Normally%20Hallo%20only%20shows%20you%20the%20content%20you%27re%20editing%20with%20no%20additional%20chrome 91 | 92 | 93 | 94 | 95 | 13576743 96 | bottom 97 | true 98 | false 99 | 100 | 101 | 102 | 103 | 104 | A%20Web%20Page%0Ahttp%3A// 105 | 106 | 107 | 108 | 109 | A%20paragraph%20of%20text.%0AA%20_second_%20%5Brow%5D%20of%20*text*. 110 | 111 | 112 | 113 | 114 | 115 | Drop%20an%20image%20to%20insert 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | Search%20images 126 | 127 | 128 | 129 | 130 | Image%20insertion%20replaces%20the%20toolbar%20with%20a%20larger%20dialog%20that%20provides%20a%20drag%20target%20to%20upload%20images%2C%20and%20a%20search%20box%20for%20images%20already%20in%20system.%0A%20%0AYou%20can%20also%20drag%20images%20straight%20into%20the%20editable%20area. 131 | 132 | 133 | 134 | 135 | 13369344 136 | false 137 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /design/hallo-toolbar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/design/hallo-toolbar.png -------------------------------------------------------------------------------- /design/logo-200x59.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/design/logo-200x59.png -------------------------------------------------------------------------------- /design/logo.eps: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/design/logo.eps -------------------------------------------------------------------------------- /design/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/design/logo.png -------------------------------------------------------------------------------- /examples/annotate.css: -------------------------------------------------------------------------------- 1 | .entity, a[typeof][about] { 2 | z-index: -1; 3 | padding: 0 3px; 4 | background-color: #E0E0E0; 5 | border-radius: 7px; 6 | border: outset rgba(0, 0, 0, 0.2); 7 | white-space: nowrap; 8 | border-width:1px; 9 | } 10 | a[typeof][about] { 11 | border-width: 1px 0; 12 | border-color: rgba(0, 0, 0, 0.8); 13 | border-style: solid; 14 | border-radius: 0; 15 | } 16 | .entity.withSuggestions {border-color: rgba(0, 0, 0, 0.8);} 17 | 18 | .entity.person, 19 | a[typeof][about].person {background-color: #ffe;} 20 | 21 | .entity.place, 22 | a[typeof][about].place {background-color: #fef;} 23 | 24 | .entity.organisation, 25 | a[typeof][about].organisation {background-color: #eff;} 26 | 27 | #loadingDiv { 28 | position: absolute; 29 | top: 10px; 30 | right: 10px; 31 | } 32 | .ui-dialog, .ui-tooltip { 33 | font-size: 95%; 34 | } 35 | -------------------------------------------------------------------------------- /examples/fixed.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 12 | 13 | 14 | 15 | 16 | Hallo example 17 | 18 | 19 | 20 | 21 | 22 |

Editables have not been modified

23 | 24 |

Hello World

25 |
26 |

27 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 28 |

29 |

30 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 31 |

32 | 33 | 34 | 35 | 36 | 37 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.
38 |
39 | 40 |
41 |

Affix Example

42 |

43 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 44 |

45 |

46 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 47 |

48 |

49 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 50 |

51 |

52 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 53 |

54 |

55 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 56 |

57 |

58 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 59 |

60 |

61 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 62 |

63 |

64 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 65 |

66 |

67 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 68 |

69 |

70 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 71 |

72 |

73 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 74 |

75 |

76 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 77 |

78 |

79 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 80 |

81 |

82 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 83 |

84 |

85 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 86 |

87 |

88 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 89 |

90 |

91 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 92 |

93 |

94 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 95 |

96 |

97 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 98 |

99 |

100 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 101 |

102 |

103 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 104 |

105 |

106 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 107 |

108 |

109 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 110 |

111 |

112 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 113 |

114 |
115 | 116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 | 153 | 232 | 233 | 234 | -------------------------------------------------------------------------------- /examples/fontawesome/README.md: -------------------------------------------------------------------------------- 1 | #Font Awesome 2 | ##the iconic font designed for use with Twitter Bootstrap 3 | 4 | The full suite of pictographic icons, examples, and documentation can be found at: 5 | http://fortawesome.github.com/Font-Awesome/ 6 | 7 | ##Contact 8 | - Email: dave@davegandy.com 9 | - Twitter: http://twitter.com/fortaweso_me 10 | - Work: http://lemonwi.se co-founder 11 | 12 | ##License 13 | The Font Awesome webfont, CSS, and LESS files are licensed under CC BY 3.0: 14 | http://creativecommons.org/licenses/by/3.0/ 15 | A mention of 'Font Awesome - http://fortawesome.github.com/Font-Awesome' 16 | in human-readable source code is considered acceptable attribution (most common on the 17 | web). If human readable source code is not available to the end user, a mention in an 'About' 18 | or 'Credits' screen is considered acceptable (most common in desktop or mobile software). 19 | -------------------------------------------------------------------------------- /examples/fontawesome/css/font-awesome-ie7.css: -------------------------------------------------------------------------------- 1 | [class^="icon-"], 2 | [class*=" icon-"] { 3 | font-family: FontAwesome; 4 | font-style: normal; 5 | font-weight: normal; 6 | } 7 | 8 | .btn.dropdown-toggle [class^="icon-"], .btn.dropdown-toggle [class*=" icon-"] { 9 | /* keeps button heights with and without icons the same */ 10 | line-height: 1.4em; 11 | } 12 | 13 | .icon-large { 14 | font-size: 1.3333em; 15 | } 16 | 17 | .icon-glass { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 18 | .icon-music { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 19 | .icon-search { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 20 | .icon-envelope { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 21 | .icon-heart { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 22 | .icon-star { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 23 | .icon-star-empty { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 24 | .icon-user { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 25 | .icon-film { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 26 | .icon-th-large { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 27 | .icon-th { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 28 | .icon-th-list { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 29 | .icon-ok { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 30 | .icon-remove { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 31 | .icon-zoom-in { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 32 | 33 | .icon-zoom-out { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 34 | .icon-off { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 35 | .icon-signal { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 36 | .icon-cog { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 37 | .icon-trash { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 38 | .icon-home { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 39 | .icon-file { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 40 | .icon-time { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 41 | .icon-road { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 42 | .icon-download-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 43 | .icon-download { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 44 | .icon-upload { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 45 | .icon-inbox { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 46 | .icon-play-circle { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 47 | .icon-repeat { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 48 | 49 | .icon-refresh { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 50 | .icon-list-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 51 | .icon-lock { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 52 | .icon-flag { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 53 | .icon-headphones { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 54 | .icon-volume-off { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 55 | .icon-volume-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 56 | .icon-volume-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 57 | .icon-qrcode { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 58 | .icon-barcode { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 59 | .icon-tag { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 60 | .icon-tags { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 61 | .icon-book { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 62 | .icon-bookmark { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 63 | .icon-print { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 64 | 65 | .icon-camera { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 66 | .icon-font { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 67 | .icon-bold { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 68 | .icon-italic { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 69 | .icon-text-height { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 70 | .icon-text-width { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 71 | .icon-align-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 72 | .icon-align-center { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 73 | .icon-align-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 74 | .icon-align-justify { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 75 | .icon-list { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 76 | .icon-indent-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 77 | .icon-indent-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 78 | .icon-facetime-video { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 79 | .icon-picture { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 80 | 81 | .icon-pencil { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 82 | .icon-map-marker { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 83 | .icon-adjust { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 84 | .icon-tint { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 85 | .icon-edit { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 86 | .icon-share { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 87 | .icon-check { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 88 | .icon-move { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 89 | .icon-step-backward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 90 | .icon-fast-backward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 91 | .icon-backward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 92 | .icon-play { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 93 | .icon-pause { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 94 | .icon-stop { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 95 | .icon-forward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 96 | 97 | .icon-fast-forward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 98 | .icon-step-forward { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 99 | .icon-eject { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 100 | .icon-chevron-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 101 | .icon-chevron-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 102 | .icon-plus-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 103 | .icon-minus-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 104 | .icon-remove-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 105 | .icon-ok-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 106 | .icon-question-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 107 | .icon-info-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 108 | .icon-screenshot { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 109 | .icon-remove-circle { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 110 | .icon-ok-circle { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 111 | .icon-ban-circle { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 112 | 113 | .icon-arrow-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 114 | .icon-arrow-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 115 | .icon-arrow-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 116 | .icon-arrow-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 117 | .icon-share-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 118 | .icon-resize-full { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 119 | .icon-resize-small { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 120 | .icon-plus { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 121 | .icon-minus { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 122 | .icon-asterisk { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 123 | .icon-exclamation-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 124 | .icon-gift { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 125 | .icon-leaf { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 126 | .icon-fire { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 127 | .icon-eye-open { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 128 | 129 | .icon-eye-close { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 130 | .icon-warning-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 131 | .icon-plane { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 132 | .icon-calendar { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 133 | .icon-random { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 134 | .icon-comment { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 135 | .icon-magnet { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 136 | .icon-chevron-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 137 | .icon-chevron-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 138 | .icon-retweet { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 139 | .icon-shopping-cart { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 140 | .icon-folder-close { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 141 | .icon-folder-open { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 142 | .icon-resize-vertical { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 143 | .icon-resize-horizontal { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 144 | 145 | .icon-bar-chart { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 146 | .icon-twitter-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 147 | .icon-facebook-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 148 | .icon-camera-retro { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 149 | .icon-key { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 150 | .icon-cogs { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 151 | .icon-comments { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 152 | .icon-thumbs-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 153 | .icon-thumbs-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 154 | .icon-star-half { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 155 | .icon-heart-empty { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 156 | .icon-signout { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 157 | .icon-linkedin-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 158 | .icon-pushpin { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 159 | .icon-external-link { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 160 | 161 | .icon-signin { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 162 | .icon-trophy { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 163 | .icon-github-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 164 | .icon-upload-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 165 | .icon-lemon { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 166 | .icon-phone { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 167 | .icon-check-empty { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 168 | .icon-bookmark-empty { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 169 | .icon-phone-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 170 | .icon-twitter { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 171 | .icon-facebook { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 172 | .icon-github { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 173 | .icon-unlock { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 174 | .icon-credit-card { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 175 | .icon-rss { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 176 | 177 | .icon-hdd { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 178 | .icon-bullhorn { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 179 | .icon-bell { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 180 | .icon-certificate { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 181 | .icon-hand-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 182 | .icon-hand-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 183 | .icon-hand-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 184 | .icon-hand-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 185 | .icon-circle-arrow-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 186 | .icon-circle-arrow-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 187 | .icon-circle-arrow-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 188 | .icon-circle-arrow-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 189 | .icon-globe { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 190 | .icon-wrench { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 191 | .icon-tasks { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 192 | 193 | .icon-filter { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 194 | .icon-briefcase { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 195 | .icon-fullscreen { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 196 | 197 | .icon-group { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 198 | .icon-link { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 199 | .icon-cloud { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 200 | .icon-beaker { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 201 | .icon-cut { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 202 | .icon-copy { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 203 | .icon-paper-clip { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 204 | .icon-save { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 205 | .icon-sign-blank { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 206 | .icon-reorder { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 207 | .icon-list-ul { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 208 | .icon-list-ol { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 209 | .icon-strikethrough { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 210 | .icon-underline { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 211 | .icon-table { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 212 | 213 | .icon-magic { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 214 | .icon-truck { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 215 | .icon-pinterest { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 216 | .icon-pinterest-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 217 | .icon-google-plus-sign { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 218 | .icon-google-plus { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 219 | .icon-money { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 220 | .icon-caret-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 221 | .icon-caret-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 222 | .icon-caret-left { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 223 | .icon-caret-right { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 224 | .icon-columns { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 225 | .icon-sort { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 226 | .icon-sort-down { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 227 | .icon-sort-up { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 228 | 229 | .icon-envelope-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 230 | .icon-linkedin { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 231 | .icon-undo { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 232 | .icon-legal { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 233 | .icon-dashboard { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 234 | .icon-comment-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 235 | .icon-comments-alt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 236 | .icon-bolt { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 237 | .icon-sitemap { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 238 | .icon-umbrella { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 239 | .icon-paste { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 240 | 241 | .icon-user-md { *zoom: expression( this.runtimeStyle['zoom'] = "1", this.innerHTML = ' '); } 242 | -------------------------------------------------------------------------------- /examples/fontawesome/fonts/FontAwesome.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/fontawesome/fonts/FontAwesome.otf -------------------------------------------------------------------------------- /examples/fontawesome/fonts/fontawesome-webfont.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/fontawesome/fonts/fontawesome-webfont.eot -------------------------------------------------------------------------------- /examples/fontawesome/fonts/fontawesome-webfont.svgz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/fontawesome/fonts/fontawesome-webfont.svgz -------------------------------------------------------------------------------- /examples/fontawesome/fonts/fontawesome-webfont.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/fontawesome/fonts/fontawesome-webfont.ttf -------------------------------------------------------------------------------- /examples/fontawesome/fonts/fontawesome-webfont.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/fontawesome/fonts/fontawesome-webfont.woff -------------------------------------------------------------------------------- /examples/hallo.css: -------------------------------------------------------------------------------- 1 | div.hallotoolbar { 2 | border: 1px solid #babdb6; 3 | padding: 2px; 4 | background-color: #eeeeec; 5 | border-radius: 6px; 6 | font-size: 12pt; 7 | line-height: 1.1em; 8 | z-index: 500; 9 | } 10 | 11 | div.halloEditIndicator { 12 | background-color: #000000; 13 | color: #ffffff; 14 | padding: 4px; 15 | border-radius: 4px; 16 | } 17 | 18 | /* Drag n Drop */ 19 | [contenteditable] .tmp { 20 | opacity: 0.3 21 | } 22 | 23 | [contenteditable] .tmpLine{ 24 | background-color: #ffffff; 25 | width: 98%; 26 | height: 2px; 27 | margin: 0 auto 10px auto; 28 | border-top: 2px solid #1cb8d6; 29 | border-bottom: 2px solid #1cb8d6; 30 | opacity: 1; 31 | padding: 1px; 32 | } 33 | 34 | .dropdown-menu { 35 | width: "200px"; 36 | background-color: #eeeeec; 37 | } 38 | 39 | .dropdown-target .selected { 40 | background-color: #729fcf; 41 | } 42 | 43 | button.blockselector, button.blockselector:focus{ 44 | display:block; 45 | width: 100%; 46 | margin:0px; 47 | padding: 0px; 48 | background: transparent; 49 | border: none; 50 | -moz-appearance: none; 51 | -webkit-appearance: none; 52 | outline: none; 53 | } 54 | 55 | .bigOverlay, .smallOverlay { 56 | display: none; 57 | position: absolute; 58 | top: 0; 59 | left: 0; 60 | background-color: rgba(28, 184, 214, 0.4); 61 | } 62 | 63 | .bigOverlayRight{ 64 | display : block; 65 | border-right : 3px dashed rgb(28, 184, 214); 66 | border-left : none; 67 | } 68 | 69 | .bigOverlayLeft{ 70 | display : block; 71 | border-left : 3px dashed rgb(28, 184, 214); 72 | border-right : none; 73 | } 74 | 75 | .smallOverlayLeft{ 76 | border-right : 3px dashed rgb(28, 184, 214); 77 | } 78 | 79 | .smallOverlayRight{ 80 | border-left : 3px dashed rgb(28, 184, 214); 81 | } 82 | 83 | .ui-draggable{ 84 | cursor: move; 85 | } 86 | 87 | .ui-draggable-dragging{ 88 | border: 3px solid white; 89 | } 90 | 91 | [contenteditable] img.ui-state-disabled { 92 | opacity: 1; 93 | } 94 | 95 | .customHelper{ 96 | background-size: cover; 97 | width: 100px; 98 | height: 100px; 99 | z-index: 1050; 100 | } 101 | 102 | .trashcan{ 103 | width: 50px; 104 | height: 50px; 105 | position: relative; 106 | top: 25px; 107 | left: 25px; 108 | background: rgba(0,0,0,0.8) url('images/trash.png') no-repeat 12px 12px; 109 | border-radius: 10px; 110 | cursor: none; 111 | } 112 | -------------------------------------------------------------------------------- /examples/image.css: -------------------------------------------------------------------------------- 1 | /****************/ 2 | /* Image Dialog */ 3 | /****************/ 4 | 5 | .halloimage-dialog .ui-dialog-content { 6 | padding: 0; 7 | } 8 | 9 | .halloimage-dialog button { 10 | cursor: pointer; 11 | } 12 | 13 | /* Nav/Tabs */ 14 | .halloimage-dialog .nav { 15 | height: 35px; 16 | width: 100%; 17 | } 18 | 19 | .halloimage-dialog .tabs { 20 | text-transform: uppercase; 21 | font-size: 10px; 22 | color: white; 23 | height: 30px; 24 | line-height: 30px; 25 | display: table; 26 | width: 100%; 27 | } 28 | 29 | #activitySpinner { 30 | display: none; 31 | width: auto; 32 | height: 20px; 33 | margin: 0 auto; 34 | font-size: 10px; 35 | } 36 | 37 | .halloimage-dialog .tabs li { 38 | display: table-cell; 39 | cursor: pointer; 40 | background: #01add2 url('images/divider.png') no-repeat right; 41 | text-align: center; 42 | } 43 | 44 | .halloimage-dialog .tabs li:hover { 45 | background-color: #2EA0BE; 46 | } 47 | 48 | .halloimage-dialog .tabs li.halloimage-tabselector span { 49 | position: relative; 50 | padding: 4px 6px 0 18px; 51 | margin-right: 1px; 52 | } 53 | .halloimage-dialog .tabs li.halloimage-tab-suggestions span { 54 | background: url('images/tabicon_suggestions.png') no-repeat left; 55 | } 56 | .halloimage-dialog .tabs li.halloimage-tab-search span { 57 | background: url('images/tabicon_search.png') no-repeat left; 58 | } 59 | .halloimage-dialog .tabs li.halloimage-tab-upload span { 60 | background: url('images/tabicon_upload.png') no-repeat left; 61 | } 62 | 63 | .halloimage-dialog .tabs li:last-of-type { 64 | background-image: none; 65 | } 66 | 67 | .halloimage-dialog .tab-search, 68 | .halloimage-dialog .tab-upload { 69 | display: none; 70 | } 71 | 72 | .halloimage-dialog .tab-activeIndicator { 73 | vertical-align: top; 74 | margin-left: 50px; 75 | width: 18px; 76 | height: 8px; 77 | display: relative; 78 | background: url('images/arrow.png'); 79 | } 80 | 81 | 82 | /* Content */ 83 | .halloimage-dialog .dialogcontent { 84 | text-align: center; 85 | padding: 15px; 86 | } 87 | 88 | .halloimage-dialog .ui-dialog-content { 89 | overflow: visible; 90 | } 91 | 92 | 93 | .halloimage-dialog .search-activeImageContainer { 94 | display: none; 95 | } 96 | 97 | /* Thumbnails */ 98 | .halloimage-dialog .imageThumbnail { 99 | max-width: 45px; 100 | max-height: 45px; 101 | padding: 2px; 102 | border: 1px solid #E1E1E1; 103 | box-shadow: 2px 2px 3px #888; 104 | cursor: pointer; 105 | float: left; 106 | } 107 | 108 | .imageThumbnailContainer li { 109 | display: block; 110 | float: left; 111 | width: 60px; 112 | height: 50px; 113 | margin-bottom: 13px; 114 | } 115 | 116 | .imageThumbnailContainer ul { 117 | overflow: hidden; 118 | } 119 | 120 | .halloimage-dialog .imageThumbnail:hover { 121 | border: 1px solid #01add2; 122 | } 123 | 124 | .halloimage-dialog .imageThumbnailActive, 125 | .halloimage-dialog .imageThumbnailActive:hover { 126 | padding: 0; 127 | border: 2px solid black; 128 | box-shadow: 2px 2px 3px #888; 129 | } 130 | 131 | /* Active image */ 132 | .halloimage-dialog .activeImageContainer { 133 | position: relative; 134 | margin: auto; 135 | margin-top: 30px; 136 | } 137 | 138 | .halloimage-dialog .rotationWrapper { 139 | -moz-transform: rotate(-3deg); 140 | -webkit-transform: rotate(-3deg); 141 | transform: rotate(-3deg); 142 | -moz-transition-duration: 0.3s; 143 | -webkit-transition-duration: 0.3s; 144 | max-width: 200px; 145 | max-height: 150px; 146 | position: relative; 147 | display: inline-block; 148 | z-index: 3; 149 | } 150 | 151 | .halloimage-dialog .rotationWrapper img, 152 | .halloimage-dialog .activeImageBg { 153 | max-height: 150px; 154 | box-shadow: 4px 4px 7px #888; 155 | } 156 | 157 | .halloimage-dialog .rotationWrapper:hover { 158 | -moz-transition-duration: 0.2s; 159 | -webkit-transition-duration: 0.2s; 160 | -moz-transform: translateX(-20px) rotate(-3deg); 161 | -webkit-transform: translateX(-20px) rotate(-3deg); 162 | transform: translateX(-20px) rotate(-3deg); 163 | cursor: move; 164 | } 165 | 166 | .halloimage-dialog .rotationWrapper .hintArrow { 167 | background: transparent url('images/drop_left.png') no-repeat -2px -2px; 168 | height: 44px; 169 | width: 44px; 170 | position: absolute; 171 | top: -5px; 172 | left: -30px; 173 | } 174 | 175 | .halloimage-dialog .rotationWrapper:hover .hintArrow{ 176 | background-position: -2px -50px; 177 | } 178 | 179 | .halloimage-dialog .activeImageBg { 180 | /*-moz-transform: rotate(-3deg); 181 | -webkit-transform: rotate(-3deg); 182 | transform: rotate(-3deg);*/ 183 | opacity: 0.2; 184 | position: absolute; 185 | left: 0; 186 | top: 0; 187 | z-index: 2; 188 | display: none; 189 | } 190 | 191 | .halloimage-dialog .metadata { 192 | margin-top: 20px; 193 | text-align: left; 194 | } 195 | 196 | .halloimage-dialog .metadata label { 197 | color: #A1A1A1; 198 | font-size: 14px; 199 | } 200 | 201 | .halloimage-dialog .metadata button { 202 | color: white; 203 | background-color: #646464; 204 | padding: 5px; 205 | border: 0; 206 | border-radius: 3px; 207 | margin-top: 10px; 208 | } 209 | 210 | .halloimage-dialog .metadata button:hover { 211 | background-color: #01add2; 212 | } 213 | 214 | .halloimage-dialog .pager-prev, 215 | .halloimage-dialog .pager-next { 216 | width: 11px; 217 | height: 21px; 218 | background-color: #FFF; 219 | cursor: pointer; 220 | position: absolute; 221 | top: 45px; 222 | } 223 | 224 | .halloimage-dialog .pager-prev { 225 | background: url('images/pager_arrows.png') no-repeat -5px 0; 226 | left: 0; 227 | } 228 | 229 | .halloimage-dialog .pager-next { 230 | background: url('images/pager_arrows.png') no-repeat -21px 0; 231 | right: 0; 232 | } 233 | .halloimage-dialog .pager-prev:hover { background-position: -5px -22px; } 234 | .halloimage-dialog .pager-next:hover { background-position: -21px -22px; } 235 | 236 | .halloimage-dialog .tab-search .searchInput { 237 | width: 175px; 238 | height: 22px; 239 | border-radius: 2px 0 0 2px; 240 | } 241 | 242 | .halloimage-dialog .tab-search .searchButton { 243 | width: 56px; 244 | top: 1px; 245 | cursor: pointer; 246 | } 247 | 248 | .halloimage-dialog .tab-search .searchResults { 249 | margin: 15px 0 0 0; 250 | position: relative; 251 | } 252 | 253 | .halloimage-dialog .tab-upload { 254 | 255 | } 256 | .halloimage-dialog .tab-upload .file { 257 | font-size: 11px; 258 | margin-bottom: 10px; 259 | } 260 | 261 | .halloimage-dialog .imageThumbnailContainer { 262 | min-height: 110px; 263 | } 264 | 265 | 266 | .inlineImage-left, .inlineImage-right, .inlineImage-middle { 267 | margin: 5px; 268 | left: 0; 269 | } 270 | .inlineImage-left { 271 | float: left; 272 | margin-right: 10px; 273 | } 274 | .inlineImage-right { 275 | float: right; 276 | margin-left: 10px; 277 | } 278 | .inlineImage-middle { 279 | float: none; 280 | } 281 | 282 | [contenteditable] .halloTmp { 283 | opacity: 0.3 284 | } 285 | 286 | [contenteditable] .halloTmpLine{ 287 | background-color: #ffffff; 288 | width: 98%; 289 | height: 2px; 290 | margin: 0 auto 10px auto; 291 | border-top: 2px solid #1cb8d6; 292 | border-bottom: 2px solid #1cb8d6; 293 | opacity: 1; 294 | padding: 1px; 295 | } 296 | 297 | .bigOverlay, .smallOverlay { 298 | display: none; 299 | position: absolute; 300 | top: 0; 301 | left: 0; 302 | background-color: rgba(28, 184, 214, 0.4); 303 | } 304 | 305 | .bigOverlayRight{ 306 | display : block; 307 | border-right : 3px dashed rgb(28, 184, 214); 308 | border-left : none; 309 | } 310 | 311 | .bigOverlayLeft{ 312 | display : block; 313 | border-left : 3px dashed rgb(28, 184, 214); 314 | border-right : none; 315 | } 316 | 317 | .smallOverlayLeft{ 318 | border-right : 3px dashed rgb(28, 184, 214); 319 | } 320 | 321 | .smallOverlayRight{ 322 | border-left : 3px dashed rgb(28, 184, 214); 323 | } 324 | -------------------------------------------------------------------------------- /examples/images/arrow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/arrow.png -------------------------------------------------------------------------------- /examples/images/divider.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/divider.png -------------------------------------------------------------------------------- /examples/images/drop_left.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/drop_left.png -------------------------------------------------------------------------------- /examples/images/pager_arrows.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/pager_arrows.png -------------------------------------------------------------------------------- /examples/images/tabicon_search.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/tabicon_search.png -------------------------------------------------------------------------------- /examples/images/tabicon_suggestions.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/tabicon_suggestions.png -------------------------------------------------------------------------------- /examples/images/tabicon_upload.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/tabicon_upload.png -------------------------------------------------------------------------------- /examples/images/trash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/images/trash.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_flat_0_aaaaaa_40x100.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_55_fbf9ee_1x400.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_65_ffffff_1x400.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_dadada_1x400.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_e6e6e6_1x400.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_glass_75_ffffff_1x400.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_highlight-soft_75_cccccc_1x100.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-bg_inset-soft_95_fef1ec_1x100.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_222222_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_222222_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_2e83ff_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_2e83ff_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_454545_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_454545_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_888888_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_888888_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_cd0a0a_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_cd0a0a_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_f6cf3b_256x240.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/bergie/hallo/3d10b2f34290fbebf75e80c397ba3b2bcc7a4615/examples/jquery-ui-bootstrap/css/custom-theme/images/ui-icons_f6cf3b_256x240.png -------------------------------------------------------------------------------- /examples/jquery-ui-bootstrap/css/custom-theme/jquery.ui.1.8.16.ie.css: -------------------------------------------------------------------------------- 1 | 2 | .ui-corner-all, .ui-corner-top, .ui-corner-right, .ui-corner-left, .ui-corner-bottom{ border-radius:0px;} 3 | .ui-state-active,.ui-tabs-selected { border-radius:0px;} 4 | .ui-tabs-selected { border-radius:0px;} 5 | .ui-tabs .ui-tabs-nav li{ filter:none;} 6 | .ui-tabs .ui-tabs-nav li a { border-radius:0px; } 7 | -------------------------------------------------------------------------------- /examples/overlay.css: -------------------------------------------------------------------------------- 1 | div[contenteditable] { 2 | position: relative; 3 | } 4 | 5 | .halloOverlay { 6 | background-color: #000000; 7 | opacity: 0.5; 8 | width: 100%; 9 | height: 100%; 10 | position: fixed; 11 | top: 0; 12 | left: 0; 13 | z-index: 250; 14 | } 15 | 16 | .halloBackground { 17 | position: absolute; 18 | background-color: #fff; 19 | z-index: 300; 20 | } 21 | 22 | -------------------------------------------------------------------------------- /examples/test-annotate.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | Hallo example 25 | 26 | 27 | 28 | 29 | 30 |

Editables have not been modified

31 | 32 |

Hello World

33 |
34 | Turkey, known officially as the Republic of Turkey, is a Eurasian country that stretches across the Anatolian peninsula in western Asia and Thrace in the Balkan region of southeastern Europe. Turkey is one of the six independent Turkic states. Turkey is bordered by eight countries: Bulgaria to the northwest; Greece to the west; Georgia to the northeast; Armenia, Azerbaijan and Iran to the east; and Iraq and Syria to the southeast. 35 |
36 | 37 | 106 | 107 | 108 | -------------------------------------------------------------------------------- /examples/test.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | Hallo example 16 | 21 | 22 | 23 | 24 | 25 | 26 |

Editables have not been modified

27 | 28 |

Hello World

29 |

30 |
31 |

32 | Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat. 33 |

34 |

35 | Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius. 36 |

37 | 38 | 39 | 40 | 41 | 42 | 43 |
Lorem ipsum dolor sit amet, consectetuer adipiscing elit, sed diam nonummy nibh euismod tincidunt ut laoreet dolore magna aliquam erat volutpat. Ut wisi enim ad minim veniam, quis nostrud exerci tation ullamcorper suscipit lobortis nisl ut aliquip ex ea commodo consequat.Nam liber tempor cum soluta nobis eleifend option congue nihil imperdiet doming id quod mazim placerat facer possim assum. Typi non habent claritatem insitam; est usus legentis in iis qui facit eorum claritatem. Investigationes demonstraverunt lectores legere me lius quod ii legunt saepius.
44 |
45 | 46 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /examples/whitelist.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | Hallo example 18 | 19 | 20 |

Editables have not been modified

21 | 22 |
23 |

Hello World Test 123

24 |
25 | 26 | 58 | 59 | 60 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hallo", 3 | "description": "Simple rich text editor", 4 | "author": "Henri Bergius ", 5 | "homepage": "http://hallojs.org", 6 | "license": "MIT", 7 | "repository": { 8 | "type": "git", 9 | "url": "git://github.com/bergie/hallo.git" 10 | }, 11 | "version": "1.1.1", 12 | "dependencies": {}, 13 | "devDependencies": { 14 | "grunt": "~1.0.1", 15 | "grunt-contrib-uglify": "~3.1.0", 16 | "grunt-contrib-concat": "~1.0.1", 17 | "grunt-contrib-qunit": "~2.0.0", 18 | "grunt-contrib-coffee": "~1.0.0", 19 | "grunt-coffeelint": "0.0.16", 20 | "grunt-contrib-clean": "~1.1.0", 21 | "grunt-contrib-jshint": "~1.1.0", 22 | "grunt-contrib-connect": "~1.0.2", 23 | "grunt-saucelabs": "^9.0.0", 24 | "grunt-bower-install-simple": "^1.0.2" 25 | }, 26 | "docco_husky": { 27 | "output_dir": "docs", 28 | "project_name": "Hallo Editor" 29 | }, 30 | "scripts": { 31 | "test": "grunt test" 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/hallo.coffee: -------------------------------------------------------------------------------- 1 | ### 2 | Hallo {{ VERSION }} - a rich text editing jQuery UI widget 3 | (c) 2011 Henri Bergius, IKS Consortium 4 | Hallo may be freely distributed under the MIT license 5 | http://hallojs.org 6 | ### 7 | ((jQuery) -> 8 | # Hallo provides a jQuery UI widget `hallo`. Usage: 9 | # 10 | # jQuery('p').hallo(); 11 | # 12 | # Getting out of the editing state: 13 | # 14 | # jQuery('p').hallo({editable: false}); 15 | # 16 | # When content is in editable state, users can just click on 17 | # an editable element in order to start modifying it. This 18 | # relies on browser having support for the HTML5 contentEditable 19 | # functionality, which means that some mobile browsers are not 20 | # supported. 21 | # 22 | # If plugins providing toolbar buttons have been enabled for 23 | # Hallo, then a toolbar will be rendered when an area is active. 24 | # 25 | # ## Toolbar 26 | # 27 | # Hallo ships with different toolbar options, including: 28 | # 29 | # * `halloToolbarContextual`: a toolbar that appears as a popover 30 | # dialog when user makes a selection 31 | # * `halloToolbarFixed`: a toolbar that is constantly visible above 32 | # the editable area when the area is activated 33 | # 34 | # The toolbar can be defined by the `toolbar` configuration key, 35 | # which has to conform to the toolbar widget being used. 36 | # 37 | # Just like with plugins, it is possible to use Hallo with your own 38 | # custom toolbar implementation. 39 | # 40 | # ## Events 41 | # 42 | # The Hallo editor provides several jQuery events that web 43 | # applications can use for integration: 44 | # 45 | # ### Activated 46 | # 47 | # When user activates an editable (usually by clicking or tabbing 48 | # to an editable element), a `halloactivated` event will be fired. 49 | # 50 | # jQuery('p').on('halloactivated', function() { 51 | # console.log("Activated"); 52 | # }); 53 | # 54 | # ### Deactivated 55 | # 56 | # When user gets out of an editable element, a `hallodeactivated` 57 | # event will be fired. 58 | # 59 | # jQuery('p').on('hallodeactivated', function() { 60 | # console.log("Deactivated"); 61 | # }); 62 | # 63 | # ### Modified 64 | # 65 | # When contents in an editable have been modified, a 66 | # `hallomodified` event will be fired. 67 | # 68 | # jQuery('p').on('hallomodified', function(event, data) { 69 | # console.log("New contents are " + data.content); 70 | # }); 71 | # 72 | # ### Restored 73 | # 74 | # When contents are restored through calling 75 | # `.hallo("restoreOriginalContent")` or the user pressing ESC while 76 | # the cursor is in the editable element, a 'hallorestored' event will 77 | # be fired. 78 | # 79 | # jQuery('p').on('hallorestored', function(event, data) { 80 | # console.log("The thrown contents are " + data.thrown); 81 | # console.log("The restored contents are " + data.content); 82 | # }); 83 | # 84 | jQuery.widget 'IKS.hallo', 85 | toolbar: null 86 | bound: false 87 | originalContent: '' 88 | previousContent: '' 89 | uuid: '' 90 | selection: null 91 | _keepActivated: false 92 | originalHref: null 93 | 94 | options: 95 | editable: true 96 | plugins: {} 97 | toolbar: 'halloToolbarContextual' 98 | parentElement: 'body' 99 | buttonCssClass: null 100 | toolbarCssClass: null 101 | toolbarPositionAbove: false 102 | toolbarOptions: {} 103 | placeholder: '' 104 | forceStructured: true 105 | checkTouch: true 106 | touchScreen: null 107 | 108 | _create: -> 109 | @id = @_generateUUID() 110 | 111 | @checkTouch() if @options.checkTouch and @options.touchScreen is null 112 | 113 | for plugin, options of @options.plugins 114 | options = {} unless jQuery.isPlainObject options 115 | jQuery.extend options, 116 | editable: this 117 | uuid: @id 118 | buttonCssClass: @options.buttonCssClass 119 | jQuery(@element)[plugin] options 120 | 121 | @element.one 'halloactivated', => 122 | # We will populate the toolbar the first time this 123 | # editable is activated. This will make multiple 124 | # Hallo instances on same page load much faster 125 | @_prepareToolbar() 126 | 127 | @originalContent = @getContents() 128 | 129 | _init: -> 130 | if @options.editable 131 | @enable() 132 | else 133 | @disable() 134 | 135 | destroy: -> 136 | @disable() 137 | 138 | if @toolbar 139 | @toolbar.remove() 140 | @element[@options.toolbar] 'destroy' 141 | 142 | for plugin, options of @options.plugins 143 | jQuery(@element)[plugin] 'destroy' 144 | 145 | jQuery.Widget::destroy.call @ 146 | 147 | # Disable an editable 148 | disable: -> 149 | @element.attr "contentEditable", false 150 | @element.off "focus", @_activated 151 | @element.off "blur", @_deactivated 152 | @element.off "keyup paste change", @_checkModified 153 | @element.off "keyup", @_keys 154 | @element.off "keyup mouseup", @_checkSelection 155 | @bound = false 156 | 157 | jQuery(@element).removeClass 'isModified' 158 | jQuery(@element).removeClass 'inEditMode' 159 | 160 | @element.parents('a').addBack().each (idx, elem) => 161 | element = jQuery elem 162 | return unless element.is 'a' 163 | return unless @originalHref 164 | element.attr 'href', @originalHref 165 | 166 | @_trigger "disabled", null 167 | 168 | # Enable an editable 169 | enable: -> 170 | @element.parents('a[href]').addBack().each (idx, elem) => 171 | element = jQuery elem 172 | return unless element.is 'a[href]' 173 | @originalHref = element.attr 'href' 174 | element.removeAttr 'href' 175 | 176 | @element.attr "contentEditable", true 177 | 178 | unless jQuery.parseHTML(@element.html()) 179 | @element.html this.options.placeholder 180 | jQuery(@element).addClass 'inPlaceholderMode' 181 | @element.css 182 | 'min-width': @element.innerWidth() 183 | 'min-height': @element.innerHeight() 184 | 185 | unless @bound 186 | @element.on "focus", this, @_activated 187 | @element.on "blur", this, @_deactivated 188 | @element.on "keyup paste change", this, @_checkModified 189 | @element.on "keyup", this, @_keys 190 | @element.on "keyup mouseup", this, @_checkSelection 191 | @bound = true 192 | 193 | @_forceStructured() if @options.forceStructured 194 | 195 | @_trigger "enabled", null 196 | 197 | # Activate an editable for editing 198 | activate: -> 199 | @element.focus() 200 | 201 | # Checks whether the editable element contains the current selection 202 | containsSelection: -> 203 | range = @getSelection() 204 | return @element.has(range.startContainer).length > 0 205 | 206 | # Only supports one range for now (i.e. no multiselection) 207 | getSelection: -> 208 | sel = rangy.getSelection() 209 | range = null 210 | if sel.rangeCount > 0 211 | range = sel.getRangeAt(0) 212 | else 213 | range = rangy.createRange() 214 | return range 215 | 216 | restoreSelection: (range) -> 217 | sel = rangy.getSelection() 218 | sel.setSingleRange(range) 219 | 220 | replaceSelection: (cb) -> 221 | if navigator.appName is 'Microsoft Internet Explorer' 222 | t = document.selection.createRange().text 223 | r = document.selection.createRange() 224 | r.pasteHTML(cb(t)) 225 | else 226 | sel = window.getSelection() 227 | range = sel.getRangeAt(0) 228 | newTextNode = document.createTextNode(cb(range.extractContents())) 229 | range.insertNode(newTextNode) 230 | range.setStartAfter(newTextNode) 231 | sel.removeAllRanges() 232 | sel.addRange(range) 233 | 234 | removeAllSelections: () -> 235 | if navigator.appName is 'Microsoft Internet Explorer' 236 | range.empty() 237 | else 238 | window.getSelection().removeAllRanges() 239 | 240 | getPluginInstance: (plugin) -> 241 | # jQuery UI 1.10 or newer 242 | instance = jQuery(@element).data "IKS-#{plugin}" 243 | return instance if instance 244 | # Older jQuery UI 245 | instance = jQuery(@element).data plugin 246 | return instance if instance 247 | throw new Error "Plugin #{plugin} not found" 248 | 249 | # Get contents of an editable as HTML string 250 | getContents: -> 251 | for plugin of @options.plugins 252 | instance = @getPluginInstance(plugin) 253 | continue unless instance 254 | cleanup = instance.cleanupContentClone 255 | continue unless jQuery.isFunction cleanup 256 | jQuery(@element)[plugin] 'cleanupContentClone', @element 257 | @element.html() 258 | 259 | # Set the contents of an editable 260 | setContents: (contents) -> 261 | @element.html contents 262 | 263 | # Check whether the editable has been modified 264 | isModified: -> 265 | @previousContent = @originalContent unless @previousContent 266 | @previousContent isnt @getContents() 267 | 268 | # Set the editable as unmodified 269 | setUnmodified: -> 270 | jQuery(@element).removeClass 'isModified' 271 | @previousContent = @getContents() 272 | 273 | # Set the editable as modified 274 | setModified: -> 275 | jQuery(@element).addClass 'isModified' 276 | @._trigger 'modified', null, 277 | editable: @ 278 | content: @getContents() 279 | 280 | # Restore the content original 281 | restoreOriginalContent: () -> 282 | @element.html(@originalContent) 283 | 284 | # Execute a contentEditable command 285 | execute: (command, value) -> 286 | if document.execCommand command, false, value 287 | @element.trigger "change" 288 | 289 | protectFocusFrom: (el) -> 290 | el.on "mousedown", (event) => 291 | event.preventDefault() 292 | @_protectToolbarFocus = true 293 | setTimeout => 294 | @_protectToolbarFocus = false 295 | , 300 296 | 297 | keepActivated: (@_keepActivated) -> 298 | 299 | _generateUUID: -> 300 | S4 = -> 301 | ((1 + Math.random()) * 0x10000|0).toString(16).substring 1 302 | "#{S4()}#{S4()}-#{S4()}-#{S4()}-#{S4()}-#{S4()}#{S4()}#{S4()}" 303 | 304 | _prepareToolbar: -> 305 | @toolbar = jQuery('
').hide() 306 | @toolbar.addClass @options.toolbarCssClass if @options.toolbarCssClass 307 | 308 | defaults = 309 | editable: @ 310 | parentElement: @options.parentElement 311 | toolbar: @toolbar 312 | positionAbove: @options.toolbarPositionAbove 313 | 314 | toolbarOptions = jQuery.extend({}, defaults, @options.toolbarOptions) 315 | @element[@options.toolbar] toolbarOptions 316 | 317 | for plugin of @options.plugins 318 | instance = @getPluginInstance(plugin) 319 | continue unless instance 320 | populate = instance.populateToolbar 321 | continue unless jQuery.isFunction populate 322 | @element[plugin] 'populateToolbar', @toolbar 323 | 324 | @element[@options.toolbar] 'setPosition' 325 | @protectFocusFrom @toolbar 326 | 327 | changeToolbar: (element, toolbar, hide = false) -> 328 | originalToolbar = @options.toolbar 329 | 330 | @options.parentElement = element 331 | @options.toolbar = toolbar if toolbar 332 | 333 | return unless @toolbar 334 | @element[originalToolbar] 'destroy' 335 | do @toolbar.remove 336 | do @_prepareToolbar 337 | 338 | @toolbar.hide() if hide 339 | 340 | _checkModified: (event) -> 341 | widget = event.data 342 | widget.setModified() if widget.isModified() 343 | 344 | _keys: (event) -> 345 | widget = event.data 346 | if event.keyCode == 27 347 | old = widget.getContents() 348 | widget.restoreOriginalContent(event) 349 | widget._trigger "restored", null, 350 | editable: widget 351 | content: widget.getContents() 352 | thrown: old 353 | 354 | widget.turnOff() 355 | 356 | _rangesEqual: (r1, r2) -> 357 | return false unless r1.startContainer is r2.startContainer 358 | return false unless r1.startOffset is r2.startOffset 359 | return false unless r1.endContainer is r2.endContainer 360 | return false unless r1.endOffset is r2.endOffset 361 | true 362 | 363 | # Check if some text is selected, and if this selection has changed. 364 | # If it changed, trigger the "halloselected" event 365 | _checkSelection: (event) -> 366 | if event.keyCode == 27 367 | return 368 | 369 | widget = event.data 370 | 371 | # The mouseup event triggers before the text selection is updated. 372 | # I did not find a better solution than setTimeout in 0 ms 373 | setTimeout -> 374 | sel = widget.getSelection() 375 | if widget._isEmptySelection(sel) or widget._isEmptyRange(sel) 376 | if widget.selection 377 | widget.selection = null 378 | widget._trigger "unselected", null, 379 | editable: widget 380 | originalEvent: event 381 | return 382 | 383 | if !widget.selection or not widget._rangesEqual sel, widget.selection 384 | widget.selection = sel.cloneRange() 385 | widget._trigger "selected", null, 386 | editable: widget 387 | selection: widget.selection 388 | ranges: [widget.selection] 389 | originalEvent: event 390 | , 0 391 | 392 | _isEmptySelection: (selection) -> 393 | if selection.type is "Caret" 394 | return true 395 | return false 396 | 397 | _isEmptyRange: (range) -> 398 | if range.collapsed 399 | return true 400 | if range.isCollapsed 401 | return range.isCollapsed() if typeof range.isCollapsed is 'function' 402 | return range.isCollapsed 403 | 404 | return false 405 | 406 | turnOn: () -> 407 | if this.getContents() is this.options.placeholder 408 | this.setContents '' 409 | 410 | jQuery(@element).removeClass 'inPlaceholderMode' 411 | jQuery(@element).addClass 'inEditMode' 412 | @_trigger "activated", null, @ 413 | 414 | turnOff: () -> 415 | jQuery(@element).removeClass 'inEditMode' 416 | @_trigger "deactivated", null, @ 417 | 418 | unless @getContents() 419 | jQuery(@element).addClass 'inPlaceholderMode' 420 | @setContents @options.placeholder 421 | 422 | _activated: (event) -> 423 | event.data.turnOn() 424 | 425 | _deactivated: (event) -> 426 | return if event.data._keepActivated 427 | 428 | unless event.data._protectToolbarFocus is true 429 | event.data.turnOff() 430 | else 431 | setTimeout -> 432 | jQuery(event.data.element).focus() 433 | , 300 434 | 435 | _forceStructured: (event) -> 436 | try 437 | document.execCommand 'styleWithCSS', 0, false 438 | catch e 439 | try 440 | document.execCommand 'useCSS', 0, true 441 | catch e 442 | try 443 | document.execCommand 'styleWithCSS', false, false 444 | catch e 445 | 446 | checkTouch: -> 447 | @options.touchScreen = !!('createTouch' of document) 448 | 449 | )(jQuery) 450 | -------------------------------------------------------------------------------- /src/plugins/annotate.coffee: -------------------------------------------------------------------------------- 1 | ((jQuery) -> 2 | z = null 3 | if @VIE isnt undefined 4 | z = new VIE 5 | z.use new z.StanbolService 6 | proxyDisabled: true 7 | url : 'http://dev.iks-project.eu:8081', 8 | 9 | jQuery.widget 'IKS.halloannotate', 10 | options: 11 | vie: z 12 | editable: null 13 | toolbar: null 14 | uuid: '' 15 | select: -> 16 | decline: -> 17 | remove: -> 18 | buttonCssClass: null 19 | 20 | _create: -> 21 | widget = @ 22 | if @options.vie is undefined 23 | throw new Error 'The halloannotate plugin requires VIE' 24 | return 25 | unless typeof @element.annotate is 'function' 26 | throw new Error 'The halloannotate plugin requires annotate.js' 27 | return 28 | 29 | # states are off, working, on 30 | @state = 'off' 31 | 32 | @instantiate() 33 | 34 | turnOffAnnotate = -> 35 | editable = @ 36 | jQuery(editable).halloannotate 'turnOff' 37 | editableElement = @options.editable.element 38 | editableElement.on 'hallodisabled', turnOffAnnotate 39 | 40 | populateToolbar: (toolbar) -> 41 | buttonHolder = jQuery "" 42 | @button = buttonHolder.hallobutton 43 | label: 'Annotate' 44 | icon: 'fa-tags' 45 | editable: @options.editable 46 | command: null 47 | uuid: @options.uuid 48 | cssClass: @options.buttonCssClass 49 | queryState: false 50 | 51 | buttonHolder.on 'change', (event) => 52 | return if @state is "pending" 53 | return @turnOn() if @state is "off" 54 | @turnOff() 55 | 56 | buttonHolder.buttonset() 57 | 58 | toolbar.append @button 59 | 60 | cleanupContentClone: (el) -> 61 | if @state is 'on' 62 | el.find(".entity:not([about])").each () -> 63 | jQuery(@).replaceWith jQuery(@).html() 64 | 65 | instantiate: -> 66 | widget = @ 67 | @options.editable.element.annotate 68 | vie: @options.vie 69 | debug: false 70 | showTooltip: true 71 | select: @options.select 72 | remove: @options.remove 73 | success: @options.success 74 | error: @options.error 75 | .on 'annotateselect', (event, data) -> 76 | widget.options.editable.setModified() 77 | # console.info @, arguments 78 | .on 'annotateremove', -> 79 | jQuery.noop() 80 | # console.info @, arguments 81 | 82 | turnPending: -> 83 | @state = 'pending' 84 | @button.hallobutton 'checked', false 85 | @button.hallobutton 'disable' 86 | 87 | turnOn: -> 88 | @turnPending() 89 | widget = @ 90 | try 91 | @options.editable.element.annotate 'enable', (success) => 92 | return unless success 93 | @state = 'on' 94 | @button.hallobutton 'checked', true 95 | @button.hallobutton 'enable' 96 | catch e 97 | alert e 98 | 99 | turnOff: -> 100 | @options.editable.element.annotate 'disable' 101 | @state = 'off' 102 | return unless @button 103 | @button.attr 'checked', false 104 | @button.find("label").removeClass "ui-state-clicked" 105 | @button.button 'refresh' 106 | )(jQuery) 107 | -------------------------------------------------------------------------------- /src/plugins/blacklist.coffee: -------------------------------------------------------------------------------- 1 | # Hallo - a rich text editing jQuery UI widget 2 | # (c) 2012 Henri Bergius, IKS Consortium 3 | # Hallo may be freely distributed under the MIT license 4 | ((jQuery) -> 5 | jQuery.widget 'IKS.halloblacklist', 6 | options: 7 | tags: [] 8 | 9 | _init: -> 10 | unless @options.tags.indexOf('br') is -1 11 | # Prevent 'enter' key if
is blacklisted 12 | @element.on 'keydown', (event) -> 13 | event.preventDefault() if event.originalEvent.keyCode is 13 14 | 15 | cleanupContentClone: (el) -> 16 | for tag in @options.tags 17 | jQuery(tag, el).remove() 18 | 19 | ) jQuery 20 | -------------------------------------------------------------------------------- /src/plugins/block.coffee: -------------------------------------------------------------------------------- 1 | # Hallo - a rich text editing jQuery UI widget 2 | # (c) 2011 Henri Bergius, IKS Consortium 3 | # Hallo may be freely distributed under the MIT license 4 | ((jQuery) -> 5 | jQuery.widget 'IKS.halloblock', 6 | options: 7 | editable: null 8 | toolbar: null 9 | uuid: '' 10 | elements: [ 11 | 'h1' 12 | 'h2' 13 | 'h3' 14 | 'p' 15 | 'pre' 16 | 'blockquote' 17 | ] 18 | buttonCssClass: null 19 | 20 | populateToolbar: (toolbar) -> 21 | buttonset = jQuery "" 22 | contentId = "#{@options.uuid}-#{@widgetName}-data" 23 | target = @_prepareDropdown contentId 24 | toolbar.append buttonset 25 | buttonset.hallobuttonset() 26 | buttonset.append target 27 | buttonset.append @_prepareButton target 28 | 29 | _prepareDropdown: (contentId) -> 30 | contentArea = jQuery "
" 31 | 32 | containingElement = @options.editable.element.get(0).tagName.toLowerCase() 33 | 34 | addElement = (element) => 35 | el = jQuery "" 38 | 39 | if containingElement is element 40 | el.addClass 'selected' 41 | 42 | unless containingElement is 'div' 43 | el.addClass 'disabled' 44 | 45 | el.on 'click', => 46 | tagName = element.toUpperCase() 47 | if el.hasClass 'disabled' 48 | return 49 | if navigator.appName is 'Microsoft Internet Explorer' 50 | # In IE FormatBlock wants tags inside brackets 51 | @options.editable.execute 'FormatBlock', "<#{tagName}>" 52 | return 53 | @options.editable.execute 'formatBlock', tagName 54 | 55 | queryState = (event) => 56 | block = document.queryCommandValue 'formatBlock' 57 | if block.toLowerCase() is element 58 | el.addClass 'selected' 59 | return 60 | el.removeClass 'selected' 61 | 62 | events = 'keyup paste change mouseup' 63 | @options.editable.element.on events, queryState 64 | 65 | @options.editable.element.on 'halloenabled', => 66 | @options.editable.element.on events, queryState 67 | @options.editable.element.on 'hallodisabled', => 68 | @options.editable.element.off events, queryState 69 | 70 | el 71 | 72 | for element in @options.elements 73 | contentArea.append addElement element 74 | contentArea 75 | 76 | _prepareButton: (target) -> 77 | buttonElement = jQuery '' 78 | buttonElement.hallodropdownbutton 79 | uuid: @options.uuid 80 | editable: @options.editable 81 | label: 'block' 82 | icon: 'fa-text-height' 83 | target: target 84 | cssClass: @options.buttonCssClass 85 | buttonElement 86 | 87 | )(jQuery) 88 | -------------------------------------------------------------------------------- /src/plugins/cleanhtml.coffee: -------------------------------------------------------------------------------- 1 | # Hallo - a rich text editing jQuery UI widget 2 | # (c) 2012 Henri Bergius, IKS Consortium 3 | # Hallo may be freely distributed under the MIT license 4 | 5 | # This plugin will tidy up pasted content with help of 6 | # the jquery-clean plugin (https://code.google.com/p/jquery-clean/). 7 | # Also the selection save and restore module from rangy 8 | # (https://code.google.com/p/rangy/wiki/SelectionSaveRestoreModule) 9 | # is required in order to resolve cross browser bugs for pasting. 10 | # The plugins have to be accessible or an error will be thrown. 11 | # 12 | # Usage (example): 13 | # 14 | #jQuery('.editable').hallo({ 15 | # plugins: { 16 | # 'hallocleanhtml': { 17 | # format: false, 18 | # allowedTags: [ 19 | # 'p', 20 | # 'em', 21 | # 'strong', 22 | # 'br', 23 | # 'div', 24 | # 'ol', 25 | # 'ul', 26 | # 'li', 27 | # 'a'], 28 | # allowedAttributes: ['style'] 29 | # } 30 | # }, 31 | # }); 32 | # 33 | # The plugin options correspond to the available jquery-clean plugin options. 34 | # 35 | # Tested in IE 10 + 9, Chrome 25, FF 19 36 | 37 | ((jQuery) -> 38 | rangyMessage = 'The hallocleanhtml plugin requires the selection save and 39 | restore module from Rangy' 40 | jQuery.widget 'IKS.hallocleanhtml', 41 | 42 | _create: -> 43 | if jQuery.htmlClean is undefined 44 | throw new Error 'The hallocleanhtml plugin requires jQuery.htmlClean' 45 | return 46 | 47 | editor = this.element 48 | 49 | # bind paste handler on first call 50 | editor.bind 'paste', this, (event) => 51 | 52 | # TODO: find out why this check always fails when placed directly 53 | # after jQuery.htmlClean check 54 | if rangy.saveSelection is undefined 55 | throw new Error rangyMessage 56 | return 57 | 58 | widget = event.data 59 | # bugfix for overwriting selected text in ie 60 | widget.options.editable.getSelection().deleteContents() 61 | lastRange = rangy.saveSelection() 62 | 63 | # make sure content will be pasted _empty_ editor and save old contents 64 | # (because we cannot access clipboard data in all browsers) 65 | lastContent = editor.html() 66 | editor.html '' 67 | 68 | setTimeout => 69 | 70 | pasted = editor.html() 71 | cleanPasted = jQuery.htmlClean pasted, @options 72 | 73 | #console.log "content before: " + lastContent 74 | #console.log "pasted content: " + pasted 75 | #console.log "tidy pasted content: " + cleanPasted 76 | 77 | # back in timne to the state before pasting 78 | editor.html lastContent 79 | rangy.restoreSelection lastRange 80 | 81 | # paste tidy pasted content back 82 | # TODO: set cursor _behind_ pasted content 83 | if cleanPasted != '' 84 | try 85 | document.execCommand 'insertHTML', false, cleanPasted 86 | catch error 87 | # most likely ie 88 | range = widget.options.editable.getSelection() 89 | range.insertNode range.createContextualFragment(cleanPasted) 90 | , 4 91 | 92 | ) jQuery 93 | -------------------------------------------------------------------------------- /src/plugins/halloformat.coffee: -------------------------------------------------------------------------------- 1 | # Hallo - a rich text editing jQuery UI widget 2 | # (c) 2011 Henri Bergius, IKS Consortium 3 | # Hallo may be freely distributed under the MIT license 4 | ((jQuery) -> 5 | jQuery.widget "IKS.halloformat", 6 | options: 7 | editable: null 8 | uuid: '' 9 | formattings: 10 | bold: true 11 | italic: true 12 | strikeThrough: false 13 | underline: false 14 | buttonCssClass: null 15 | 16 | populateToolbar: (toolbar) -> 17 | widget = this 18 | buttonset = jQuery "" 19 | 20 | buttonize = (format) => 21 | buttonHolder = jQuery '' 22 | buttonHolder.hallobutton 23 | label: format 24 | editable: @options.editable 25 | command: format 26 | uuid: @options.uuid 27 | cssClass: @options.buttonCssClass 28 | buttonset.append buttonHolder 29 | 30 | for format, enabled of @options.formattings 31 | continue unless enabled 32 | buttonize format 33 | 34 | buttonset.hallobuttonset() 35 | toolbar.append buttonset 36 | )(jQuery) 37 | -------------------------------------------------------------------------------- /src/plugins/headings.coffee: -------------------------------------------------------------------------------- 1 | # Hallo - a rich text editing jQuery UI widget 2 | # (c) 2011 Henri Bergius, IKS Consortium 3 | # Hallo may be freely distributed under the MIT license 4 | ((jQuery) -> 5 | jQuery.widget "IKS.halloheadings", 6 | options: 7 | editable: null 8 | uuid: '' 9 | formatBlocks: ["p", "h1", "h2", "h3"] 10 | buttonCssClass: null 11 | 12 | populateToolbar: (toolbar) -> 13 | widget = this 14 | buttonset = jQuery "" 15 | ie = navigator.appName is 'Microsoft Internet Explorer' 16 | command = (if ie then "FormatBlock" else "formatBlock") 17 | 18 | buttonize = (format) => 19 | buttonHolder = jQuery '' 20 | buttonHolder.hallobutton 21 | label: format 22 | editable: @options.editable 23 | command: command 24 | commandValue: (if ie then "<#{format}>" else format) 25 | uuid: @options.uuid 26 | cssClass: @options.buttonCssClass 27 | queryState: (event) -> 28 | try 29 | value = document.queryCommandValue command 30 | if ie 31 | map = { p: "normal" } 32 | for val in [1,2,3,4,5,6] 33 | map["h#{val}"] = val 34 | compared = value.match(new RegExp(map[format],"i")) 35 | else 36 | compared = value.match(new RegExp(format,"i")) 37 | 38 | result = if compared then true else false 39 | buttonHolder.hallobutton('checked', result) 40 | catch e 41 | return 42 | buttonHolder.find('button .ui-button-text').text(format.toUpperCase()) 43 | buttonset.append buttonHolder 44 | 45 | for format in @options.formatBlocks 46 | buttonize format 47 | 48 | buttonset.hallobuttonset() 49 | toolbar.append buttonset 50 | )(jQuery) 51 | -------------------------------------------------------------------------------- /src/plugins/html.coffee: -------------------------------------------------------------------------------- 1 | ((jQuery) -> 2 | jQuery.widget "IKS.hallohtml", 3 | options: 4 | editable: null 5 | toolbar: null 6 | uuid: "" 7 | lang: 'en' 8 | dialogOpts: 9 | autoOpen: false 10 | width: 600 11 | height: 'auto' 12 | modal: false 13 | resizable: true 14 | draggable: true 15 | dialogClass: 'htmledit-dialog' 16 | dialog: null 17 | buttonCssClass: null 18 | 19 | translations: 20 | en: 21 | title: 'Edit HTML' 22 | update: 'Update' 23 | de: 24 | title: 'HTML bearbeiten' 25 | update: 'Aktualisieren' 26 | 27 | texts: null 28 | 29 | 30 | populateToolbar: ($toolbar) -> 31 | widget = this 32 | 33 | @texts = @translations[@options.lang] 34 | 35 | @options.toolbar = $toolbar 36 | selector = "#{@options.uuid}-htmledit-dialog" 37 | @options.dialog = jQuery("
").attr 'id', selector 38 | 39 | $buttonset = jQuery("").addClass widget.widgetName 40 | 41 | id = "#{@options.uuid}-htmledit" 42 | $buttonHolder = jQuery '' 43 | $buttonHolder.hallobutton 44 | label: @texts.title 45 | icon: 'fa-list-alt' 46 | editable: @options.editable 47 | command: null 48 | queryState: false 49 | uuid: @options.uuid 50 | cssClass: @options.buttonCssClass 51 | $buttonset.append $buttonHolder 52 | 53 | @button = $buttonHolder 54 | @button.click -> 55 | if widget.options.dialog.dialog "isOpen" 56 | widget._closeDialog() 57 | else 58 | widget._openDialog() 59 | false 60 | 61 | @options.editable.element.on "hallodeactivated", -> 62 | widget._closeDialog() 63 | 64 | $toolbar.append $buttonset 65 | 66 | @options.dialog.dialog(@options.dialogOpts) 67 | @options.dialog.dialog("option", "title", @texts.title) 68 | 69 | 70 | _openDialog: -> 71 | 72 | widget = this 73 | 74 | $editableEl = jQuery @options.editable.element 75 | xposition = $editableEl.offset().left + $editableEl.outerWidth() + 10 76 | yposition = @options.toolbar.offset().top - jQuery(document).scrollTop() 77 | @options.dialog.dialog("option", "position", [xposition, yposition]) 78 | 79 | @options.editable.keepActivated true 80 | @options.dialog.dialog("open") 81 | 82 | @options.dialog.on 'dialogclose', => 83 | jQuery('label', @button).removeClass 'ui-state-active' 84 | @options.editable.element.focus() 85 | @options.editable.keepActivated false 86 | 87 | @options.dialog.html jQuery("