2 * (C) Copyright 2004-2007 Shawn Betts
3 * (C) Copyright 2007-2009,2011-2012 John J. Foerch
4 * (C) Copyright 2007-2008 Jeremy Maitin-Shepard
6 * Use, modification, and distribution are subject to the terms specified in the
11 require("load-spec.js");
12 require("history.js");
14 define_variable("homepage", "chrome://conkeror-help/content/help.html",
15 "The url loaded by default for new content buffers.");
17 define_buffer_local_hook("content_buffer_finished_loading_hook");
18 define_buffer_local_hook("content_buffer_started_loading_hook");
19 define_buffer_local_hook("content_buffer_progress_change_hook");
20 define_buffer_local_hook("content_buffer_location_change_hook");
21 define_buffer_local_hook("content_buffer_status_change_hook");
22 define_buffer_local_hook("content_buffer_focus_change_hook");
23 define_buffer_local_hook("content_buffer_dom_link_added_hook");
24 define_buffer_local_hook("content_buffer_popup_blocked_hook");
26 define_current_buffer_hook("current_content_buffer_finished_loading_hook", "content_buffer_finished_loading_hook");
27 define_current_buffer_hook("current_content_buffer_progress_change_hook", "content_buffer_progress_change_hook");
28 define_current_buffer_hook("current_content_buffer_location_change_hook", "content_buffer_location_change_hook");
29 define_current_buffer_hook("current_content_buffer_status_change_hook", "content_buffer_status_change_hook");
30 define_current_buffer_hook("current_content_buffer_focus_change_hook", "content_buffer_focus_change_hook");
33 function content_buffer_modality (buffer
) {
34 var elem
= buffer
.focused_element
;
35 function push_keymaps (tag
) {
36 buffer
.content_modalities
.map(
39 buffer
.keymaps
.push(m
[tag
]);
43 push_keymaps('normal');
45 let p
= elem
.parentNode
;
46 while (p
&& !(p
instanceof Ci
.nsIDOMHTMLFormElement
))
51 if (elem
instanceof Ci
.nsIDOMHTMLInputElement
) {
52 var type
= (elem
.getAttribute("type") || "").toLowerCase();
53 if ({checkbox
:1, radio
:1, submit
:1, reset
:1}[type
])
54 return push_keymaps(type
);
56 return push_keymaps('text');
58 if (elem
instanceof Ci
.nsIDOMHTMLTextAreaElement
)
59 return push_keymaps('textarea');
60 if (elem
instanceof Ci
.nsIDOMHTMLSelectElement
)
61 return push_keymaps('select');
62 if (elem
instanceof Ci
.nsIDOMHTMLAnchorElement
)
63 return push_keymaps('anchor');
64 if (elem
instanceof Ci
.nsIDOMHTMLButtonElement
)
65 return push_keymaps('button');
66 if (elem
instanceof Ci
.nsIDOMHTMLEmbedElement
||
67 elem
instanceof Ci
.nsIDOMHTMLObjectElement
)
69 return push_keymaps('embed');
71 var frame
= buffer
.focused_frame
;
72 if (frame
&& frame
.document
.designMode
&&
73 frame
.document
.designMode
== "on")
75 return push_keymaps('richedit');
78 switch (elem
.contentEditable
) {
80 return push_keymaps('richedit');
84 elem
= elem
.parentNode
;
91 define_keywords("$load");
92 function content_buffer (window
) {
94 this.constructor_begin();
96 conkeror
.buffer
.call(this, window
, forward_keywords(arguments
));
98 this.browser
.addProgressListener(this);
100 this.browser
.addEventListener("DOMTitleChanged", function (event
) {
101 buffer_title_change_hook
.run(buffer
);
102 }, true /* capture */);
104 this.browser
.addEventListener("scroll", function (event
) {
105 buffer_scroll_hook
.run(buffer
);
106 }, true /* capture */);
108 this.browser
.addEventListener("focus", function (event
) {
109 content_buffer_focus_change_hook
.run(buffer
, event
);
110 }, true /* capture */);
112 this.browser
.addEventListener("DOMLinkAdded", function (event
) {
113 content_buffer_dom_link_added_hook
.run(buffer
, event
);
114 }, true /* capture */);
116 this.browser
.addEventListener("DOMPopupBlocked", function (event
) {
117 dumpln("Blocked popup: " + event
.popupWindowURI
.spec
);
118 content_buffer_popup_blocked_hook
.run(buffer
, event
);
119 }, true /* capture */);
121 this.page_modes
= [];
123 this.ignore_initial_blank
= true;
125 var lspec
= arguments
.$load
;
127 if (load_spec_uri_string(lspec
) == "about:blank")
128 this.ignore_initial_blank
= false;
130 /* Ensure that an existing load of about:blank is stopped */
131 this.web_navigation
.stop(Ci
.nsIWebNavigation
.STOP_ALL
);
137 this.modalities
.push(content_buffer_modality
);
138 this.content_modalities
= [{
139 normal
: content_buffer_normal_keymap
,
140 form
: content_buffer_form_keymap
,
141 checkbox
: content_buffer_checkbox_keymap
,
142 radio
: content_buffer_checkbox_keymap
,
143 submit
: content_buffer_button_keymap
,
144 reset
: content_buffer_button_keymap
,
145 text
: content_buffer_text_keymap
,
146 textarea
: content_buffer_textarea_keymap
,
147 select
: content_buffer_select_keymap
,
148 anchor
: content_buffer_anchor_keymap
,
149 button
: content_buffer_button_keymap
,
150 embed
: content_buffer_embed_keymap
,
151 richedit
: content_buffer_richedit_keymap
154 this.constructor_end();
157 content_buffer
.prototype = {
158 constructor: content_buffer
,
159 toString: function () "#<content_buffer>",
161 destroy: function () {
162 this.browser
.removeProgressListener(this);
163 buffer
.prototype.destroy
.call(this);
166 content_modalities
: null,
168 get scrollX () { return this.top_frame
.scrollX
; },
169 get scrollY () { return this.top_frame
.scrollY
; },
170 get scrollMaxX () { return this.top_frame
.scrollMaxX
; },
171 get scrollMaxY () { return this.top_frame
.scrollMaxY
; },
173 /* Used to display the correct URI when the buffer opens initially
174 * even before loading has progressed far enough for currentURI to
175 * contain the correct URI. */
178 get display_uri_string () {
179 if (this._display_uri
)
180 return this._display_uri
;
181 if (this.current_uri
)
182 return this.current_uri
.spec
;
186 get title () { return this.browser
.contentTitle
; },
187 get description () { return this.display_uri_string
; },
189 load: function (load_spec
) {
190 apply_load_spec(this, load_spec
);
197 // nsIWebProgressListener interface
199 QueryInterface
: generate_QI(Ci
.nsIWebProgressListener
, Ci
.nsISupportsWeakReference
),
201 // This method is called to indicate state changes.
202 onStateChange: function (aWebProgress
, aRequest
, aStateFlags
, aStatus
) {
205 if (aStateFlags
& Ci
.nsIWebProgressListener
.STATE_START
) {
206 this._request_count
++;
207 } else if (aStateFlags
& Ci
.nsIWebProgressListener
.STATE_STOP
) {
208 const NS_ERROR_UNKNOWN_HOST
= 2152398878;
209 if (--this._request_count
> 0 && aStatus
== NS_ERROR_UNKNOWN_HOST
) {
210 // to prevent bug 235825: wait for the request handled
211 // by the automatic keyword resolver
214 // since we (try to) only handle STATE_STOP of the last request,
215 // the count of open requests should now be 0
216 this._request_count
= 0;
219 if (aStateFlags
& Ci
.nsIWebProgressListener
.STATE_START
&&
220 aStateFlags
& Ci
.nsIWebProgressListener
.STATE_IS_NETWORK
) {
221 // It's okay to clear what the user typed when we start
222 // loading a document. If the user types, this counter gets
223 // set to zero, if the document load ends without an
224 // onLocationChange, this counter gets decremented
225 // (so we keep it while switching tabs after failed loads)
227 content_buffer_started_loading_hook
.run(this);
228 } else if (aStateFlags
& Ci
.nsIWebProgressListener
.STATE_STOP
&&
229 aStateFlags
& Ci
.nsIWebProgressListener
.STATE_IS_NETWORK
) {
230 if (this.loading
== true) {
231 this.loading
= false;
232 content_buffer_finished_loading_hook
.run(this);
236 if (aStateFlags
& (Ci
.nsIWebProgressListener
.STATE_STOP
|
237 Ci
.nsIWebProgressListener
.STATE_START
)) {
239 this.set_default_message("Done");
243 // This method is called to indicate progress changes for the
244 // currently loading page.
245 onProgressChange: function (webProgress
, request
, curSelf
, maxSelf
,
248 content_buffer_progress_change_hook
.run(this, request
, curSelf
, maxSelf
, curTotal
, maxTotal
);
251 // This method is called to indicate a change to the current location.
252 // The url can be gotten as location.spec.
253 onLocationChange: function (webProgress
, request
, location
) {
254 /* Attempt to ignore onLocationChange calls due to the initial
255 * loading of about:blank by all xul:browser elements. */
256 if (location
.spec
== "about:blank" && this.ignore_initial_blank
)
259 this.ignore_initial_blank
= false;
261 //dumpln("spec: " + location.spec +" ;;; " + this.display_uri_string);
262 /* Use the real location URI now */
263 this._display_uri
= null;
264 this.set_input_mode();
266 local
: { __proto__
: this.local
}
268 this.default_browser_object_classes
= {};
269 content_buffer_location_change_hook
.run(this, request
, location
);
270 buffer_description_change_hook
.run(this);
273 // This method is called to indicate a status changes for the currently
274 // loading page. The message is already formatted for display.
275 // Status messages could be displayed in the minibuffer output area.
276 onStatusChange: function (webProgress
, request
, status
, msg
) {
277 this.set_default_message(msg
);
278 content_buffer_status_change_hook
.run(this, request
, status
, msg
);
281 // This method is called when the security state of the browser changes.
282 onSecurityChange: function (webProgress
, request
, state
) {
283 //FIXME: implement this.
285 const WPL = Components.interfaces.nsIWebProgressListener;
287 if (state & WPL.STATE_IS_INSECURE) {
288 // update visual indicator
290 var level = "unknown";
291 if (state & WPL.STATE_IS_SECURE) {
292 if (state & WPL.STATE_SECURE_HIGH)
294 else if (state & WPL.STATE_SECURE_MED)
296 else if (state & WPL.STATE_SECURE_LOW)
298 } else if (state & WPL_STATE_IS_BROKEN) {
301 // provide a visual indicator of the security state here.
306 /* Inherit from buffer */
307 __proto__
: buffer
.prototype
311 add_hook("current_content_buffer_finished_loading_hook",
313 buffer.window.minibuffer.show("Done");
316 add_hook("current_content_buffer_status_change_hook",
317 function (buffer, request, status, msg) {
318 buffer.set_default_message(msg);
323 define_variable("read_url_handler_list", [],
324 "A list of handler functions which transform a typed url into a valid " +
325 "url or webjump. If the typed input is not valid then each function " +
326 "on this list is tried in turn. The handler function is called with " +
327 "a single string argument and it should return either a string or " +
328 "null. The result of the first function on the list that returns a " +
329 "string is used in place of the input.");
332 * read_url_make_default_webjump_handler returns a function that
333 * transforms any input into the given webjump. It should be the last
334 * handler on read_url_handler_list (because any input is
337 function read_url_make_default_webjump_handler (default_webjump
) {
338 return function (input
) {
339 return default_webjump
+ " " + input
;
344 * read_url_make_blank_url_handler returns a function that replaces a
345 * blank (empty) input with the given url (or webjump). The url may
346 * perform some function, eg. "javascript:location.reload()".
348 function read_url_make_blank_url_handler (url
) {
349 return function (input
) {
350 if (input
.length
== 0)
356 function try_read_url_handlers (input
) {
358 for (var i
= 0; i
< read_url_handler_list
.length
; ++i
) {
359 if ((result
= read_url_handler_list
[i
](input
)))
365 define_variable("url_completion_use_webjumps", true,
366 "Specifies whether URL completion should complete webjumps.");
368 define_variable("url_completion_use_bookmarks", true,
369 "Specifies whether URL completion should complete bookmarks.");
371 define_variable("url_completion_use_history", false,
372 "Specifies whether URL completion should complete using browser "+
375 define_variable("url_completion_sort_order", "visitcount_descending",
376 "Gives the default sort order for history and bookmark completion.\n"+
377 "The value is given as a string, and the available options include: "+
378 "'none', 'title_ascending', 'date_ascending', 'uri_ascending', "+
379 "'visitcount_ascending', 'keyword_ascending', 'dateadded_ascending', "+
380 "'lastmodified_ascending', 'tags_ascending', and 'annotation_ascending'. "+
381 "For every 'ascending' option, there is a corresponding 'descending' "+
382 "option. Additionally, with XULRunner 6 and later, the options "+
383 "'frecency_ascending' and 'frecency_descending' are available. See also "+
384 "<https://developer.mozilla.org/en/NsINavHistoryQueryOptions#Sorting_methods>.");
386 define_variable("minibuffer_read_url_select_initial", true,
387 "Specifies whether a URL presented in the minibuffer for editing "+
388 "should be selected. This affects find-alternate-url.");
391 minibuffer_auto_complete_preferences
["url"] = true;
392 minibuffer
.prototype.read_url = function () {
393 keywords(arguments
, $prompt
= "URL:", $history
= "url", $initial_value
= "",
394 $select
= minibuffer_read_url_select_initial
,
395 $use_webjumps
= url_completion_use_webjumps
,
396 $use_history
= url_completion_use_history
,
397 $use_bookmarks
= url_completion_use_bookmarks
,
398 $sort_order
= url_completion_sort_order
);
399 var completer
= new url_completer(
400 $use_webjumps
= arguments
.$use_webjumps
,
401 $use_bookmarks
= arguments
.$use_bookmarks
,
402 $use_history
= arguments
.$use_history
,
403 $sort_order
= arguments
.$sort_order
);
404 var result
= yield this.read(
405 $prompt
= arguments
.$prompt
,
406 $history
= arguments
.$history
,
407 $completer
= completer
,
408 $initial_value
= arguments
.$initial_value
,
409 $auto_complete
= "url",
410 $select
= arguments
.$select
,
411 $require_match
= false);
412 if (!possibly_valid_url(result
) && !get_webjump(result
))
413 result
= try_read_url_handlers(result
);
414 if (result
== "") // well-formedness check. (could be better!)
415 throw ("invalid url or webjump (\""+ result
+"\")");
416 yield co_return(load_spec(result
));
423 function overlink_update_status (buffer
, node
) {
424 if (node
&& node
.href
.length
> 0)
425 buffer
.window
.minibuffer
.show("Link: " + node
.href
);
427 buffer
.window
.minibuffer
.clear();
430 function overlink_predicate (node
) {
431 while (node
&& !(node
instanceof Ci
.nsIDOMHTMLAnchorElement
))
432 node
= node
.parentNode
;
436 function overlink_initialize (buffer
) {
437 buffer
.current_overlink
= null;
438 buffer
.overlink_mouseover = function (event
) {
439 if (buffer
!= buffer
.window
.buffers
.current
||
440 event
.target
== buffer
.browser
)
444 var node
= overlink_predicate(event
.target
);
446 buffer
.current_overlink
= event
.target
;
447 overlink_update_status(buffer
, node
);
450 buffer
.overlink_mouseout = function (event
) {
451 if (buffer
!= buffer
.window
.buffers
.current
)
453 if (buffer
.current_overlink
== event
.target
) {
454 buffer
.current_overlink
= null;
455 overlink_update_status(buffer
, null);
458 buffer
.browser
.addEventListener("mouseover", buffer
.overlink_mouseover
, true);
459 buffer
.browser
.addEventListener("mouseout", buffer
.overlink_mouseout
, true);
462 define_global_mode("overlink_mode",
464 add_hook("create_buffer_hook", overlink_initialize
);
465 for_each_buffer(overlink_initialize
);
467 function disable () {
468 remove_hook("create_buffer_hook", overlink_initialize
);
469 for_each_buffer(function (b
) {
470 b
.browser
.removeEventListener("mouseover", b
.overlink_mouseover
, true);
471 b
.browser
.removeEventListener("mouseout", b
.overlink_mouseout
, true);
472 delete b
.current_overlink
;
473 delete b
.overlink_mouseover
;
474 delete b
.overlink_mouseout
;
477 $doc
= "Overlink-mode is a programmable mode for showing information "+
478 "about DOM nodes (such as link URLs) in the minibuffer when "+
479 "hovering with the mouse.");
485 * Navigation Commands
487 function go_back (b
, prefix
) {
489 go_forward(b
, -prefix
);
491 check_buffer(b
, content_buffer
);
493 if (b
.web_navigation
.canGoBack
) {
494 var hist
= b
.web_navigation
.sessionHistory
;
495 var idx
= hist
.index
- prefix
;
498 b
.web_navigation
.gotoIndex(idx
);
500 throw interactive_error("Can't go back");
504 "Go back in the session history for the current buffer.",
505 function (I
) {go_back(I
.buffer
, I
.p
);});
508 function go_forward (b
, prefix
) {
512 check_buffer(b
, content_buffer
);
514 if (b
.web_navigation
.canGoForward
) {
515 var hist
= b
.web_navigation
.sessionHistory
;
516 var idx
= hist
.index
+ prefix
;
517 if (idx
>= hist
.count
) idx
= hist
.count
-1;
518 b
.web_navigation
.gotoIndex(idx
);
520 throw interactive_error("Can't go forward");
523 interactive("forward",
524 "Go forward in the session history for the current buffer.",
525 function (I
) {go_forward(I
.buffer
, I
.p
);});
528 function stop_loading (b
) {
529 check_buffer(b
, content_buffer
);
530 b
.web_navigation
.stop(Ci
.nsIWebNavigation
.STOP_NETWORK
);
533 interactive("stop-loading",
534 "Stop loading the current document.",
535 function (I
) {stop_loading(I
.buffer
);});
538 function reload (b
, bypass_cache
, element
, forced_charset
) {
539 check_buffer(b
, content_buffer
);
541 if (element
instanceof Ci
.nsIDOMHTMLImageElement
) {
543 var cache
= Cc
['@mozilla.org/image/cache;1']
544 .getService(Ci
.imgICache
);
545 cache
.removeEntry(make_uri(element
.src
));
548 element
.parentNode
.replaceChild(element
.cloneNode(true), element
);
549 } else if (b
.current_uri
.spec
!= b
.display_uri_string
) {
550 apply_load_spec(b
, load_spec({ uri
: b
.display_uri_string
,
551 forced_charset
: forced_charset
}));
553 var flags
= bypass_cache
== null ?
554 Ci
.nsIWebNavigation
.LOAD_FLAGS_NONE
:
555 Ci
.nsIWebNavigation
.LOAD_FLAGS_BYPASS_CACHE
;
557 if (! forced_charset
&& forced_charset_list
)
558 forced_charset
= predicate_alist_match(forced_charset_list
,
561 if (forced_charset
) {
563 var atomservice
= Cc
['@mozilla.org/atom-service;1']
564 .getService(Ci
.nsIAtomService
);
565 b
.web_navigation
.documentCharsetInfo
.forcedCharset
=
566 atomservice
.getAtom(forced_charset
);
569 b
.web_navigation
.reload(flags
);
573 interactive("reload",
574 "Reload the current document.\n" +
575 "If a prefix argument is specified, the cache is bypassed. If a "+
576 "DOM node is supplied via browser object, that node will be "+
579 check_buffer(I
.buffer
, content_buffer
);
580 var element
= yield read_browser_object(I
);
581 reload(I
.buffer
, I
.P
, element
, I
.forced_charset
|| null);
583 $browser_object
= null);
586 * browserDOMWindow: intercept window opening
588 function initialize_browser_dom_window (window
) {
589 window
.QueryInterface(Ci
.nsIDOMChromeWindow
).browserDOMWindow
=
590 new browser_dom_window(window
);
593 define_variable("browser_default_open_target", OPEN_NEW_BUFFER
,
594 "Specifies how new window requests by content pages (e.g. by "+
595 "window.open from JavaScript or by using the target attribute of "+
596 "anchor and form elements) will be handled. This will generally "+
597 "be `OPEN_NEW_BUFFER', `OPEN_NEW_BUFFER_BACKGROUND', or "+
598 "`OPEN_NEW_WINDOW'.");
601 function browser_dom_window (window
) {
602 this.window
= window
;
603 this.next_target
= null;
605 browser_dom_window
.prototype = {
606 constructor: browser_dom_window
,
607 QueryInterface
: generate_QI(Ci
.nsIBrowserDOMWindow
),
609 openURI: function (aURI
, aOpener
, aWhere
, aContext
) {
610 // Reference: http://www.xulplanet.com/references/xpcomref/ifaces/nsIBrowserDOMWindow.html
611 var target
= this.next_target
;
612 if (target
== null || target
== FOLLOW_DEFAULT
)
613 target
= browser_default_open_target
;
614 this.next_target
= null;
616 /* Determine the opener buffer */
617 var opener
= get_buffer_from_frame(this.window
, aOpener
);
619 switch (browser_default_open_target
) {
620 case OPEN_CURRENT_BUFFER
:
622 case FOLLOW_CURRENT_FRAME
:
624 case OPEN_NEW_BUFFER
:
625 var buffer
= new content_buffer(this.window
, $opener
= opener
);
626 this.window
.buffers
.current
= buffer
;
627 return buffer
.top_frame
;
628 case OPEN_NEW_BUFFER_BACKGROUND
:
629 var buffer
= new content_buffer(this.window
, $opener
= opener
);
630 return buffer
.top_frame
;
631 case OPEN_NEW_WINDOW
:
632 default: /* shouldn't be needed */
634 /* We don't call make_window here, because that will result
635 * in the URL being loaded as the top-level document,
636 * instead of within a browser buffer. Instead, we can
637 * rely on Mozilla using browser.chromeURL. */
638 window_set_extra_arguments(
639 {initial_buffer_creator
: buffer_creator(content_buffer
, $opener
= opener
)}
646 add_hook("window_initialize_early_hook", initialize_browser_dom_window
);
653 define_keywords("$test");
654 function page_mode (name
, enable
, disable
) {
656 buffer_mode
.call(this, name
, enable
, disable
,
657 forward_keywords(arguments
));
658 this.test
= make_array(arguments
.$test
);
660 page_mode
.prototype = {
661 constructor: page_mode
,
662 __proto__
: buffer_mode
.prototype,
664 enable: function (buffer
) {
665 buffer_mode
.prototype.enable
.call(this, buffer
);
666 buffer
.page_modes
.push(this.name
);
667 buffer
.set_input_mode();
670 disable: function (buffer
) {
671 buffer_mode
.prototype.disable
.call(this, buffer
);
672 var i
= buffer
.page_modes
.indexOf(this.name
);
674 buffer
.page_modes
.splice(i
, 1);
675 buffer
.set_input_mode();
679 function define_page_mode (name
, test
, enable
, disable
) {
680 keywords(arguments
, $constructor = page_mode
);
681 define_buffer_mode(name
, enable
, disable
,
683 forward_keywords(arguments
));
685 ignore_function_for_get_caller_source_code_reference("define_page_mode");
688 define_keywords("$modality");
689 function keymaps_page_mode (name
, enable
, disable
) {
691 page_mode
.call(this, name
, enable
, disable
,
692 forward_keywords(arguments
));
693 this.modality
= arguments
.$modality
;
695 keymaps_page_mode
.prototype = {
696 constructor: keymaps_page_mode
,
697 __proto__
: page_mode
.prototype,
699 _enable: function (buffer
) {
700 buffer
.content_modalities
.push(this.modality
);
702 _disable: function (buffer
) {
703 var i
= buffer
.content_modalities
.indexOf(this.modality
);
705 buffer
.content_modalities
.splice(i
, 1);
708 function define_keymaps_page_mode (name
, test
, modality
) {
709 keywords(arguments
, $constructor = keymaps_page_mode
);
710 define_buffer_mode(name
, null, null,
712 $modality
= modality
,
713 forward_keywords(arguments
));
715 ignore_function_for_get_caller_source_code_reference("define_keymaps_page_mode");
718 var active_page_modes
= [];
720 function page_mode_activate (page_mode
) {
721 var i
= active_page_modes
.indexOf(page_mode
.name
);
723 active_page_modes
.push(page_mode
.name
);
726 function page_mode_deactivate (page_mode
) {
727 var i
= active_page_modes
.indexOf(page_mode
.name
);
729 active_page_modes
.splice(i
, 1);
733 function page_mode_update (buffer
) {
734 for (var i
= buffer
.page_modes
.length
- 1; i
>= 0; --i
) {
735 var p
= buffer
.page_modes
[i
];
736 conkeror
[p
].disable(buffer
);
738 var uri
= buffer
.current_uri
;
739 for each (var name
in active_page_modes
) {
740 var m
= conkeror
[name
];
743 if (test
instanceof RegExp
) {
744 if (test
.exec(uri
.spec
))
745 return m
.enable(buffer
);
746 } else if (test(uri
))
747 return m
.enable(buffer
);
753 add_hook("content_buffer_location_change_hook", page_mode_update
);
755 provide("content-buffer");