├── .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 | 
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 [](http://travis-ci.org/bergie/hallo) [](https://greenkeeper.io/)
2 | =====================================
3 |
4 | 
5 |
6 | [](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 | Enable
21 | Disable
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 | 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.
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 |
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 | Enable
29 | Disable
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 | Enable
25 | Disable
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 | 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.
41 | 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.
42 |
43 |
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 "
36 | <#{element} class=\"menu-item\">#{element}#{element}>
37 | "
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("